package mtwm import ( "errors" "math" "regexp" "strings" "git.rosy.net.cn/baseapi/platformapi/mtwmapi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/baseapi/utils/errlist" "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" ) var ( opTimeErrReg = regexp.MustCompile(`当前配送营业时间为:([\d:~,]*)`) ) type tEbaiStoreInfo struct { model.Store VendorStoreID string `orm:"column(vendor_store_id)"` RealLastOperator string EbaiStoreStatus int SyncStatus int ProvinceID int `orm:"column(province_id)"` CityID int `orm:"column(city_id)"` DistrictID int `orm:"column(district_id)"` } func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (retVal *dao.StoreDetail, err error) { result, err := api.MtwmAPI.PoiGet(vendorStoreID) if err == nil { // globals.SugarLogger.Debug(utils.Format4Output(result, false)) retVal = &dao.StoreDetail{ Store: model.Store{ Address: result.Address, Tel1: result.Phone, }, } retVal.OriginalName = result.Name _, retVal.Name = jxutils.SplitStoreName(retVal.OriginalName, partner.StoreNameSeparator, globals.StoreNameMtwm) retVal.SetOpTime(openTimeMtwm2JX(result.ShippingTime)) retVal.Status = bizStatusMtwm2JX(result.OpenLevel, result.IsOnline) tel2 := result.StandbyTel if tel2 != "" && tel2 != retVal.Tel1 { retVal.Tel2 = tel2 } retVal.Lng = int(result.Longitude) retVal.Lat = int(result.Latitude) lng := jxutils.IntCoordinate2Standard(retVal.Lng) lat := jxutils.IntCoordinate2Standard(retVal.Lat) db := dao.GetDB() retVal.DistrictCode = api.AutonaviAPI.GetCoordinateDistrictCode(lng, lat) city, err := dao.GetPlaceByCode(db, result.CityID) retVal.CityName = city.Name retVal.CityCode = result.CityID poiCode := result.AppPoiCode retVal.VendorStoreID = vendorStoreID retVal.ID = int(utils.Str2Int64WithDefault(poiCode, 0)) retVal.DeliveryRangeType = model.DeliveryRangeTypePolygon var deliveryRangeInfo []map[string]interface{} deliveryRangeInfo, err = api.MtwmAPI.ShippingFetch(poiCode) if err != nil { deliveryRangeInfo, err = api.MtwmAPI.ShippingList(poiCode) } if err == nil { if len(deliveryRangeInfo) > 0 { retVal.DeliveryRange = rangeMtwm2JX(deliveryRangeInfo[0]["area"].(string)) logisticsCode := utils.Interface2String(deliveryRangeInfo[0]["logistics_code"]) if logisticsCode == "" || logisticsCode == mtwmapi.PeiSongTypeSelf { retVal.DeliveryType = scheduler.StoreDeliveryTypeByStore } else { retVal.DeliveryType = scheduler.StoreDeliveryTypeByPlatform } } } return retVal, nil } return nil, err } func (p *PurchaseHandler) CreateStore(db *dao.DaoDB, storeID int, userName string) (err error) { return p.UpdateStore(db, storeID, userName) } func (p *PurchaseHandler) CreateStore2(db *dao.DaoDB, storeID int, userName string) (vendorStoreID string, err error) { return vendorStoreID, err } func (p *PurchaseHandler) DeleteStore(db *dao.DaoDB, storeID int, userName string) (err error) { return err } func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) { var name string if db == nil { db = dao.GetDB() } storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDMTWM) if err != nil { return err } errList := errlist.New() remoteStoreInfo, err := api.MtwmAPI.PoiGet(storeDetail.VendorStoreID) if err != nil { return err } mergedStoreStatus := jxutils.MergeStoreStatus(storeDetail.Status, storeDetail.VendorStatus) name = remoteStoreInfo.Name if storeDetail.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreName) != 0 { if storeDetail.VendorStoreName != "" { name = storeDetail.VendorStoreName } // else { // name = jxutils.ComposeStoreName(storeDetail.Store.Name, model.VendorIDMTWM) // } } // openLevel, isOnline := bizStatusJX2Mtwm(mergedStoreStatus) //TODO 美团暂时不用那个电话 phone := storeDetail.Tel1 // if storeDetail.MarketManPhone != "" { // phone = storeDetail.MarketManPhone // } else { // phone = model.VendorStoreTel // } params := map[string]interface{}{ "name": name, //jxutils.ComposeStoreName(storeDetail.Store.Name, model.VendorIDMTWM), "address": storeDetail.Address, // 美团好像地址也不能改的? "longitude": jxutils.IntCoordinate2Standard(int(remoteStoreInfo.Longitude)), "latitude": jxutils.IntCoordinate2Standard(int(remoteStoreInfo.Latitude)), "phone": phone, "shipping_fee": remoteStoreInfo.ShippingFee, "shipping_time": remoteStoreInfo.ShippingTime, "open_level": remoteStoreInfo.OpenLevel, "is_online": remoteStoreInfo.IsOnline, "third_tag_name": remoteStoreInfo.ThirdTagName, "promotion_info": storeDetail.PromoteInfo, } // globals.SugarLogger.Debug(utils.Format4Output(params, false)) if globals.EnableMtwmStoreWrite { errList.AddErr(api.MtwmAPI.PoiSave(storeDetail.VendorStoreID, params)) } // PoiSave有时会报错:商家已接入美团配送,不可修改门店配送相关信息,这里放弃信息修改 // if err != nil { // if utils.IsErrMatch(err, utils.Int2Str(mtwmapi.ErrCodeCanNotModifyStoreDeliveryInfo), nil) { // globals.SugarLogger.Infof("mtwm UpdateStore vendorStoreID:%s, params:%s failed with err:%v", storeDetail.VendorStoreID, utils.Format4Output(params, true), err) // if storeDetail.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreStatus) != 0 { // err = p.UpdateStoreStatus(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID, mergedStoreStatus) // } else { // err = nil // } // } // errList.AddErr(err) // } if storeDetail.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreStatus) != 0 { errList.AddErr(p.UpdateStoreStatus(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID, mergedStoreStatus)) } errList.AddErr(p.UpdateStoreOpTime(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID, storeDetail.GetOpTimeList())) errList.AddErr(p.UpdateStoreBoxFee(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID)) return errList.GetErrListAsOne() } func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) { return "", errors.New("美团外卖不支持此操作") } func (p *PurchaseHandler) onStoreStatusChanged(msg *mtwmapi.CallbackMsg) (response *mtwmapi.CallbackResponse) { var err error poiStatus := int(utils.Str2Int64(msg.FormData.Get("poi_status"))) vendorStoreID := msg.FormData.Get("app_poi_code") storeStatus := 0 if poiStatus == mtwmapi.MsgPoiStatusOpened { storeStatus = model.StoreStatusOpened } else if poiStatus == mtwmapi.MsgPoiStatusClosed { storeStatus = model.StoreStatusClosed } else if poiStatus == mtwmapi.MsgPoiStatusOffline { storeStatus = model.StoreStatusDisabled } else { storeStatus, err = p.GetStoreStatus(jxcontext.AdminCtx, "", 0, vendorStoreID) } if err == nil { err = partner.CurStoreManager.OnStoreStatusChanged(vendorStoreID, model.VendorIDMTWM, storeStatus) } response = mtwmapi.Err2CallbackResponse(err, "") return response } func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) { result, err := api.MtwmAPI.PoiGet(vendorStoreID) if err == nil { return bizStatusMtwm2JX(result.OpenLevel, result.IsOnline), nil } return 0, err } func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, isSetEnable bool) (err error) { return err } func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) { openLevel, isOnline := bizStatusJX2Mtwm(status) if globals.EnableMtwmStoreWrite { if isOnline != mtwmapi.PoiStatusOnline { err = api.MtwmAPI.PoiOffline(vendorStoreID) } else { if err = api.MtwmAPI.PoiOnline(vendorStoreID); err == nil { // 这个函数成功返回也并不表示上线成功。。。 remoteStoreInfo, err2 := api.MtwmAPI.PoiGet(vendorStoreID) if err = err2; err != nil { return err } if remoteStoreInfo.IsOnline == mtwmapi.PoiStatusOnline { if openLevel == mtwmapi.PoiOpenLevelHaveRest { err = api.MtwmAPI.PoiClose(vendorStoreID) } else { err = api.MtwmAPI.PoiOpen(vendorStoreID) } } else { err = errors.New("门店还未上线,不能修改营业状态") } } } } return err } func errOpStr2Int16(str string) []int16 { list := strings.Split(str, "~") if len(list) >= 2 { return []int16{jxutils.StrTime2JxOperationTime(list[0]+":00", 0), jxutils.StrTime2JxOperationTime(list[1]+":00", 2359)} } return nil } func getOpTimeListFromErr(err error) (opTimeList []int16) { if errExt, ok := err.(*utils.ErrorWithCode); ok && errExt.IntCode() == mtwmapi.ErrCodeOpFailed { if result := opTimeErrReg.FindStringSubmatch(errExt.ErrMsg()); len(result) >= 2 { timeStrList := strings.Split(result[1], ",") for _, v := range timeStrList { v = utils.TrimBlankChar(v) if len(v) == len("00:00~02:00") { opTimeList = append(opTimeList, errOpStr2Int16(v)...) } } } } return opTimeList } // 此函数只是简单实现,不支持区间切分,只做单一区间限制 func constrainOpTimeList(opTimeList, validOpTimeList []int16) (newOpTimeList []int16) { for k := 0; k < len(opTimeList); k += 2 { beginTime := opTimeList[k] endTime := opTimeList[k+1] for k2 := 0; k2 < len(validOpTimeList); k2 += 2 { beginTime2 := validOpTimeList[k2] endTime2 := validOpTimeList[k2+1] if beginTime >= beginTime2 && beginTime <= endTime2 { newOpTimeList = append(newOpTimeList, beginTime) newOpTimeList = append(newOpTimeList, int16(math.Min(float64(endTime), float64(endTime2)))) } else if beginTime2 >= beginTime && beginTime2 <= endTime { newOpTimeList = append(newOpTimeList, beginTime2) newOpTimeList = append(newOpTimeList, int16(math.Min(float64(endTime), float64(endTime2)))) } } } return newOpTimeList } func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, opTimeList []int16) (err error) { shippingTime := openTimeJX2Mtwm(opTimeList) if globals.EnableMtwmStoreWrite { err = api.MtwmAPI.PoiShipTimeUpdate(vendorStoreID, shippingTime) if err != nil { shippingTime = "" if validOpTimeList := getOpTimeListFromErr(err); len(validOpTimeList) > 0 { shippingTime = openTimeJX2Mtwm(constrainOpTimeList(opTimeList, validOpTimeList)) } if shippingTime != "" { err = api.MtwmAPI.PoiShipTimeUpdate(vendorStoreID, shippingTime) } } } return err } func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) { vendorStoreIDs, err = api.MtwmAPI.PoiGetIDs() return vendorStoreIDs, err } func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string, storeID int64) (err error) { return err } func (c *PurchaseHandler) UpdateStoreBoxFee(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (err error) { boxFee, err := dao.GetSysConfigAsInt64(dao.GetDB(), model.ConfigSysMtwmBoxFee) if err == nil { if globals.EnableMtwmStoreWrite && globals.IsProductEnv() { err = api.MtwmAPI.PackagePriceUpdate(vendorStoreID, 1, int(boxFee)) } } return err }