Files
baseapi/platformapi/mtwmapi/poi.go
2025-11-21 09:09:09 +08:00

420 lines
16 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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"
AuditTypeStore = 1 //审核类型1-门店入驻2-门店logo(头图)
AuditTypeStoreLogo = 2
MtStoreIsOnlineOffLine = 0 // 0 下线 3审核通过可上线
MtStoreIsOnlineOnLine = 1 // 1上线 2上单
)
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"` // 0-下线1-上线2-上单中3-审核通过可上线。
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) {
result, err := a.AccessAPI("poi/save", false, utils.MergeMaps(utils.Params2Map(KeyAppPoiCode, poiCode), poiParams))
fmt.Println(result)
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
}
// PoiOffline 接口已经下线了,现在默认打开
func (a *API) PoiOffline(poiCode string) (err error) {
return nil
_, err = a.AccessAPI("poi/offline", false, map[string]interface{}{
KeyAppPoiCode: poiCode,
})
return err
}
// PoiOnline 接口已经下线了,现在默认打开
func (a *API) PoiOnline(poiCode string) (err error) {
return nil
_, 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
}
//func (a *API) PoiSettleSave2222() (vendorStoreID string, err error) {
// result, err := a.AccessAPI3("ecommerce/poi/settle/multi/save", false, map[string]interface{}{
// "type": 0,
// "apply_info": `[{"app_poi_code":"669387","settlement_id":0,"multi_poi_basic_info":{"name":"京西菜市(优乐购)","city":"南京","address":"南京市六合区大厂街道宁六路366-7号","longitude":"118.742342","latitude":"32.230126","first_tag":"13030000","call_center":"18981810340","contact_name":"赵宇","contact_phone":"18981810340","ecommerce_account_phone":"18048531223","shipping_time":"07:00-19:00"},"multi_poi_cert_infos":[{"is_long_time":0,"type":1,"license_name":"门脸图","license_pic":"https://image.jxc4.com/image/bde4712a92fbf35f002e0960a46bad12.jpg"},{"is_long_time":0,"type":2,"license_name":"环境图","license_pic":"https://image.jxc4.com/image/8bfa70de3eb667d1edcb1c33b3adb4f8.jpg"},{"is_long_time":1,"type":5,"license_address":"南京市六合区大厂街道宁六路366-7号","license_legal_person":"赵宇","license_name":"营业执照","license_register_date":"2024-06-14","license_check_organization":"南京市江北新区管理委员会市场监督管理局","license_check_date":"2024-06-14","license_number":"92320191MADM6X3Y0MM","license_social_credit_code":"92320191MADM6X3Y0MM","license_pic":"https://image.jxc4.com/image/e585db68bc1675b83a2fc79705d42751.jpg","license_valid_start_date":"2024-06-14"},{"is_long_time":0,"type":6,"license_address":"南京市六合区大厂街道宁六路366-7号","license_legal_person":"赵宇","license_name":"食品经营许可证","license_number":"YB23201190095426","license_social_credit_code":"YB23201190095426","license_pic":"https://image.jxc4.com/image/84c3894a73cd06d337e6c3a82ca4e318.jpg","license_validity":"2024-06-14","license_valid_start_date":"2029-12-12"}],"multi_poi_shipping_info":{"shipping_type":5,"min_price":0,"shipping_fee":0}}]`,
// })
// 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
}
type AuthorizationStatus struct {
AppID int `json:"app_id"`
AppPoiCode string `json:"app_poi_code"`
IsOnline int `json:"is_online"`
PoiName string `json:"poi_name"`
WmPoiID int `json:"wm_poi_id"`
}
// 获取授权门店列表
func (a *API) GetBoundList(otherStoreId string) ([]*AuthorizationStatus, error) {
param := make(map[string]interface{}, 0)
param["page_num"] = 1
param["page_size"] = 20
if otherStoreId != "" {
param["app_poi_code"] = otherStoreId
}
result, err := a.AccessAPI("ecommerce/poi/bound/list", true, param)
if err != nil {
return nil, err
}
var data []*AuthorizationStatus
if err := utils.Map2StructByJson(result, &data, false); err != nil {
return nil, err
}
return data, nil
}
type SettleAuditList struct {
AppPoiCode string `json:"app_poi_code"`
Status int `json:"status"` //任务状态:0-待完善1-审核中2-已驳回4-待提审5-审核通过7-暂不合作9-创建失败
//audit_type=1时有效
BaseStatus int `json:"base_status"` //基本信息模块0-待录入1-已录入2-审核中3-已驳回4-签约中5-签约失败6-已生效7-缺失
LegalPersonStatus int `json:"legal_person_status"` //法人信息模块(仅单店)
ShippingStatus int `json:"shipping_status"` //配送信息模块
QualificationStatus int `json:"qualification_status"` //资质信息模块
SettlementStatus int `json:"settlement_status"` //结算信息模块(仅连锁门店)
//audit_type=2时有效
LogoStatus int `json:"logo_status"` //门店logo审核结果1-审核中2-审核通过3-已驳回
Reason string `json:"reason"` //审核描述
}
// GetSettleAuditList 批量查询门店审核状态,目前只用
func (a *API) GetSettleAuditList(appPoiCodes string) ([]*SettleAuditList, error) {
param := make(map[string]interface{}, 0)
param["app_poi_codes"] = appPoiCodes
param["audit_type"] = AuditTypeStoreLogo
result, err := a.AccessAPI("ecommerce/poi/settle/audit/list", true, param)
if err != nil {
return nil, err
}
var data []*SettleAuditList
if err := utils.Map2StructByJson(result, &data, false); err != nil {
return nil, err
}
return data, nil
}