package mtwmapi import ( "encoding/json" "fmt" "io/ioutil" "net/http" "strings" "git.rosy.net.cn/baseapi/platformapi" "git.rosy.net.cn/baseapi/utils" ) const ( MtwmSCTag = "13030000" MtwmC4Tag = "11010000" MtwmSGTag = "10010000" ) type PoiCategoryInfo struct { ID int `json:"id"` Name string `json:"name"` } type PoiInfo struct { Address string `json:"address,omitempty"` AppID int `json:"app_id,omitempt"` AppPoiCode string `json:"app_poi_code,omitempt"` CityID int `json:"city_id,omitempt"` Ctime int64 `json:"ctime,omitempt"` InvoiceDescription string `json:"invoice_description,omitempt"` InvoiceMinPrice int `json:"invoice_min_price,omitempt"` InvoiceSupport int `json:"invoice_support,omitempt"` IsOnline int `json:"is_online,omitempt"` Latitude float64 `json:"latitude,omitempt"` LocationID int `json:"location_id,omitempt"` Longitude float64 `json:"longitude,omitempt"` Name string `json:"name,omitempt"` OpenLevel int `json:"open_level,omitempt"` Phone string `json:"phone,omitempt"` PicURL string `json:"pic_url,omitempt"` PicURLLarge string `json:"pic_url_large,omitempt"` PreBook int `json:"pre_book,omitempt"` PreBookMaxDays int `json:"pre_book_max_days,omitempt"` PreBookMinDays int `json:"pre_book_min_days,omitempt"` PromotionInfo string `json:"promotion_info,omitempt"` Remark string `json:"remark,omitempt"` ShippingFee float64 `json:"shipping_fee,omitempt"` ShippingTime string `json:"shipping_time,omitempt"` StandbyTel string `json:"standby_tel,omitempt"` TagName string `json:"tag_name,omitempt"` ThirdTagName string `json:"third_tag_name,omitempt"` TimeSelect int `json:"time_select,omitempt"` Utime int64 `json:"utime,omitempt"` LogisticsCodes string `json:"logistics_codes,omitempt"` } // todo 此函数在open_level与is_online开店,由于一些原因并没有成功时,好像并不会报错 // 经常会奇怪的报错:商家已接入美团配送,不可修改门店配送相关信息,但实际并没有修改任何与配送相关的东西 // 参见:https://developer.waimai.meituan.com/home/myquestionDetail/6194 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 []*PoiInfo, err error) { result, err := a.AccessAPI("poi/mget", true, map[string]interface{}{ KeyAppPoiCodes: strings.Join(poiCodes, ","), }) if err == nil { err = utils.Map2StructByJson(result, &pois, false) } return pois, err } func (a *API) PoiGet(poiCode string) (poi *PoiInfo, err error) { result, err := a.PoiMGet([]string{poiCode}) if err == nil { if len(result) == 0 { return nil, fmt.Errorf("找不到ID为%s的美团外卖门店", poiCode) } 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) PoiOpen(poiCode string) (err error) { _, err = a.AccessAPI("poi/open", false, map[string]interface{}{ KeyAppPoiCode: poiCode, }) return err } func (a *API) PoiOffline(poiCode string) (err error) { _, err = a.AccessAPI("poi/offline", 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, shippingTime string) (err error) { _, err = a.AccessAPI("poi/shippingtime/update", false, map[string]interface{}{ KeyAppPoiCode: poiCode, "shipping_time": shippingTime, }) return err } // 美团要求必须是jpg|jpeg图片格式,且imgName必须以jpg或jpeg结尾 // 此接口虽然要求poiCode参数,但经过测试,发现上传的图片可以跨门店使用 // imgName好像不支持中文,否则会报签名错 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 } type PoiSettleSaveParam struct { Type int `json:"type"` //0创建,1更新 ApplyInfos []*ApplyInfo `json:"apply_info"` } type ApplyInfo struct { AppPoiCode string `json:"app_poi_code"` SettlementID int `json:"settlement_id"` MultiPoiBasicInfo *MultiPoiBasicInfo `json:"multi_poi_basic_info"` MultiPoiCertInfos []*MultiPoiCertInfo `json:"multi_poi_cert_infos"` MultiPoiShippingInfo *MultiPoiShippingInfo `json:"multi_poi_shipping_info"` } type MultiPoiBasicInfo struct { Name string `json:"name"` City string `json:"city"` Address string `json:"address"` Longitude string `json:"longitude"` Latitude string `json:"latitude"` FirstTag string `json:"first_tag"` CallCenter string `json:"call_center"` ContactName string `json:"contact_name"` ContactPhone string `json:"contact_phone"` EcommerceAccountPhone string `json:"ecommerce_account_phone"` ShippingTime string `json:"shipping_time"` } type MultiPoiCertInfo struct { IsLongTime int `json:"is_long_time"` Type int `json:"type"` LicenseAddress string `json:"license_address,omitempty"` LicenseCheckDate string `json:"license_check_date,omitempty"` LicenseCheckOrganization string `json:"license_check_organization,omitempty"` LicenseLegalPerson string `json:"license_legal_person,omitempty"` LicenseName string `json:"license_name,omitempty"` LicenseNumber string `json:"license_number,omitempty"` LicenseOperator string `json:"license_operator,omitempty"` LicenseProject string `json:"license_project,omitempty"` LicenseRegisterDate string `json:"license_register_date,omitempty"` LicenseSocialCreditCode string `json:"license_social_credit_code,omitempty"` LicenseSubject string `json:"license_subject,omitempty"` LicensePic string `json:"license_pic"` LicenseValidity string `json:"license_validity,omitempty"` LicenseValidStartDate string `json:"license_valid_start_date,omitempty"` } type MultiPoiShippingInfo struct { ShippingType int `json:"shipping_type"` MinPrice float64 `json:"min_price"` ShippingFee float64 `json:"shipping_fee"` } //https://open-shangou.meituan.com/home/docDetail/530 func (a *API) PoiSettleSave(poiSettleSaveParam *PoiSettleSaveParam) (vendorStoreID string, err error) { data, _ := json.Marshal(poiSettleSaveParam.ApplyInfos) result, err := a.AccessAPI3("ecommerce/poi/settle/multi/save", false, map[string]interface{}{ "type": poiSettleSaveParam.Type, "apply_info": string(data), }) if err == nil { vendorStoreID = result.(map[string]interface{})["success_list"].([]interface{})[0].(map[string]interface{})["app_poi_code"].(string) } return vendorStoreID, err } type PoiSettleCategoryListResult struct { SingleCategoryTree []struct { LevelOneName string `json:"level_one_name"` LevelOneCode int `json:"level_one_code"` LevelTwoInfo []struct { LevelTwoName string `json:"level_two_name"` LevelTwoCode int `json:"level_two_code"` } `json:"level_two_info"` } `json:"single_category_tree"` MultiCategoryTree []struct { LevelOneName string `json:"level_one_name"` LevelOneCode int `json:"level_one_code"` LevelTwoInfo []struct { LevelTwoName string `json:"level_two_name"` LevelTwoCode int `json:"level_two_code"` } `json:"level_two_info"` } `json:"multi_category_tree"` } //查询门店经营品类列表 func (a *API) PoiSettleCategoryList() (poiSettleCategoryListResult *PoiSettleCategoryListResult, err error) { result, err := a.AccessAPI("ecommerce/poi/settle/category/list", true, nil) if err == nil { utils.Map2StructByJson(result, &poiSettleCategoryListResult, false) } return poiSettleCategoryListResult, err } type PoiSettleSettlementListResult struct { ID int `json:"id"` Name string `json:"name"` BankName string `json:"bank_name"` BranchName string `json:"branch_name"` BankNum string `json:"bank_num"` AccountName string `json:"account_name"` FinancialName string `json:"financial_name"` FinancialPhone string `json:"financial_phone"` } //查询连锁门店结算信息 func (a *API) PoiSettleSettlementList() (poiSettleSettlementListResult *[]PoiSettleSettlementListResult, err error) { result, err := a.AccessAPI("ecommerce/poi/settle/settlement/list", true, map[string]interface{}{ "page_num": 1, "page_size": 50, }) if err == nil { utils.Map2StructByJson(result, &poiSettleSettlementListResult, false) } return poiSettleSettlementListResult, err } //批量提交门店审核 func (a *API) PoiSettleAuditSubmit(appPoiCodes []string) (err error) { _, err = a.AccessAPI("ecommerce/poi/settle/audit/submit", false, map[string]interface{}{ "app_poi_codes": strings.Join(appPoiCodes, ","), }) return err } type CommentScoreResult struct { AppPoiCode string `json:"appPoiCode"` AvgPoiScore float64 `json:"avgPoiScore"` AvgTasteScore float64 `json:"avgTasteScore"` AvgPackingScore float64 `json:"avgPackingScore"` AvgDeliveryScore float64 `json:"avgDeliveryScore"` } // 通过门店ID获取当前门店评分 func (a *API) CommentScore(appPoiCode string) (commentScoreResult *CommentScoreResult, err error) { result, err := a.AccessAPI("comment/score", true, map[string]interface{}{ "app_poi_code": appPoiCode, }) if err == nil { utils.Map2StructByJson(result, &commentScoreResult, false) } return commentScoreResult, err }