package feieapi import ( "crypto/sha1" "fmt" "net/http" "strings" "time" "unicode" "git.rosy.net.cn/baseapi" "git.rosy.net.cn/baseapi/platformapi" "git.rosy.net.cn/baseapi/utils" ) const ( prodURL = "https://api.feieyun.cn/Api/Open/" signKey = "sig" ) const ( // ResponseCodeSuccess 操作成功 ResponseCodeSuccess = 0 ) const ( PrinterStatusStrOffline = "离线。" PrinterStatusStrOnlineOK = "在线,工作状态正常。" PrinterStatusStrOnlineAbnormal = "在线,工作状态不正常。" PrinterStatusUnknown = 0 PrinterStatusOffline = 1 PrinterStatusOnlineOK = 2 PrinterStatusOnlineAbnormal = 3 ) var ( printStatusMap = map[string]int{ PrinterStatusStrOffline: PrinterStatusOffline, PrinterStatusStrOnlineOK: PrinterStatusOnlineOK, PrinterStatusStrOnlineAbnormal: PrinterStatusOnlineAbnormal, } ) const ( ErrMsgAlredyAdded = "(错误:已被添加过)" ) 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(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) { if jsonResult1 == nil { return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil") } 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 map[string]string, 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"], true), interface2PrinterResultList4Add(resultMap["no"], false), nil } return nil, nil, err } func interface2PrinterResultList4Add(value interface{}, isOk bool) (printerResultMap map[string]string) { printerResultMap = make(map[string]string) for _, v := range value.([]interface{}) { strList := strings.Split(v.(string), "#") if len(strList) == 4 { if isOk { strList2 := strings.Split(strList[3], " ") if len(strList2) == 1 { strList2 = append(strList2, "") } printerResultMap[strList[0]] = strList2[1] } else { printerResultMap[strList[0]] = strList[3] } } } return printerResultMap } 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 { if result != nil { return result.(string), nil } err = fmt.Errorf("飞鹅sn:%s非正常的结果返回", sn) } return "", err } func (a *API) PrinterDelList(snList []string) (ok, no map[string]string, 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{}) (printerResultMap map[string]string) { printerResultMap = make(map[string]string) for _, v := range value.([]interface{}) { sn, errMsg := splitMsg(v.(string)) printerResultMap[sn] = errMsg } return printerResultMap } func splitMsg(msg string) (sn, errMsg string) { runeList := []rune(msg) index := 0 for ; index < len(runeList); index++ { if !unicode.Is(unicode.ASCII_Hex_Digit, runeList[index]) { break } } if index > 0 && index < len(runeList) { sn = string(runeList[:index]) errMsg = string(runeList[index:]) } return sn, errMsg } 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) (printed, waiting int, err error) { result, err := a.AccessAPI("Open_queryOrderInfoByDate", map[string]interface{}{ "sn": sn, "date": utils.Time2DateStr(date), }) if err == nil { resultMap := result.(map[string]interface{}) return int(utils.Interface2Int64WithDefault(resultMap["print"], 0)), int(utils.Interface2Int64WithDefault(resultMap["waiting"], 0)), nil } return 0, 0, err } func (a *API) QueryPrinterStatus(sn string) (status int, err error) { result, err := a.AccessAPI("Open_queryPrinterStatus", map[string]interface{}{ "sn": sn, }) if err == nil { return printStatusMap[result.(string)], nil } return PrinterStatusUnknown, err }