465 lines
19 KiB
Go
465 lines
19 KiB
Go
package mtwmapi
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"git.rosy.net.cn/baseapi/platformapi"
|
|
"git.rosy.net.cn/baseapi/utils"
|
|
)
|
|
|
|
const (
|
|
userURL = "http://i.waimai.meituan.com"
|
|
orderURL = "https://shangoue.meituan.com"
|
|
actURL = "https://waimaieapp.meituan.com"
|
|
)
|
|
|
|
const (
|
|
ResponseCodeSuccess = 0
|
|
)
|
|
|
|
type ListShopItem struct {
|
|
Address string `json:"address"`
|
|
AveragePriceTip string `json:"averagePriceTip"`
|
|
DeliveryTimeTip string `json:"deliveryTimeTip"`
|
|
DeliveryType int `json:"deliveryType"`
|
|
Distance string `json:"distance"`
|
|
MinPriceTip string `json:"minPriceTip"`
|
|
MonthSalesTip string `json:"monthSalesTip"`
|
|
MtWmPoiID string `json:"mtWmPoiId"`
|
|
PicURL string `json:"picUrl"`
|
|
PoiTypeIcon string `json:"poiTypeIcon"`
|
|
ShippingFeeTip string `json:"shippingFeeTip"`
|
|
ShippingTime string `json:"shipping_time"`
|
|
ShopName string `json:"shopName"`
|
|
Status int `json:"status"`
|
|
StatusDesc string `json:"statusDesc"`
|
|
WmPoiScore int `json:"wmPoiScore"`
|
|
}
|
|
|
|
var (
|
|
actionHostMap = map[string]string{
|
|
"v2/order/receive/processed/w/distribute/tipAmount/v2": orderURL,
|
|
"v2/order/receive/processed/r/distribute/list/v2": orderURL,
|
|
"reuse/sc/product/packageprice/w/update": orderURL,
|
|
"reuse/sc/product/packageprice/r/get": orderURL,
|
|
"reuse/sc/product/retail/r/getStandardProductListWithCond": orderURL,
|
|
"api/sg/promotion/invite/centerList": actURL,
|
|
"api/invite/detail": actURL,
|
|
"v2/logon/setToken": orderURL,
|
|
"reuse/sc/product/retail/r/searchListPage": orderURL,
|
|
}
|
|
)
|
|
|
|
func getRootURL(subURL string) (rootURL string) {
|
|
rootURL = actionHostMap[subURL]
|
|
if rootURL == "" {
|
|
rootURL = userURL
|
|
}
|
|
return rootURL
|
|
}
|
|
|
|
func (a *API) AccessUserPage2(subURL string, params map[string]interface{}, isPost bool) (retVal map[string]interface{}, err error) {
|
|
if a.GetCookieCount() == 0 {
|
|
return nil, fmt.Errorf("需要设置User Cookie才能使用此方法")
|
|
}
|
|
rootURL := getRootURL(subURL)
|
|
err = platformapi.AccessPlatformAPIWithRetry(a.client,
|
|
func() *http.Request {
|
|
var request *http.Request
|
|
if isPost {
|
|
fullURL := utils.GenerateGetURL(rootURL, subURL, nil)
|
|
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.Header.Set("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1")
|
|
request.Header.Set("Pragma", "no-cache")
|
|
if subURL == `reuse/sc/product/retail/r/searchListPage` {
|
|
//request.Header.Set("")
|
|
}
|
|
} else {
|
|
request, _ = http.NewRequest(http.MethodGet, utils.GenerateGetURL(rootURL, subURL, params), nil)
|
|
}
|
|
a.FillRequestCookies(request)
|
|
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")
|
|
}
|
|
retVal = jsonResult1
|
|
if jsonResult1["code"] == nil {
|
|
return platformapi.ErrLevelGeneralFail, fmt.Errorf("返回结果格式不正常")
|
|
}
|
|
code := int(utils.MustInterface2Int64(jsonResult1["code"]))
|
|
if code == ResponseCodeSuccess {
|
|
retVal, _ = jsonResult1["data"].(map[string]interface{})
|
|
return platformapi.ErrLevelSuccess, nil
|
|
}
|
|
newErr := utils.NewErrorIntCode(jsonResult1["msg"].(string), code)
|
|
return platformapi.ErrLevelCodeIsNotOK, newErr
|
|
})
|
|
return retVal, err
|
|
}
|
|
|
|
func (a *API) AccessUserPage(subURL string, params map[string]interface{}) (retVal map[string]interface{}, err error) {
|
|
return a.AccessUserPage2(subURL, params, true)
|
|
}
|
|
|
|
func (a *API) AccessUserPage3(subURL string, params map[string]interface{}) (retVal map[string]interface{}, err error) {
|
|
return a.AccessUserPage2(subURL, params, false)
|
|
}
|
|
|
|
func (a *API) GetStoreList(lng, lat float64) (shopList []*ListShopItem, err error) {
|
|
params := map[string]interface{}{
|
|
"sortId": 1,
|
|
"navigateType": 101578,
|
|
"firstCategoryId": 101578,
|
|
"secondCategoryId": 101578,
|
|
"initialLng": lng,
|
|
"initialLat": lat,
|
|
"geoType": 2,
|
|
"wm_longitude": int(lng * 1000000),
|
|
"wm_latitude": int(lat * 1000000),
|
|
}
|
|
startIndex := 0
|
|
for {
|
|
params["startIndex"] = startIndex
|
|
result, err := a.AccessUserPage("openh5/channel/kingkongshoplist", params)
|
|
if err != nil {
|
|
return shopList, err
|
|
}
|
|
var batchShopList []*ListShopItem
|
|
if err = utils.Map2StructByJson(result["shopList"], &batchShopList, false); err != nil {
|
|
return shopList, err
|
|
}
|
|
shopList = append(shopList, batchShopList...)
|
|
if poiHasNextPage, ok := result["poiHasNextPage"].(bool); !ok || !poiHasNextPage {
|
|
break
|
|
}
|
|
startIndex++
|
|
}
|
|
return shopList, nil
|
|
}
|
|
|
|
func (a *API) GetStoreInfo(storeID string) (storeInfo map[string]interface{}, err error) {
|
|
params := map[string]interface{}{
|
|
"mtWmPoiId": storeID,
|
|
}
|
|
retVal, err := a.AccessUserPage("openh5/poi/info", params)
|
|
return retVal, err
|
|
}
|
|
|
|
type GetStandardProductListWithCondResult struct {
|
|
IsMedicare bool `json:"isMedicare"`
|
|
SpVideoVo interface{} `json:"spVideoVo"`
|
|
LockStatus int `json:"lockStatus"`
|
|
LockTips interface{} `json:"lockTips"`
|
|
SpPicContent string `json:"spPicContent"`
|
|
ExistInPoi bool `json:"existInPoi"`
|
|
MonthSale int `json:"monthSale"`
|
|
Skus []struct {
|
|
ShelfNum string `json:"shelfNum"`
|
|
ItemNum string `json:"itemNum"`
|
|
LimitStock int `json:"limitStock"`
|
|
Sequence int `json:"sequence"`
|
|
Weight float64 `json:"weight"`
|
|
Price interface{} `json:"price"`
|
|
WeightUnit string `json:"weightUnit"`
|
|
SkuAttrs interface{} `json:"skuAttrs"`
|
|
Spec string `json:"spec"`
|
|
Stock interface{} `json:"stock"`
|
|
MinOrderCount int `json:"minOrderCount"`
|
|
Unit string `json:"unit"`
|
|
UpcCode string `json:"upcCode"`
|
|
BizValue interface{} `json:"bizValue"`
|
|
ProductName interface{} `json:"productName"`
|
|
BoxPrice float64 `json:"boxPrice"`
|
|
BoxNum int `json:"boxNum"`
|
|
ID int `json:"id"`
|
|
} `json:"skus"`
|
|
CategoryAttrMap struct {
|
|
Num1200000088 struct {
|
|
SupportFilter int `json:"supportFilter"`
|
|
Application string `json:"application"`
|
|
OptionMaxSize int `json:"optionMaxSize"`
|
|
TextMaxLength int `json:"textMaxLength"`
|
|
CharacterType string `json:"characterType"`
|
|
SupportExtend string `json:"supportExtend"`
|
|
AttrName string `json:"attrName"`
|
|
Sequence int `json:"sequence"`
|
|
Level int `json:"level"`
|
|
InputType int `json:"inputType"`
|
|
WmPoiID int `json:"wmPoiId"`
|
|
CategoryID int `json:"categoryId"`
|
|
IsLeaf int `json:"isLeaf"`
|
|
SpuID int `json:"spuId"`
|
|
ValueList []struct {
|
|
Sequence int `json:"sequence"`
|
|
Text interface{} `json:"text"`
|
|
IsLeaf int `json:"isLeaf"`
|
|
ValueID int `json:"valueId"`
|
|
ValueIDPath string `json:"valueIdPath"`
|
|
ValuePath string `json:"valuePath"`
|
|
Selected int `json:"selected"`
|
|
Value string `json:"value"`
|
|
} `json:"valueList"`
|
|
AttrID int `json:"attrId"`
|
|
AttrType int `json:"attrType"`
|
|
TemplateID int `json:"templateId"`
|
|
IsRequired int `json:"isRequired"`
|
|
ID int `json:"id"`
|
|
} `json:"1200000088"`
|
|
Num1200000094 struct {
|
|
SupportFilter int `json:"supportFilter"`
|
|
Application string `json:"application"`
|
|
OptionMaxSize int `json:"optionMaxSize"`
|
|
TextMaxLength int `json:"textMaxLength"`
|
|
CharacterType string `json:"characterType"`
|
|
SupportExtend string `json:"supportExtend"`
|
|
AttrName string `json:"attrName"`
|
|
Sequence int `json:"sequence"`
|
|
Level int `json:"level"`
|
|
InputType int `json:"inputType"`
|
|
WmPoiID int `json:"wmPoiId"`
|
|
CategoryID int `json:"categoryId"`
|
|
IsLeaf int `json:"isLeaf"`
|
|
SpuID int `json:"spuId"`
|
|
ValueList []struct {
|
|
Sequence int `json:"sequence"`
|
|
Text interface{} `json:"text"`
|
|
IsLeaf int `json:"isLeaf"`
|
|
ValueID int `json:"valueId"`
|
|
ValueIDPath string `json:"valueIdPath"`
|
|
ValuePath string `json:"valuePath"`
|
|
Selected int `json:"selected"`
|
|
Value string `json:"value"`
|
|
} `json:"valueList"`
|
|
AttrID int `json:"attrId"`
|
|
AttrType int `json:"attrType"`
|
|
TemplateID int `json:"templateId"`
|
|
IsRequired int `json:"isRequired"`
|
|
ID int `json:"id"`
|
|
} `json:"1200000094"`
|
|
Num1200000135 struct {
|
|
SupportFilter int `json:"supportFilter"`
|
|
Application string `json:"application"`
|
|
OptionMaxSize int `json:"optionMaxSize"`
|
|
TextMaxLength int `json:"textMaxLength"`
|
|
CharacterType string `json:"characterType"`
|
|
SupportExtend string `json:"supportExtend"`
|
|
AttrName string `json:"attrName"`
|
|
Sequence int `json:"sequence"`
|
|
Level int `json:"level"`
|
|
InputType int `json:"inputType"`
|
|
WmPoiID int `json:"wmPoiId"`
|
|
CategoryID int `json:"categoryId"`
|
|
IsLeaf int `json:"isLeaf"`
|
|
SpuID int `json:"spuId"`
|
|
ValueList []struct {
|
|
Sequence int `json:"sequence"`
|
|
Text interface{} `json:"text"`
|
|
IsLeaf int `json:"isLeaf"`
|
|
ValueID int `json:"valueId"`
|
|
ValueIDPath interface{} `json:"valueIdPath"`
|
|
ValuePath interface{} `json:"valuePath"`
|
|
Selected int `json:"selected"`
|
|
Value string `json:"value"`
|
|
} `json:"valueList"`
|
|
AttrID int `json:"attrId"`
|
|
AttrType int `json:"attrType"`
|
|
TemplateID int `json:"templateId"`
|
|
IsRequired int `json:"isRequired"`
|
|
ID int `json:"id"`
|
|
} `json:"1200000135"`
|
|
Num1200000210 struct {
|
|
SupportFilter int `json:"supportFilter"`
|
|
Application string `json:"application"`
|
|
OptionMaxSize int `json:"optionMaxSize"`
|
|
TextMaxLength int `json:"textMaxLength"`
|
|
CharacterType string `json:"characterType"`
|
|
SupportExtend string `json:"supportExtend"`
|
|
AttrName string `json:"attrName"`
|
|
Sequence int `json:"sequence"`
|
|
Level int `json:"level"`
|
|
InputType int `json:"inputType"`
|
|
WmPoiID int `json:"wmPoiId"`
|
|
CategoryID int `json:"categoryId"`
|
|
IsLeaf int `json:"isLeaf"`
|
|
SpuID int `json:"spuId"`
|
|
ValueList []struct {
|
|
Sequence int `json:"sequence"`
|
|
Text interface{} `json:"text"`
|
|
IsLeaf int `json:"isLeaf"`
|
|
ValueID int `json:"valueId"`
|
|
ValueIDPath interface{} `json:"valueIdPath"`
|
|
ValuePath interface{} `json:"valuePath"`
|
|
Selected int `json:"selected"`
|
|
Value string `json:"value"`
|
|
} `json:"valueList"`
|
|
AttrID int `json:"attrId"`
|
|
AttrType int `json:"attrType"`
|
|
TemplateID int `json:"templateId"`
|
|
IsRequired int `json:"isRequired"`
|
|
ID int `json:"id"`
|
|
} `json:"1200000210"`
|
|
} `json:"categoryAttrMap"`
|
|
SpuSaleAttrMap interface{} `json:"spuSaleAttrMap"`
|
|
OriginName string `json:"originName"`
|
|
SetOrigin bool `json:"setOrigin"`
|
|
SetWeightUnit bool `json:"setWeightUnit"`
|
|
AvgPrice int `json:"avgPrice"`
|
|
SetAvgPrice bool `json:"setAvgPrice"`
|
|
SetEan bool `json:"setEan"`
|
|
SetShelfStatus bool `json:"setShelfStatus"`
|
|
ShelfStatus int `json:"shelfStatus"`
|
|
RefCount int `json:"refCount"`
|
|
SetRefCount bool `json:"setRefCount"`
|
|
IsReceipt int `json:"is_receipt"`
|
|
SetPic bool `json:"setPic"`
|
|
CheckerID int `json:"checkerId"`
|
|
SetCheckerID bool `json:"setCheckerId"`
|
|
CheckerName string `json:"checkerName"`
|
|
SetCheckerName bool `json:"setCheckerName"`
|
|
CheckRemark interface{} `json:"checkRemark"`
|
|
SetCheckRemark bool `json:"setCheckRemark"`
|
|
CheckTime int `json:"checkTime"`
|
|
SetCheckTime bool `json:"setCheckTime"`
|
|
IsMulitEan int `json:"isMulitEan"`
|
|
SetIsMulitEan bool `json:"setIsMulitEan"`
|
|
SetCategoryNamePath bool `json:"setCategoryNamePath"`
|
|
CategoryIDPath string `json:"categoryIdPath"`
|
|
SetCategoryIDPath bool `json:"setCategoryIdPath"`
|
|
SetBrandNamePath bool `json:"setBrandNamePath"`
|
|
SuggestedPrice int `json:"suggestedPrice"`
|
|
SetSuggestedPrice bool `json:"setSuggestedPrice"`
|
|
SetRiseMax bool `json:"setRiseMax"`
|
|
SetDropMax bool `json:"setDropMax"`
|
|
ExpPeriod int `json:"expPeriod"`
|
|
SetExpPeriod bool `json:"setExpPeriod"`
|
|
ExpUnit int `json:"expUnit"`
|
|
SetExpUnit bool `json:"setExpUnit"`
|
|
SuppleFact string `json:"suppleFact"`
|
|
SetSuppleFact bool `json:"setSuppleFact"`
|
|
SubOrigin int `json:"subOrigin"`
|
|
SetSubOrigin bool `json:"setSubOrigin"`
|
|
SalePriceWeight int `json:"salePriceWeight"`
|
|
SetSalePriceWeight bool `json:"setSalePriceWeight"`
|
|
SrcPic string `json:"srcPic"`
|
|
SetSrcPic bool `json:"setSrcPic"`
|
|
BrandZhName interface{} `json:"brandZhName"`
|
|
SetBrandZhName bool `json:"setBrandZhName"`
|
|
BrandEnName interface{} `json:"brandEnName"`
|
|
SetBrandEnName bool `json:"setBrandEnName"`
|
|
SetIsReceipt bool `json:"setIs_receipt"`
|
|
ReceiptorID int `json:"receiptorId"`
|
|
SetReceiptorID bool `json:"setReceiptorId"`
|
|
SpecNew float64 `json:"specNew"`
|
|
SetSpecNew bool `json:"setSpecNew"`
|
|
SpecUnit string `json:"specUnit"`
|
|
SetSpecUnit bool `json:"setSpecUnit"`
|
|
SpecCount int `json:"specCount"`
|
|
SetSpecCount bool `json:"setSpecCount"`
|
|
SpecCountUnit string `json:"specCountUnit"`
|
|
SetSpecCountUnit bool `json:"setSpecCountUnit"`
|
|
IsBigSpec int `json:"isBigSpec"`
|
|
SetIsBigSpec bool `json:"setIsBigSpec"`
|
|
WeightNew float64 `json:"weightNew"`
|
|
SetWeightNew bool `json:"setWeightNew"`
|
|
Description string `json:"description"`
|
|
Sequence int `json:"sequence"`
|
|
SetSize bool `json:"setSize"`
|
|
Source int `json:"source"`
|
|
Origin int `json:"origin"`
|
|
OriginType int `json:"originType"`
|
|
SetName bool `json:"setName"`
|
|
SetID bool `json:"setId"`
|
|
Weight int `json:"weight"`
|
|
SetWeight bool `json:"setWeight"`
|
|
Valid int `json:"valid"`
|
|
BrandID int `json:"brandId"`
|
|
CategoryName string `json:"categoryName"`
|
|
CategoryID int `json:"categoryId"`
|
|
WeightUnit interface{} `json:"weightUnit"`
|
|
Pic string `json:"pic"`
|
|
Spec string `json:"spec"`
|
|
Ctime int `json:"ctime"`
|
|
EanList []string `json:"eanList"`
|
|
CategoryNamePath string `json:"categoryNamePath"`
|
|
Utime int `json:"utime"`
|
|
Unit string `json:"unit"`
|
|
IsSp int `json:"isSp"`
|
|
Ean string `json:"ean"`
|
|
CheckStatus int `json:"checkStatus"`
|
|
SpName string `json:"spName"`
|
|
BrandNamePath string `json:"brandNamePath"`
|
|
Cuid int `json:"cuid"`
|
|
RiseMax int `json:"riseMax"`
|
|
DropMax int `json:"dropMax"`
|
|
SetSpName bool `json:"setSpName"`
|
|
SetOriginType bool `json:"setOriginType"`
|
|
SetIsSp bool `json:"setIsSp"`
|
|
SetBrandID bool `json:"setBrandId"`
|
|
SetCheckStatus bool `json:"setCheckStatus"`
|
|
EanListSize int `json:"eanListSize"`
|
|
EanListIterator []string `json:"eanListIterator"`
|
|
SetEanList bool `json:"setEanList"`
|
|
SetCategoryID bool `json:"setCategoryId"`
|
|
SetSpec bool `json:"setSpec"`
|
|
Muid int `json:"muid"`
|
|
SetMuid bool `json:"setMuid"`
|
|
SetSource bool `json:"setSource"`
|
|
SetUnit bool `json:"setUnit"`
|
|
SetSequence bool `json:"setSequence"`
|
|
SetCtime bool `json:"setCtime"`
|
|
SetUtime bool `json:"setUtime"`
|
|
SetValid bool `json:"setValid"`
|
|
SetDescription bool `json:"setDescription"`
|
|
Cuname interface{} `json:"cuname"`
|
|
SetCuname bool `json:"setCuname"`
|
|
Muname interface{} `json:"muname"`
|
|
SetMuname bool `json:"setMuname"`
|
|
SetCuid bool `json:"setCuid"`
|
|
SetCategoryName bool `json:"setCategoryName"`
|
|
Name string `json:"name"`
|
|
ID int `json:"id"`
|
|
Size string `json:"size"`
|
|
}
|
|
|
|
//https://shangoue.meituan.com/reuse/sc/product/retail/r/getStandardProductListWithCond
|
|
func (a *API) GetStandardProductListWithCond(upc string) (getStandardProductListWithCondResult *GetStandardProductListWithCondResult, err error) {
|
|
params := map[string]interface{}{
|
|
"keyword": upc,
|
|
"pageNo": 1,
|
|
"pageSize": 20,
|
|
}
|
|
result, err := a.AccessUserPage("reuse/sc/product/retail/r/getStandardProductListWithCond", params)
|
|
if err == nil {
|
|
if len(result["list"].([]interface{})) == 0 {
|
|
return nil, err
|
|
} else {
|
|
utils.Map2StructByJson(result["list"].([]interface{})[0], &getStandardProductListWithCondResult, false)
|
|
}
|
|
}
|
|
return getStandardProductListWithCondResult, err
|
|
}
|
|
|
|
func (a *API) SetTokenPage() (err error) {
|
|
params := map[string]interface{}{
|
|
"acctId": 57396785,
|
|
"wmPoiId": -1,
|
|
"bsid": "y-5VaK3uFxP705tpXsnJPee2sJc9dJ23LmGwYmg2kCO81d9EjD7TJrUeflcJRrqRxg9DFCNGhrJSaWYSCgXvxg",
|
|
"device_uuid": "!ac34e5d7-5472-47fd-b7c4-029c1f7e7576",
|
|
"token": "1bWbK5VbK50E2BmIhIH2zHB-am_y7mB37yXHm6RLZWx4*",
|
|
"region_version": 0,
|
|
"region_id": "",
|
|
}
|
|
a.SetCookieWithStr(`
|
|
uuid=350a86177dd64c43b875.1619071312.1.0.0; _lxsdk_cuid=178f88ba3cec8-0db6e384ebfa36-5b1f321a-1fa400-178f88ba3cec8; _lxsdk=178f88ba3cec8-0db6e384ebfa36-5b1f321a-1fa400-178f88ba3cec8; uuid_update=true; _ga=GA1.2.2092976141.1619502287; pushToken=04OVj3PayJdT62H_Irz4BXYfNQHh9N33gDO_WFnGaovs*; device_uuid=!ac34e5d7-5472-47fd-b7c4-029c1f7e7576; mtcdn=K; lsu=; e_u_id_3299326472=e5ae16afe444349d24af7d33b66620a1; wpush_server_url=wss://wpush.meituan.com; shopCategory=food; _lxsdk_s=17b15442f31-e81-89b-533%7C%7C187
|
|
`)
|
|
_, err = a.AccessUserPage3("v2/logon/setToken", params)
|
|
return err
|
|
}
|