package partner import ( "errors" "fmt" "time" "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" ) const ( StoreNameSeparator = "-" ) const ( CreatedPeration = "create" UpdatedPeration = "update" ) const ( CancelWaybillReasonNotAcceptIntime = 1 CancelWaybillReasonSwitch2SelfFailed = 2 CancelWaybillReasonOther = 10 ) const ( AfsApproveTypeRefund = 1 // 退款 AfsApproveTypeReturnGoods = 2 // 退货 AfsApproveTypeRefused = 3 // 驳回 ) const ( TimerTypeNoOverride = 0 // GetStatusActionConfig 返回表示不修改缺省配置 TimerTypeByPass = 1 TimerTypeBaseNow = 2 TimerTypeBaseStatusTime = 3 TimerTypeBaseOrderCreatedAt = 4 ) type StatusActionParams struct { TimerType int // 参见上面的相关常量定义 Timeout time.Duration // 超时时间,0在GetStatusActionConfig返回时表示不修改缺省 TimeoutGap int // 以秒为单位的随机时间,0在GetStatusActionConfig返回时表示不修改缺省 } type OrderInFoChange struct { } func (s *StatusActionParams) GetRefTimeout(statusTime time.Time, orderCreatedAt time.Time) (timeout time.Duration) { switch s.TimerType { case TimerTypeBaseNow: timeout = s.Timeout case TimerTypeBaseStatusTime: timeout = statusTime.Sub(time.Now()) + s.Timeout case TimerTypeBaseOrderCreatedAt: timeout = orderCreatedAt.Sub(time.Now()) + s.Timeout default: timeout = 0 } if timeout < 0 { timeout = 0 } return timeout } var ( CancelWaybillReasonStrNotAcceptIntime = "没有及时抢单" CancelWaybillReasonStrSwitch2SelfFailed = "转自送失败" CancelWaybillReasonStrOrderAlreadyFinished = "订单已经结束" CancelWaybillReasonStrActive = "操作由人员主动发起" ) var ( ErrCanNotFindItem = errors.New("没有找到指定的东西") ErrStoreHaveNoCourier = errors.New("门店没有绑定相应的配送信息") ) var ( CurOrderManager IOrderManager CurStoreManager IStoreManager PurchasePlatformHandlers map[int]IPurchasePlatformHandler PurchaseOrderHandlers map[int]IPurchasePlatformOrderHandler ) type IOrderManager interface { SaveOrder(order *model.GoodsOrder, isAdjust bool, db *dao.DaoDB) (isDuplicated bool, err error) OnOrderNew(order *model.GoodsOrder, orderStatus *model.OrderStatus) (err error) OnOrderAdjust(order *model.GoodsOrder, orderStatus *model.OrderStatus) (err error) OnOrderStatusChanged(vendorOrgCode string, orderStatus *model.OrderStatus) (err error) OnOrderMsg(order *model.GoodsOrder, vendorStatus, remark string) (err error) OnWaybillStatusChanged(bill *model.Waybill) (err error) CreateAfsOrderFromOrder(vendorOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) LoadOrder(vendorOrderID string, vendorID int) (order *model.GoodsOrder, err error) LoadOrder2(vendorOrderID2 string, vendorID int) (order *model.GoodsOrder, err error) LoadOrderFinancial(vendorOrderID string, vendorID int) (order *model.OrderFinancial, err error) LoadOrderFinancial2(vendorOrderID2 string, vendorID int) (order *model.OrderFinancial, err error) UpdateOrderStatusAndDeliveryFlag(order *model.GoodsOrder) (err error) UpdateOrderFields(order *model.GoodsOrder, fieldList []string) (err error) LoadStoreDetail(storeID, vendorID int) (storeDetail *dao.StoreDetail, err error) LoadWaybill(vendorWaybillID string, waybillVendorID int) (bill *model.Waybill, err error) OnOrderComments(orderCommentList []*model.OrderComment) (err error) SaveOrderFinancialInfo(order *model.OrderFinancial, operation string) (err error) SaveAfsOrderFinancialInfo(afsOrder *model.AfsOrder) (err error) GetOrderWaybillInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID int, isNotEnded, isGetPos bool) (bills []*model.WaybillExt, err error) ChangeOrderInfo(order *model.GoodsOrder) (err error) // afs order OnAfsOrderAdjust(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus) (err error) OnAfsOrderNew(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus) (err error) OnAfsOrderStatusChanged(orderStatus *model.OrderStatus) (err error) LoadAfsOrder(vendorAfsOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) UpdateAfsOrderFields(afsOrder *model.AfsOrder, fieldList []string) (err error) GetStatusDuplicatedCount(status *model.OrderStatus) (duplicatedCount int) } type IStoreManager interface { OnStoreStatusChanged(vendorStoreID string, vendorID int, storeStatus int) (err error) OnCourierStoreStatusChanged(ctx *jxcontext.Context, vendorStoreID string, vendorID int, auditStatus int) (err error) } // purchase handler中 // 所有Sync,Refresh开头的函数都必须自己清理sync_status标记 // 所有非以Sync,Refresh开头的函数不用自己清理sync_status标记(VendorSync统一处理) type IPurchasePlatformHandler interface { IPurchasePlatformActHandler IPurchasePlatformOrderHandler GetVendorID() int // 只与平台相关 GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) //////// // Store ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (store *dao.StoreDetail, err error) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) CreateStore2(db *dao.DaoDB, storeID int, userName string) (vendorStoreID string, err error) DeleteStore(db *dao.DaoDB, storeID int, userName string) (err error) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string, storeID int64) (err error) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) } // db *dao.DaoDB, type IMultipleStoresHandler interface { IPurchasePlatformHandler GetAllCategories(ctx *jxcontext.Context, vendorOrgCode string) (cats []*BareCategoryInfo, err error) // CreateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) // UpdateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error // DeleteCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error // ReorderCategories(db *dao.DaoDB, parentCatID int, userName string) (err error) CreateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error) UpdateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error) DeleteCategory2(ctx *jxcontext.Context, vendorOrgCode, vendorCatID string) (err error) ReorderCategories2(ctx *jxcontext.Context, vendorOrgCode, vendorParentCatID string, vendorCatIDList []string) (err error) // sku // CreateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) // UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) // DeleteSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) // ReadSku(ctx *jxcontext.Context, vendorOrgCode, vendorSkuID string) (skuNameExt *model.SkuNameExt, err error) CreateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error) UpdateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error) DeleteSku2(ctx *jxcontext.Context, vendorOrgCode string, sku *StoreSkuInfo) (err error) // RefreshAllSkusID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) GetSkus(ctx *jxcontext.Context, vendorOrgCode string, skuID int, vendorSkuID string) (skuNameList []*SkuNameInfo, err error) } type ISingleStoreHandler interface { IPurchasePlatformHandler ISingleStoreStoreSkuHandler // SyncStoreCategory(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync bool) (hint string, err error) // RefreshStoresAllSkusID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool, storeIDs []int) (hint string, err error) } type BasePurchasePlatform struct { } func (p *BasePurchasePlatform) GetStatusActionTimeout(order *model.GoodsOrder, statusType, status int) (params *StatusActionParams) { return params } func (c *BasePurchasePlatform) CanSwitch2SelfDeliver(order *model.GoodsOrder) (isCan bool, err error) { return true, nil } func init() { PurchasePlatformHandlers = make(map[int]IPurchasePlatformHandler) PurchaseOrderHandlers = make(map[int]IPurchasePlatformOrderHandler) DeliveryPlatformHandlers = make(map[int]*DeliveryPlatformHandlerInfo) } func InitOrderManager(curOrderManager IOrderManager) { CurOrderManager = curOrderManager } func InitStoreManager(curStoreManager IStoreManager) { CurStoreManager = curStoreManager } func RegisterPurchasePlatform(handler IPurchasePlatformHandler) { vendorID := handler.GetVendorID() if !(model.IsPurchaseVendorExist(vendorID)) { panic(fmt.Sprintf("purchase vendor:%d is illegal", vendorID)) } if _, ok := PurchasePlatformHandlers[vendorID]; ok { panic(fmt.Sprintf("purchase vendor:%d, already exists", vendorID)) } _, isSingleStore := handler.(ISingleStoreHandler) _, isMultiStore := handler.(IMultipleStoresHandler) if !isSingleStore && !isMultiStore { panic(fmt.Sprintf("platform:%d type is wrong!", vendorID)) } PurchasePlatformHandlers[vendorID] = handler } func RegisterPurchaseOrderHandler(vendorID int, handler IPurchasePlatformOrderHandler) { PurchaseOrderHandlers[vendorID] = handler } func GetPurchasePlatformFromVendorID(vendorID int) IPurchasePlatformHandler { return PurchasePlatformHandlers[vendorID] } func GetPurchaseOrderHandlerFromVendorID(vendorID int) (handler IPurchasePlatformOrderHandler) { handler = PurchasePlatformHandlers[vendorID] if handler == nil { handler = PurchaseOrderHandlers[vendorID] } return handler } func GetPurchasePlatformVendorIDs() (vendorIDs []int) { for k := range PurchasePlatformHandlers { vendorIDs = append(vendorIDs, k) } return vendorIDs } func GetMultiStoreVendorIDs() (vendorIDs []int) { for k, v := range PurchasePlatformHandlers { if _, ok := v.(IMultipleStoresHandler); ok { vendorIDs = append(vendorIDs, k) } } return vendorIDs } func GetSingleStoreVendorIDs() (vendorIDs []int) { for k, v := range PurchasePlatformHandlers { if _, ok := v.(ISingleStoreHandler); ok { vendorIDs = append(vendorIDs, k) } } return vendorIDs } func IsMultiStore(vendorID int) bool { if _, ok := GetPurchasePlatformFromVendorID(vendorID).(IMultipleStoresHandler); ok { return true } return false } func GetRidderPositionGetter(vendorID int) (handler IRidderPositionGetter) { if handlerInfo := GetDeliveryPlatformFromVendorID(vendorID); handlerInfo != nil { if handler, _ = handlerInfo.Handler.(IRidderPositionGetter); handler != nil { return handler } } handler, _ = GetPurchasePlatformFromVendorID(vendorID).(IRidderPositionGetter) return handler } func GetWaybillTipUpdater(vendorID int) (handler IAddWaybillTip) { if handlerInfo := GetDeliveryPlatformFromVendorID(vendorID); handlerInfo != nil { if handler, _ = handlerInfo.Handler.(IAddWaybillTip); handler != nil { return handler } } handler, _ = GetPurchasePlatformFromVendorID(vendorID).(IAddWaybillTip) return handler }