- mtwmapi

This commit is contained in:
gazebo
2018-11-22 10:21:16 +08:00
parent 5a43ff8e20
commit 684a104a25
14 changed files with 1044 additions and 0 deletions

View File

@@ -124,3 +124,10 @@ func TestGetProductStatust(t *testing.T) {
t.Fatal("GetProductStatus should return error")
}
}
func TestDelShopCategory(t *testing.T) {
err := jdapi.DelShopCategory(4784689)
if err != nil {
t.Fatal(err)
}
}

147
platformapi/mtwmapi/food.go Normal file
View File

@@ -0,0 +1,147 @@
package mtwmapi
import (
"time"
"git.rosy.net.cn/baseapi/utils"
)
type FoodCategoryInfo struct {
Name string `json:"name"`
Sequence int `json:"sequence"`
CTime time.Time `json:"ctime"`
UTime time.Time `json:"utime"`
}
func (a *API) FoodCatUpdate(poiCode, originName, name string, sequence int) (err error) {
params := map[string]interface{}{
KeyAppPoiCode: poiCode,
"category_name_origin": originName,
"sequence": sequence,
}
if name != "" {
params["category_name"] = name
}
_, err = a.AccessAPI("foodCat/update", false, params)
return err
}
func (a *API) FoodCatDelete(poiCode, name string) (err error) {
_, err = a.AccessAPI("foodCat/delete", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
"category_name": name,
})
return err
}
func (a *API) FoodInitData(poiCode, foodCode string, params map[string]interface{}) (err error) {
_, err = a.AccessAPI("food/initdata", false, utils.MergeMaps(map[string]interface{}{
KeyAppPoiCode: poiCode,
KeyAppFoodCode: foodCode,
}, params))
return err
}
func (a *API) FoodDelete(poiCode, foodCode string) (err error) {
_, err = a.AccessAPI("food/delete", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
KeyAppFoodCode: foodCode,
})
return err
}
// offset 从0开始limit最大不能超过200
func (a *API) FoodList(poiCode string, offset, limit int) (foodList []map[string]interface{}, err error) {
result, err := a.AccessAPI("food/list", true, map[string]interface{}{
KeyAppPoiCode: poiCode,
"offset": offset,
"limit": limit,
})
if err == nil {
return utils.Slice2MapSlice(result.([]interface{})), nil
}
return nil, err
}
func (a *API) FoodBatchInitData(poiCode string, foodData map[string]interface{}) (err error) {
_, err = a.AccessAPI("food/batchinitdata", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
"food_data": foodData,
})
return err
}
func (a *API) FoodCatList(poiCode string) (foodCatList []*FoodCategoryInfo, err error) {
result, err := a.AccessAPI("foodCat/list", true, map[string]interface{}{
KeyAppPoiCode: poiCode,
})
if err == nil {
catListTmp := result.([]interface{})
foodCatList = make([]*FoodCategoryInfo, len(catListTmp))
for k, v := range catListTmp {
cat := v.(map[string]interface{})
foodCatList[k] = &FoodCategoryInfo{
Name: utils.Interface2String(cat["name"]),
Sequence: int(utils.MustInterface2Int64(cat["sequence"])),
CTime: time.Unix(utils.MustInterface2Int64(cat["ctime"]), 0),
UTime: time.Unix(utils.MustInterface2Int64(cat["utime"]), 0),
}
}
return foodCatList, nil
}
return nil, err
}
func (a *API) FoodSkuSave(poiCode, foodCode string, skus []map[string]interface{}) (err error) {
_, err = a.AccessAPI("food/sku/save", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
KeyAppFoodCode: foodCode,
"skus": skus,
})
return err
}
func (a *API) FoodSkuDelete(poiCode, foodCode, skuID string) (err error) {
_, err = a.AccessAPI("food/sku/delete", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
KeyAppFoodCode: foodCode,
"sku_id": skuID,
})
return err
}
func (a *API) FoodSkuPrice(poiCode string, foodData []map[string]interface{}) (err error) {
_, err = a.AccessAPI("food/sku/price", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
"food_data": foodData,
})
return err
}
func (a *API) FoodSkuStock(poiCode string, foodData []map[string]interface{}) (err error) {
_, err = a.AccessAPI("food/sku/stock", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
"food_data": foodData,
})
return err
}
func (a *API) FoodGet(poiCode, foodCode string) (food map[string]interface{}, err error) {
result, err := a.AccessAPI("food/get", true, map[string]interface{}{
KeyAppPoiCode: poiCode,
KeyAppFoodCode: foodCode,
})
if err == nil {
return result.(map[string]interface{}), nil
}
return nil, err
}
func (a *API) FoodSkuSellStatus(poiCode string, foodData []map[string]interface{}, status int) (err error) {
_, err = a.AccessAPI("food/sku/sellStatus", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
"food_data": foodData,
"status": status,
})
return err
}

View File

@@ -0,0 +1,16 @@
package mtwmapi
import (
"testing"
)
func TestFoodList(t *testing.T) {
result, err := api.FoodList(testPoiCode, 0, 200)
if err != nil {
t.Fatal(err)
}
if len(result) == 0 {
t.Fatal("should have food")
}
// t.Log(result)
}

View File

@@ -0,0 +1,143 @@
package mtwmapi
import (
"bytes"
"crypto/md5"
"fmt"
"mime/multipart"
"net/http"
"net/url"
"sort"
"strings"
"time"
"git.rosy.net.cn/baseapi/platformapi"
"git.rosy.net.cn/baseapi/utils"
)
const (
apiURL = "https://waimaiopen.meituan.com/api/v1"
sandboxAPIURL = "http://openapi.b.waimai.test.sankuai.com/api/v1"
signKey = "sig"
)
const (
KeyAppPoiCode = "app_poi_code"
KeyAppPoiCodes = "app_poi_codes"
KeyAppFoodCode = "app_food_code"
KeyImgName = "img_name"
KeyImgData = "img_data"
KeyOrderID = "order_id"
)
const (
GeneralMaxLimit = 200 // 大多数的API的批处理最大条数
)
type API struct {
appID string
secret string
client *http.Client
config *platformapi.APIConfig
}
func New(appID, secret string, config ...*platformapi.APIConfig) *API {
curConfig := platformapi.DefAPIConfig
if len(config) > 0 {
curConfig = *config[0]
}
return &API{
appID: appID,
secret: secret,
client: &http.Client{Timeout: curConfig.ClientTimeout},
config: &curConfig,
}
}
func (a *API) genURL(cmd string) string {
return apiURL + "/" + cmd
}
func (a *API) signParams(cmd string, params map[string]interface{}) string {
keys := make([]string, 0)
for k := range params {
if k != signKey {
keys = append(keys, k)
}
}
sort.Strings(keys)
finalStr := a.genURL(cmd) + "?"
kvPaires := make([]string, len(keys))
for k, key := range keys {
if params[key] != nil {
kvPaires[k] = key + "=" + fmt.Sprintf("%v", params[key])
}
}
finalStr += strings.Join(kvPaires, "&") + a.secret
// baseapi.SugarLogger.Debug(finalStr)
return fmt.Sprintf("%x", md5.Sum([]byte(finalStr)))
}
func (a *API) AccessAPI(cmd string, isGet bool, bizParams map[string]interface{}) (retVal interface{}, err error) {
params := make(map[string]interface{})
params["timestamp"] = time.Now().Unix()
params["app_id"] = a.appID
params = utils.MergeMaps(params, bizParams)
imgData := params[KeyImgData]
if imgData != nil {
delete(params, KeyImgData)
}
params[signKey] = a.signParams(cmd, params)
err = platformapi.AccessPlatformAPIWithRetry(a.client,
func() *http.Request {
var request *http.Request
if isGet {
fullURL := utils.GenerateGetURL(apiURL, cmd, params)
// baseapi.SugarLogger.Debug(fullURL)
request, _ = http.NewRequest(http.MethodGet, fullURL, nil)
} else {
fullURL := a.genURL(cmd)
// baseapi.SugarLogger.Debug(utils.Map2URLValues(params).Encode())
if imgData == nil {
request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(utils.Map2URLValues(params).Encode()))
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
} else {
var b bytes.Buffer
w := multipart.NewWriter(&b)
if fw, err := w.CreateFormFile("file", params[KeyImgName].(string)); err != nil {
panic(err.Error())
} else {
fw.Write(imgData.([]byte))
}
for k, v := range params {
fmt.Println(k, " ", v)
w.WriteField(k, url.QueryEscape(fmt.Sprint(v)))
}
w.Close()
// b.WriteString(utils.Map2URLValues(params).Encode())
request, _ = http.NewRequest(http.MethodPost, fullURL, &b)
request.Header.Set("Content-Type", w.FormDataContentType())
}
request.Header.Set("charset", "UTF-8")
}
// request.Close = true //todo 为了性能考虑还是不要关闭
return request
},
a.config,
func(response *http.Response) (errLevel string, err error) {
jsonResult1, err := utils.HTTPResponse2Json(response)
// baseapi.SugarLogger.Debug(utils.Format4Output(jsonResult1, false))
if err != nil {
return platformapi.ErrLevelGeneralFail, platformapi.ErrResponseDataFormatWrong
}
if _, ok := jsonResult1["error"]; ok {
errorInfo := jsonResult1["error"].(map[string]interface{})
newErr := utils.NewErrorIntCode(errorInfo["msg"].(string), int(utils.MustInterface2Int64(errorInfo["code"])))
return platformapi.ErrLevelCodeIsNotOK, newErr
}
retVal = jsonResult1["data"]
return platformapi.ErrLevelSuccess, nil
})
return retVal, err
}

View File

@@ -0,0 +1,30 @@
package mtwmapi
import (
"testing"
"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("589", "a81eb3df418d83d6a1a4b7c572156d2f")
}
func TestAccessAPI(t *testing.T) {
result, err := api.AccessAPI("poi/getids", true, nil)
if err != nil {
t.Fatal(err)
}
t.Log(utils.Format4Output(result, false))
}

View File

@@ -0,0 +1,125 @@
package mtwmapi
import (
"git.rosy.net.cn/baseapi/utils"
)
const (
MaxBatchPullPhoneNumberLimit = 1000
)
func (a *API) OrderReceived(orderID int64) (err error) {
_, err = a.AccessAPI("order/poi_received", true, map[string]interface{}{
KeyOrderID: orderID,
})
return err
}
func (a *API) OrderConfirm(orderID int64) (err error) {
_, err = a.AccessAPI("order/confirm", true, map[string]interface{}{
KeyOrderID: orderID,
})
return err
}
func (a *API) OrderCancel(orderID int64) (err error) {
_, err = a.AccessAPI("order/cancel", true, map[string]interface{}{
KeyOrderID: orderID,
})
return err
}
func (a *API) OrderDelivering(orderID int64) (err error) {
_, err = a.AccessAPI("order/delivering", true, map[string]interface{}{
KeyOrderID: orderID,
})
return err
}
func (a *API) OrderArrived(orderID int64) (err error) {
_, err = a.AccessAPI("order/arrived", true, map[string]interface{}{
KeyOrderID: orderID,
})
return err
}
func (a *API) OrderRefundAgree(orderID int64, reason string) (err error) {
_, err = a.AccessAPI("order/refund/agree", true, map[string]interface{}{
KeyOrderID: orderID,
"reason": reason,
})
return err
}
func (a *API) OrderRefundReject(orderID int64, reason string) (err error) {
_, err = a.AccessAPI("order/refund/reject", true, map[string]interface{}{
KeyOrderID: orderID,
"reason": reason,
})
return err
}
func (a *API) OrderViewStatus(orderID int64) (status int, err error) {
result, err := a.AccessAPI("order/viewstatus", true, map[string]interface{}{
KeyOrderID: orderID,
})
if err == nil {
// baseapi.SugarLogger.Debug(result)
return int(utils.MustInterface2Int64(result.(map[string]interface{})["status"])), nil
}
return 0, err
}
func (a *API) OrderGetOrderDetail(orderID int64, isMTLogistics bool) (orderInfo map[string]interface{}, err error) {
params := map[string]interface{}{
KeyOrderID: orderID,
}
if isMTLogistics {
params["is_mt_logistics"] = 1
}
result, err := a.AccessAPI("order/getOrderDetail", true, params)
if err == nil {
return result.(map[string]interface{}), nil
}
return nil, err
}
func (a *API) OrderLogisticsPush(orderID int64, reason string) (err error) {
_, err = a.AccessAPI("order/logistics/push", true, map[string]interface{}{
KeyOrderID: orderID,
})
return err
}
func (a *API) OrderLogisticsCancel(orderID int64, reason string) (err error) {
_, err = a.AccessAPI("order/logistics/cancel", true, map[string]interface{}{
KeyOrderID: orderID,
})
return err
}
func (a *API) OrderLogisticsStatus(orderID int64) (status map[string]interface{}, err error) {
result, err := a.AccessAPI("order/logistics/status", true, map[string]interface{}{
KeyOrderID: orderID,
})
if err == nil {
return result.(map[string]interface{}), nil
}
return nil, err
}
// limit最大为MaxBatchPullPhoneNumberLimit = 1000
func (a *API) OrderBatchPullPhoneNumber(poiCode string, offset, limit int) (realNumberList []map[string]interface{}, err error) {
params := map[string]interface{}{
"offset": offset,
"limit": limit,
}
if poiCode != "" {
params[KeyAppPoiCode] = poiCode
}
result, err := a.AccessAPI("order/batchPullPhoneNumber", false, params)
if err == nil {
return utils.Slice2MapSlice(result.([]interface{})), nil
}
return nil, err
}

View File

@@ -0,0 +1,13 @@
package mtwmapi
import (
"testing"
)
func TestOrderViewStatus(t *testing.T) {
result, err := api.OrderViewStatus(9)
if err != nil {
t.Fatal(err)
}
t.Log(result)
}

135
platformapi/mtwmapi/poi.go Normal file
View File

@@ -0,0 +1,135 @@
package mtwmapi
import (
"io/ioutil"
"net/http"
"strings"
"git.rosy.net.cn/baseapi/platformapi"
"git.rosy.net.cn/baseapi/utils"
)
type PoiCategoryInfo struct {
ID int `json:"id"`
Name string `json:"name"`
}
func (a *API) PoiSave(poiCode string, poiParams map[string]interface{}) (err error) {
_, err = a.AccessAPI("poi/save", false, utils.MergeMaps(utils.Params2Map(KeyAppPoiCode, poiCode), poiParams))
return err
}
func (a *API) PoiGetIDs() (ids []string, err error) {
result, err := a.AccessAPI("poi/getids", true, nil)
if err == nil {
idsTmp := result.([]interface{})
ids = make([]string, len(idsTmp))
for k, v := range idsTmp {
ids[k] = v.(string)
}
return ids, nil
}
return nil, err
}
func (a *API) PoiMGet(poiCodes []string) (pois []map[string]interface{}, err error) {
result, err := a.AccessAPI("poi/mget", true, map[string]interface{}{
KeyAppPoiCodes: strings.Join(poiCodes, ","),
})
if err == nil {
return utils.Slice2MapSlice(result.([]interface{})), nil
}
return nil, err
}
func (a *API) PoiGet(poiCode string) (poi map[string]interface{}, err error) {
result, err := a.PoiMGet([]string{poiCode})
if err == nil {
return result[0], nil
}
return nil, err
}
func (a *API) PoiClose(poiCode string) (err error) {
_, err = a.AccessAPI("poi/close", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
})
return err
}
func (a *API) PoiOnline(poiCode string) (err error) {
_, err = a.AccessAPI("poi/online", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
})
return err
}
func (a *API) PoiUpdatePromoteInfo(poiCode, promotionInfo string) (err error) {
_, err = a.AccessAPI("poi/updatepromoteinfo", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
"promotion_info": promotionInfo,
})
return err
}
func (a *API) PoiTagList(poiCode string) (catList []*PoiCategoryInfo, err error) {
result, err := a.AccessAPI("poiTag/list", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
})
if err == nil {
catListTmp := result.([]interface{})
catList = make([]*PoiCategoryInfo, len(catListTmp))
for k, v := range catListTmp {
cat := v.(map[string]interface{})
catList[k] = &PoiCategoryInfo{
ID: int(utils.MustInterface2Int64(cat["id"])),
Name: utils.Interface2String(cat["name"]),
}
}
return catList, nil
}
return nil, err
}
func (a *API) PoiShipTimeUpdate(poiCode string, beginTime1, endTime1, beginTime2, endTime2 string) (err error) {
shippingTime := beginTime1 + "-" + endTime1
if beginTime2 != "" {
shippingTime += "," + beginTime2 + "-" + endTime2
}
_, err = a.AccessAPI("poi/updatepromoteinfo", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
"shipping_time": shippingTime,
})
return err
}
// 美团要求必须是jpg|jpeg图片格式且imgName必须以jpg或jpeg结尾
func (a *API) ImageUpload(poiCode, imgName string, imgData []byte) (imgID string, err error) {
result, err := a.AccessAPI("image/upload", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
KeyImgName: imgName,
KeyImgData: imgData,
})
if err == nil {
return result.(string), nil
}
return "", err
}
func (a *API) ImageUploadByURL(poiCode, imgName, imgURL string) (imgID string, err error) {
response, err := http.Get(imgURL)
if err == nil {
defer func() {
response.Body.Close()
}()
if response.StatusCode == http.StatusOK {
bodyData, err2 := ioutil.ReadAll(response.Body)
if err = err2; err == nil {
return a.ImageUpload(poiCode, imgName, bodyData)
}
} else {
err = platformapi.ErrHTTPCodeIsNot200
}
}
return "", err
}

View File

@@ -0,0 +1,71 @@
package mtwmapi
import (
"testing"
"git.rosy.net.cn/baseapi/utils"
)
const (
testPoiCode = "test_poi_01"
)
func TestPoiGetIDs(t *testing.T) {
result, err := api.PoiGetIDs()
if err != nil {
t.Fatal(err)
}
if len(result) == 0 {
t.Fatal("should have ids")
}
// t.Log(result)
}
func TestPoiMGet(t *testing.T) {
result, err := api.PoiMGet([]string{testPoiCode})
if err != nil {
t.Fatal(err)
}
if len(result) != 1 {
t.Fatal("result len is not ok")
}
if result[0][KeyAppPoiCode] != testPoiCode {
t.Fatal("test_poi_01 is not equal")
}
t.Log(utils.Format4Output(result, false))
}
func TestPoiSave(t *testing.T) {
result, err := api.PoiMGet([]string{testPoiCode})
if err != nil {
t.Fatal(err)
}
poiParams := utils.FilterMapNilMembers(result[0])
poiParams["name"] = "中国"
err = api.PoiSave(testPoiCode, poiParams)
if err != nil {
t.Fatal(err)
}
}
func TestPoiTagList(t *testing.T) {
result, err := api.PoiTagList(testPoiCode)
if err != nil {
t.Fatal(err)
}
if len(result) == 0 {
t.Fatal("should have cats")
}
t.Log(utils.Format4Output(result, false))
}
func TestImageUploadByURL(t *testing.T) {
result, err := api.ImageUploadByURL(testPoiCode, "hello.jpg", "http://image.jxc4.com/56cd1e88ada3660f37548c2d29ea2158.jpg")
if err != nil {
t.Fatal(err)
}
if len(result) == 0 {
t.Fatal("should have result")
}
t.Log(result)
}

View File

@@ -0,0 +1,207 @@
package mtwmapi
import (
"strings"
"git.rosy.net.cn/baseapi/utils"
)
type RetailCategoryInfo struct {
Name string `json:"name"`
Sequence int `json:"sequence"`
Level int `json:"level"`
Children []*RetailCategoryInfo `json:"children"`
}
// 美团分类没有ID就以名字为唯一标识不论级别都必须不能重名
// name和originName的长度不能超过10个字符字符不是字节
// 首次创建分类时如果secondaryName不为空会把一级如果不存在及二级分类创建起来
// 如果一级分类已经存在时要创建二级分类则要求originName与name都不为空且值是一样的
// 大概逻辑是:
// 如果originName不存在则是创建一级分类如果secondaryName相应还要创建二级分类此时的sequence指的是二级的一级的sequence就没有指定了
// 如果originName存在则指的是更新一级分类就必须存在如果不想改名将name填成与originName一样的即可
// todo 但这个函数好像就无法实现变更二级分类的名字及sequence
func (a *API) RetailCatUpdate(poiCode, originName, name, secondaryName string, sequence int) (err error) {
params := map[string]interface{}{
KeyAppPoiCode: poiCode,
"category_name": name,
"sequence": sequence,
}
if originName != "" {
params["category_name_origin"] = originName
}
if secondaryName != "" {
params["secondary_category_name"] = secondaryName
}
_, err = a.AccessAPI("retailCat/update", false, params)
return err
}
func (a *API) RetailCatDelete(poiCode, name string) (err error) {
_, err = a.AccessAPI("retailCat/delete", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
"category_name": name,
})
return err
}
func (a *API) RetailCatList(poiCode string) (retailCatList []*RetailCategoryInfo, err error) {
result, err := a.AccessAPI("retailCat/list", true, map[string]interface{}{
KeyAppPoiCode: poiCode,
})
if err == nil {
return interface2CatList(result, 1, nil), nil
}
return nil, err
}
func (a *API) RetailInitData(poiCode, foodCode string, params map[string]interface{}) (err error) {
_, err = a.AccessAPI("retail/initdata", false, utils.MergeMaps(map[string]interface{}{
KeyAppPoiCode: poiCode,
KeyAppFoodCode: foodCode,
}, params))
return err
}
// offset 从0开始limit最大不能超过200
func (a *API) RetailList(poiCode string, offset, limit int) (foodList []map[string]interface{}, err error) {
result, err := a.AccessAPI("retail/list", true, map[string]interface{}{
KeyAppPoiCode: poiCode,
"offset": offset,
"limit": limit,
})
if err == nil {
return utils.Slice2MapSlice(result.([]interface{})), nil
}
return nil, err
}
func (a *API) RetailBatchInitData(poiCode string, foodData map[string]interface{}) (err error) {
_, err = a.AccessAPI("retail/batchinitdata", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
"food_data": string(utils.MustMarshal(foodData)),
})
return err
}
func (a *API) RetailSkuPrice(poiCode string, foodData []map[string]interface{}) (err error) {
_, err = a.AccessAPI("retail/sku/price", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
"food_data": foodData,
})
return err
}
func (a *API) RetailSkuStock(poiCode string, foodData []map[string]interface{}) (err error) {
_, err = a.AccessAPI("retail/sku/stock", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
"food_data": foodData,
})
return err
}
func (a *API) RetailGet(poiCode, foodCode string) (food map[string]interface{}, err error) {
result, err := a.AccessAPI("retail/get", true, map[string]interface{}{
KeyAppPoiCode: poiCode,
KeyAppFoodCode: foodCode,
})
if err == nil {
return result.(map[string]interface{}), nil
}
return nil, err
}
func (a *API) RetailSkuSave(poiCode, foodCode string, standardSkus, unstandardSkus []map[string]interface{}) (err error) {
_, err = a.AccessAPI("retail/sku/save", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
KeyAppFoodCode: foodCode,
"standard_skus": standardSkus,
"unstandard_skus": unstandardSkus,
})
return err
}
func (a *API) RetailSkuSellStatus(poiCode string, foodData []map[string]interface{}, status int) (err error) {
_, err = a.AccessAPI("retail/sku/sellStatus", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
"food_data": foodData,
"status": status,
})
return err
}
func (a *API) RetailDelete(poiCode, foodCode string) (err error) {
_, err = a.AccessAPI("retail/delete", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
KeyAppFoodCode: foodCode,
})
return err
}
func (a *API) RetailSkuDelete(poiCode, foodCode, skuID string) (err error) {
_, err = a.AccessAPI("retail/sku/delete", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
KeyAppFoodCode: foodCode,
"sku_id": skuID,
})
return err
}
// 就是厂商商品类别
func (a *API) RetailGetSpTagIds() (tagIds []map[string]interface{}, err error) {
result, err := a.AccessAPI("retail/getSpTagIds", true, nil)
if err == nil {
return utils.Slice2MapSlice(result.([]interface{})), nil
}
return nil, err
}
// 此接口将申请授权后方可接入
func (a *API) RetailCatSkuBatchDelete(poiCode string, catNames []string, secondaryCatNames []string, foodCodes []string) (err error) {
params := map[string]interface{}{
KeyAppPoiCode: poiCode,
}
if len(catNames) > 0 {
params["category_names"] = strings.Join(catNames, ",")
}
if len(secondaryCatNames) > 0 {
params["secondary_category_names"] = strings.Join(secondaryCatNames, ",")
}
if len(foodCodes) > 0 {
params["app_food_codes"] = strings.Join(foodCodes, ",")
}
_, err = a.AccessAPI("retailCat/batchdelete/catandretail", false, params)
return err
}
//////////////////////
// 私有辅助函数
func interface2Cat(data interface{}, level int) (cat *RetailCategoryInfo) {
mapData, ok := data.(map[string]interface{})
if ok {
cat = &RetailCategoryInfo{
Name: utils.Interface2String(mapData["name"]),
Sequence: int(utils.Interface2Int64WithDefault(mapData["sequence"], 0)),
Level: level,
}
children := mapData["children"]
if children != nil {
cat.Children = interface2CatList(children, level+1, nil)
}
}
return cat
}
func interface2CatList(data interface{}, level int, interface2CatHandler func(data interface{}, level int) (cat *RetailCategoryInfo)) (cats []*RetailCategoryInfo) {
if interface2CatHandler == nil {
interface2CatHandler = interface2Cat
}
maps, ok := data.([]interface{})
if ok {
cats = make([]*RetailCategoryInfo, len(maps))
for index, v := range maps {
cats[index] = interface2CatHandler(v, level)
}
}
return cats
}

View File

@@ -0,0 +1,69 @@
package mtwmapi
import (
"testing"
"git.rosy.net.cn/baseapi/utils"
)
func TestRetailCatList(t *testing.T) {
result, err := api.RetailCatList(testPoiCode)
if err != nil {
t.Fatal(err)
}
t.Log(utils.Format4Output(result, false))
}
func TestRetailCatUpdate(t *testing.T) {
// err := api.RetailCatUpdate(testPoiCode, "测试一级类别", "测试一级类别2", "", 2)
err := api.RetailCatUpdate(testPoiCode, "测试一级类别", "测试一级类别", "", 2)
if err != nil {
t.Fatal(err)
}
}
func TestRetailCatDelete(t *testing.T) {
var err error
err = api.RetailCatDelete(testPoiCode, utils.GetUpperUUID())
if err == nil {
t.Fatal("should return error that can not find such cat")
}
uniqueCatName := "一二三四五六七八九十"
// uniqueCatName := "1234567890" //fmt.Sprintf("CAT%d", time.Now().Unix())
err = api.RetailCatUpdate(testPoiCode, "", uniqueCatName, "", 15)
if err != nil {
t.Fatal(err)
}
err = api.RetailCatDelete(testPoiCode, uniqueCatName)
if err != nil {
t.Fatal(err)
}
}
func TestRetailList(t *testing.T) {
result, err := api.RetailList(testPoiCode, 0, GeneralMaxLimit)
if err != nil {
t.Fatal(err)
}
if len(result) == 0 {
t.Fatal("should have items")
}
// t.Log(utils.Format4Output(result, false))
}
func TestRetailGetSpTagIds(t *testing.T) {
result, err := api.RetailGetSpTagIds()
if err != nil {
t.Fatal(err)
}
if len(result) == 0 {
t.Fatal("should have items")
}
// t.Log(utils.Format4Output(result, false))
}
func TestRetailCatSkuBatchDelete(t *testing.T) {
err := api.RetailCatSkuBatchDelete(testPoiCode, []string{"测试一级类别"}, nil, nil)
if err != nil {
t.Fatal(err)
}
}

View File

@@ -0,0 +1,42 @@
package mtwmapi
import "git.rosy.net.cn/baseapi/utils"
const (
PoiOpenLevelNormal = 1
PoiOpenLevelHaveRest = 3
PoiOnline = 1
PoiOffline = 0
)
func (a *API) ShippingSave(poiCode string, area string, minPrice, shippingFee float32) (err error) {
_, err = a.AccessAPI("shipping/save", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
"app_shipping_code": 1,
"type": 1,
"area": area,
"min_price": minPrice,
"shipping_fee": shippingFee,
})
return err
}
func (a *API) ShippingList(poiCode string) (shippingList []map[string]interface{}, err error) {
result, err := a.AccessAPI("shipping/list", true, map[string]interface{}{
KeyAppPoiCode: poiCode,
})
if err == nil {
return utils.Slice2MapSlice(result.([]interface{})), nil
}
return nil, err
}
func (a *API) ShippingFetch(poiCode string) (shippingList []map[string]interface{}, err error) {
result, err := a.AccessAPI("shipping/fetch", true, map[string]interface{}{
KeyAppPoiCode: poiCode,
})
if err == nil {
return utils.Slice2MapSlice(result.([]interface{})), nil
}
return nil, err
}

View File

@@ -0,0 +1,30 @@
package mtwmapi
import (
"testing"
"git.rosy.net.cn/baseapi/utils"
)
func TestShippingSave(t *testing.T) {
err := api.ShippingSave(testPoiCode, `[{"x":39941199,"y":116385384},{"x":39926983,"y":116361694},{"x":39921586,"y":116398430}]`, 0, 0)
if err != nil {
t.Fatal(err)
}
}
func TestShippingList(t *testing.T) {
result, err := api.ShippingList(testPoiCode)
if err != nil {
t.Fatal(err)
}
t.Log(utils.Format4Output(result, false))
}
func TestShippingFetch(t *testing.T) {
result, err := api.ShippingFetch(testPoiCode)
if err != nil {
t.Fatal(err)
}
t.Log(utils.Format4Output(result, false))
}