Files
jx-callback/business/partner/purchase/mtwm/store.go
苏尹岚 a2c7eecdca aa
2021-02-19 11:32:20 +08:00

407 lines
15 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 mtwm
import (
"encoding/json"
"errors"
"fmt"
"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:~,]*)`)
storeVendorOrgCodeMap = map[string]string{
"589": mtwmapi.MtwmC4Tag,
"5873": mtwmapi.MtwmSCTag,
"4123": mtwmapi.MtwmSGTag,
}
)
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 := getAPI(vendorOrgCode, 0, vendorStoreID).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 = getAPI(vendorOrgCode, 0, vendorStoreID).ShippingFetch(poiCode)
if err != nil {
deliveryRangeInfo, err = getAPI(vendorOrgCode, 0, vendorStoreID).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, params map[string]interface{}, storeDetail *dao.StoreDetail) (vendorStoreID string, err error) {
vendorOrgCode := params["vendorOrgCode"].(string)
if vendorOrgCode == "" {
return "", fmt.Errorf("平台账号必传!")
}
cityName := storeDetail.CityName
if strings.Contains(cityName, "市") {
cityName = strings.Replace(cityName, "市", "", strings.LastIndex(cityName, "市"))
}
shippingTime := ""
if storeDetail.OpenTime1 != 0 && storeDetail.CloseTime1 != 0 {
shippingTime += jxutils.JxOperationTime2StrTime(storeDetail.OpenTime1)
shippingTime += "-"
shippingTime += jxutils.JxOperationTime2StrTime(storeDetail.CloseTime1)
if storeDetail.OpenTime2 != 0 && storeDetail.CloseTime2 != 0 {
shippingTime += ","
shippingTime += jxutils.JxOperationTime2StrTime(storeDetail.OpenTime2)
shippingTime += "-"
shippingTime += jxutils.JxOperationTime2StrTime(storeDetail.CloseTime2)
}
}
poiSettleSaveParam := &mtwmapi.PoiSettleSaveParam{
Type: 0, //创建
ApplyInfos: []*mtwmapi.ApplyInfo{
&mtwmapi.ApplyInfo{
AppPoiCode: utils.Int2Str(storeDetail.ID),
SettlementID: 0, //结算ID暂时还没得
MultiPoiBasicInfo: &mtwmapi.MultiPoiBasicInfo{
Name: params["vendorStoreName"].(string),
City: cityName,
Address: storeDetail.Address,
Longitude: utils.Float64ToStr(jxutils.IntCoordinate2Standard(storeDetail.Lng)),
Latitude: utils.Float64ToStr(jxutils.IntCoordinate2Standard(storeDetail.Lat)),
FirstTag: storeVendorOrgCodeMap[vendorOrgCode],
CallCenter: storeDetail.Tel1,
ContactPhone: storeDetail.Tel1,
ContactName: storeDetail.IDName,
EcommerceAccountPhone: "18048531223",
ShippingTime: shippingTime,
},
MultiPoiShippingInfo: &mtwmapi.MultiPoiShippingInfo{
ShippingType: 5, //1:商家自配 5:美团专送,101:美团快送
MinPrice: params["minPrice"].(float64),
ShippingFee: params["shippingFee"].(float64),
},
//资质
},
},
}
mtapi := getAPIWithoutToken(storeDetail.VendorOrgCode)
mtapi.PoiSettleSave(poiSettleSaveParam)
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()
}
mtapi := getAPI(getStoreVendorOrgCode(storeID), storeID, "")
storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDMTWM, "")
if err != nil {
return err
}
errList := errlist.New()
remoteStoreInfo, err := mtapi.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(mtapi.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
vendorStoreID := msg.FormData.Get("app_poi_code")
storeStatus := 0
if msg.Cmd == mtwmapi.MsgTypeStoreStatusChanged {
poiStatus := int(utils.Str2Int64(msg.FormData.Get("poi_status")))
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)
}
} else if msg.Cmd == mtwmapi.MsgTypeStoreAuditStatusChanged {
auditDetails := []map[string]interface{}{}
auditDetail := msg.FormData.Get("audit_detail")
openFlag := false
openCount := 0
closeFlag := false
if err = json.Unmarshal([]byte(auditDetail), &auditDetails); err == nil {
for _, v := range auditDetails {
if v["module_status"].(string) == "3" || v["module_status"].(string) == "5" || v["module_status"].(string) == "7" {
closeFlag = true
break
}
if v["module_status"].(string) == "6" {
openCount++
}
}
if openCount == len(auditDetails) {
openFlag = true
}
if closeFlag {
storeStatus = model.StoreStatusDisabled
} else if openFlag {
storeStatus = model.StoreStatusOpened
} else {
storeStatus = model.StoreStatusClosed
}
}
}
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 := getAPI(vendorOrgCode, storeID, "").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 = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiOffline(vendorStoreID)
} else {
if err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiOnline(vendorStoreID); err == nil { // 这个函数成功返回也并不表示上线成功。。。
remoteStoreInfo, err2 := getAPI(vendorOrgCode, storeID, vendorStoreID).PoiGet(vendorStoreID)
if err = err2; err != nil {
return err
}
if remoteStoreInfo.IsOnline == mtwmapi.PoiStatusOnline {
if openLevel == mtwmapi.PoiOpenLevelHaveRest {
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiClose(vendorStoreID)
} else {
err = getAPI(vendorOrgCode, storeID, vendorStoreID).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 = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiShipTimeUpdate(vendorStoreID, shippingTime)
if err != nil {
shippingTime = ""
if validOpTimeList := getOpTimeListFromErr(err); len(validOpTimeList) > 0 {
shippingTime = openTimeJX2Mtwm(constrainOpTimeList(opTimeList, validOpTimeList))
}
if shippingTime != "" {
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiShipTimeUpdate(vendorStoreID, shippingTime)
}
}
}
return err
}
func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) {
vendorStoreIDs, err = getAPIWithoutToken(vendorOrgCode).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 = getAPI(vendorOrgCode, storeID, vendorStoreID).PackagePriceUpdate(vendorStoreID, 1, int(boxFee))
}
}
return err
}