diff --git a/business/jxcallback/orderman/order.go b/business/jxcallback/orderman/order.go index aeb29c68d..82e66354e 100644 --- a/business/jxcallback/orderman/order.go +++ b/business/jxcallback/orderman/order.go @@ -162,12 +162,12 @@ func (c *OrderManager) OnOrderAdjust(order *model.GoodsOrder, orderStatus *model return err } -func (c *OrderManager) OnOrderStatusChanged(orderStatus *model.OrderStatus) (err error) { +func (c *OrderManager) OnOrderStatusChanged(vendorOrgCode string, orderStatus *model.OrderStatus) (err error) { // 有些平台(比如美团外卖),在新订单事件没有成功返回,但在重发订单消息前,订单状态转换,则不会再重发新订单事件,特殊处理一下 if orderStatus.Status == model.OrderStatusAccepted { if _, err2 := c.LoadOrder(orderStatus.VendorOrderID, orderStatus.VendorID); err2 == ErrCanNotFindOrder { if handler := partner.GetPurchaseOrderHandlerFromVendorID(orderStatus.VendorID); handler != nil { - if order, err2 := handler.GetOrder(orderStatus.VendorOrderID); err2 == nil { + if order, err2 := handler.GetOrder(vendorOrgCode, orderStatus.VendorOrderID); err2 == nil { c.OnOrderNew(order, orderStatus) } } @@ -634,7 +634,7 @@ func (c *OrderManager) UpdateOrderFields(order *model.GoodsOrder, fieldList []st return err } -func (c *OrderManager) RefreshHistoryOrdersEarningPrice(ctx *jxcontext.Context, vendorOrderID string, actID int, vendorIDs []int, storeID int, fromDate, toDate string, isAsync, isContinueWhenError bool) (hint string, err error) { +func (c *OrderManager) RefreshHistoryOrdersEarningPrice(ctx *jxcontext.Context, vendorOrderID string, actID int, vendorIDs []int, storeID int, fromDate, toDate string, isAsync, isContinueWhenError bool) (hint string, errCode string, err error) { var ( orderList []*model.GoodsOrder fromDateParam time.Time @@ -652,10 +652,10 @@ func (c *OrderManager) RefreshHistoryOrdersEarningPrice(ctx *jxcontext.Context, actBeginAt := actList.Data[0].BeginAt actEndAt := actList.Data[0].EndAt if fromDateParam.Sub(actBeginAt) > 0 && fromDateParam.Sub(actEndAt) > 0 { - return "", errors.New(fmt.Sprintf("结算活动有效时间范围与订单创建时间范围不一致!,活动时间范围:[%v] 至 [%v] ,订单创建时间范围 :[%v] 至 [%v]", actBeginAt, actEndAt, fromDateParam, toDateParam)) + return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("结算活动有效时间范围与订单创建时间范围不一致!,活动时间范围:[%v] 至 [%v] ,订单创建时间范围 :[%v] 至 [%v]", actBeginAt, actEndAt, fromDateParam, toDateParam)) } if actBeginAt.Sub(toDateParam) > 0 && actEndAt.Sub(toDateParam) > 0 { - return "", errors.New(fmt.Sprintf("结算活动有效时间范围与订单创建时间范围不一致!,活动时间范围:[%v] 至 [%v] ,订单创建时间范围 :[%v] 至 [%v]", actBeginAt, actEndAt, fromDateParam, toDateParam)) + return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("结算活动有效时间范围与订单创建时间范围不一致!,活动时间范围:[%v] 至 [%v] ,订单创建时间范围 :[%v] 至 [%v]", actBeginAt, actEndAt, fromDateParam, toDateParam)) } if fromDateParam.Sub(actBeginAt) > 0 { beginAt = fromDateParam @@ -674,17 +674,17 @@ func (c *OrderManager) RefreshHistoryOrdersEarningPrice(ctx *jxcontext.Context, } orderList, _ = dao.QueryOrders(db, vendorOrderID, actID, vendorIDs, storeID, beginAt, endAt) } else { - return "", errors.New(fmt.Sprintf("未查询到相关结算活动,活动ID:[%d]", actID)) + return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("未查询到相关结算活动,活动ID:[%d]", actID)) } } else if fromDate == "" && toDate == "" { actList, _ := dao.QueryActs(db, actID, 0, math.MaxInt32, 0, "", -1, nil, nil, nil, 0, 0, 0, utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue) if len(actList.Data) > 0 { orderList, _ = dao.QueryOrders(db, vendorOrderID, actID, vendorIDs, storeID, actList.Data[0].BeginAt, actList.Data[0].EndAt) } else { - return "", errors.New(fmt.Sprintf("未查询到相关结算活动,活动ID:[%d]", actID)) + return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("未查询到相关结算活动,活动ID:[%d]", actID)) } } else { - return "", errors.New(fmt.Sprintf("间隔时间必须完整!时间范围:[%v] 至 [%v]", fromDate, toDate)) + return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("间隔时间必须完整!时间范围:[%v] 至 [%v]", fromDate, toDate)) } } else { if fromDate != "" && toDate != "" { @@ -692,15 +692,15 @@ func (c *OrderManager) RefreshHistoryOrdersEarningPrice(ctx *jxcontext.Context, toDateParam = utils.Str2Time(toDate) //若未传入活动ID,且时间间隔大于10天则不允许查询 if math.Ceil(toDateParam.Sub(fromDateParam).Hours()/24) > 10 { - return "", errors.New(fmt.Sprintf("查询间隔时间不允许大于10天!时间范围:[%v] 至 [%v]", fromDate, toDate)) + return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("查询间隔时间不允许大于10天!时间范围:[%v] 至 [%v]", fromDate, toDate)) } orderList, _ = dao.QueryOrders(db, vendorOrderID, actID, vendorIDs, storeID, fromDateParam, toDateParam) } else { - return "", errors.New(fmt.Sprintf("若不按活动查询则间隔时间必须完整!时间范围:[%v] 至 [%v]", fromDate, toDate)) + return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("若不按活动查询则间隔时间必须完整!时间范围:[%v] 至 [%v]", fromDate, toDate)) } } if len(orderList) <= 0 { - return "", errors.New(fmt.Sprintf("未查询到订单!,vendorOrderID : %s, actID : %d, 时间范围:[%v] 至 [%v]", vendorOrderID, actID, fromDate, toDate)) + return "", model.ErrCodePoint, errors.New(fmt.Sprintf("所选活动没有要更新结算价的订单!,vendorOrderID : %s, actID : %d, 时间范围:[%v] 至 [%v]", vendorOrderID, actID, fromDate, toDate)) } task := tasksch.NewParallelTask("刷新历史订单结算价", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { @@ -718,24 +718,28 @@ func (c *OrderManager) RefreshHistoryOrdersEarningPrice(ctx *jxcontext.Context, }() for _, value := range order.Skus { if _, err = dao.UpdateEntity(db, value, "EarningPrice", "StoreSubID"); err != nil { - return "", err + return nil, err } } jxutils.RefreshOrderSkuRelated(order) - if _, err = dao.UpdateEntity(db, order, "EarningPrice"); err != nil { - return "", err + num, err := dao.UpdateEntity(db, order, "EarningPrice") + if err != nil { + return nil, err } dao.Commit(db) + retVal = []string{utils.Int64ToStr(num)} return retVal, err }, orderList) tasksch.HandleTask(task, nil, true).Run() if !isAsync { - _, err = task.GetResult(0) - hint = "1" + resultNum, err2 := task.GetResult(0) + if err = err2; err == nil { + hint = resultNum[0].(string) + } } else { hint = task.GetID() } - return hint, err + return hint, model.ErrCodeSuccess, err } func RefreshOrdersWithoutJxStoreID(ctx *jxcontext.Context, fromDate, toDate string, isAsync, isContinueWhenError bool) (hint string, err error) { diff --git a/business/jxcallback/orderman/order_afs.go b/business/jxcallback/orderman/order_afs.go index f550d9555..f65bd0dba 100644 --- a/business/jxcallback/orderman/order_afs.go +++ b/business/jxcallback/orderman/order_afs.go @@ -385,6 +385,7 @@ func (c *OrderManager) CreateAfsOrderFromOrder(vendorOrderID string, vendorID in JxStoreID: order.JxStoreID, VendorStoreID: order.VendorStoreID, StoreID: order.StoreID, + VendorOrgCode: order.VendorOrgCode, } } else { globals.SugarLogger.Warnf("CreateAfsOrderFromOrder, orderID:%s is not found from partner.CurOrderManager.LoadOrder", vendorOrderID) diff --git a/business/jxcallback/orderman/order_comment.go b/business/jxcallback/orderman/order_comment.go index 484d5ea7d..5bdd9ed26 100644 --- a/business/jxcallback/orderman/order_comment.go +++ b/business/jxcallback/orderman/order_comment.go @@ -84,7 +84,9 @@ func (c *OrderManager) OnOrderComments(orderCommentList []*model.OrderComment) ( err = nil isNewComment = true if orderComment.IsReplied == 0 && time.Now().Sub(orderComment.CommentCreatedAt) < time.Duration(orderComment.ModifyDuration)*time.Hour { - c.replyOrderComment(orderComment) + if storeDetail, err2 := dao.GetStoreDetail(db, orderComment.StoreID, orderComment.VendorID); err2 == nil { + c.replyOrderComment(storeDetail.VendorOrgCode, orderComment) + } } } if isNewComment /*&& orderComment.Score <= JX_BAD_COMMENTS_MAX_LEVEL*/ || !isNewComment && orderComment.Score > JX_BAD_COMMENTS_MAX_LEVEL { // 如果是直接非差评,或补评仍然是差评,忽略 @@ -164,7 +166,7 @@ func (c *OrderManager) OnOrderComments(orderCommentList []*model.OrderComment) ( return err } -func (c *OrderManager) replyOrderComment(orderComment *model.OrderComment) (err error) { +func (c *OrderManager) replyOrderComment(vendorOrgCode string, orderComment *model.OrderComment) (err error) { score := int(orderComment.Score) if score <= 2 { score = 1 @@ -177,7 +179,7 @@ func (c *OrderManager) replyOrderComment(orderComment *model.OrderComment) (err globals.SugarLogger.Debugf("replyOrderComment orderID:%s, delaySeconds:%d, content:%s", orderComment.VendorOrderID, delaySeconds, content) utils.AfterFuncWithRecover(time.Duration(delaySeconds)*time.Second, func() { if handler := partner.GetPurchaseOrderHandlerFromVendorID(orderComment.VendorID); handler != nil { - if err = handler.ReplyOrderComment(jxcontext.AdminCtx, orderComment, content); err != nil { + if err = handler.ReplyOrderComment(jxcontext.AdminCtx, vendorOrgCode, orderComment, content); err != nil { globals.SugarLogger.Debugf("replyOrderComment orderID:%s, error:%v", orderComment.VendorOrderID, err) } } else { diff --git a/business/jxcallback/orderman/orderman_ext.go b/business/jxcallback/orderman/orderman_ext.go index e3ceefd1c..39c6b15d3 100644 --- a/business/jxcallback/orderman/orderman_ext.go +++ b/business/jxcallback/orderman/orderman_ext.go @@ -16,6 +16,7 @@ import ( "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/apimanager" "github.com/astaxie/beego/orm" ) @@ -141,7 +142,7 @@ func (c *OrderManager) GetOrderInfo(ctx *jxcontext.Context, vendorOrderID string if err == nil && num > 0 { order = orders[0] if isRefresh && vendorID == model.VendorIDJD { - tmpOrder, err2 := partner.GetPurchaseOrderHandlerFromVendorID(vendorID).GetOrder(vendorOrderID) + tmpOrder, err2 := partner.GetPurchaseOrderHandlerFromVendorID(vendorID).GetOrder(order.VendorOrgCode, vendorOrderID) if err = err2; err == nil { order.CurrentConsigneeMobile = tmpOrder.ConsigneeMobile } else { @@ -913,21 +914,26 @@ func (c *OrderManager) AmendMissingOrders(ctx *jxcontext.Context, vendorIDs []in } type tDateVendorPair struct { - QueryDate time.Time - VendorID int + QueryDate time.Time + VendorID int + VendorOrgCode string } var dateVendorList []*tDateVendorPair for _, vendorID := range vendorIDs { - for tmpDate := fromDate; tmpDate.Sub(toDate) <= 0; tmpDate = tmpDate.Add(24 * time.Hour) { - dateVendorList = append(dateVendorList, &tDateVendorPair{ - QueryDate: tmpDate, - VendorID: vendorID, - }) + for _, vendorOrgCode := range apimanager.CurAPIManager.GetAppOrgCodeList(vendorID) { + for tmpDate := fromDate; tmpDate.Sub(toDate) <= 0; tmpDate = tmpDate.Add(24 * time.Hour) { + dateVendorList = append(dateVendorList, &tDateVendorPair{ + QueryDate: tmpDate, + VendorID: vendorID, + VendorOrgCode: vendorOrgCode, + }) + } } } type tOrderVendorPair struct { VendorOrderID string VendorID int + VendorOrgCode string } if len(dateVendorList) > 0 { var missingOrderList []*tOrderVendorPair @@ -950,13 +956,14 @@ func (c *OrderManager) AmendMissingOrders(ctx *jxcontext.Context, vendorIDs []in func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { vendorDate := batchItemList[0].(*tDateVendorPair) if handler, _ := partner.GetPurchaseOrderHandlerFromVendorID(vendorDate.VendorID).(partner.IPurchasePlatformStoreSkuHandler); handler != nil { - orderIDs, err2 := handler.ListOrders(ctx, task, vendorDate.QueryDate, vendorStoreIDMap[vendorDate.VendorID]) + orderIDs, err2 := handler.ListOrders(ctx, vendorDate.VendorOrgCode, task, vendorDate.QueryDate, vendorStoreIDMap[vendorDate.VendorID]) if err = err2; err == nil && len(orderIDs) > 0 { var orderList []*tOrderVendorPair for _, v := range orderIDs { orderList = append(orderList, &tOrderVendorPair{ VendorOrderID: v, VendorID: vendorDate.VendorID, + VendorOrgCode: vendorDate.VendorOrgCode, }) } retVal = orderList @@ -989,7 +996,7 @@ func (c *OrderManager) AmendMissingOrders(ctx *jxcontext.Context, vendorIDs []in func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { pair := batchItemList[0].(*tOrderVendorPair) if handler := partner.GetPurchaseOrderHandlerFromVendorID(pair.VendorID); handler != nil { - order, err2 := handler.GetOrder(pair.VendorOrderID) + order, err2 := handler.GetOrder(pair.VendorOrgCode, pair.VendorOrderID) if err = err2; err == nil { isDuplicated, err2 := c.SaveOrder(order, false, dao.GetDB()) if err2 == nil && !isDuplicated { @@ -1042,7 +1049,7 @@ func (c *OrderManager) RefreshOrderFinancial(ctx *jxcontext.Context, fromTime, t order := batchItemList[0].(*model.GoodsOrder) handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID) if handler != nil { - remoteOrder, err2 := handler.GetOrder(order.VendorOrderID) + remoteOrder, err2 := handler.GetOrder(order.VendorOrgCode, order.VendorOrderID) if err = err2; err == nil { order.TotalShopMoney = remoteOrder.TotalShopMoney order.PmSubsidyMoney = remoteOrder.PmSubsidyMoney diff --git a/business/jxcallback/orderman/waybill.go b/business/jxcallback/orderman/waybill.go index 8ef0425a1..1e9cba812 100644 --- a/business/jxcallback/orderman/waybill.go +++ b/business/jxcallback/orderman/waybill.go @@ -176,7 +176,7 @@ func (w *OrderManager) OnWaybillStatusChanged(bill *model.Waybill) (err error) { StatusTime: bill.StatusTime, Remark: bill.Remark, } - w.OnOrderStatusChanged(fakeOrderStatus) + w.OnOrderStatusChanged(bill.VendorOrgCode, fakeOrderStatus) } } return err diff --git a/business/jxcallback/scheduler/basesch/basesch.go b/business/jxcallback/scheduler/basesch/basesch.go index 0d7716a12..72a09852d 100644 --- a/business/jxcallback/scheduler/basesch/basesch.go +++ b/business/jxcallback/scheduler/basesch/basesch.go @@ -124,7 +124,8 @@ func (c *BaseScheduler) SelfDeliverDelivering(order *model.GoodsOrder, userName func (c *BaseScheduler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) { globals.SugarLogger.Infof("SelfDeliverDelivered orderID:%s", order.VendorOrderID) - if /*order.LockStatus == model.OrderStatusUnknown && */ order.Status == model.OrderStatusDelivering { + if /*order.LockStatus == model.OrderStatusUnknown && */ order.Status >= model.OrderStatusFinishedPickup && + order.Status <= model.OrderStatusDelivering { if c.IsReallyCallPlatformAPI { err = utils.CallFuncLogError(func() error { return partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).SelfDeliverDelivered(order, userName) diff --git a/business/jxcallback/scheduler/basesch/basesch_ext.go b/business/jxcallback/scheduler/basesch/basesch_ext.go index 3ceada398..31d20b865 100644 --- a/business/jxcallback/scheduler/basesch/basesch_ext.go +++ b/business/jxcallback/scheduler/basesch/basesch_ext.go @@ -2,10 +2,13 @@ package basesch import ( "fmt" + "time" + "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/baseapi/utils/errlist" "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" @@ -13,6 +16,10 @@ import ( "git.rosy.net.cn/jx-callback/globals" ) +const ( + autoSelfTakeCode = "135246" +) + func (c *BaseScheduler) CreateWaybillOnProviders(ctx *jxcontext.Context, order *model.GoodsOrder, courierVendorIDs, excludeCourierVendorIDs []int, maxDeliveryFee int64, createOnlyOne bool) (bills []*model.Waybill, err error) { userName := ctx.GetUserName() globals.SugarLogger.Infof("CreateWaybillOnProviders orderID:%s userName:%s, courierVendorIDs:%v, excludeCourierVendorIDs:%v", order.VendorOrderID, userName, courierVendorIDs, excludeCourierVendorIDs) @@ -222,18 +229,61 @@ func (c *BaseScheduler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOr } func (c *BaseScheduler) ConfirmSelfTake(ctx *jxcontext.Context, vendorOrderID string, vendorID int, selfTakeCode string) (err error) { - if vendorID == model.VendorIDJD { - if selfTakeCode == "135246" { - if selfTakeCode, err = jd.CurPurchaseHandler.GetSelfTakeCode(ctx, vendorOrderID); err != nil { - return fmt.Errorf("获取订单:%s自提货码失败,原始错误:%s", vendorOrderID, err.Error()) - } - if selfTakeCode == "" { - return fmt.Errorf("订单:%s看起来不是一个自提订单,如果确认是自提订单,请联系开发", vendorOrderID) - } - } - err = jd.CurPurchaseHandler.ConfirmSelfTake(ctx, vendorOrderID, selfTakeCode) - } else { - err = fmt.Errorf("自提核销不支持%s平台订单", model.VendorChineseNames[vendorID]) + order, err2 := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID) + if err = err2; err == nil { + err = c.confirmSelfTake(ctx, order, selfTakeCode) } return err } + +func (c *BaseScheduler) confirmSelfTake(ctx *jxcontext.Context, order *model.GoodsOrder, selfTakeCode string) (err error) { + globals.SugarLogger.Debugf("confirmSelfTake orderID:%s, selfTakeCode:%s", order.VendorOrderID, selfTakeCode) + if order.VendorID == model.VendorIDJD { + if selfTakeCode == autoSelfTakeCode { + if selfTakeCode, err = jd.CurPurchaseHandler.GetSelfTakeCode(ctx, order); err != nil { + return fmt.Errorf("获取订单:%s自提货码失败,原始错误:%s", order.VendorOrderID, err.Error()) + } + if selfTakeCode == "" { + return fmt.Errorf("订单:%s看起来不是一个自提订单,如果确认是自提订单,请联系开发", order.VendorOrderID) + } + } + err = jd.CurPurchaseHandler.ConfirmSelfTake(ctx, order, selfTakeCode) + } else { + err = fmt.Errorf("自提核销不支持%s平台订单", model.VendorChineseNames[order.VendorID]) + } + return err +} + +func (c *BaseScheduler) ConfirmSelfTakeOrders(ctx *jxcontext.Context, vendorIDs []int, orderCreatedAfter, orderCreatedBefore time.Time, isAsync, isContinueWhenError bool) (hint string, err error) { + orderList, err := dao.GetPendingFakeOrders(dao.GetDB(), vendorIDs, orderCreatedAfter, orderCreatedBefore) + if err == nil { + if len(orderList) > 0 { + task := tasksch.NewParallelTask(fmt.Sprintf("自动完成内部自提单%v,%s", vendorIDs, utils.Time2Str(orderCreatedAfter)), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + order := batchItemList[0].(*model.GoodsOrder) + if order.Status == model.OrderStatusAccepted { + if handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID); handler != nil { + err = handler.AcceptOrRefuseOrder(order, true, ctx.GetUserName()) + time.Sleep(2 * time.Second) + } + } + if err == nil { + if err = c.confirmSelfTake(ctx, order, autoSelfTakeCode); err == nil { + retVal = []int{1} + } + } + return retVal, err + }, orderList) + tasksch.HandleTask(task, nil, true).Run() + if isAsync { + hint = task.GetID() + } else { + resultList, err2 := task.GetResult(0) + if err = err2; err == nil { + hint = utils.Int2Str(len(resultList)) + } + } + } + } + return hint, err +} diff --git a/business/jxcallback/scheduler/defsch/defsch.go b/business/jxcallback/scheduler/defsch/defsch.go index 45487d5c2..1d757083c 100644 --- a/business/jxcallback/scheduler/defsch/defsch.go +++ b/business/jxcallback/scheduler/defsch/defsch.go @@ -225,7 +225,7 @@ func init() { partner.CurOrderManager.OnOrderMsg(order, "自动接单失败", err.Error()) // 为了解决京东新消息与接单消息乱序的问题 if errWithCode, ok := err.(*utils.ErrorWithCode); ok && errWithCode.Level() == 1 && errWithCode.IntCode() == -1 { - if order2, err2 := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).GetOrder(order.VendorOrderID); err2 == nil { + if order2, err2 := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).GetOrder(order.VendorOrgCode, order.VendorOrderID); err2 == nil { if order2.Status > order.Status { order.Status = order2.Status jxutils.CallMsgHandlerAsync(func() { diff --git a/business/jxstore/act/act.go b/business/jxstore/act/act.go index d30e74910..4de287908 100644 --- a/business/jxstore/act/act.go +++ b/business/jxstore/act/act.go @@ -115,7 +115,7 @@ func ActStoreSkuParam2Model(ctx *jxcontext.Context, db *dao.DaoDB, act *model.Ac if !(len(vendorIDs) == 1 && vendorIDs[0] == model.VendorIDJD || act.Type == model.ActSkuFake) { effectActStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, vendorIDs, storeIDs, skuIDs, act.BeginAt, act.EndAt) if err != nil { - globals.SugarLogger.Errorf("updateActPrice4StoreSkuNameNew can not get sku promotion info for error:%v", err) + globals.SugarLogger.Errorf("GetEffectiveActStoreSkuInfo can not get sku promotion info for error:%v", err) return nil, nil, nil, err } if len(effectActStoreSkuList) > 0 { @@ -293,11 +293,13 @@ func AddActStoreSkuBind(ctx *jxcontext.Context, db *dao.DaoDB, actID int, actSto } if act.Type != model.ActSkuFake { for _, act := range actMap { - if _, err = dao.UpdateEntityLogically(db, partner.Act2ActMap(act), - map[string]interface{}{ - model.FieldSyncStatus: act.SyncStatus | model.SyncFlagModifiedMask, - }, ctx.GetUserName(), nil); err != nil { - return err + if act.VendorID != model.VendorIDJX { + if _, err = dao.UpdateEntityLogically(db, partner.Act2ActMap(act), + map[string]interface{}{ + model.FieldSyncStatus: act.SyncStatus | model.SyncFlagModifiedMask, + }, ctx.GetUserName(), nil); err != nil { + return err + } } } } @@ -400,11 +402,15 @@ func PreCreateAct(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, actRu return preCreateActInfo, nil } -func CreateAct(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam, isAsync bool) (hint string, err error) { +func CreateAct(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, vendorOrgCode string, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam, isAsync bool) (hint string, err error) { if err = checkActValidation(act, vendorIDs); err != nil { return "", err } act.VendorMask = model.GetVendorMask(vendorIDs...) + if act.VendorMask&(^model.GetVendorMask(model.VendorIDJX)) != 0 && + vendorOrgCode == "" { + return "", fmt.Errorf("必须指定平台分账号信息") + } setActDefault(act) db := dao.GetDB() @@ -435,8 +441,9 @@ func CreateAct(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, actRules var actMapList []*model.ActMap for _, vendorID := range validVendorIDs { actMap := &model.ActMap{ - ActID: act.ID, - VendorID: vendorID, + ActID: act.ID, + VendorID: vendorID, + VendorOrgCode: vendorOrgCode, } if !(vendorID == model.VendorIDJX || act.Type == model.ActSkuFake) { actMap.SyncStatus = model.SyncFlagNewMask @@ -529,9 +536,10 @@ func (a *ActManager) CreateActFromVendor(ctx *jxcontext.Context, act2 *model.Act func createActFromVendor(ctx *jxcontext.Context, db *dao.DaoDB, act2 *model.Act2, actStoreSku []*model.ActStoreSku2) (actID int, err error) { actMap := &model.ActMap{ - VendorID: act2.VendorID, - VendorActID: act2.VendorActID, - SyncStatus: 0, + VendorID: act2.VendorID, + VendorOrgCode: act2.VendorOrgCode, + VendorActID: act2.VendorActID, + SyncStatus: 0, } dao.WrapAddIDCULDEntity(actMap, ctx.GetUserName()) if actMap.VendorActID != "" { @@ -710,7 +718,7 @@ func DeleteActStoreSkuBind(ctx *jxcontext.Context, db *dao.DaoDB, actID int, act syncStatus = model.SyncFlagDeletedMask } syncStatus |= act.SyncStatus - if act.Type != model.ActSkuFake { + if act.Type != model.ActSkuFake && vendorID != model.VendorIDJX { if _, err = dao.UpdateEntityLogically(db, partner.Act2ActMap(act), map[string]interface{}{ model.FieldSyncStatus: syncStatus, diff --git a/business/jxstore/cms/cms.go b/business/jxstore/cms/cms.go index 5cb3071bc..59f0ecda8 100644 --- a/business/jxstore/cms/cms.go +++ b/business/jxstore/cms/cms.go @@ -359,7 +359,7 @@ func UpdateConfig(ctx *jxcontext.Context, key, configType, value string) (hint s if vendorID != model.VendorIDJX { dao.SetStoreSkuSyncStatus(db, vendorID, storeIDs, nil, model.SyncFlagPriceMask) } else { - ReCalculateJxPrice(ctx, storeIDs) + hint, err = ReCalculateJxPrice(db, ctx, storeIDs) } } case model.ConfigTypeFreightPack: diff --git a/business/jxstore/cms/sku.go b/business/jxstore/cms/sku.go index f4a4b0e8a..202d80a75 100644 --- a/business/jxstore/cms/sku.go +++ b/business/jxstore/cms/sku.go @@ -52,17 +52,26 @@ func GetVendorCategories(ctx *jxcontext.Context, vendorID int, parentID string) } // parentID 为-1表示所有 -func GetCategories(ctx *jxcontext.Context, parentID int) (cats []*model.SkuCategory, err error) { - params := []interface{}{ - utils.DefaultTimeValue, +func GetCategories(ctx *jxcontext.Context, parentID int) (catList []*dao.SkuCategoryWithVendor, err error) { + db := dao.GetDB() + cats, err := dao.GetCategories(db, parentID, nil) + if err == nil { + var ids []int + for _, v := range cats { + ids = append(ids, v.ID) + } + thingMapMap, err2 := dao.GetThingMapMap(db, model.ThingTypeCategory, nil, ids) + // globals.SugarLogger.Debug(utils.Format4Output(thingMapMap, false)) + if err = err2; err == nil { + for _, v := range cats { + catList = append(catList, &dao.SkuCategoryWithVendor{ + SkuCategory: v, + MapList: thingMapMap[int64(v.ID)], + }) + } + } } - sql := "SELECT * FROM sku_category WHERE deleted_at = ?" - if parentID != -1 { - sql += " AND parent_id = ?" - params = append(params, parentID) - } - sql += " ORDER BY level, seq" - return cats, dao.GetRows(nil, &cats, sql, params) + return catList, err } func AddCategory(ctx *jxcontext.Context, cat *model.SkuCategory, userName string) (outCat *model.SkuCategory, err error) { @@ -88,7 +97,15 @@ func AddCategory(ctx *jxcontext.Context, cat *model.SkuCategory, userName string dao.WrapAddIDCULDEntity(cat, userName) cat.JdSyncStatus = model.SyncFlagNewMask cat.JdID = 0 + cat.Status = model.CategoryStatusEnable cat.Name = strings.Trim(cat.Name, " ") + if cat.Img != "" { + _, err2 := datares.TryRegisterDataResource(ctx, cat.Name, cat.Img, model.ImgTypeLocal, false) + if err = err2; err != nil { + return nil, err + } + } + if cat.Seq <= 0 { var maxSeq struct { MaxSeq int @@ -109,7 +126,7 @@ func AddCategory(ctx *jxcontext.Context, cat *model.SkuCategory, userName string dao.Rollback(db) return nil, err } - if err = OnCreateThing(db, int64(cat.ID), model.ThingTypeCategory); err != nil { + if err = OnCreateThing(ctx, db, nil, int64(cat.ID), model.ThingTypeCategory); err != nil { dao.Rollback(db) return nil, err } @@ -135,6 +152,22 @@ func UpdateCategory(ctx *jxcontext.Context, categoryID int, payload map[string]i syncStatus = model.SyncFlagModifiedMask valid[model.FieldJdSyncStatus] = int8(syncStatus) | cat.JdSyncStatus } + if valid["status"] != nil { + if utils.Interface2Int64WithDefault(valid["status"], -1) == model.CategoryStatusDisabled { + if skuList, err2 := dao.GetSkuByCats(db, []int{categoryID}); err2 == nil && len(skuList) > 0 { + return 0, fmt.Errorf("暂不允许禁用分类下有商品的分类!") + } + } + } + + if valid["img"] != nil { + if imgStr := utils.Interface2String(valid["img"]); imgStr != "" { + _, err2 := datares.TryRegisterDataResource(ctx, cat.Name, utils.Interface2String(valid["img"]), model.ImgTypeLocal, false) + if err = err2; err != nil { + return 0, err + } + } + } dao.Begin(db) defer func() { @@ -147,7 +180,7 @@ func UpdateCategory(ctx *jxcontext.Context, categoryID int, payload map[string]i dao.Rollback(db) return 0, err } - if err = OnUpdateThing(db, int64(categoryID), model.ThingTypeCategory); err != nil { + if err = OnUpdateThing(ctx, db, nil, int64(categoryID), model.ThingTypeCategory); err != nil { dao.Rollback(db) return 0, err } @@ -241,7 +274,7 @@ func ReorderCategories(ctx *jxcontext.Context, parentID int, categoryIDs []int, dao.Rollback(db) return err } - if err = OnUpdateThing(db, int64(catsMap[v].ID), model.ThingTypeCategory); err != nil { + if err = OnUpdateThing(ctx, db, nil, int64(catsMap[v].ID), model.ThingTypeCategory); err != nil { dao.Rollback(db) return err } @@ -293,7 +326,7 @@ func DeleteCategory(ctx *jxcontext.Context, categoryID int, userName string) (nu dao.Rollback(db) return 0, err } - if err = OnDeleteThing(db, int64(categoryID), model.ThingTypeCategory); err != nil { + if err = OnDeleteThing(ctx, db, nil, int64(categoryID), model.ThingTypeCategory); err != nil { dao.Rollback(db) return 0, err } @@ -336,10 +369,17 @@ func GetSkuNames(ctx *jxcontext.Context, keyword string, isBySku bool, params ma keywordLike := "%" + keyword + "%" sql += " AND (t1.name LIKE ? OR t1.prefix LIKE ? OR t2.comment LIKE ? OR t1.upc LIKE ?" sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike) - + if globals.IsUseThingMap { + sql += " OR (SELECT COUNT(*) FROM thing_map tm WHERE tm.vendor_thing_id LIKE ? AND tm.thing_type = ? AND tm.thing_id = t2.id AND tm.deleted_at = ?) > 0" + sqlParams = append(sqlParams, keywordLike, model.ThingTypeSku, utils.DefaultTimeValue) + } if keywordInt64, err2 := strconv.ParseInt(keyword, 10, 64); err2 == nil { - sql += " OR t1.id = ? OR t2.id = ? OR t2.jd_id = ? OR t1.category_id = ?" - sqlParams = append(sqlParams, keywordInt64, keywordInt64, keywordInt64, keywordInt64) + sql += " OR t1.id = ? OR t2.id = ? OR t1.category_id = ?" + sqlParams = append(sqlParams, keywordInt64, keywordInt64, keywordInt64) + if !globals.IsUseThingMap { + sql += " OR t2.jd_id = ?" + sqlParams = append(sqlParams, keywordInt64) + } } sql += ")" } @@ -532,12 +572,17 @@ func GetSkuNames(ctx *jxcontext.Context, keyword string, isBySku bool, params ma if err = dao.GetRows(db, &skuNamesInfo.SkuNames, sqlData, sqlParams...); err == nil { skuNamesInfo.TotalCount = dao.GetLastTotalRowCount(db) dao.Commit(db) + + var skuIDs []int for _, skuName := range skuNamesInfo.SkuNames { if skuName.SkusStr != "" { if err = utils.UnmarshalUseNumber([]byte(skuName.SkusStr), &skuName.Skus); err != nil { dao.Rollback(db) return nil, err } + for _, v := range skuName.Skus { + skuIDs = append(skuIDs, v.ID) + } } if skuName.PlacesStr != "" { if err = utils.UnmarshalUseNumber([]byte(skuName.PlacesStr), &skuName.Places); err != nil { @@ -546,6 +591,16 @@ func GetSkuNames(ctx *jxcontext.Context, keyword string, isBySku bool, params ma } } } + if len(skuIDs) > 0 { + thingMapMap, err2 := dao.GetThingMapMap(db, model.ThingTypeSku, nil, skuIDs) + if err = err2; err == nil { + for _, skuName := range skuNamesInfo.SkuNames { + for _, v := range skuName.Skus { + v.MapList = thingMapMap[int64(v.ID)] + } + } + } + } } else { dao.Rollback(db) } @@ -604,6 +659,7 @@ func AddSkuName(ctx *jxcontext.Context, skuNameExt *model.SkuNameExt, userName s } skuNameExt.SkuName.Status = model.SkuStatusNormal if skuNameExt.IsSpu == 1 { + return nil, fmt.Errorf("不允许创建多规格商品") skuNameExt.SkuName.JdSyncStatus = model.SyncFlagNewMask } if skuNameExt.Unit == model.SpecialUnit { @@ -614,39 +670,29 @@ func AddSkuName(ctx *jxcontext.Context, skuNameExt *model.SkuNameExt, userName s skuNameExt.SpecUnit = skuNameExt.Skus[0].SpecUnit } - if globals.EnableStoreWrite { - // imgContent, imgMD5, err := jxutils.DownloadFileByURL(skuNameExt.Img) - // if err != nil { - // return nil, err - // } - // if skuNameExt.ImgHashCode == "" { - // skuNameExt.ImgHashCode = imgMD5 - // } else if skuNameExt.ImgHashCode != imgMD5 { - // return nil, errors.New("图片HASH值不同") - // } - // imgHintMap, err := UploadImg2Platforms(ctx, nil, skuNameExt.Img, imgContent, "") - // if err != nil { - // return nil, err - // } - // skuNameExt.ImgEbai = imgHintMap[model.VendorIDEBAI] - dataRes, err2 := datares.TryRegisterDataResource(ctx, skuNameExt.Name, skuNameExt.Img, model.ImgTypeMain, false) - if err = err2; err != nil { - return nil, err - } - // skuNameExt.ImgHashCode = dataRes.HashCode - skuNameExt.ImgEbai = dataRes.EbaiURL - if skuNameExt.Img2 != "" { - datares.TryRegisterDataResource(ctx, skuNameExt.Name, skuNameExt.Img2, model.ImgTypeMain, true) - } - - if skuNameExt.DescImg != "" { - dataRes, err2 := datares.TryRegisterDataResource(ctx, skuNameExt.Name+"desc", skuNameExt.DescImg, model.ImgTypeDesc, false) + picType := true + for _, imgName := range []string{skuNameExt.Img, skuNameExt.Img2} { + if imgName != "" { + dataRes, err2 := datares.TryRegisterDataResource(ctx, skuNameExt.Name, imgName, model.ImgTypeMain, false) + if dataRes.ResourceType == model.MimeTypeJpeg || dataRes.ResourceType == model.MimeTypePng { + picType = false + } if err = err2; err != nil { return nil, err } - skuNameExt.DescImgEbai = dataRes.EbaiURL } - if err != nil { + } + + if picType { + return nil, fmt.Errorf("商品图片应至少包含一张非gif格式的图片!") + } + + if skuNameExt.DescImg != "" { + dataRes, err2 := datares.TryRegisterDataResource(ctx, skuNameExt.Name+"desc", skuNameExt.DescImg, model.ImgTypeDesc, false) + if dataRes.ResourceType == model.MimeTypeGif { + return nil, fmt.Errorf("商品详情图片不能上传gif格式的图片!") + } + if err = err2; err != nil { return nil, err } } @@ -663,11 +709,12 @@ func AddSkuName(ctx *jxcontext.Context, skuNameExt *model.SkuNameExt, userName s dao.Rollback(db) return nil, err } - if err = OnCreateThing(db, int64(skuNameExt.SkuName.ID), model.ThingTypeSkuName); err != nil { + if err = OnCreateThing(ctx, db, nil, int64(skuNameExt.SkuName.ID), model.ThingTypeSkuName); err != nil { dao.Rollback(db) return nil, err } - for _, sku := range skuNameExt.Skus { + for _, v := range skuNameExt.Skus { + sku := v.Sku dao.WrapAddIDCULDEntity(sku, userName) sku.NameID = skuNameExt.ID sku.JdSyncStatus = model.SyncFlagNewMask @@ -676,6 +723,10 @@ func AddSkuName(ctx *jxcontext.Context, skuNameExt *model.SkuNameExt, userName s dao.Rollback(db) return nil, err } + if err = OnCreateThing(ctx, db, nil, int64(sku.ID), model.ThingTypeSku); err != nil { + dao.Rollback(db) + return nil, err + } } for _, placeCode := range skuNameExt.Places { placeBind := &model.SkuNamePlaceBind{} @@ -719,10 +770,6 @@ func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interf } delete(payload, "isSpu") - delete(payload, "imgHashCode") - delete(payload, "imgWeimob") - delete(payload, "imgEbai") - delete(payload, "descImgEbai") delete(payload, "seq") valid := dao.StrictMakeMapByStructObject(payload, skuName, userName) @@ -742,31 +789,27 @@ func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interf } err = nil } - if globals.EnableStoreWrite { - if valid["img"] != nil { - dataRes, err2 := datares.TryRegisterDataResource(ctx, skuName.Name, valid["img"].(string), model.ImgTypeMain, false) - if err = err2; err != nil { - return 0, err - } - valid["ImgEbai"] = dataRes.EbaiURL - } - if valid["img2"] != nil { - datares.TryRegisterDataResource(ctx, skuName.Name, valid["img2"].(string), model.ImgTypeMain, true) - } - - if valid["descImg"] != nil { - descImg := valid["descImg"].(string) - if descImg != "" { - dataRes, err2 := datares.TryRegisterDataResource(ctx, skuName.Name+"_desc", descImg, model.ImgTypeDesc, false) + for _, imgName := range []string{"img", "img2"} { + if valid[imgName] != nil { + if imgStr := utils.Interface2String(valid[imgName]); imgStr != "" { + _, err2 := datares.TryRegisterDataResource(ctx, skuName.Name, valid[imgName].(string), model.ImgTypeMain, true) if err = err2; err != nil { return 0, err } - valid["descImgEbai"] = dataRes.EbaiURL - } else { - valid["descImgEbai"] = "" } } } + + if valid["descImg"] != nil { + descImg := valid["descImg"].(string) + if descImg != "" { + _, err2 := datares.TryRegisterDataResource(ctx, skuName.Name+"_desc", descImg, model.ImgTypeDesc, false) + if err = err2; err != nil { + return 0, err + } + } + } + dao.Begin(db) defer func() { if r := recover(); r != nil { @@ -779,7 +822,7 @@ func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interf dao.Rollback(db) return 0, err } - if err = OnUpdateThing(db, int64(nameID), model.ThingTypeSkuName); err != nil { + if err = OnUpdateThing(ctx, db, nil, int64(nameID), model.ThingTypeSkuName); err != nil { dao.Rollback(db) return 0, err } @@ -816,7 +859,7 @@ func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interf return 0, err } - if err = OnUpdateThing(db, int64(v.ID), model.ThingTypeSku); err != nil { + if err = OnUpdateThing(ctx, db, nil, int64(v.ID), model.ThingTypeSku); err != nil { dao.Rollback(db) return 0, err } @@ -879,6 +922,10 @@ func DeleteSkuName(ctx *jxcontext.Context, nameID int, userName string) (num int if err = err2; err == nil { for _, v := range skuList { sku := &v.Sku + if err = OnDeleteThing(ctx, db, nil, int64(v.ID), model.ThingTypeSku); err != nil { + dao.Rollback(db) + return 0, err + } if _, err = dao.DeleteEntityLogically(db, sku, map[string]interface{}{ model.FieldJdSyncStatus: model.SyncFlagDeletedMask, model.FieldStatus: model.SkuStatusDeleted, @@ -886,15 +933,10 @@ func DeleteSkuName(ctx *jxcontext.Context, nameID int, userName string) (num int dao.Rollback(db) return 0, err } - - if err = OnDeleteThing(db, int64(v.ID), model.ThingTypeSku); err != nil { - dao.Rollback(db) - return 0, err - } } } - if err = OnDeleteThing(db, int64(nameID), model.ThingTypeSkuName); err != nil { + if err = OnDeleteThing(ctx, db, nil, int64(nameID), model.ThingTypeSkuName); err != nil { dao.Rollback(db) return 0, err } @@ -943,7 +985,7 @@ func AddSku(ctx *jxcontext.Context, nameID int, sku *model.Sku, userName string) dao.Rollback(db) return nil, err } - if err = OnCreateThing(db, int64(sku.ID), model.ThingTypeSku); err != nil { + if err = OnCreateThing(ctx, db, nil, int64(sku.ID), model.ThingTypeSku); err != nil { dao.Rollback(db) return nil, err } @@ -991,20 +1033,20 @@ func UpdateSku(ctx *jxcontext.Context, skuID int, payload map[string]interface{} } return 0, err } - if num, err = dao.ExecuteSQL(db, ` + if _, err = dao.ExecuteSQL(db, ` UPDATE sku_name t1 JOIN sku t2 ON t1.id = t2.name_id SET t1.spec_quality = t2.spec_quality, t1.spec_unit = t2.spec_unit WHERE t1.deleted_at = ? AND t2.id = ? AND t1.unit <> ? - `, utils.DefaultTimeValue, skuID, model.SpecialUnit); err != nil || num == 0 { + `, utils.DefaultTimeValue, skuID, model.SpecialUnit); err != nil { dao.Rollback(db) if err == nil { err = ErrEntityNotExist } return 0, err } - if err = OnUpdateThing(db, int64(skuID), model.ThingTypeSku); err != nil { + if err = OnUpdateThing(ctx, db, nil, int64(skuID), model.ThingTypeSku); err != nil { dao.Rollback(db) return 0, err } @@ -1044,7 +1086,7 @@ func refreshStoreSkuPrice(ctx *jxcontext.Context, db *dao.DaoDB, skuID int) (err storeSku.ID = v.BindID if _, err = dao.UpdateEntityLogically(db, storeSku, map[string]interface{}{ "Price": v.Price, - dao.GetSyncStatusStructField(model.VendorNames[vendorID]): v.StoreSkuSyncStatus | model.SyncFlagPriceMask, + dao.GetSyncStatusStructField(model.VendorNames[vendorID]): v.SkuSyncStatus | model.SyncFlagPriceMask, }, ctx.GetUserName(), nil); err != nil { return err } @@ -1069,7 +1111,7 @@ func DeleteSku(ctx *jxcontext.Context, skuID int, userName string) (num int64, e dao.Rollback(db) return 0, err } - if err = OnDeleteThing(db, int64(skuID), model.ThingTypeSku); err != nil { + if err = OnDeleteThing(ctx, db, nil, int64(skuID), model.ThingTypeSku); err != nil { dao.Rollback(db) return 0, err } @@ -1149,7 +1191,7 @@ func AddSkuNamePlace(ctx *jxcontext.Context, nameID, placeCode int, userName str dao.Rollback(db) return nil, err } - if err = OnUpdateThing(db, int64(nameID), model.ThingTypeSkuName); err != nil { + if err = OnUpdateThing(ctx, db, nil, int64(nameID), model.ThingTypeSkuName); err != nil { dao.Rollback(db) return nil, err } @@ -1179,7 +1221,7 @@ func DeleteSkuNamePlace(ctx *jxcontext.Context, nameID, placeCode int, userName } return 0, err } - if err = OnUpdateThing(db, int64(nameID), model.ThingTypeSkuName); err != nil { + if err = OnUpdateThing(ctx, db, nil, int64(nameID), model.ThingTypeSkuName); err != nil { dao.Rollback(db) return 0, err } @@ -1189,12 +1231,12 @@ func DeleteSkuNamePlace(ctx *jxcontext.Context, nameID, placeCode int, userName return num, err } -func GetVendorSku(ctx *jxcontext.Context, vendorID int, vendorSkuID string) (skuNameInfo *model.SkuNameExt, err error) { - if handler := CurVendorSync.GetMultiStoreHandler(vendorID); handler != nil { - return handler.ReadSku(vendorSkuID) - } - return nil, ErrCanNotFindVendor -} +// func GetVendorSku(ctx *jxcontext.Context, vendorID int, vendorOrgCode, vendorSkuID string) (skuNameInfo *model.SkuNameExt, err error) { +// if handler := CurVendorSync.GetMultiStoreHandler(vendorID); handler != nil { +// return handler.ReadSku(ctx, vendorOrgCode, vendorSkuID) +// } +// return nil, ErrCanNotFindVendor +// } func SortCategorySkus(ctx *jxcontext.Context, catID int, skuIDList []int) (err error) { db := dao.GetDB() diff --git a/business/jxstore/cms/store.go b/business/jxstore/cms/store.go index 5254a0ed5..44e86dcac 100644 --- a/business/jxstore/cms/store.go +++ b/business/jxstore/cms/store.go @@ -35,6 +35,7 @@ import ( "git.rosy.net.cn/jx-callback/business/model/legacymodel" "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai" + "git.rosy.net.cn/jx-callback/business/partner/purchase/jd" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" ) @@ -55,15 +56,17 @@ type StoreExt struct { FloatLng float64 `json:"lng"` FloatLat float64 `json:"lat"` - ProvinceCode int `json:"provinceCode"` - ProvinceName string `json:"provinceName"` - CityName string `json:"cityName"` - DistrictName string `json:"districtName"` - StoreMapStr string `json:"-"` - CourierMapStr string `json:"-"` - PayeeBankName string `json:"payeeBankName"` // 开户行名称 - StoreMaps []map[string]interface{} `orm:"-"` - CourierMaps []map[string]interface{} `orm:"-"` + ProvinceCode int `json:"provinceCode"` + ProvinceName string `json:"provinceName"` + CityName string `json:"cityName"` + DistrictName string `json:"districtName"` + StoreMapStr string `json:"-"` + CourierMapStr string `json:"-"` + PayeeBankName string `json:"payeeBankName"` // 开户行名称 + // StoreMaps []map[string]interface{} `orm:"-"` + // CourierMaps []map[string]interface{} `orm:"-"` + StoreMaps []*model.StoreMap `json:"StoreMaps"` + CourierMaps []*model.StoreCourierMap `json:"CourierMaps"` OrderCount int `json:"orderCount"` } @@ -129,6 +132,19 @@ type JxBadCommentsExt struct { VendorOrderID2 string `orm:"column(vendor_order_id2);size(48);index" json:"vendorOrderID2"` } +type VendorStoreExcel struct { + StoreID int `json:"门店ID"` + VendorStoreName string `json:"门店名"` + Status string `json:"营业状态"` + Tel1 string `json:"电话1"` + Tel2 string `json:"电话2"` + CityName string `json:"城市名"` + Address string `json:"地址"` + MarketManName string `json:"市场负责人"` + OperatorName string `json:"运营负责人"` + OperatorName2 string `json:"运营负责人2"` +} + var ( ErrMissingInput = errors.New("没有有效的输入参数") ErrCanNotFindVendor = errors.New("vendorID参数不合法") @@ -160,6 +176,35 @@ var ( "15:00:00", "20:00:00", } + titleListStore = []string{ + "门店ID", + "门店名", + "营业状态", + "电话1", + "电话2", + "城市名", + "地址", + "市场负责人", + "运营负责人", + "运营负责人2", + } + roleMap = map[string]string{ + "marketManPhone": "市场负责人电话", + "marketManRole": "市场负责人组(角色,单人)", + "jxBrandFeeFactor": "京西品牌费因子", + "marketAddFeeFactor": "市场附加费因子", + "payeeName": "收款人姓名", + "payeeAccountNo": "收款账号", + "payeeBankBranchName": "开户支行", + "payeeBankCode": "开户行代码", + "payPercentage": "支付比例", + } + roleMoblieMap = map[string]string{ + "17380734342": "17380734342", //漆云的手机 ,用于判断updatestore的权限 + "18328080405": "18328080405", //肖娜娜的手机 + "13350726500": "13350726500", //谭翔心 + "15928865396": "15928865396", //何佳梦 + } ) func getStoresSql(ctx *jxcontext.Context, keyword string, params map[string]interface{}, orderTimeFrom, orderTimeTo time.Time) (sql string, sqlParams []interface{}, sqlFrom string, sqlFromParams []interface{}, err error) { @@ -199,14 +244,21 @@ func getStoresSql(ctx *jxcontext.Context, keyword string, params map[string]inte if mapCond := strings.ToUpper(utils.Interface2String(params[mapCondKey])); mapCond == "AND" || mapCond == "OR" { mapCondsStr := utils.Interface2String(params[mapCondKey+"s"]) if mapCondsStr != "" { - var vendorStoreConds map[string]int + var vendorStoreConds map[string]interface{} if err = utils.UnmarshalUseNumber([]byte(mapCondsStr), &vendorStoreConds); err != nil { return "", nil, "", nil, err } sqlVendorStoreCond := "" - for vendor, cond := range vendorStoreConds { + for vendor, cond2 := range vendorStoreConds { + var cond string + if condStr, ok := cond2.(string); !ok { + cond = utils.Int64ToStr(utils.ForceInterface2Int64(cond2)) + } else { + cond = condStr + } + tableAlias := tableName + vendor - if cond != 0 { + if cond != "0" && cond != "" { if sqlVendorStoreCond == "" { if mapCond == "AND" { sqlVendorStoreCond += " AND ( 1 = 1" @@ -218,10 +270,14 @@ func getStoresSql(ctx *jxcontext.Context, keyword string, params map[string]inte tableAlias + ".store_id = t1.id AND " + tableAlias + ".deleted_at = ? AND " + tableAlias + ".is_sync <> 0 " sqlFromParams = append(sqlFromParams, vendor, utils.DefaultTimeValue) - if cond == 1 { + if cond == "1" { sqlVendorStoreCond += " " + mapCond + " " + tableAlias + ".id IS NOT NULL" - } else { + } else if cond == "-1" { sqlVendorStoreCond += " " + mapCond + " " + tableAlias + ".id IS NULL" + } else { + sqlFrom += " AND " + tableAlias + ".vendor_org_code = ?" + sqlFromParams = append(sqlFromParams, cond) + sqlVendorStoreCond += " " + mapCond + " " + tableAlias + ".id IS NOT NULL" } } } @@ -353,10 +409,10 @@ func setStoreMapInfo(ctx *jxcontext.Context, db *dao.DaoDB, storesInfo *StoresIn v.Licence2Image = "" } for _, v2 := range storeMapMap[v.ID] { - v.StoreMaps = append(v.StoreMaps, utils.Struct2FlatMap(v2)) + v.StoreMaps = append(v.StoreMaps, v2) } for _, v2 := range storeCourierMap[v.ID] { - v.CourierMaps = append(v.CourierMaps, utils.Struct2FlatMap(v2)) + v.CourierMaps = append(v.CourierMaps, v2) } } return nil @@ -547,9 +603,9 @@ func getMapCenter(storeList []*StoreExt) (lng, lat float64) { return getMapCenter(newStoreList) } -func GetVendorStore(ctx *jxcontext.Context, vendorStoreID string, vendorID int) (retVal *StoreExt, err error) { +func GetVendorStore(ctx *jxcontext.Context, vendorID int, vendorOrgCode, vendorStoreID string) (retVal *StoreExt, err error) { if handler := CurVendorSync.GetStoreHandler(vendorID); handler != nil { - result, err2 := handler.ReadStore(ctx, vendorStoreID) + result, err2 := handler.ReadStore(ctx, vendorOrgCode, vendorStoreID) if err = err2; err == nil { retVal = &StoreExt{ Store: result.Store, @@ -722,6 +778,10 @@ func UpdateStore(ctx *jxcontext.Context, storeID int, payload map[string]interfa if valid["status"] != nil { syncStatus |= model.SyncFlagStoreStatus status = int(utils.Interface2Int64WithDefault(valid["status"], 0)) + if status == model.StoreStatusDisabled { + valid["deliveryRangeType"] = model.DeliveryRangeTypeRadius + valid["deliveryRange"] = "1" + } } else { status = store.Status } @@ -770,6 +830,16 @@ func UpdateStore(ctx *jxcontext.Context, storeID int, payload map[string]interfa } } + for k, _ := range valid { + if roleMap[k] != "" { + if authInfo, err := ctx.GetV2AuthInfo(); err == nil { + if roleMoblieMap[authInfo.Mobile] == "" { + return 0, errors.New(fmt.Sprintf("当前用户 [%v] 无权限修改 [%v] 字段!", authInfo.Name, roleMap[k])) + } + } + } + } + // districtCode := 0 // if valid["districtCode"] != nil { // districtCode = int(utils.MustInterface2Int64(valid["districtCode"])) @@ -814,6 +884,7 @@ func UpdateStore(ctx *jxcontext.Context, storeID int, payload map[string]interfa dao.Commit(db) } notifyStoreOperatorChanged(store, valid["operatorPhone"]) + notifyStoreMarketChanged(store, valid["marketManPhone"]) if err == nil { if valid["openTime1"] != 0 || valid["closeTime1"] != 0 || valid["openTime2"] != 0 || valid["closeTime2"] != 0 { err = CurVendorSync.ChangeStoreSkuSaleStatus(ctx, storeID, true, true) @@ -841,6 +912,21 @@ func notifyStoreOperatorChanged(store *model.Store, newOperator2 interface{}) { } } +func notifyStoreMarketChanged(store *model.Store, newMarketManPhone2 interface{}) { + if store.MarketManPhone != "" && newMarketManPhone2 != nil { + db := dao.GetDB() + if user, err := dao.GetUserByID(db, "mobile", store.MarketManPhone); err == nil { + curUserName := "" + if newOperator := utils.Interface2String(newMarketManPhone2); newOperator != "" { + if curUser, err := dao.GetUserByID(db, "mobile", newOperator); err == nil { + curUserName = curUser.GetName() + } + } + ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.GetID(), "门店市场变更", fmt.Sprintf("门店:%d-%s,原市场:%s,变更为:%s", store.ID, store.Name, user.GetName(), curUserName)) + } + } +} + func SetStoreStatus(ctx *jxcontext.Context, storeID, status int) (err error) { payload := map[string]interface{}{ "status": status, @@ -946,7 +1032,7 @@ func GetStoreVendorMaps(ctx *jxcontext.Context, db *dao.DaoDB, storeID int, vend } // todo 需要对字段做有效性检查 -func AddStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendorID int, storeMap *model.StoreMap) (outStoreMap *model.StoreMap, err error) { +func AddStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, vendorID int, vendorOrgCode string, storeID int, storeMap *model.StoreMap) (outStoreMap *model.StoreMap, err error) { if storeID == 0 { return nil, fmt.Errorf("storeID不能为0") } @@ -954,42 +1040,50 @@ func AddStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendorID return nil, fmt.Errorf("非京东平台要求必须自动拣货") } userName := ctx.GetUserName() - if handler := CurVendorSync.GetStoreHandler(vendorID); handler != nil { - store, err2 := handler.ReadStore(ctx, storeMap.VendorStoreID) - if err = err2; err == nil || storeMap.IsSync == 0 { - dao.WrapAddIDCULDEntity(storeMap, userName) - storeMap.StoreID = storeID - storeMap.VendorID = vendorID - if store != nil { - storeMap.DeliveryType = store.DeliveryType - storeMap.Status = store.Status - } - err = nil - storeMap.SyncStatus = model.SyncFlagModifiedMask | model.SyncFlagStoreName | model.SyncFlagStoreAddress // 新增绑定门店是修改的概念 - if db == nil { - db = dao.GetDB() - } - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if err = dao.CreateEntity(db, storeMap); err == nil { - outStoreMap = storeMap + storeMap.StoreID = storeID + storeMap.VendorID = vendorID + storeMap.Status = model.StoreStatusOpened + storeMap.DeliveryType = model.StoreDeliveryTypeByStore + storeMap.SyncStatus = 0 + if vendorID != model.VendorIDJX { + if storeMap.VendorOrgCode == "" { + return nil, fmt.Errorf("必须指定平台分账号信息") + } + if handler := CurVendorSync.GetStoreHandler(vendorID); handler != nil { + store, err2 := handler.ReadStore(ctx, vendorOrgCode, storeMap.VendorStoreID) + if err = err2; err == nil || storeMap.IsSync == 0 { if store != nil { - _, err = CurVendorSync.SyncStore(ctx, db, storeMap.VendorID, storeID, false, userName) + storeMap.DeliveryType = store.DeliveryType + storeMap.Status = store.Status } + err = nil + storeMap.SyncStatus = model.SyncFlagModifiedMask | model.SyncFlagStoreName | model.SyncFlagStoreAddress // 新增绑定门店是修改的概念 } - if err != nil { - dao.Rollback(db) - } else { - dao.Commit(db) - } + } else { + err = ErrCanNotFindVendor } } else { - err = ErrCanNotFindVendor + ReCalculateJxPriceLight(db, ctx, storeID) + } + if err == nil { + dao.WrapAddIDCULDEntity(storeMap, userName) + if db == nil { + db = dao.GetDB() + } + dao.Begin(db) + defer func() { + if r := recover(); r != nil { + dao.Rollback(db) + panic(r) + } + }() + if err = dao.CreateEntity(db, storeMap); err == nil { + dao.Commit(db) + outStoreMap = storeMap + _, err = CurVendorSync.SyncStore(ctx, db, storeMap.VendorID, storeID, false, userName) + } else { + dao.Rollback(db) + } } return outStoreMap, err } @@ -1005,7 +1099,7 @@ func DeleteStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendor storeMap.DeletedAt = utils.DefaultTimeValue if err = dao.GetEntity(db, storeMap, model.FieldStoreID, model.FieldVendorID, model.FieldDeletedAt); err == nil { if handler := partner.GetPurchasePlatformFromVendorID(vendorID); handler != nil { - handler.UpdateStoreCustomID(ctx, storeMap.VendorStoreID, utils.Str2Int64WithDefault(storeMap.VendorStoreID, 0)) + handler.UpdateStoreCustomID(ctx, storeMap.VendorOrgCode, storeMap.VendorStoreID, utils.Str2Int64WithDefault(storeMap.VendorStoreID, 0)) } num, err = dao.DeleteEntityLogically(db, storeMap, map[string]interface{}{ model.FieldStatus: model.StoreStatusDisabled, @@ -1020,9 +1114,12 @@ func UpdateStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendor return 0, fmt.Errorf("非京东平台要求必须自动拣货") } } - storeHandler := CurVendorSync.GetStoreHandler(vendorID) - if storeHandler == nil { - return 0, ErrCanNotFindVendor + var storeHandler partner.IPurchasePlatformHandler + if vendorID != model.VendorIDJX { + storeHandler = CurVendorSync.GetStoreHandler(vendorID) + if storeHandler == nil { + return 0, ErrCanNotFindVendor + } } if db == nil { db = dao.GetDB() @@ -1060,19 +1157,25 @@ func UpdateStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendor } } - if vendorStoreID := utils.Interface2String(valid["vendorStoreID"]); vendorStoreID != "" { - vendorStoreInfo, err2 := storeHandler.ReadStore(ctx, vendorStoreID) - if err = err2; err == nil { - valid["deliveryType"] = vendorStoreInfo.DeliveryType + if vendorID != model.VendorIDJX { + if vendorStoreID := utils.Interface2String(valid["vendorStoreID"]); vendorStoreID != "" { + vendorStoreInfo, err2 := storeHandler.ReadStore(ctx, storeMap.VendorOrgCode, vendorStoreID) + if err = err2; err == nil { + valid["deliveryType"] = vendorStoreInfo.DeliveryType + } + err = nil // todo 忽略读不到DeliveryType的错误 } - err = nil // todo 忽略读不到DeliveryType的错误 } + if err == nil { // globals.SugarLogger.Debug(utils.Format4Output(valid, false)) if len(valid) > 0 { dao.Begin(db) defer func() { - dao.Rollback(db) + if r := recover(); r != nil { + dao.Rollback(db) + panic(r) + } }() if valid["status"] != nil { // 对于store vendor map,只有Status改变才需要同步到厂商 num, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, storeMap, valid, userName, map[string]interface{}{ @@ -1085,19 +1188,30 @@ func UpdateStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendor model.FieldVendorID: vendorID, }) } - if err == nil && num > 0 { - if valid["pricePercentage"] != nil || valid["pricePercentagePack"] != nil { - storeSkuBind := &model.StoreSkuBind{} - if num, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, storeSkuBind, nil, userName, map[string]interface{}{ - model.FieldStoreID: storeID, - }, dao.GetSyncStatusStructField(model.VendorNames[vendorID]), model.SyncFlagPriceMask); err != nil { - return 0, err + if err != nil { + dao.Rollback(db) + return 0, err + } + if num > 0 { + if vendorID != model.VendorIDJX { + if valid["pricePercentage"] != nil || valid["pricePercentagePack"] != nil { + storeSkuBind := &model.StoreSkuBind{} + if num, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, storeSkuBind, nil, userName, map[string]interface{}{ + model.FieldStoreID: storeID, + }, dao.GetSyncStatusStructField(model.VendorNames[vendorID]), model.SyncFlagPriceMask); err != nil { + dao.Rollback(db) + return 0, err + } + } + } else { + if valid["pricePercentage"] != nil || valid["pricePercentagePack"] != nil { + ReCalculateJxPriceLight(db, ctx, storeID) } } - dao.Commit(db) - if valid["status"] != nil || valid["freightDeductionPack"] != nil { - _, err = CurVendorSync.SyncStore(ctx, db, vendorID, storeID, false, userName) - } + } + dao.Commit(db) + if vendorID != model.VendorIDJX && (valid["status"] != nil || valid["freightDeductionPack"] != nil) { + _, err = CurVendorSync.SyncStore(ctx, db, vendorID, storeID, false, userName) } } } @@ -1576,7 +1690,7 @@ func GetStoresVendorSnapshot(ctx *jxcontext.Context, parentTask tasksch.ITask, v storeMap := batchItemList[0].(*model.StoreMap) if model.IsVendorRemote(storeMap.VendorID) { if handler := partner.GetPurchasePlatformFromVendorID(storeMap.VendorID); handler != nil { - store, err2 := handler.ReadStore(ctx, storeMap.VendorStoreID) + store, err2 := handler.ReadStore(ctx, storeMap.VendorOrgCode, storeMap.VendorStoreID) if err = err2; err == nil { retVal = []interface{}{&model.VendorStoreSnapshot{ StoreID: storeMap.StoreID, @@ -1649,7 +1763,7 @@ func updateVendorStoreStatusBySnapshot(db *dao.DaoDB, curSnapshotList []*model.V if snapshot := snapshotMap[jxutils.Combine2Int(v.StoreID, v.VendorID)]; snapshot != nil { if snapshot.IsAutoOrder == 1 { if handler, ok := partner.GetPurchasePlatformFromVendorID(snapshot.VendorID).(partner.IStoreHandler); ok { - handler.EnableAutoAcceptOrder(jxcontext.AdminCtx, v.StoreID, v.VendorStoreID, false) + handler.EnableAutoAcceptOrder(jxcontext.AdminCtx, v.VendorOrgCode, v.StoreID, v.VendorStoreID, false) } } } @@ -2189,7 +2303,7 @@ func GetStoreListByLocation(ctx *jxcontext.Context, lng, lat float64, needWalkDi return storeList, err } -func JdStoreInfoCoordinateRecover(ctx *jxcontext.Context, files []*multipart.FileHeader) (err error) { +func JdStoreInfoCoordinateRecover(ctx *jxcontext.Context, vendorOrgCode string, files []*multipart.FileHeader) (err error) { if len(files) == 0 { return errors.New("没有文件上传!") } @@ -2203,7 +2317,7 @@ func JdStoreInfoCoordinateRecover(ctx *jxcontext.Context, files []*multipart.Fil var validStoreList []*dao.StoreDetail for _, v := range storeList { if v.Status != model.StoreStatusDisabled && v.CreatedAt.Sub(utils.Str2Time("2019-10-01")) > 0 { - storeInfo, err := api.JdAPI.GetStoreInfoByStationNo2(v.VendorStoreID) + storeInfo, err := jd.GetAPI(vendorOrgCode).GetStoreInfoByStationNo2(v.VendorStoreID) if err == nil && storeInfo.CreateTime.GoTime().Sub(utils.Str2Time("2019-10-25")) > 0 { if storeDetail, err := dao.GetStoreDetail(db, v.StoreID, v.VendorID); err == nil { validStoreList = append(validStoreList, storeDetail) @@ -2269,3 +2383,197 @@ func ExecuteFileName(filename string) (name string) { name = fileRealName + utils.Int64ToStr(time.Now().Unix()) + filePrefix return name } + +func GetVendorStoreInfo(ctx *jxcontext.Context, vendorIDList []int, isAsync, isContinueWhenError bool) (hint string, err error) { + var ( + storeListJD []VendorStoreExcel + storeListMT []VendorStoreExcel + storeListEB []VendorStoreExcel + storeIDs []string + ) + taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + switch step { + case 0: + for _, vendorID := range vendorIDList { + iStoreHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IStoreHandler) + if vendorID == model.VendorIDEBAI { + storeIDs, err = ebai.CurPurchaseHandler.GetShopIDsByPage() + } else { + storeIDs, err = iStoreHandler.GetAllStoresVendorID(ctx, "") + } + if err != nil { + return "", err + } + taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + var storeDetail *dao.StoreDetail + storeID := batchItemList[0].(string) + if partner.IsMultiStore(vendorID) { + multiHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler) + storeDetail, err = multiHandler.ReadStore(ctx, "", storeID) + if err != nil { + return retVal, err + } + } else { + singleHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreHandler) + storeDetail, err = singleHandler.ReadStore(ctx, "", storeID) + if err != nil { + return retVal, err + } + } + db := dao.GetDB() + storeDetail2, err := dao.GetStoreDetailByVendorStoreID(db, storeDetail.VendorStoreID, vendorID) + if err != nil { + return "", err + } + if storeDetail.Status != model.StoreStatusOpened { + if storeDetail2 != nil { + var storeExcel = VendorStoreExcel{ + StoreID: storeDetail2.ID, + VendorStoreName: storeDetail.Name, + Tel1: storeDetail.Tel1, + Tel2: storeDetail.Tel2, + Address: storeDetail.Address, + Status: StoreStatus2Chinese(storeDetail.Status), + CityName: storeDetail.CityName, + MarketManName: storeDetail2.MarketManName, + OperatorName: storeDetail2.OperatorName, + OperatorName2: storeDetail2.OperatorName2, + } + retVal = []VendorStoreExcel{storeExcel} + } + } + return retVal, err + } + taskParallel := tasksch.NewParallelTask("获取各平台未营业门店", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, taskFunc, storeIDs) + tasksch.HandleTask(taskParallel, task, true).Run() + storeList, _ := taskParallel.GetResult(0) + for _, v := range storeList { + if vendorID == model.VendorIDJD { + storeListJD = append(storeListJD, v.(VendorStoreExcel)) + } + if vendorID == model.VendorIDEBAI { + storeListEB = append(storeListEB, v.(VendorStoreExcel)) + } + if vendorID == model.VendorIDMTWM { + storeListMT = append(storeListMT, v.(VendorStoreExcel)) + } + } + } + case 1: + WriteToExcelStore(task, storeListJD, storeListMT, storeListEB) + } + return result, err + } + taskSeq := tasksch.NewSeqTask2("导出各平台未营业门店-序列任务", ctx, isContinueWhenError, taskSeqFunc, 2) + tasksch.HandleTask(taskSeq, nil, true).Run() + if !isAsync { + _, err = taskSeq.GetResult(0) + hint = "1" + } else { + hint = taskSeq.GetID() + } + return hint, err +} + +func WriteToExcelStore(task *tasksch.SeqTask, storeListJD, storeListMT, storeListEB []VendorStoreExcel) (err error) { + var sheetList []*excel.Obj2ExcelSheetConfig + var downloadURL, fileName string + if len(storeListJD) > 0 { + excelConf := &excel.Obj2ExcelSheetConfig{ + Title: "京东平台", + Data: storeListJD, + CaptionList: titleListStore, + } + sheetList = append(sheetList, excelConf) + } + if len(storeListMT) > 0 { + excelConf := &excel.Obj2ExcelSheetConfig{ + Title: "美团平台", + Data: storeListMT, + CaptionList: titleListStore, + } + sheetList = append(sheetList, excelConf) + } + if len(storeListEB) > 0 { + excelConf := &excel.Obj2ExcelSheetConfig{ + Title: "饿百平台", + Data: storeListEB, + CaptionList: titleListStore, + } + sheetList = append(sheetList, excelConf) + } + if len(sheetList) == 0 { + return errors.New("所选平台没有未营业的门店!") + } else { + downloadURL, fileName, err = jxutils.UploadExeclAndPushMsg(sheetList, "各平台未营业门店统计") + if err != nil { + baseapi.SugarLogger.Errorf("WriteToExcel:upload %s failed error:%v", fileName, err) + } else { + noticeMsg := fmt.Sprintf("[详情点我]path=%s \n", downloadURL) + task.SetNoticeMsg(noticeMsg) + baseapi.SugarLogger.Debugf("WriteToExcel:upload %s success, downloadURL:%s", fileName, downloadURL) + } + } + return err +} + +func StoreStatus2Chinese(status int) (str string) { + if status == model.StoreStatusOpened { + return "正常营业" + } else if status == model.StoreStatusDisabled { + return "暂停营业" + } else if status == model.StoreStatusClosed { + return "休息中" + } else { + return "未知的营业状态" + } +} + +func GetStorePriceScore(ctx *jxcontext.Context, storeIDs []int, fromScore, toScore, sort int, snapDate string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { + var snapDateParam time.Time + db := dao.GetDB() + if snapDate != "" { + snapDateParam = utils.Str2Time(snapDate) + } + storePriceScore, totalCount, err := dao.GetStorePriceScore(db, storeIDs, fromScore, toScore, sort, snapDateParam, offset, pageSize) + pagedInfo = &model.PagedInfo{ + Data: storePriceScore, + TotalCount: totalCount, + } + return pagedInfo, err +} + +func CreateStorePriceScore(ctx *jxcontext.Context, forRefresh bool) (err error) { + db := dao.GetDB() + var snapshotAt time.Time + if forRefresh { + snapshotAt = utils.Time2Date(time.Now().AddDate(0, 0, -1)) + } else { + snapshotAt = utils.Time2Date(time.Now()) + } + storePriceScoreSnapshot, err := dao.GetStorePriceScoreSnapshot(db, snapshotAt) + if len(storePriceScoreSnapshot) > 0 { + dao.Begin(db) + defer func() { + if r := recover(); r != nil || err != nil { + dao.Rollback(db) + if r != nil { + panic(r) + } + } + }() + priceReferSnapshotDeleteHis := &model.StorePriceScoreSnapshot{SnapshotAt: snapshotAt.AddDate(0, -1, 0)} + priceReferSnapshotDelete := &model.StorePriceScoreSnapshot{SnapshotAt: snapshotAt} + dao.DeleteEntity(db, priceReferSnapshotDeleteHis, "SnapshotAt") + dao.DeleteEntity(db, priceReferSnapshotDelete, "SnapshotAt") + for _, v := range storePriceScoreSnapshot { + dao.WrapAddIDCULDEntity(v, ctx.GetUserName()) + v.SnapshotAt = snapshotAt + if err = dao.CreateEntity(db, v); err != nil { + return err + } + } + dao.Commit(db) + } + return err +} diff --git a/business/jxstore/cms/store_sku.go b/business/jxstore/cms/store_sku.go index 54274907d..d7e4771ab 100644 --- a/business/jxstore/cms/store_sku.go +++ b/business/jxstore/cms/store_sku.go @@ -3,18 +3,26 @@ package cms import ( "errors" "fmt" + "io" "math" + "mime/multipart" "sort" "strconv" + "strings" "sync" "time" + "unicode" + "git.rosy.net.cn/baseapi" + + "git.rosy.net.cn/jx-callback/business/jxutils/excel" "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" "git.rosy.net.cn/jx-callback/business/partner/purchase/jd" "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/baseapi/utils/errlist" "git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" @@ -22,6 +30,7 @@ import ( "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/globals" + "github.com/360EntSecGroup-Skylar/excelize" "github.com/astaxie/beego/orm" ) @@ -33,80 +42,6 @@ const ( CopyStoreSkuModeUpdatePrice = "updatePrice" // 增量复制价格 ) -type StoreSkuExt struct { - NameID int `orm:"column(name_id)" json:"nameID"` - SkuID int `orm:"column(sku_id)" json:"id"` - Comment string `orm:"size(255)" json:"comment"` - SkuCategoryID int `orm:"column(sku_category_id)" json:"categoryID"` - SkuSpecQuality float32 `json:"specQuality"` - SkuSpecUnit string `orm:"size(8)" json:"specUnit"` // 质量或容量 - Weight int `json:"weight"` // 重量/质量,单位为克,当相应的SkuName的SpecUnit为g或kg时,必须等于SpecQuality - JdID string `orm:"column(sku_jd_id);null;index" json:"jdID"` - SkuStatus int `json:"status"` - - BindCreatedAt time.Time `orm:"auto_now_add;type(datetime)" json:"createdAt"` - BindUpdatedAt time.Time `orm:"auto_now;type(datetime)" json:"updatedAt"` - BindLastOperator string `orm:"size(32)" json:"lastOperator"` // 最后操作员 - BindDeletedAt time.Time `orm:"type(datetime)" json:"deletedAt"` - SubStoreID int `orm:"column(sub_store_id)" json:"subStoreID"` - BindPrice int `json:"price"` // 单位为分,不用int64的原因是这里不需要累加 - UnitPrice int `json:"unitPrice"` // 这个是一斤的门店商品价,放在这里的原因是避免额外增加一张store sku_name表,逻辑上要保证同一SKU NAME中的所有SKU这个字段的数据一致 - StoreSkuStatus int `json:"storeSkuStatus"` - - EbaiID string `orm:"column(ebai_id);index" json:"ebaiID"` - MtwmID string `orm:"column(mtwm_id)" json:"mtwmID"` // 这个也不是必须的,只是为了DAO取数据语句一致 - // WscID string `orm:"column(wsc_id);index" json:"wscID"` // 表示微盟skuId - // WscID2 string `orm:"column(wsc_id2);index" json:"wscID2"` // 表示微盟goodsId - - JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"` - EbaiSyncStatus int8 `orm:"default(2)" json:"ebaiSyncStatus"` - MtwmSyncStatus int8 `orm:"default(2)" json:"mtwmSyncStatus"` - // WscSyncStatus int8 `orm:"default(2)" json:"wscSyncStatus"` - - JdPrice int `json:"jdPrice"` - EbaiPrice int `json:"ebaiPrice"` - MtwmPrice int `json:"mtwmPrice"` - JxPrice int `json:"jxPrice"` - - AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"` - - ActPrice int `json:"actPrice"` - ActID int `orm:"column(act_id)" json:"actID"` - ActType int `orm:"column(act_type)" json:"actType"` - - EarningPrice int `json:"earningPrice"` - EarningActID int `orm:"column(earning_act_id)" json:"earningActID"` - - RealEarningPrice int `json:"realEarningPrice"` - - StatusSaleBegin int16 `json:"statusSaleBegin"` //商品可售时间范围 - StatusSaleEnd int16 `json:"statusSaleEnd"` - - Count int `json:"count"` - Times int `json:"times"` -} - -// GetStoreSkus用 -type StoreSkuNameExt struct { - StoreID int `orm:"column(store_id)" json:"storeID"` - StoreName string `json:"storeName"` - - model.SkuName - PayPercentage int `json:"-"` - UnitPrice int `json:"unitPrice"` - Skus []*StoreSkuExt `orm:"-" json:"skus,omitempty"` - SkusStr string `json:"-"` - - PendingOpType int8 `json:"pendingOpType"` // 取值同 StoreOpRequest.Type - PendingUnitPrice int `json:"pendingUnitPrice"` // 这个是待审核的价格申请 -} - -// GetStoreSkus用 -type StoreSkuNamesInfo struct { - TotalCount int `json:"totalCount"` - SkuNames []*StoreSkuNameExt `json:"skuNames"` -} - // UpdateStoreSku用,API调用时 type StoreSkuBindSkuInfo struct { SkuID int `json:"skuID"` @@ -170,7 +105,37 @@ type tGetStoresSkusInfo struct { model.SkuName PayPercentage int `json:"-"` - StoreSkuExt + dao.StoreSkuExt +} + +type SheetParam struct { + OutSkuIDCol int + SkuNameIDCol int + SkuPriceCol int + SkuNameCol int + SkuUnitCol int + SkuRow int +} + +type DataSuccess struct { + NameID int `json:"商品NameID"` + Name string `json:"商品名称"` + Unit string `json:"单位"` + OrgPrice float64 `json:"原价"` + NowPrice float64 `json:"现价"` + MixPrice float64 `json:"涨跌"` +} + +type DataFailed struct { + NameID int `json:"商品NameID"` + Name string `json:"商品名称"` + Comment string `json:"备注"` +} + +type DataLock struct { + dataSuccessList []DataSuccess + dataFailedList []DataFailed + locker sync.RWMutex } const ( @@ -186,9 +151,23 @@ var ( "18180948107": 1, // 徐 // "13684045763": 1, // 周 } + dataLock DataLock + titleListSuccess = []string{ + "商品NameID", + "商品名称", + "单位", + "原价", + "现价", + "涨跌", + } + titleListFailed = []string{ + "商品NameID", + "商品名称", + "备注", + } ) -func GetStoreSkus(ctx *jxcontext.Context, storeID int, skuIDs []int, isFocus bool, keyword string, isBySku, isAct bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *StoreSkuNamesInfo, err error) { +func GetStoreSkus(ctx *jxcontext.Context, storeID int, skuIDs []int, isFocus bool, keyword string, isBySku, isAct bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *dao.StoreSkuNamesInfo, err error) { return GetStoresSkus(ctx, []int{storeID}, skuIDs, isFocus, keyword, isBySku, isAct, params, offset, pageSize) } @@ -203,6 +182,12 @@ func getGetStoresSkusBaseSQL(db *dao.DaoDB, storeIDs, skuIDs []int, isFocus bool // model.SkuStatusNormal, utils.DefaultTimeValue, } + if globals.IsUseThingMap { + sql += ` + LEFT JOIN store_map sm ON sm.store_id = t3.id AND sm.vendor_id = ? AND sm.deleted_at = ? + LEFT JOIN thing_map t2m ON t2m.thing_type = ? AND t2m.thing_id = t2.id AND t2m.vendor_id = sm.vendor_id AND t2m.vendor_org_code = sm.vendor_org_code AND t2m.deleted_at = ?` + sqlParams = append(sqlParams, model.VendorIDJD, utils.DefaultTimeValue, model.ThingTypeSku, utils.DefaultTimeValue) + } if isAct { sql += ` JOIN ( @@ -307,10 +292,6 @@ func getGetStoresSkusBaseSQL(db *dao.DaoDB, storeIDs, skuIDs []int, isFocus bool } sql += ")" } - if params["jdID"] != nil { - sql += " AND t1.jd_id = ?" - sqlParams = append(sqlParams, params["jdID"].(int)) - } if params["name"] != nil { sql += " AND t1.name LIKE ?" sqlParams = append(sqlParams, "%"+params["name"].(string)+"%") @@ -355,7 +336,11 @@ func getGetStoresSkusBaseSQL(db *dao.DaoDB, storeIDs, skuIDs []int, isFocus bool } sql += " AND ( 1 = 0" if params["jdSyncStatus"] != nil && realVendorMap[model.VendorIDJD] == 1 { - sql += " OR (t4.jd_sync_status & ? <> 0 AND t2.jd_id <> 0 AND t1.status = ? AND t2.status = ?)" + if globals.IsUseThingMap { + sql += " OR (t4.jd_sync_status & ? <> 0 AND t1.status = ? AND t2.status = ?)" + } else { + sql += " OR (t4.jd_sync_status & ? <> 0 AND t2.jd_id <> 0 AND t1.status = ? AND t2.status = ?)" + } sqlParams = append(sqlParams, params["jdSyncStatus"], model.SkuStatusNormal, model.SkuStatusNormal) } if params["ebaiSyncStatus"] != nil && realVendorMap[model.VendorIDEBAI] == 1 { @@ -372,11 +357,11 @@ func getGetStoresSkusBaseSQL(db *dao.DaoDB, storeIDs, skuIDs []int, isFocus bool return sql, sqlParams, err } -func GetStoresSkus(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bool, keyword string, isBySku, isAct bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *StoreSkuNamesInfo, err error) { +func GetStoresSkus(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bool, keyword string, isBySku, isAct bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *dao.StoreSkuNamesInfo, err error) { return GetStoresSkusNew(ctx, storeIDs, skuIDs, isFocus, keyword, isBySku, isAct, params, offset, pageSize) } -func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bool, keyword string, isBySku, isAct bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *StoreSkuNamesInfo, err error) { +func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bool, keyword string, isBySku, isAct bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *dao.StoreSkuNamesInfo, err error) { if !isFocus && !isBySku && (len(storeIDs) > 1 || len(storeIDs) == 0) { return nil, fmt.Errorf("未关注按SkuName只能查询单店") } @@ -415,7 +400,7 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bo catOrderBy = "t2.seq, " } - skuNamesInfo = &StoreSkuNamesInfo{} + skuNamesInfo = &dao.StoreSkuNamesInfo{} if !isBySku && sqlPageSize != model.UnlimitedPageSize { sql2 := ` SELECT SQL_CALC_FOUND_ROWS @@ -451,11 +436,15 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bo LIMIT ? OFFSET ?` sqlParams = append(sqlParams, sqlParamsPage) } - sql = ` + jdVendorIDField := "t2.jd_id" + if globals.IsUseThingMap { + jdVendorIDField = "t2m.vendor_thing_id" + } + sql = fmt.Sprintf(` SELECT SQL_CALC_FOUND_ROWS t3.id store_id, t3.name store_name, t3.pay_percentage, t1.*, - t2.name_id, t2.id sku_id, t2.spec_quality sku_spec_quality, t2.spec_unit sku_spec_unit, t2.weight, t2.jd_id sku_jd_id, + t2.name_id, t2.id sku_id, t2.spec_quality sku_spec_quality, t2.spec_unit sku_spec_unit, t2.weight, %s sku_jd_id, t2.comment, t2.category_id sku_category_id, t2.status sku_status, t4.created_at bind_created_at, t4.updated_at bind_updated_at, t4.last_operator bind_last_operator, t4.deleted_at bind_deleted_at, t4.sub_store_id, t4.price bind_price, IF(t4.unit_price IS NOT NULL, t4.unit_price, t1.price) unit_price, t4.status store_sku_status, t4.auto_sale_at, @@ -463,7 +452,7 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bo t4.jd_sync_status, t4.ebai_sync_status, t4.mtwm_sync_status, t4.jd_price, t4.ebai_price, t4.mtwm_price, t4.jx_price, t4.status_sale_begin, t4.status_sale_end - ` + sql + `, jdVendorIDField) + sql var tmpList []*tGetStoresSkusInfo beginTime := time.Now() if err = dao.GetRows(db, &tmpList, sql, sqlParams...); err != nil { @@ -475,12 +464,12 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bo } dao.Commit(db) globals.SugarLogger.Debugf("GetStoresSkusNew get result2:%v", time.Now().Sub(beginTime)) - storeNameMap := make(map[int64]*StoreSkuNameExt) + storeNameMap := make(map[int64]*dao.StoreSkuNameExt) for _, v := range tmpList { - var storeName *StoreSkuNameExt + var storeName *dao.StoreSkuNameExt index := jxutils.Combine2Int(v.StoreID, v.ID) if isBySku || storeNameMap[index] == nil { - storeName = &StoreSkuNameExt{ + storeName = &dao.StoreSkuNameExt{ StoreID: v.StoreID, StoreName: v.StoreName, SkuName: v.SkuName, @@ -507,7 +496,7 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bo storeIDs, skuIDs = GetStoreAndSkuIDsFromInfo(skuNamesInfo) } beginTime := time.Now() - err = updateActPrice4StoreSkuNameNew(db, storeIDs, skuIDs, skuNamesInfo, actVendorID) + err = dao.UpdateActPrice4StoreSkuNameNew(db, storeIDs, skuIDs, skuNamesInfo, actVendorID) globals.SugarLogger.Debugf("GetStoresSkusNew updateActPrice4StoreSkuName:%v", time.Now().Sub(beginTime)) if !isFocus { err = updateUnitPrice4StoreSkuNameNew(db, skuNamesInfo) @@ -518,7 +507,7 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bo return skuNamesInfo, err } -func GetStoreAndSkuIDsFromInfo(skuNamesInfo *StoreSkuNamesInfo) (storeIDs, skuIDs []int) { +func GetStoreAndSkuIDsFromInfo(skuNamesInfo *dao.StoreSkuNamesInfo) (storeIDs, skuIDs []int) { storeIDMap := make(map[int]int) skuIDMap := make(map[int]int) for _, skuName := range skuNamesInfo.SkuNames { @@ -531,7 +520,7 @@ func GetStoreAndSkuIDsFromInfo(skuNamesInfo *StoreSkuNamesInfo) (storeIDs, skuID } // 根据已经部分关注的商品,得到已经存在的门店商品单价 -func updateUnitPrice4StoreSkuNameNew(db *dao.DaoDB, skuNamesInfo *StoreSkuNamesInfo) (err error) { +func updateUnitPrice4StoreSkuNameNew(db *dao.DaoDB, skuNamesInfo *dao.StoreSkuNamesInfo) (err error) { storeIDMap := make(map[int]int) skuNameIDMap := make(map[int]int) for _, skuName := range skuNamesInfo.SkuNames { @@ -553,49 +542,7 @@ func updateUnitPrice4StoreSkuNameNew(db *dao.DaoDB, skuNamesInfo *StoreSkuNamesI return err } -// skuIDs为空,会导致性能极低,所以要skuIDs必须有值 -func updateActPrice4StoreSkuNameNew(db *dao.DaoDB, storeIDs, skuIDs []int, skuNamesInfo *StoreSkuNamesInfo, actVendorID int) (err error) { - if len(skuIDs) == 0 { - return nil - } - var vendorIDs []int - if actVendorID >= 0 { - vendorIDs = []int{actVendorID} - } - actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, vendorIDs, storeIDs, skuIDs, time.Now(), time.Now()) - if err != nil { - globals.SugarLogger.Errorf("updateActPrice4StoreSkuNameNew can not get sku promotion info for error:%v", err) - return err - } - actStoreSkuMap4Act := jxutils.NewActStoreSkuMap(actStoreSkuList, true) - actStoreSkuMap4EarningPrice := jxutils.NewActStoreSkuMap(actStoreSkuList, false) - - for _, skuName := range skuNamesInfo.SkuNames { - if len(skuName.Skus) > 0 { - for _, v := range skuName.Skus { - if actStoreSku := actStoreSkuMap4Act.GetActStoreSku(skuName.StoreID, v.SkuID, -1); actStoreSku != nil { - v.ActPrice = int(actStoreSku.ActualActPrice) - v.ActID = actStoreSku.ActID - v.ActType = actStoreSku.Type - } - if actStoreSku := actStoreSkuMap4EarningPrice.GetActStoreSku(skuName.StoreID, v.SkuID, -1); actStoreSku != nil { - v.EarningPrice = int(actStoreSku.EarningPrice) - v.EarningActID = actStoreSku.ActID - } - - v.RealEarningPrice = v.EarningPrice - if v.RealEarningPrice == 0 { - v.RealEarningPrice = int(jxutils.CaculateSkuEarningPrice(int64(v.BindPrice), int64(v.BindPrice), skuName.PayPercentage)) - } - } - } else { - skuName.UnitPrice = skuName.Price - } - } - return err -} - -func updateSaleInfo4StoreSkuName(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs, skuIDs []int, params map[string]interface{}, skuNamesInfo *StoreSkuNamesInfo, offset, pageSize int) (err error) { +func updateSaleInfo4StoreSkuName(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs, skuIDs []int, params map[string]interface{}, skuNamesInfo *dao.StoreSkuNamesInfo, offset, pageSize int) (err error) { var ( saleInfoList []*SkuSaleInfo timeList []time.Time @@ -624,9 +571,9 @@ func updateSaleInfo4StoreSkuName(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs for _, saleInfo := range saleInfoList { saleInfoMap[jxutils.Combine2Int(saleInfo.StoreID, saleInfo.SkuID)] = saleInfo } - var newSkuNames []*StoreSkuNameExt + var newSkuNames []*dao.StoreSkuNameExt for _, skuName := range skuNamesInfo.SkuNames { - var newSkus []*StoreSkuExt + var newSkus []*dao.StoreSkuExt for _, sku := range skuName.Skus { saleInfo := saleInfoMap[jxutils.Combine2Int(skuName.StoreID, sku.SkuID)] if saleInfo == nil && fromCount == 0 { @@ -763,8 +710,6 @@ func GetStoresSkusSaleInfo(ctx *jxcontext.Context, storeIDs []int, skuIDs []int, HAVING count >= ? AND count <= ? ` sqlParams = append(sqlParams, fromCount, toCount) - // fmt.Println(sql) - // fmt.Println(utils.Format4Output(sqlParams, false)) if err = dao.GetRows(db, &saleInfoList, sql, sqlParams...); err == nil { // globals.SugarLogger.Debug(utils.Format4Output(saleInfoList, false)) return saleInfoList, nil @@ -788,15 +733,15 @@ func UpdateStoreSku(ctx *jxcontext.Context, storeID int, skuBindInfo *StoreSkuBi } func UpdateStoreSkus(ctx *jxcontext.Context, storeID int, skuBindInfos []*StoreSkuBindInfo, isAsync, isContinueWhenError bool) (hint string, err error) { - return UpdateStoresSkus(ctx, []int{storeID}, skuBindInfos, isAsync, isContinueWhenError) + return UpdateStoresSkus(ctx, []int{storeID}, skuBindInfos, false, isAsync, isContinueWhenError) } -func UpdateStoresSkus(ctx *jxcontext.Context, storeIDs []int, skuBindInfos []*StoreSkuBindInfo, isAsync, isContinueWhenError bool) (hint string, err error) { +func UpdateStoresSkus(ctx *jxcontext.Context, storeIDs []int, skuBindInfos []*StoreSkuBindInfo, isScale, isAsync, isContinueWhenError bool) (hint string, err error) { globals.SugarLogger.Debugf("UpdateStoresSkus:%s, storeIDs:%v, skuBindInfos:%s", ctx.GetTrackInfo(), storeIDs, utils.Format4Output(skuBindInfos, true)) var num int64 db := dao.GetDB() - skuIDs, err := updateStoresSkusWithoutSync(ctx, db, storeIDs, skuBindInfos) + skuIDs, err := updateStoresSkusWithoutSync(ctx, db, storeIDs, skuBindInfos, isScale) if err != nil { return "", err } @@ -836,7 +781,7 @@ func UpdateStoresSkusByBind(ctx *jxcontext.Context, skuBindInfos []*StoreSkuBind } }() for _, storeID := range storeIDs { - skuIDs, err2 := updateStoresSkusWithoutSync(ctx, db, []int{storeID}, skuBindInfosMap[storeID]) + skuIDs, err2 := updateStoresSkusWithoutSync(ctx, db, []int{storeID}, skuBindInfosMap[storeID], false) if err = err2; err != nil { dao.Rollback(db) return "", err @@ -916,7 +861,7 @@ func uniqueStoreNameBind(skuBindInfos []*StoreSkuBindInfo) (outSkuBindInfos []*S return outSkuBindInfos } -func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs []int, skuBindInfos []*StoreSkuBindInfo) (needSyncSkus []int, err error) { +func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs []int, skuBindInfos []*StoreSkuBindInfo, isScale bool) (needSyncSkus []int, err error) { if len(storeIDs)*len(skuBindInfos) > maxStoreNameBind2 { return nil, fmt.Errorf("门店商品信息大于%d", maxStoreNameBind2) } @@ -957,6 +902,10 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs dao.Rollback(db) return nil, err } + scaleFactor := float64(1) + if isScale { + scaleFactor = 100 / float64(jxutils.ConstrainPayPercentage(storeDetail.PayPercentage)) + } for _, skuBindInfo := range skuBindInfos { // 关注且没有给价时,需要尝试从store_sku_bind中得到已有的单价 needGetExistingUnitPrice := skuBindInfo.UnitPrice == 0 && skuBindInfo.IsFocus == 1 @@ -1018,6 +967,7 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs unitPrice = allBinds[0].SkuNamePrice } } + unitPrice = int(float64(unitPrice) * scaleFactor) for _, v := range allBinds { var num int64 inSkuBind := inSkuBinsMap[v.RealSkuID] @@ -1263,19 +1213,16 @@ func UpdateStoresSkusSale(ctx *jxcontext.Context, storeIDs []int, skuBindSkuInfo return hint, err } -func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode string, params map[string]interface{}, userName string) (num int64, err error) { +func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID int, toStoreIDs []int, copyMode string, isScale bool, params map[string]interface{}, userName string) (num int64, err error) { if copyMode != CopyStoreSkuModeFresh && copyMode != CopyStoreSkuModeUpdate && copyMode != CopyStoreSkuModeUpdatePrice { return 0, fmt.Errorf("不支持的拷贝模式:%s", copyMode) } db := dao.GetDB() - if err = checkStoreExisting(db, fromStoreID); err != nil { + fromStore, err := checkStoreExisting(db, fromStoreID) + if err != nil { return 0, err } - if err = checkStoreExisting(db, toStoreID); err != nil { - return 0, err - } - sqlCatAndSku := "" sqlCatAndSkuParams := make([]interface{}, 0) if params["categoryIDs"] != nil { @@ -1302,10 +1249,16 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode if params["pricePercentage"] != nil { pricePercentage = params["pricePercentage"].(int) } - - now := time.Now() - if fromStoreID == toStoreID { - sql := ` + errList := errlist.New() + for _, toStoreID := range toStoreIDs { + toStore, err := checkStoreExisting(db, toStoreID) + if err != nil { + errList.AddErr(err) + break + } + now := time.Now() + if fromStoreID == toStoreID { + sql := ` UPDATE store_sku_bind t1 JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ? JOIN sku_name t3 ON t2.name_id = t3.id AND t2.deleted_at = ? @@ -1320,36 +1273,41 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode t1.ebai_sync_status = t1.ebai_sync_status | ? WHERE t1.store_id = ? AND t1.deleted_at = ? ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - userName, - now, - pricePercentage, - pricePercentage, - pricePercentage, - model.SyncFlagPriceMask, - model.SyncFlagPriceMask, - model.SyncFlagPriceMask, - toStoreID, - utils.DefaultTimeValue, + sqlParams := []interface{}{ + utils.DefaultTimeValue, + utils.DefaultTimeValue, + utils.DefaultTimeValue, + userName, + now, + pricePercentage, + pricePercentage, + pricePercentage, + model.SyncFlagPriceMask, + model.SyncFlagPriceMask, + model.SyncFlagPriceMask, + toStoreID, + utils.DefaultTimeValue, + } + sql += sqlCatAndSku + sqlParams = append(sqlParams, sqlCatAndSkuParams) + num2, err2 := dao.ExecuteSQL(db, sql, sqlParams) + if err2 != nil { + errList.AddErr(err2) + } else { + num += num2 + } + break } - sql += sqlCatAndSku - sqlParams = append(sqlParams, sqlCatAndSkuParams) - num, err = dao.ExecuteSQL(db, sql, sqlParams) - return num, err - } - dao.Begin(db) - defer func() { - dao.Rollback(db) - if r := recover(); r != nil { - panic(r) - } - }() - if copyMode == CopyStoreSkuModeFresh { - // 将toStore中存在,但fromStore中不存在的置删除标志 - sqlDelete := ` + dao.Begin(db) + defer func() { + if r := recover(); r != nil { + dao.Rollback(db) + panic(r) + } + }() + if copyMode == CopyStoreSkuModeFresh { + // 将toStore中存在,但fromStore中不存在的置删除标志 + sqlDelete := ` UPDATE store_sku_bind t1 LEFT JOIN store_sku_bind t0 ON t0.store_id = ? AND t0.sku_id = t1.sku_id AND t0.deleted_at = ? JOIN sku t2 ON t1.sku_id = t2.id/* AND t2.deleted_at = ?*/ @@ -1365,43 +1323,55 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode t1.ebai_sync_status = IF((t1.ebai_sync_status & ?) <> 0, 0, ?) WHERE t1.store_id = ? AND t1.deleted_at = ? AND t0.id IS NULL ` - sqlDeleteParams := []interface{}{ - fromStoreID, - utils.DefaultTimeValue, - // utils.DefaultTimeValue, - // utils.DefaultTimeValue, - utils.DefaultTimeValue, - now, - now, - userName, - model.StoreSkuBindStatusDeleted, - model.SyncFlagNewMask, - model.SyncFlagDeletedMask, - model.SyncFlagNewMask, - model.SyncFlagDeletedMask, - model.SyncFlagNewMask, - model.SyncFlagDeletedMask, - toStoreID, - utils.DefaultTimeValue, + sqlDeleteParams := []interface{}{ + fromStoreID, + utils.DefaultTimeValue, + // utils.DefaultTimeValue, + // utils.DefaultTimeValue, + utils.DefaultTimeValue, + now, + now, + userName, + model.StoreSkuBindStatusDeleted, + model.SyncFlagNewMask, + model.SyncFlagDeletedMask, + model.SyncFlagNewMask, + model.SyncFlagDeletedMask, + model.SyncFlagNewMask, + model.SyncFlagDeletedMask, + toStoreID, + utils.DefaultTimeValue, + } + sqlDelete += sqlCatAndSku + sqlDeleteParams = append(sqlDeleteParams, sqlCatAndSkuParams) + // globals.SugarLogger.Debug(sqlDelete) + num2, err2 := dao.ExecuteSQL(db, sqlDelete, sqlDeleteParams) + if err = err2; err != nil { + errList.AddErr(err) + dao.Rollback(db) + break + } + num += num2 + globals.SugarLogger.Debugf("CopyStoreSkus fromStoreID:%d, toStoreID:%d, trackInfo:%s num1:%d", fromStoreID, toStoreID, ctx.GetTrackInfo(), num2) } - sqlDelete += sqlCatAndSku - sqlDeleteParams = append(sqlDeleteParams, sqlCatAndSkuParams) - // globals.SugarLogger.Debug(sqlDelete) - if num, err = dao.ExecuteSQL(db, sqlDelete, sqlDeleteParams); err != nil { - return 0, err + isModifyStatus := 1 + syncStatus := model.SyncFlagStoreSkuOnlyMask + if copyMode == CopyStoreSkuModeUpdatePrice { + isModifyStatus = 0 + syncStatus = model.SyncFlagPriceMask } - globals.SugarLogger.Debugf("CopyStoreSkus trackInfo:%s num1:%d", ctx.GetTrackInfo(), num) - } - isModifyStatus := 1 - syncStatus := model.SyncFlagStoreSkuOnlyMask - if copyMode == CopyStoreSkuModeUpdatePrice { - isModifyStatus = 0 - syncStatus = model.SyncFlagPriceMask - } - // 处理toStore中与fromStore中都存在的 - sql := ` + scaleFactor := float64(1) + if isScale { + fromPayPercentage := jxutils.ConstrainPayPercentage(fromStore.PayPercentage) + toPayPercentage := jxutils.ConstrainPayPercentage(toStore.PayPercentage) + scaleFactor = float64(fromPayPercentage) / float64(toPayPercentage) + } + // 处理toStore中与fromStore中都存在的 + sql := ` UPDATE store_sku_bind t1 + JOIN store t11 ON t11.id = t1.store_id LEFT JOIN store_sku_bind t0 ON t0.store_id = ? AND t0.sku_id = t1.sku_id AND t0.deleted_at = ? + JOIN store t01 ON t01.id = t0.store_id JOIN sku t2 ON t1.sku_id = t2.id/* AND t2.deleted_at = ?*/ JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/ LEFT JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ? @@ -1409,52 +1379,59 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode t1.last_operator = ?, t1.updated_at = ?, t1.sub_store_id = 0, - t1.price = IF(t0.price * ? / 100 > 0, t0.price * ? / 100, 1), - t1.jx_price = IF(t0.jx_price * ? / 100 > 0, t0.jx_price * ? / 100, 1), - t1.unit_price = IF(t0.unit_price * ? / 100 > 0, t0.unit_price * ? / 100, 1), + t1.price = IF(t0.price * ? / 100 > 0, t0.price * ? / 100, 1) * ?, + t1.jx_price = IF(t0.jx_price * ? / 100 > 0, t0.jx_price * ? / 100, 1) * ?, + t1.unit_price = IF(t0.unit_price * ? / 100 > 0, t0.unit_price * ? / 100, 1) * ?, t1.status = IF(? = 0, t1.status, t0.status), t1.jd_sync_status = t1.jd_sync_status | ?, t1.mtwm_sync_status = t1.mtwm_sync_status | ?, t1.ebai_sync_status = t1.ebai_sync_status | ? WHERE t1.store_id = ? AND t1.deleted_at = ? AND t0.id IS NOT NULL ` - sqlParams := []interface{}{ - fromStoreID, - utils.DefaultTimeValue, - // utils.DefaultTimeValue, - // utils.DefaultTimeValue, - utils.DefaultTimeValue, - userName, - now, - pricePercentage, - pricePercentage, - pricePercentage, - pricePercentage, - pricePercentage, - pricePercentage, - isModifyStatus, - syncStatus, - syncStatus, - syncStatus, - toStoreID, - utils.DefaultTimeValue, - } - sql += sqlCatAndSku - sqlParams = append(sqlParams, sqlCatAndSkuParams) - // globals.SugarLogger.Debug(sql) - num, err = dao.ExecuteSQL(db, sql, sqlParams) - globals.SugarLogger.Debugf("CopyStoreSkus trackInfo:%s num2:%d", ctx.GetTrackInfo(), num) - if err != nil { - return 0, err - } - - // 添加toStore中不存在,但fromStore存在的 - sql = ` + sqlParams := []interface{}{ + fromStoreID, + utils.DefaultTimeValue, + // utils.DefaultTimeValue, + // utils.DefaultTimeValue, + utils.DefaultTimeValue, + userName, + now, + pricePercentage, + pricePercentage, + scaleFactor, + pricePercentage, + pricePercentage, + scaleFactor, + pricePercentage, + pricePercentage, + scaleFactor, + isModifyStatus, + syncStatus, + syncStatus, + syncStatus, + toStoreID, + utils.DefaultTimeValue, + } + sql += sqlCatAndSku + sqlParams = append(sqlParams, sqlCatAndSkuParams) + // globals.SugarLogger.Debug(sql) + num2, err2 := dao.ExecuteSQL(db, sql, sqlParams) + globals.SugarLogger.Debugf("CopyStoreSkus fromStoreID:%d, toStoreID:%d, trackInfo:%s num2:%d", fromStoreID, toStoreID, ctx.GetTrackInfo(), num2) + if err = err2; err != nil { + errList.AddErr(err) + dao.Rollback(db) + break + } + num += num2 + // 添加toStore中不存在,但fromStore存在的 + sql = ` INSERT INTO store_sku_bind(created_at, updated_at, last_operator, deleted_at, store_id, sku_id, sub_store_id, price, jx_price, unit_price, status, jd_sync_status, ebai_sync_status, mtwm_sync_status) SELECT ?, ?, ?, ?, ?, t1.sku_id, 0, - IF(t1.price * ? / 100 > 0, t1.price * ? / 100, 1), IF(t1.jx_price * ? / 100 > 0, t1.jx_price * ? / 100, 1), IF(t1.unit_price * ? / 100 > 0, t1.unit_price * ? / 100, 1), + IF(t1.price * ? / 100 > 0, t1.price * ? / 100, 1) * ?, + IF(t1.jx_price * ? / 100 > 0, t1.jx_price * ? / 100, 1) * ?, + IF(t1.unit_price * ? / 100 > 0, t1.unit_price * ? / 100, 1) * ?, IF(? = 0, ?, t1.status), ?, ?, ? FROM store_sku_bind t1 JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ? @@ -1463,36 +1440,43 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode LEFT JOIN store_sku_bind t0 ON t1.sku_id = t0.sku_id AND t0.store_id = ? AND t0.deleted_at = ? WHERE t1.store_id = ? AND t1.deleted_at = ? ` - sqlParams = []interface{}{ - now, now, userName, utils.DefaultTimeValue, toStoreID, - pricePercentage, - pricePercentage, - pricePercentage, - pricePercentage, - pricePercentage, - pricePercentage, - isModifyStatus, - model.SkuStatusDontSale, - model.SyncFlagNewMask, - model.SyncFlagNewMask, - model.SyncFlagNewMask, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - toStoreID, - utils.DefaultTimeValue, - fromStoreID, - utils.DefaultTimeValue, + sqlParams = []interface{}{ + now, now, userName, utils.DefaultTimeValue, toStoreID, + pricePercentage, + pricePercentage, + scaleFactor, + pricePercentage, + pricePercentage, + scaleFactor, + pricePercentage, + pricePercentage, + scaleFactor, + isModifyStatus, + model.SkuStatusDontSale, + model.SyncFlagNewMask, + model.SyncFlagNewMask, + model.SyncFlagNewMask, + utils.DefaultTimeValue, + utils.DefaultTimeValue, + utils.DefaultTimeValue, + toStoreID, + utils.DefaultTimeValue, + fromStoreID, + utils.DefaultTimeValue, + } + sql += sqlCatAndSku + " AND t0.id IS NULL" + sqlParams = append(sqlParams, sqlCatAndSkuParams) + num2, err = dao.ExecuteSQL(db, sql, sqlParams) + if err != nil { + errList.AddErr(err) + dao.Rollback(db) + break + } + num += num2 + globals.SugarLogger.Debugf("CopyStoreSkus fromStoreID:%d, toStoreID:%d, trackInfo:%s num3:%d", fromStoreID, toStoreID, ctx.GetTrackInfo(), num2) + dao.Commit(db) } - sql += sqlCatAndSku + " AND t0.id IS NULL" - sqlParams = append(sqlParams, sqlCatAndSkuParams) - num, err = dao.ExecuteSQL(db, sql, sqlParams) - if err != nil { - return 0, err - } - globals.SugarLogger.Debugf("CopyStoreSkus trackInfo:%s num3:%d", ctx.GetTrackInfo(), num) - dao.Commit(db) - return num, err + return num, errList.GetErrListAsOne() } func shouldPendingStorePriceChange(ctx *jxcontext.Context, storeID int, skuBindInfo *StoreSkuBindInfo) (shouldPending bool, err error) { @@ -1648,7 +1632,7 @@ func AcceptStoreOpRequests(ctx *jxcontext.Context, reqIDs []int) (err error) { } } if err2 == nil { - _, err2 := UpdateStoresSkus(ctx, []int{op.StoreID}, []*StoreSkuBindInfo{skuBindInfo}, false, false) + _, err2 := UpdateStoresSkus(ctx, []int{op.StoreID}, []*StoreSkuBindInfo{skuBindInfo}, false, false, false) isLocalSucess := true if err2 != nil { subErrors[reqID] = err2 @@ -1845,16 +1829,16 @@ func setStoreSkuBindStatus(skuBind *model.StoreSkuBind, status int8) { skuBind.MtwmSyncStatus |= status } -func checkStoreExisting(db *dao.DaoDB, storeID int) (err error) { - store := &model.Store{} +func checkStoreExisting(db *dao.DaoDB, storeID int) (store *model.Store, err error) { + store = &model.Store{} store.ID = storeID if err = dao.GetEntity(db, store); err != nil { if err == orm.ErrNoRows { - return fmt.Errorf("门店:%d不存在", storeID) + return nil, fmt.Errorf("门店:%d不存在", storeID) } - return err + return nil, err } - return nil + return store, nil } func RefreshStoresSkuByVendor(ctx *jxcontext.Context, storeIDs []int, vendorID int, isAsync bool) (hint string, err error) { @@ -1909,7 +1893,7 @@ func RefreshStoresSkuByVendor(ctx *jxcontext.Context, storeIDs []int, vendorID i func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { switch step { case 0: - bareStoreSkuList, err2 := handler.GetStoreSkusBareInfo(ctx, task, oneStoreMap.StoreID, oneStoreMap.VendorStoreID, bareStoreSkuList) + bareStoreSkuList, err2 := handler.GetStoreSkusBareInfo(ctx, oneStoreMap.VendorOrgCode, task, oneStoreMap.StoreID, oneStoreMap.VendorStoreID, bareStoreSkuList) // globals.SugarLogger.Debug(utils.Format4Output(bareStoreSkuList, false)) if err = err2; err == nil || len(bareStoreSkuList) > 0 { err = nil // todo 如果部分失败,强制忽略错误 @@ -2009,7 +1993,7 @@ func GetVendorStoreSkusInfo(ctx *jxcontext.Context, storeID int, vendorIDs, skuI VendorSkuID: v.VendorSkuID, } } - outBareStoreSkuInfoList, err2 := handler.GetStoreSkusBareInfo(ctx, t, loopMapInfo.StoreMapList[0].StoreID, loopMapInfo.StoreMapList[0].VendorStoreID, bareStoreSkuInfoList) + outBareStoreSkuInfoList, err2 := handler.GetStoreSkusBareInfo(ctx, loopMapInfo.StoreMapList[0].VendorOrgCode, t, loopMapInfo.StoreMapList[0].StoreID, loopMapInfo.StoreMapList[0].VendorStoreID, bareStoreSkuInfoList) if err = err2; err == nil && outBareStoreSkuInfoList != nil { locker.Lock() defer locker.Unlock() @@ -2033,7 +2017,7 @@ func SyncJdStoreProducts(ctx *jxcontext.Context, storeIDs, skuIDs []int, isAsync loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) if handler := partner.GetPurchasePlatformFromVendorID(loopMapInfo.VendorID); handler != nil { jdHandler := handler.(*jd.PurchaseHandler) - hint, err2 := jdHandler.SyncStoreProducts(ctx, t, loopMapInfo.StoreMapList[0].StoreID, skuIDs, false, isContinueWhenError) + hint, err2 := jdHandler.SyncStoreProducts(ctx, loopMapInfo.StoreMapList[0].VendorOrgCode, t, loopMapInfo.StoreMapList[0].StoreID, skuIDs, false, isContinueWhenError) if err = err2; err == nil { retVal = []interface{}{hint} } @@ -2102,9 +2086,31 @@ func AutoSaleStoreSku(ctx *jxcontext.Context, storeIDs []int, isNeedSync bool) ( return err } -func ReCalculateJxPrice(ctx *jxcontext.Context, storeIDs []int) (err error) { - db := dao.GetDB() - for _, storeID := range storeIDs { +func ReCalculateJxPrice(db *dao.DaoDB, ctx *jxcontext.Context, storeIDs []int) (hint string, err error) { + task := tasksch.NewParallelTask("刷新京西平台价格", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + storeID := batchItemList[0].(int) + if storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJX); err == nil { + if storeSkuList, err := dao.GetStoresSkusInfo(db, []int{storeID}, nil); err == nil { + for _, skuBind := range storeSkuList { + skuBind.JxPrice = jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), skuBind.Price) + dao.UpdateEntity(db, skuBind) + } + } else { + return nil, err + } + } else { + return nil, err + } + return retVal, err + }, storeIDs) + tasksch.HandleTask(task, nil, true).Run() + hint = task.GetID() + return hint, err +} + +func ReCalculateJxPriceLight(db *dao.DaoDB, ctx *jxcontext.Context, storeID int) (err error) { + if storeID != 0 { if storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJX); err == nil { if storeSkuList, err := dao.GetStoresSkusInfo(db, []int{storeID}, nil); err == nil { for _, skuBind := range storeSkuList { @@ -2121,14 +2127,319 @@ func ReCalculateJxPrice(ctx *jxcontext.Context, storeIDs []int) (err error) { return err } -func GetTopSkusByStoreIDs(ctx *jxcontext.Context, storeIDs []int) (skuAndName []*model.SkuAndName, err error) { +func GetTopSkusByStoreIDs(ctx *jxcontext.Context, storeIDs []int) (storeSkuNameExt []*dao.StoreSkuNameExt, err error) { if len(storeIDs) == 0 { - return skuAndName, err + return storeSkuNameExt, err } db := dao.GetDB() - skuAndName, err = dao.GetTopSkusByStoreIDs(db, storeIDs) + storeSkuNameExt, err = dao.GetTopSkusByStoreIDs(db, storeIDs) if err != nil { return nil, err } - return skuAndName, err + return storeSkuNameExt, err +} + +func GetTopCategorysByStoreIDs(ctx *jxcontext.Context, storeIDs []int) (skuCategory []*model.SkuCategory, err error) { + if len(storeIDs) == 0 { + return skuCategory, err + } + db := dao.GetDB() + skuCategory, err = dao.GetTopCategorysByStoreIDs(db, storeIDs) + if err != nil { + return nil, err + } + return skuCategory, err +} + +func RefershStoreSkusMidPrice(ctx *jxcontext.Context, storeIDs []int) (err error) { + db := dao.GetDB() + _, err = dao.RefershStoreSkusMidPrice(db, storeIDs) + if err == nil { + CreateStorePriceScore(ctx, true) + } + return err +} + +func RefreshJxPriceByExcel(ctx *jxcontext.Context, storeIDs []int, files []*multipart.FileHeader, isAsync, isContinueWhenError bool) (hint string, err error) { + if len(files) == 0 { + return "", errors.New("没有文件上传!") + } + if len(storeIDs) == 0 { + return "", errors.New("请选择至少一个门店!") + } + fileHeader := files[0] + file, err := fileHeader.Open() + hint, err = RefreshJxPriceByExcelBin(ctx, storeIDs, file, true, true) + file.Close() + return hint, err +} + +func RefreshJxPriceByExcelBin(ctx *jxcontext.Context, storeIDs []int, reader io.Reader, isAsync, isContinueWhenError bool) (hint string, err error) { + var ( + storeSkuNamePriceList []*model.StoreSkuNamePrice + storeSkuNamePriceListUpdate []*model.StoreSkuNamePrice + skuBindInfosInter []interface{} + skuBindInfoList []*StoreSkuBindInfo + errMsg string + isErr bool = false + nameMap = make(map[string]string) + ) + dataLock.dataFailedList = dataLock.dataFailedList[0:0] + dataLock.dataSuccessList = dataLock.dataSuccessList[0:0] + sheetParam := &SheetParam{ + SkuNameIDCol: 5, + SkuPriceCol: 3, + SkuNameCol: 1, + SkuRow: 1, + SkuUnitCol: 2, + OutSkuIDCol: 0, + } + taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + switch step { + case 0: + // xlsx, err := excelize.OpenFile("111.xlsx") + xlsx, err := excelize.OpenReader(reader) + if err != nil { + return "", err + } + rows, _ := xlsx.GetRows(xlsx.GetSheetName(1)) + for rowNum, row := range rows { + if rowNum < sheetParam.SkuRow { + continue + } + storeSkuNamePrice := &model.StoreSkuNamePrice{} + errMsg += GetCellIntoStruct(rowNum, row, sheetParam, storeSkuNamePrice, nameMap) + storeSkuNamePriceList = append(storeSkuNamePriceList, storeSkuNamePrice) + } + if errMsg != "" { + return "", errors.New(errMsg) + } else { + isErr = true + } + case 1: + db := dao.GetDB() + storeSkuNamePriceListOrg, _ := dao.GetStoreSkuNamePrice(db) + CreateOrUpdateStoreSkuNamePriceByExcel(db, ctx, storeSkuNamePriceList, storeSkuNamePriceListOrg) + storeSkuNamePriceListNew, _ := dao.GetStoreSkuNamePrice(db) + storeSkuNamePriceMapNew := StoreSkuNamePriceList2Map(ctx, storeSkuNamePriceListNew) + for _, v := range storeSkuNamePriceList { + if storeSkuNamePriceMapNew[v.OutSkuID] != nil { + storeSkuNamePriceListUpdate = append(storeSkuNamePriceListUpdate, storeSkuNamePriceMapNew[v.OutSkuID]) + } + } + taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + storeSkuNamePrice := batchItemList[0].(*model.StoreSkuNamePrice) + var skuBindInfos []*StoreSkuBindInfo + nameIDGroup := strings.Split(storeSkuNamePrice.NameIDGroup, ",") + for _, v := range nameIDGroup { + if v != "" { + nameID := int(utils.Str2Int64(v)) + for _, vv := range storeIDs { + skuList, err2 := dao.GetStoreSkusByNameIDs(db, []int{vv}, nameID) + err = err2 + if len(skuList) > 0 { + unitPrice := 0 + if skuList[0].Unit == model.UnitNames[0] { + if storeSkuNamePrice.Unit == "KG" { + unitPrice = storeSkuNamePrice.Price / 2 + } else { + unitPrice = storeSkuNamePrice.Price + } + } else { + unitPrice = storeSkuNamePrice.Price + } + storeSkuBindInfo := &StoreSkuBindInfo{ + NameID: nameID, + UnitPrice: unitPrice, + } + skuBindInfos = append(skuBindInfos, storeSkuBindInfo) + outSuccess := DataSuccess{ + NameID: nameID, + Name: skuList[0].Name, + Unit: storeSkuNamePrice.Unit, + OrgPrice: utils.Str2Float64(utils.Int64ToStr(skuList[0].UnitPrice)) / 100, + NowPrice: utils.Str2Float64(utils.Int64ToStr(int64(unitPrice))) / 100, + MixPrice: utils.Str2Float64(utils.Int64ToStr(int64(unitPrice)-skuList[0].UnitPrice)) / 100, + } + dataLock.AppendDataSuccess(outSuccess) + } else { + //京西xx门店没有关注该商品 + outFailed := DataFailed{ + NameID: nameID, + Name: storeSkuNamePrice.Name, + Comment: fmt.Sprintf("京西[%v]门店没有关注该商品,商品nameID[%v],Excel上商品名[%v]", vv, nameID, storeSkuNamePrice.Name), + } + dataLock.AppendDataFailed(outFailed) + } + } + } else { + //nameID为空,还未填写nameID + outFailed := DataFailed{ + NameID: 0, + Name: storeSkuNamePrice.Name, + Comment: fmt.Sprintf("商品nameID为空!,还未填写商品nameID,Excel上商品名[%v]", storeSkuNamePrice.Name), + } + dataLock.AppendDataFailed(outFailed) + } + } + retVal = skuBindInfos + return retVal, err + } + taskParallel := tasksch.NewParallelTask("刷新京西价", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, taskFunc, storeSkuNamePriceListUpdate) + tasksch.HandleTask(taskParallel, task, true).Run() + skuBindInfosInter, err = taskParallel.GetResult(0) + case 2: + //更新京西价 + for _, v := range skuBindInfosInter { + skuBindInfoList = append(skuBindInfoList, v.(*StoreSkuBindInfo)) + } + if isErr { + UpdateStoresSkus(ctx, storeIDs, skuBindInfoList, false, isAsync, isContinueWhenError) + } + case 3: + //写Excel + WriteToExcelJx(task, dataLock.dataSuccessList, dataLock.dataFailedList) + } + return result, err + } + taskSeq := tasksch.NewSeqTask2("根据Excel刷新京西价", ctx, isContinueWhenError, taskSeqFunc, 4) + tasksch.HandleTask(taskSeq, nil, true).Run() + if !isAsync { + _, err = taskSeq.GetResult(0) + hint = "1" + } else { + hint = taskSeq.GetID() + } + return hint, err +} + +func WriteToExcelJx(task *tasksch.SeqTask, dataSuccess []DataSuccess, dataFailed []DataFailed) (err error) { + var sheetList1 []*excel.Obj2ExcelSheetConfig + var sheetList2 []*excel.Obj2ExcelSheetConfig + var downloadURL1, downloadURL2, fileName1, fileName2 string + excelConf1 := &excel.Obj2ExcelSheetConfig{ + Title: "sheet1", + Data: dataSuccess, + CaptionList: titleListSuccess, + } + sheetList1 = append(sheetList1, excelConf1) + excelConf2 := &excel.Obj2ExcelSheetConfig{ + Title: "sheet1", + Data: dataFailed, + CaptionList: titleListFailed, + } + sheetList2 = append(sheetList2, excelConf2) + if excelConf1 != nil { + downloadURL1, fileName1, err = jxutils.UploadExeclAndPushMsg(sheetList1, "京西已更新商品") + } else { + baseapi.SugarLogger.Debug("WriteToExcel: dataSuccess is nil!") + } + if excelConf2 != nil { + downloadURL2, fileName2, err = jxutils.UploadExeclAndPushMsg(sheetList2, "未更新商品") + } else { + baseapi.SugarLogger.Debug("WriteToExcel: dataFailed is nil!") + } + if err != nil { + baseapi.SugarLogger.Errorf("WriteToExcel:upload %s , %s failed error:%v", fileName1, fileName2, err) + } else { + noticeMsg := fmt.Sprintf("[详情点我]path1=%s, path2=%s \n", downloadURL1, downloadURL2) + task.SetNoticeMsg(noticeMsg) + baseapi.SugarLogger.Debugf("WriteToExcel:upload %s ,%s success, downloadURL1:%s ,downloadURL2:%s", fileName1, fileName2, downloadURL1, downloadURL2) + } + return err +} + +func CreateOrUpdateStoreSkuNamePriceByExcel(db *dao.DaoDB, ctx *jxcontext.Context, storeSkuNamePriceList []*model.StoreSkuNamePrice, storeSkuNamePriceListOrg []*model.StoreSkuNamePrice) (err error) { + storeSkuNamePriceMap := StoreSkuNamePriceList2Map(ctx, storeSkuNamePriceListOrg) + dao.Begin(db) + defer func() { + if r := recover(); r != nil || err != nil { + dao.Rollback(db) + if r != nil { + panic(r) + } + } + }() + for _, v := range storeSkuNamePriceList { + dao.WrapAddIDCULDEntity(v, ctx.GetUserName()) + if storeSkuNamePriceMap[v.OutSkuID] != nil { + v.ID = storeSkuNamePriceMap[v.OutSkuID].ID + v.UpdatedAt = time.Now() + dao.UpdateEntity(db, v) + } else { + dao.CreateEntity(db, v) + } + } + dao.Commit(db) + return err +} + +func StoreSkuNamePriceList2Map(ctx *jxcontext.Context, storeSkuNamePriceList []*model.StoreSkuNamePrice) (result map[string]*model.StoreSkuNamePrice) { + result = make(map[string]*model.StoreSkuNamePrice, len(storeSkuNamePriceList)) + for _, v := range storeSkuNamePriceList { + result[v.OutSkuID] = v + } + return result +} + +func GetCellIntoStruct(rowNum int, row []string, sheetParam *SheetParam, storeSkuNamePrice *model.StoreSkuNamePrice, nameMap map[string]string) (errMsg string) { + for k, cell := range row { + if k == sheetParam.OutSkuIDCol { + if IsChineseChar(cell) { + return fmt.Sprintf("Excel格式排版发生了变化!在[%v]列,[%v]行附近可能增加或减少了一列", k+1, rowNum+1) + } + storeSkuNamePrice.OutSkuID = cell + } + if k == sheetParam.SkuNameCol { + storeSkuNamePrice.Name = cell + } + if k == sheetParam.SkuNameIDCol { + cellReplace := strings.ReplaceAll(cell, ",", ",") + if cellReplace != "" { + if cellReplace[len(cellReplace)-1:len(cellReplace)] == "," { + cellReplace = cellReplace[0 : len(cellReplace)-1] + } + nameIDs := strings.Split(cellReplace, ",") + for _, v := range nameIDs { + if nameMap[v] != "" { + return fmt.Sprintf(" Excel中含有重复的nameID![%v]列,[%v]行,nameID [%v]\n", k+1, rowNum+1, v) + } else { + nameMap[v] = v + } + } + } + storeSkuNamePrice.NameIDGroup = cellReplace + } + if k == sheetParam.SkuPriceCol { + if IsChineseChar(cell) { + return fmt.Sprintf("Excel格式排版发生了变化!在[%v]列,[%v]行附近可能增加或减少了一列", k+1, rowNum+1) + } + storeSkuNamePrice.Price = int(utils.Float64TwoInt64(utils.Str2Float64(cell) * 100)) + } + if k == sheetParam.SkuUnitCol { + storeSkuNamePrice.Unit = cell + } + } + return errMsg +} + +func (d *DataLock) AppendDataSuccess(dataSuccess DataSuccess) { + d.locker.Lock() + defer d.locker.Unlock() + d.dataSuccessList = append(d.dataSuccessList, dataSuccess) +} + +func (d *DataLock) AppendDataFailed(dataFailed DataFailed) { + d.locker.Lock() + defer d.locker.Unlock() + d.dataFailedList = append(d.dataFailedList, dataFailed) +} + +func IsChineseChar(str string) bool { + for _, r := range str { + if unicode.Is(unicode.Scripts["Han"], r) { + return true + } + } + return false } diff --git a/business/jxstore/cms/store_sku_check.go b/business/jxstore/cms/store_sku_check.go index e7ef4cd53..4f524d104 100644 --- a/business/jxstore/cms/store_sku_check.go +++ b/business/jxstore/cms/store_sku_check.go @@ -17,6 +17,7 @@ import ( "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/globals" + "git.rosy.net.cn/jx-callback/globals/api/apimanager" ) const ( @@ -96,8 +97,9 @@ var ( diffData DiffDataLock depotDiffData DeoptDiffDataLock - multiStoreAllSkuInfoMap map[int]map[int]*partner.SkuNameInfo - multiStoreAllSkuInfoList map[int][]*partner.StoreSkuInfo + multiStoreAllSkuInfoMap map[int]map[string]map[int]*partner.SkuNameInfo + multiStoreAllSkuInfoList map[int]map[string][]*partner.StoreSkuInfo + skuNameInfoList []*partner.SkuNameInfo filterVendorDepotUnSaleSkuIds []int filterJxDepotUnSaleSkuIds []int @@ -166,16 +168,22 @@ func (d *DiffDataLock) InitData() { } func InitMultiStoreData() { - multiStoreAllSkuInfoMap = make(map[int]map[int]*partner.SkuNameInfo) - multiStoreAllSkuInfoList = make(map[int][]*partner.StoreSkuInfo) + multiStoreAllSkuInfoMap = make(map[int]map[string]map[int]*partner.SkuNameInfo) + multiStoreAllSkuInfoList = make(map[int]map[string][]*partner.StoreSkuInfo) } -func GetMultiStoreAllSkuInfoMap(vendorID int) map[int]*partner.SkuNameInfo { - return multiStoreAllSkuInfoMap[vendorID] +func GetMultiStoreAllSkuInfoMap(vendorID int, vendorOrgCode string) (retVal map[int]*partner.SkuNameInfo) { + if multiStoreAllSkuInfoMap[vendorID] != nil { + retVal = multiStoreAllSkuInfoMap[vendorID][vendorOrgCode] + } + return retVal } -func GetMultiStoreAllSkuInfoList(vendorID int) []*partner.StoreSkuInfo { - return multiStoreAllSkuInfoList[vendorID] +func GetMultiStoreAllSkuInfoList(vendorID int, vendorOrgCode string) (retVal []*partner.StoreSkuInfo) { + if multiStoreAllSkuInfoList[vendorID] != nil { + retVal = multiStoreAllSkuInfoList[vendorID][vendorOrgCode] + } + return retVal } //过滤掉平台下架的 @@ -202,30 +210,33 @@ func GetMultiStoreAllSkuInfo(ctx *jxcontext.Context, vendorMap map[int]bool) { } if partner.IsMultiStore(vendorID) { multiHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler) - allSkuNameInfoList, err := multiHandler.GetSkus(ctx, 0, "", "") - skuNameInfoList = allSkuNameInfoList - if err != nil { - baseapi.SugarLogger.Errorf("GetMultiStoreAllSkuInfo error:%v", err) - } else { - multiStoreAllSkuInfoList[vendorID] = StoreSkuFullList2BareFilter(allSkuNameInfoList) //map[平台ID:[]StoreSkuInfo1,StoreSkuInfo2...] - tempMap := make(map[int]*partner.SkuNameInfo) - for _, value := range allSkuNameInfoList { - for _, skuInfo := range value.SkuList { - //表示平台商品库未下架的 - if skuInfo.Status > model.SkuStatusDontSale { - filterVendorDepotUnSaleSkuIds = append(filterVendorDepotUnSaleSkuIds, skuInfo.SkuID) - tempMap[skuInfo.SkuID] = value + for _, vendorOrgCode := range apimanager.CurAPIManager.GetAppOrgCodeList(vendorID) { + allSkuNameInfoList, err := multiHandler.GetSkus(ctx, vendorOrgCode, 0, "") + skuNameInfoList = allSkuNameInfoList + if err != nil { + baseapi.SugarLogger.Errorf("GetMultiStoreAllSkuInfo error:%v", err) + } else { + multiStoreAllSkuInfoList[vendorID][vendorOrgCode] = StoreSkuFullList2BareFilter(allSkuNameInfoList) //map[平台ID:[]StoreSkuInfo1,StoreSkuInfo2...] + tempMap := make(map[int]*partner.SkuNameInfo) + for _, value := range allSkuNameInfoList { + for _, skuInfo := range value.SkuList { + //表示平台商品库未下架的 + if skuInfo.Status > model.SkuStatusDontSale { + filterVendorDepotUnSaleSkuIds = append(filterVendorDepotUnSaleSkuIds, skuInfo.SkuID) + tempMap[skuInfo.SkuID] = value + } } } + multiStoreAllSkuInfoMap[vendorID] = make(map[string]map[int]*partner.SkuNameInfo) + multiStoreAllSkuInfoMap[vendorID][vendorOrgCode] = tempMap //map[平台ID][map[skuID1:SkuNameInfo1,skuID2:SkuNameInfo2]...] } - multiStoreAllSkuInfoMap[vendorID] = tempMap //map[平台ID][map[skuID1:SkuNameInfo1,skuID2:SkuNameInfo2]...] } } } } -func GetFilterJxSkuInfoMap(jxSkuInfoList []*StoreSkuNameExt) map[int]*StoreSkuNameExt { - filterJxSkuInfoMap := make(map[int]*StoreSkuNameExt) +func GetFilterJxSkuInfoMap(jxSkuInfoList []*dao.StoreSkuNameExt) map[int]*dao.StoreSkuNameExt { + filterJxSkuInfoMap := make(map[int]*dao.StoreSkuNameExt) for _, value := range jxSkuInfoList { for _, skuInfo := range value.Skus { filterJxSkuInfoMap[skuInfo.SkuID] = value @@ -254,8 +265,8 @@ func GetFilterJxSkuInfoMap2(jxSkuInfoList []*model.SkuAndName) map[int]*model.Sk return filterVendorSkuInfoMap } -func GetFilterMultiStoreSkuInfoMap(vendorID int, skuInfoList []*partner.StoreSkuInfo) map[int]*partner.SkuNameInfo { - allSkuInfoMap := GetMultiStoreAllSkuInfoMap(vendorID) +func GetFilterMultiStoreSkuInfoMap(vendorID int, vendorOrgCode string, skuInfoList []*partner.StoreSkuInfo) map[int]*partner.SkuNameInfo { + allSkuInfoMap := GetMultiStoreAllSkuInfoMap(vendorID, vendorOrgCode) filterSkuInfoMap := make(map[int]*partner.SkuNameInfo) for _, value := range skuInfoList { if value.Stock > 0 { @@ -276,10 +287,10 @@ func GetFilterStoreList(storeList []*StoreExt, vendorMap, storeIDMap map[int]boo } } if storeInfo.StoreMaps != nil { - var tempStoreMaps []map[string]interface{} + var tempStoreMaps []*model.StoreMap for _, vendorStoreInfo := range storeInfo.StoreMaps { - vendorID := int(utils.MustInterface2Int64(vendorStoreInfo["vendorID"])) - isSyncStoreSku := int(utils.MustInterface2Int64(vendorStoreInfo["isSync"])) + vendorID := vendorStoreInfo.VendorID + isSyncStoreSku := int(vendorStoreInfo.IsSync) if isSyncStoreSku == 0 { continue } @@ -322,7 +333,7 @@ func IsSkuCanSale(saleStatus int) bool { //京西平台和其他平台商品的对比 //storeIDStr 京西商家id ,vendorStoreID 平台商家id -func CompareJxAndVendor(vendorID int, storeIDStr, vendorStoreID, storeName string, filterJxSkuInfoMap map[int]*StoreSkuNameExt, filterVendorSkuInfoMap map[int]*partner.SkuNameInfo) { +func CompareJxAndVendor(vendorID int, storeIDStr, vendorStoreID, storeName string, filterJxSkuInfoMap map[int]*dao.StoreSkuNameExt, filterVendorSkuInfoMap map[int]*partner.SkuNameInfo) { for skuID, jxSkuInfo := range filterJxSkuInfoMap { skuIDStr := utils.Int2Str(skuID) var jxSkuDetailName string @@ -543,14 +554,14 @@ func CheckSkuDiffBetweenJxAndVendor(ctx *jxcontext.Context, vendorIDList []int, storeID := jxStoreInfoListValue.ID storeIDStr := utils.Int2Str(storeID) storeName := jxStoreInfoListValue.Name + jxSkuInfoDataSingle := &dao.StoreSkuNamesInfo{} + jxSkuInfoDataMulti := &dao.StoreSkuNamesInfo{} if jxStoreInfoListValue.StoreMaps != nil { - var filterJxSkuInfoMapSingle map[int]*StoreSkuNameExt - var filterJxSkuInfoMapMulti map[int]*StoreSkuNameExt - var multiFlag = false - var singleFlag = false - //循环平台vendor + var filterJxSkuInfoMapSingle map[int]*dao.StoreSkuNameExt + var filterJxSkuInfoMapMulti map[int]*dao.StoreSkuNameExt for _, vendorListValue := range jxStoreInfoListValue.StoreMaps { - vendorID := int(utils.MustInterface2Int64(vendorListValue["vendorID"])) + vendorID := vendorListValue.VendorID + var flag = false if partner.IsMultiStore(vendorID) { if multiFlag == false { jxSkuInfoDataMulti, _ := GetStoreSkus(ctx, storeID, filterJxDepotUnSaleSkuIds, true, "", true, false, map[string]interface{}{}, 0, -1) @@ -565,17 +576,17 @@ func CheckSkuDiffBetweenJxAndVendor(ctx *jxcontext.Context, vendorIDList []int, } } - vendorStoreID := utils.Interface2String(vendorListValue["vendorStoreID"]) + vendorStoreID := vendorListValue.VendorStoreID baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor storeID:%d vendorID:%d vendorStoreID:%s vendorListValue:%v", storeID, vendorID, vendorStoreID, vendorListValue) if partner.IsMultiStore(vendorID) { singleStoreHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformStoreSkuHandler) - allSkuInfoList := GetMultiStoreAllSkuInfoList(vendorID) - skuBareInfoList, err := singleStoreHandler.GetStoreSkusBareInfo(ctx, task, storeID, vendorStoreID, allSkuInfoList) + allSkuInfoList := GetMultiStoreAllSkuInfoList(vendorID, vendorListValue.VendorOrgCode) + skuBareInfoList, err := singleStoreHandler.GetStoreSkusBareInfo(ctx, vendorListValue.VendorOrgCode, task, storeID, vendorStoreID, allSkuInfoList) if err != nil { baseapi.SugarLogger.Infof("CheckSkuDiffBetweenJxAndVendor GetStoreSkusBareInfo error:%v", err) } else if len(skuBareInfoList) > 0 { - filterSkuInfoMap := GetFilterMultiStoreSkuInfoMap(vendorID, skuBareInfoList) //map[京东商品ID:SkuNameInfo] + filterSkuInfoMap := GetFilterMultiStoreSkuInfoMap(vendorID, vendorListValue.VendorOrgCode, skuBareInfoList) //map[京东商品ID:SkuNameInfo] CompareJxAndVendor(vendorID, storeIDStr, vendorStoreID, storeName, filterJxSkuInfoMapMulti, filterSkuInfoMap) } } else { diff --git a/business/jxstore/cms/sync.go b/business/jxstore/cms/sync.go index 7777ca685..de67b3528 100644 --- a/business/jxstore/cms/sync.go +++ b/business/jxstore/cms/sync.go @@ -60,11 +60,6 @@ type SingleStoreHandlerWrapper struct { partner.ISingleStoreHandler } -type tMultiStoreVendorInfo struct { - VendorID int - OrgCode string -} - var ( CurVendorSync VendorSync ) @@ -134,20 +129,6 @@ func (v *VendorSync) GetSingleStoreHandler(vendorID int) partner.ISingleStoreHan return nil } -func getMultiStoreVendorInfoList() (list []*tMultiStoreVendorInfo) { - vendorIDs := partner.GetMultiStoreVendorIDs() - for _, vendorID := range vendorIDs { - orgCodeList := partner.CurAPIManager.GetAppOrgCodeList(vendorID) - for _, v := range orgCodeList { - list = append(list, &tMultiStoreVendorInfo{ - VendorID: vendorID, - OrgCode: v, - }) - } - } - return list -} - func (v *VendorSync) syncCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID int, db *dao.DaoDB, cats []*model.SkuCategory, userName string) (err error) { multiStoresHandler := v.GetMultiStoreHandler(vendorID) syncStatusFieldName := dao.GetSyncStatusStructField(model.VendorNames[vendorID]) @@ -181,10 +162,17 @@ func (v *VendorSync) syncCategories(ctx *jxcontext.Context, parentTask tasksch.I } func (v *VendorSync) SyncCategory(ctx *jxcontext.Context, db *dao.DaoDB, categoryID int, isAsync bool, userName string) (hint string, err error) { + if !globals.IsUseThingMap { + return v.oldSyncCategory(ctx, db, categoryID, isAsync, userName) + } + return SyncCategories(ctx, nil, nil, nil, []int{categoryID}, isAsync) +} + +func (v *VendorSync) oldSyncCategory(ctx *jxcontext.Context, db *dao.DaoDB, categoryID int, isAsync bool, userName string) (hint string, err error) { globals.SugarLogger.Debug("SyncCategory") hint, err = v.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("同步分类信息:%d", categoryID), isAsync, false, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { - vendorInfo := batchItemList[0].(*tMultiStoreVendorInfo) + vendorInfo := batchItemList[0].(*MultiStoreVendorInfo) var cats []*model.SkuCategory cond := make(map[string]interface{}) if categoryID > 0 { @@ -210,8 +198,15 @@ func (v *VendorSync) SyncCategory(ctx *jxcontext.Context, db *dao.DaoDB, categor } func (v *VendorSync) SyncReorderCategories(ctx *jxcontext.Context, db *dao.DaoDB, categoryID int, isAsync bool, userName string) (hint string, err error) { + if !globals.IsUseThingMap { + return v.oldSyncReorderCategories(ctx, db, categoryID, isAsync, userName) + } + return SyncReorderCategories(ctx, -1, isAsync) +} + +func (v *VendorSync) oldSyncReorderCategories(ctx *jxcontext.Context, db *dao.DaoDB, categoryID int, isAsync bool, userName string) (hint string, err error) { hint, err = v.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("分类重排序:%d", categoryID), isAsync, false, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { - vendorInfo := batchItemList[0].(*tMultiStoreVendorInfo) + vendorInfo := batchItemList[0].(*MultiStoreVendorInfo) multiStoresHandler := v.GetMultiStoreHandler(vendorInfo.VendorID) err2 := multiStoresHandler.ReorderCategories(db, categoryID, userName) if err2 == nil { @@ -226,7 +221,6 @@ func (v *VendorSync) SyncReorderCategories(ctx *jxcontext.Context, db *dao.DaoDB func (v *VendorSync) SyncStore(ctx *jxcontext.Context, db *dao.DaoDB, vendorID, storeID int, isAsync bool, userName string) (hint string, err error) { globals.SugarLogger.Debugf("SyncStore, storeID:%d", storeID) - var vendorIDs []int if vendorID != -1 { vendorIDs = []int{ @@ -236,35 +230,38 @@ func (v *VendorSync) SyncStore(ctx *jxcontext.Context, db *dao.DaoDB, vendorID, hint, err = v.LoopStoresMap(ctx, db, fmt.Sprintf("同步门店信息:%d", storeID), isAsync, false, vendorIDs, []int{storeID}, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (resultList interface{}, err error) { loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) handler := v.GetStoreHandler(loopMapInfo.VendorID) - if len(loopMapInfo.StoreMapList) > 1 { - loopStoreTask := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), nil, ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - var resultList []interface{} - storeMap := batchItemList[0].(*model.StoreMap) - db2 := db - if len(loopMapInfo.StoreMapList) > 1 { - db2 = dao.GetDB() - } - if err = handler.UpdateStore(db2, storeMap.StoreID, userName); err == nil { - storeMap.SyncStatus = 0 - _, err = dao.UpdateEntity(db2, storeMap, model.FieldSyncStatus) - resultList = append(resultList, 1) - } - return resultList, err - }, loopMapInfo.StoreMapList) - t.AddChild(loopStoreTask).Run() - resultList, err = loopStoreTask.GetResult(0) - } else { - storeMap := loopMapInfo.StoreMapList[0] - if err = handler.UpdateStore(db, storeMap.StoreID, userName); err == nil { - storeMap.SyncStatus = 0 - _, err = dao.UpdateEntity(db, storeMap, model.FieldSyncStatus) - } - if err == nil { - resultList = []interface{}{1} + if handler != nil { + if len(loopMapInfo.StoreMapList) > 1 { + loopStoreTask := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), nil, ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + var resultList []interface{} + storeMap := batchItemList[0].(*model.StoreMap) + db2 := db + if len(loopMapInfo.StoreMapList) > 1 { + db2 = dao.GetDB() + } + if err = handler.UpdateStore(db2, storeMap.StoreID, userName); err == nil { + storeMap.SyncStatus = 0 + _, err = dao.UpdateEntity(db2, storeMap, model.FieldSyncStatus) + resultList = append(resultList, 1) + } + return resultList, err + }, loopMapInfo.StoreMapList) + t.AddChild(loopStoreTask).Run() + resultList, err = loopStoreTask.GetResult(0) + } else { + storeMap := loopMapInfo.StoreMapList[0] + if err = handler.UpdateStore(db, storeMap.StoreID, userName); err == nil { + storeMap.SyncStatus = 0 + _, err = dao.UpdateEntity(db, storeMap, model.FieldSyncStatus) + } + if err == nil { + resultList = []interface{}{1} + } } + err = partner.AddVendorInfo2Err(err, loopMapInfo.VendorID) } - return resultList, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID) + return resultList, err }, true) return hint, makeSyncError(err) } @@ -284,12 +281,19 @@ func (v *VendorSync) SyncSku(ctx *jxcontext.Context, db *dao.DaoDB, nameID, skuI } func (v *VendorSync) SyncSkus(ctx *jxcontext.Context, db *dao.DaoDB, nameIDs []int, skuIDs []int, isAsync, isContinueWhenError bool, userName string) (hint string, err error) { + if !globals.IsUseThingMap { + return v.oldSyncSkus(ctx, db, nameIDs, skuIDs, isAsync, isContinueWhenError, userName) + } + return SyncSkus(ctx, nil, nil, nil, nameIDs, skuIDs, isAsync) +} + +func (v *VendorSync) oldSyncSkus(ctx *jxcontext.Context, db *dao.DaoDB, nameIDs []int, skuIDs []int, isAsync, isContinueWhenError bool, userName string) (hint string, err error) { globals.SugarLogger.Debugf("SyncSku trackInfo:%s, nameIDs:%v, skuIDs:%v, userName:%s", ctx.GetTrackInfo(), nameIDs, skuIDs, userName) isManagedIt := !(len(nameIDs) > 0 && len(nameIDs) <= 2 || len(skuIDs) > 0 && len(skuIDs) < 8) return v.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("同步商品信息, nameIDs:%v, skuIDs:%v", nameIDs, skuIDs), isAsync, isManagedIt, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { var resultList []interface{} - vendorInfo := batchItemList[0].(*tMultiStoreVendorInfo) + vendorInfo := batchItemList[0].(*MultiStoreVendorInfo) multiStoresHandler := v.GetMultiStoreHandler(vendorInfo.VendorID) syncStatusFieldName := dao.GetSyncStatusStructField(model.VendorNames[multiStoresHandler.GetVendorID()]) dbField := dao.ConvertDBFieldPrefix(model.VendorNames[multiStoresHandler.GetVendorID()]) @@ -463,11 +467,11 @@ func (v *VendorSync) proxySyncStoreSku(ctx *jxcontext.Context, parentTask tasksc return SyncStoreSkuNew(ctx, parentTask, storeMap.VendorID, storeMap.StoreID, storeMap.VendorStoreID, nil, skuIDs, excludeSkuIDs, isAsync, isContinueWhenError) } -func (v *VendorSync) proxyFullSyncStoreSku(ctx *jxcontext.Context, parentTask tasksch.ITask, storeMap *model.StoreMap, isAsync, isContinueWhenError bool) (hint string, err error) { - return FullSyncStoreSkuNew(ctx, parentTask, storeMap.VendorID, storeMap.StoreID, storeMap.VendorStoreID, isAsync, isContinueWhenError) +func (v *VendorSync) proxyFullSyncStoreSku(ctx *jxcontext.Context, parentTask tasksch.ITask, storeMap *model.StoreMap, excludeSkuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { + return FullSyncStoreSkuNew(ctx, parentTask, storeMap.VendorID, storeMap.StoreID, storeMap.VendorStoreID, excludeSkuIDs, isAsync, isContinueWhenError) } -func (v *VendorSync) FullSyncStoresSkus(ctx *jxcontext.Context, db *dao.DaoDB, vendorIDs []int, storeIDs []int, syncDisabled, isAsync, isContinueWhenError bool) (hint string, err error) { +func (v *VendorSync) FullSyncStoresSkus(ctx *jxcontext.Context, db *dao.DaoDB, vendorIDs []int, storeIDs []int, syncDisabled bool, excludeSkuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { globals.SugarLogger.Debug("FullSyncStoresSkus") hint, err = v.LoopStoresMap(ctx, db, fmt.Sprintf("初始化门店商品信息:%v", storeIDs), isAsync, true, vendorIDs, storeIDs, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { @@ -482,7 +486,7 @@ func (v *VendorSync) FullSyncStoresSkus(ctx *jxcontext.Context, db *dao.DaoDB, v func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { storeMap := batchItemList[0].(*model.StoreMap) if syncDisabled || storeMap.Status > model.StoreStatusDisabled { - if _, err = v.proxyFullSyncStoreSku(ctx, task, storeMap, false, isContinueWhenError); err != nil { + if _, err = v.proxyFullSyncStoreSku(ctx, task, storeMap, excludeSkuIDs, false, isContinueWhenError); err != nil { globals.SugarLogger.Debugf("FullSyncStoresSkus failed2 store:%d failed with error:%v", storeMap.StoreID, err) } } @@ -592,6 +596,7 @@ func (v *VendorSync) LoopStoresMap2(ctx *jxcontext.Context, db *dao.DaoDB, taskN if len(loopInfoList) == 1 { taskName = fmt.Sprintf("%s,处理平台%s", taskName, model.VendorChineseNames[loopInfoList[0].VendorID]) } + // globals.SugarLogger.Debugf("LoopStoresMap2 loopInfoList:%s", utils.Format4Output(loopInfoList, false)) task = tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, handler, loopInfoList) task.SetFinishHook(func(task tasksch.ITask, ctx *jxcontext.Context) { err = WirteToExcelBySyncFailed(task, ctx) @@ -688,24 +693,16 @@ func isSyncError(err error) bool { } func (v *VendorSync) SyncSkuNames(ctx *jxcontext.Context, nameIDs []int, isForce, isAsync, isContinueWhenError bool) (hint string, err error) { + if !globals.IsUseThingMap { + return v.oldSyncSkuNames(ctx, nameIDs, isForce, isAsync, isContinueWhenError) + } + return SyncSkus(ctx, nil, nil, nil, nameIDs, nil, isAsync) +} + +func (v *VendorSync) oldSyncSkuNames(ctx *jxcontext.Context, nameIDs []int, isForce, isAsync, isContinueWhenError bool) (hint string, err error) { db := dao.GetDB() if isForce { - sql := ` - UPDATE sku t1 - SET t1.jd_sync_status = t1.jd_sync_status | ? - WHERE t1.deleted_at = ? - ` - sqlParams := []interface{}{ - model.SyncFlagModifiedMask, - utils.DefaultTimeValue, - } - if len(nameIDs) > 0 { - sql += " AND t1.name_id IN(" + dao.GenQuestionMarks(len(nameIDs)) + ")" - sqlParams = append(sqlParams, nameIDs) - } - if _, err = dao.ExecuteSQL(db, sql, sqlParams...); err != nil { - return "", err - } + dao.SetSkuNameSyncStatus(db, nil, nil, nameIDs, model.SyncFlagModifiedMask) } return v.SyncSkus(ctx, db, nameIDs, nil, isAsync, isContinueWhenError, ctx.GetUserName()) } @@ -806,6 +803,7 @@ func (d *SyncErrResultLock) AppendData(syncErrResult SyncErrResult) { defer d.locker.Unlock() d.syncErrResult = append(d.syncErrResult, syncErrResult) } + func OnCreateThing(db *dao.DaoDB, thingID int64, thingType int8) (err error) { return err } diff --git a/business/jxstore/cms/sync2.go b/business/jxstore/cms/sync2.go index 6c9e9db9a..0d28c262a 100644 --- a/business/jxstore/cms/sync2.go +++ b/business/jxstore/cms/sync2.go @@ -1,30 +1,574 @@ package cms import ( + "fmt" + "time" + + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/baseapi/utils/errlist" + "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/business/partner/putils" + "git.rosy.net.cn/jx-callback/globals" ) -func SyncCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs []int, appOrgCodes []string, catIDs []int, isAsync bool) (hint string, err error) { - // if len(vendorIDs) == 0 { - // vendorIDs = partner.GetMultiStoreVendorIDs() - // } - // vendorOrgCodeList := apimanager.CurAPIManager.GetVendorOrgCodeList(vendorIDs, appOrgCodes) - // task := tasksch.NewParallelTask("同步商家分类", nil, ctx, - // func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - // vendorOrgCodePair := batchItemList[0].(*apimanager.VendorOrgCodePair) - // if handler := partner.GetPurchasePlatformFromVendorID(vendorOrgCodePair.VendorID); handler != nil { - // } - // return retVal, err - // }, vendorOrgCodeList) - // tasksch.HandleTask(task, parentTask, len(catIDs) > 0).Run() - // if isAsync { - // hint = task.GetID() - // } else { - // resultList, err2 := task.GetResult(0) - // if err = err2; err == nil { - // hint = utils.Int2Str(len(resultList)) - // } - // } +type MultiStoreVendorInfo struct { + VendorID int + OrgCode string +} + +func CombineVendorIDAndOrgCode(vendorID int, orgCode string) string { + return fmt.Sprintf("%d-%s", vendorID, orgCode) +} + +func getMultiStoreVendorInfoList() (list []*MultiStoreVendorInfo) { + vendorIDs := partner.GetMultiStoreVendorIDs() + for _, vendorID := range vendorIDs { + orgCodeList := partner.CurAPIManager.GetAppOrgCodeList(vendorID) + for _, v := range orgCodeList { + list = append(list, &MultiStoreVendorInfo{ + VendorID: vendorID, + OrgCode: v, + }) + } + } + return list +} + +func syncCategories(ctx *jxcontext.Context, db *dao.DaoDB, parentTask tasksch.ITask, catList []*dao.SkuStoreCatInfo, isAsync bool) (hint string, err error) { + if len(catList) > 0 { + // todo 按vendorID orgCode合并操作 + task := tasksch.NewParallelTask(fmt.Sprintf("同步分类2:%D", len(catList)), tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + catVendorInfo := batchItemList[0].(*dao.SkuStoreCatInfo) + if catVendorInfo.Level != 1 && catVendorInfo.ParentVendorCatID == "" { + return nil, fmt.Errorf("%d的父目录%d没有同步", catVendorInfo.ID, catVendorInfo.ParentID) + } + if catVendorInfo.MapID == 0 { + return nil, fmt.Errorf("分类:%d的数据异常", catVendorInfo.ID) + } + if multiStoresHandler, ok := partner.GetPurchasePlatformFromVendorID(catVendorInfo.VendorID).(partner.IMultipleStoresHandler); ok { + if model.IsSyncStatusDelete(catVendorInfo.CatSyncStatus) { //删除 + if !dao.IsVendorThingIDEmpty(catVendorInfo.VendorCatID) && + model.IsSyncStatusNeedDelete(catVendorInfo.CatSyncStatus) { + err = multiStoresHandler.DeleteCategory2(ctx, catVendorInfo.VendorOrgCode, catVendorInfo.VendorCatID) + } + } else if model.IsSyncStatusNew(catVendorInfo.CatSyncStatus) { // 新增 + err = multiStoresHandler.CreateCategory2(ctx, catVendorInfo) + } else if model.IsSyncStatusUpdate(catVendorInfo.CatSyncStatus) { // 修改 + err = multiStoresHandler.UpdateCategory2(ctx, catVendorInfo) + } + } else { + err = fmt.Errorf("平台:%d不合法", catVendorInfo.VendorID) + } + if err = OnThingSync(ctx, dao.GetDB(), SkuCategoryVendor2ThingMap(catVendorInfo), err); err == nil { + retVal = []int{1} + } + return retVal, err + }, catList) + tasksch.HandleTask(task, parentTask, len(catList) == 0 || len(catList) > 10).Run() + if isAsync { + hint = task.GetID() + } else { + resultList, err2 := task.GetResult(0) + if err = err2; err == nil { + hint = utils.Int2Str(len(resultList)) + } + } + } + return hint, err +} + +func SyncCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs []int, appOrgCodes []string, catIDs []int, isAsync bool) (hint string, err error) { + globals.SugarLogger.Debugf("SyncCategories catIDs:%v", catIDs) + db := dao.GetDB() + catList, err := dao.GetSkuCategoryWithVendor(db, vendorIDs, appOrgCodes, -1, catIDs, true) + if err == nil && len(catList) > 0 { + var needSyncParentIDs []int + for _, cat := range catList { + if cat.Level == 2 && cat.ParentVendorCatID == "" { + needSyncParentIDs = append(needSyncParentIDs, cat.ParentID) + } + } + if len(needSyncParentIDs) > 0 { + task := tasksch.NewSeqTask(fmt.Sprintf("同步分类1:%v", catIDs), ctx, + func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + switch step { + case 0: + catList2, err := dao.GetSkuCategoryWithVendor(db, vendorIDs, appOrgCodes, -1, needSyncParentIDs, true) + if err == nil { + _, err = syncCategories(ctx, db, task, catList2, false) + } + case 1: + catList2, err := dao.GetSkuCategoryWithVendor(db, vendorIDs, appOrgCodes, -1, catIDs, true) + if err == nil { + _, err = syncCategories(ctx, db, task, catList2, false) + } + } + return result, err + }, 2) + tasksch.HandleTask(task, parentTask, len(catIDs) == 0 || len(catIDs) > 10).Run() + if isAsync { + hint = task.GetID() + } else { + resultList, err2 := task.GetResult(0) + if err = err2; err == nil { + hint = utils.Int2Str(len(resultList)) + } + } + } else { + hint, err = syncCategories(ctx, db, parentTask, catList, false) + } + } + return hint, err +} + +func SyncSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs []int, appOrgCodes []string, nameIDs, skuIDs []int, isAsync bool) (hint string, err error) { + globals.SugarLogger.Debugf("SyncSkus nameIDs:%v, skuIDs:%v", nameIDs, skuIDs) + db := dao.GetDB() + skuList, err := dao.GetSkusWithVendor(db, vendorIDs, appOrgCodes, nameIDs, skuIDs, true) + if err == nil && len(skuList) > 0 { + // todo 按vendorID orgCode合并操作 + task := tasksch.NewParallelTask(fmt.Sprintf("同步商品:%v,%v", nameIDs, skuIDs), tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + skuVendorInfo := batchItemList[0].(*dao.StoreSkuSyncInfo) + if skuVendorInfo.VendorCatID == "" { + return nil, fmt.Errorf("商品:%d的商家分类没有同步", skuVendorInfo.SkuID) + } + if skuVendorInfo.BindID == 0 { + return nil, fmt.Errorf("商品:%d的数据异常", skuVendorInfo.SkuID) + } + skuVendorInfo.SkuName = jxutils.ComposeSkuName(skuVendorInfo.Prefix, skuVendorInfo.Name, skuVendorInfo.Comment, skuVendorInfo.Unit, skuVendorInfo.SpecQuality, skuVendorInfo.SpecUnit, 0) + skuVendorInfo.MergedStatus = jxutils.MergeSkuStatus(skuVendorInfo.Status, skuVendorInfo.NameStatus) + if multiStoresHandler, ok := partner.GetPurchasePlatformFromVendorID(skuVendorInfo.VendorID).(partner.IMultipleStoresHandler); ok { + if model.IsSyncStatusDelete(skuVendorInfo.SkuSyncStatus) { //删除 + if !dao.IsVendorThingIDEmpty(skuVendorInfo.VendorSkuID) && + model.IsSyncStatusNeedDelete(skuVendorInfo.SkuSyncStatus) { + err = multiStoresHandler.DeleteSku2(ctx, skuVendorInfo.VendorOrgCode, storeSkuSyncInfo2Bare(skuVendorInfo)) + } + } else if model.IsSyncStatusNew(skuVendorInfo.SkuSyncStatus) { // 新增 + err = multiStoresHandler.CreateSku2(ctx, skuVendorInfo) + } else if model.IsSyncStatusUpdate(skuVendorInfo.SkuSyncStatus) { // 修改 + err = multiStoresHandler.UpdateSku2(ctx, skuVendorInfo) + } + } else { + err = fmt.Errorf("平台:%d不合法", skuVendorInfo.VendorID) + } + if err = OnThingSync(ctx, dao.GetDB(), SkuVendor2ThingMap(skuVendorInfo), err); err == nil { + retVal = []int{1} + } + return retVal, err + }, skuList) + tasksch.HandleTask(task, parentTask, len(skuList) == 0 || len(skuList) > 10).Run() + if isAsync { + hint = task.GetID() + } else { + resultList, err2 := task.GetResult(0) + if err = err2; err == nil { + hint = utils.Int2Str(len(resultList)) + } + } + } + return hint, err +} + +func SyncReorderCategories(ctx *jxcontext.Context, parentCatID int, isAsync bool) (hint string, err error) { + globals.SugarLogger.Debugf("SyncReorderCategories parentCatID:%d", parentCatID) + db := dao.GetDB() + hint, err = CurVendorSync.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("分类重排序:%d", parentCatID), isAsync, false, + func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + vendorInfo := batchItemList[0].(*MultiStoreVendorInfo) + multiStoresHandler := CurVendorSync.GetMultiStoreHandler(vendorInfo.VendorID) + if multiStoresHandler != nil { + catList, err2 := dao.GetSkuCategoryWithVendor(db, []int{vendorInfo.VendorID}, []string{vendorInfo.OrgCode}, parentCatID, nil, false) + if err = err2; err == nil { + var vendorCatIDList []string + for _, v := range catList { + if v.VendorCatID != "" { + vendorCatIDList = append(vendorCatIDList, v.VendorCatID) + } + } + if len(vendorCatIDList) > 0 { + if err = multiStoresHandler.ReorderCategories2(ctx, vendorInfo.OrgCode, catList[0].ParentVendorCatID, vendorCatIDList); err == nil { + retVal = []int{len(vendorCatIDList)} + } + } + } + } else { + err = fmt.Errorf("非法平台:%d", vendorInfo.VendorID) + } + return retVal, err + }) + return hint, err +} + +func getThingMap(db *dao.DaoDB, thingMap *model.ThingMap) (err error) { + return dao.GetEntity(db, thingMap, "ThingID", "ThingType", "VendorID", "VendorOrgCode", model.FieldDeletedAt) +} + +func OnCreateThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*MultiStoreVendorInfo, thingID int64, thingType int8) (err error) { + if thingType == model.ThingTypeSkuName { + return nil + } + if len(vendorInfoList) == 0 { + vendorInfoList = getMultiStoreVendorInfoList() + } + errList := errlist.New() + for _, v := range vendorInfoList { + thingMap := &model.ThingMap{ + ThingID: thingID, + ThingType: thingType, + VendorID: v.VendorID, + VendorOrgCode: v.OrgCode, + SyncStatus: model.SyncFlagNewMask, + } + dao.WrapAddIDCULDEntity(thingMap, ctx.GetUserName()) + if err2 := dao.CreateEntity(db, thingMap); err2 != nil { + if dao.IsDuplicateError(err2) { + errList.AddErr(onUpdateThing(ctx, db, vendorInfoList, thingID, thingType, model.SyncFlagNewMask)) + } else { + errList.AddErr(err2) + } + } + updateThingMapEntity(db, thingMap) + } + if globals.IsUseThingMap { + err = errList.GetErrListAsOne() + } + return err +} + +func onUpdateThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*MultiStoreVendorInfo, thingID int64, thingType int8, syncStatus int8) (err error) { + if thingType == model.ThingTypeSkuName { + return nil + } + if len(vendorInfoList) == 0 { + vendorInfoList = getMultiStoreVendorInfoList() + } + errList := errlist.New() + for _, v := range vendorInfoList { + thingMap := &model.ThingMap{ + ThingID: thingID, + ThingType: thingType, + VendorID: v.VendorID, + VendorOrgCode: v.OrgCode, + } + thingMap.DeletedAt = utils.DefaultTimeValue + if err2 := getThingMap(db, thingMap); err2 == nil { + thingMap.SyncStatus |= syncStatus + thingMap.LastOperator = ctx.GetUserName() + _, err2 = dao.UpdateEntity(db, thingMap) + errList.AddErr(err2) + + updateThingMapEntity(db, thingMap) + } else { + errList.AddErr(err2) + } + } + if globals.IsUseThingMap { + err = errList.GetErrListAsOne() + } + return err +} + +func OnUpdateThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*MultiStoreVendorInfo, thingID int64, thingType int8) (err error) { + return onUpdateThing(ctx, db, vendorInfoList, thingID, thingType, model.SyncFlagModifiedMask) +} + +func OnDeleteThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*MultiStoreVendorInfo, thingID int64, thingType int8) (err error) { + if thingType == model.ThingTypeSkuName { + return nil + } + if len(vendorInfoList) == 0 { + vendorInfoList = getMultiStoreVendorInfoList() + } + errList := errlist.New() + for _, v := range vendorInfoList { + thingMap := &model.ThingMap{ + ThingID: thingID, + ThingType: thingType, + VendorID: v.VendorID, + VendorOrgCode: v.OrgCode, + } + thingMap.DeletedAt = utils.DefaultTimeValue + if err2 := getThingMap(db, thingMap); err2 == nil { + if model.IsSyncStatusNew(thingMap.SyncStatus) { + thingMap.SyncStatus = 0 + thingMap.DeletedAt = time.Now() + } else { + thingMap.SyncStatus |= model.SyncFlagDeletedMask + } + thingMap.LastOperator = ctx.GetUserName() + _, err2 = dao.UpdateEntity(db, thingMap) + errList.AddErr(err2) + + updateThingMapEntity(db, thingMap) + } else if !dao.IsNoRowsError(err2) { + errList.AddErr(err2) + } + } + if globals.IsUseThingMap { + err = errList.GetErrListAsOne() + } + return err +} + +func SkuCategoryVendor2ThingMap(cat *dao.SkuStoreCatInfo) (thingMap *model.ThingMap) { + thingMap = &model.ThingMap{ + ThingID: int64(cat.ID), + ThingType: model.ThingTypeCategory, + VendorID: cat.VendorID, + VendorOrgCode: cat.VendorOrgCode, + + SyncStatus: cat.CatSyncStatus, + VendorThingID: cat.VendorCatID, + } + thingMap.ID = cat.MapID // 一定要赋值 + return thingMap +} + +func SkuVendor2ThingMap(sku *dao.StoreSkuSyncInfo) (thingMap *model.ThingMap) { + thingMap = &model.ThingMap{ + ThingID: int64(sku.SkuID), + ThingType: model.ThingTypeSku, + VendorID: sku.VendorID, + VendorOrgCode: sku.VendorOrgCode, + + SyncStatus: sku.SkuSyncStatus, + VendorThingID: sku.VendorSkuID, + } + thingMap.DeletedAt = utils.DefaultTimeValue + thingMap.ID = sku.BindID // 一定要赋值 + return thingMap +} + +func OnThingSync(ctx *jxcontext.Context, db *dao.DaoDB, thingMap *model.ThingMap, syncErr error) (err error) { + globals.SugarLogger.Debugf("OnThingSync thingMap:%s", utils.Format4Output(thingMap, true)) + if syncErr != nil { + err = syncErr + thingMap.Remark = utils.LimitUTF8StringLen(err.Error(), 255) + dao.UpdateEntity(db, thingMap, "Remark") + } else { + updateFields := []string{ + model.FieldSyncStatus, + model.FieldUpdatedAt, + model.FieldLastOperator, + "Remark", + } + if model.IsSyncStatusDelete(thingMap.SyncStatus) { //删除 + thingMap.DeletedAt = time.Now() + thingMap.VendorThingID = "" + updateFields = append(updateFields, "VendorThingID", model.FieldDeletedAt) + } else if model.IsSyncStatusNew(thingMap.SyncStatus) { // 新增 + updateFields = append(updateFields, "VendorThingID") + } + thingMap.SyncStatus = 0 + thingMap.LastOperator = ctx.GetUserName() + thingMap.UpdatedAt = time.Now() + thingMap.Remark = "" + _, err = dao.UpdateEntity(db, thingMap, updateFields...) + + updateThingMapEntity(db, thingMap) + } + return err +} + +func updateThingMapEntity(db *dao.DaoDB, thingMap *model.ThingMap) { + if thingMap.VendorOrgCode == globals.JdOrgCode { + if thingMap.ThingType == model.ThingTypeCategory { + cat := &model.SkuCategory{ + JdID: utils.Str2Int64WithDefault(thingMap.VendorThingID, 0), + JdSyncStatus: thingMap.SyncStatus, + } + cat.ID = int(thingMap.ThingID) + dao.UpdateEntity(db, cat, "JdID", "JdSyncStatus") + } else if thingMap.ThingType == model.ThingTypeSku { + sku := &model.Sku{ + JdID: utils.Str2Int64WithDefault(thingMap.VendorThingID, 0), + JdSyncStatus: thingMap.SyncStatus, + } + sku.ID = int(thingMap.ThingID) + dao.UpdateEntity(db, sku, "JdID", "JdSyncStatus") + } + } +} + +func amendAndPruneVendorStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID int, vendorOrgCode string, isAsync, isContinueWhenError bool, opType int, isForceUpdate bool) (hint string, err error) { + handler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler) + if handler == nil { + return "", fmt.Errorf("平台:%s不支持此操作", model.VendorChineseNames[vendorID]) + } + db := dao.GetDB() + vendorInfo := []*MultiStoreVendorInfo{ + &MultiStoreVendorInfo{ + VendorID: vendorID, + OrgCode: vendorOrgCode, + }, + } + var sku2Delete []*partner.StoreSkuInfo + var cat2Delete []*partner.BareCategoryInfo + task := tasksch.NewParallelTask(fmt.Sprintf("平台:%s,账号:%s上的商品与商家分类", model.VendorChineseNames[vendorID], vendorOrgCode), + tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + step := batchItemList[0].(int) + switch step { + case 0: + localSkuList, err := dao.GetSkusWithVendor(db, []int{vendorID}, []string{vendorOrgCode}, nil, nil, false) + if err != nil { + return nil, err + } + localSkuMap := make(map[string]*dao.StoreSkuSyncInfo) + for _, v := range localSkuList { + if v.VendorSkuID != "" { + localSkuMap[v.VendorSkuID] = v + } + } + + remoteSkuList, err2 := handler.GetSkus(ctx, vendorOrgCode, 0, "") + if err = err2; err == nil { + remoteSkuMap := make(map[string]int) + for _, v := range remoteSkuList { + if vendorSkuID := v.SkuList[0].VendorSkuID; vendorSkuID != "" { + if localSkuMap[vendorSkuID] == nil { + sku2Delete = append(sku2Delete, &partner.StoreSkuInfo{ + SkuID: v.SkuList[0].SkuID, + VendorSkuID: vendorSkuID, + }) + } else { + remoteSkuMap[vendorSkuID] = 1 + } + } else if v.VendorNameID != "" { + sku2Delete = append(sku2Delete, &partner.StoreSkuInfo{ + SkuID: v.NameID, + VendorSkuID: v.VendorNameID, + }) + } + } + + if opType == AmendPruneOnlyAmend || opType == AmendPruneAll { + for _, v := range localSkuList { + if v.BindID != 0 { + if !model.IsSyncStatusDelete(v.SkuSyncStatus) { + if remoteSkuMap[v.VendorSkuID] == 0 { + if !model.IsSyncStatusNew(v.SkuSyncStatus) { + OnCreateThing(ctx, db, vendorInfo, int64(v.SkuID), model.ThingTypeSku) + } + } else if isForceUpdate { + OnUpdateThing(ctx, db, vendorInfo, int64(v.SkuID), model.ThingTypeSku) + } + } + } else { + OnCreateThing(ctx, db, vendorInfo, int64(v.SkuID), model.ThingTypeSku) + } + } + } + } + case 1: + if (opType == AmendPruneOnlyPrune || opType == AmendPruneAll) && len(sku2Delete) > 0 { + _, err = putils.FreeBatchStoreSkuInfo("删除商品", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { + if err = handler.DeleteSku2(ctx, vendorOrgCode, batchedStoreSkuList[0]); err == nil { + successCount = 1 + } + return nil, successCount, err + }, ctx, task, sku2Delete, 1, isContinueWhenError) + } + sku2Delete = nil + case 2: + localCatList, err := dao.GetSkuCategoryWithVendor(db, []int{vendorID}, []string{vendorOrgCode}, -1, nil, false) + if err != nil { + return nil, err + } + localCatMap := make(map[string]*dao.SkuStoreCatInfo) + for _, v := range localCatList { + localCatMap[v.VendorCatID] = v + localCatMap[v.Name] = v + localCatMap[utils.Int2Str(v.ID)] = v + } + + remoteCatList, err2 := handler.GetAllCategories(ctx, vendorOrgCode) + if err = err2; err == nil { + remoteCatMap := make(map[string]int) + cat2Delete = checkRemoteCatExist(remoteCatMap, localCatMap, remoteCatList) + + for _, v := range localCatList { + if v.MapID != 0 { + if !model.IsSyncStatusDelete(v.CatSyncStatus) { + if remoteCatMap[v.VendorCatID] == 0 { + if !model.IsSyncStatusNew(v.CatSyncStatus) { + OnCreateThing(ctx, db, vendorInfo, int64(v.ID), model.ThingTypeCategory) + } + } else if isForceUpdate && !model.IsSyncStatusUpdate(v.CatSyncStatus) { + OnUpdateThing(ctx, db, vendorInfo, int64(v.ID), model.ThingTypeCategory) + } + } + } else { + OnCreateThing(ctx, db, vendorInfo, int64(v.ID), model.ThingTypeCategory) + } + } + } + case 3: + if (opType == AmendPruneOnlyPrune || opType == AmendPruneAll) && len(cat2Delete) > 0 { + for i := 0; i < 2; i++ { + level := 2 - i + var levelCat2Delete []*partner.BareCategoryInfo + for _, v := range cat2Delete { + if v.Level == level { + levelCat2Delete = append(levelCat2Delete, v) + } + } + if len(levelCat2Delete) > 0 { + task4Delete := tasksch.NewParallelTask(fmt.Sprintf("删除商家分类,level:%d", level), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + cat := batchItemList[0].(*partner.BareCategoryInfo) + err = handler.DeleteCategory2(ctx, vendorOrgCode, cat.VendorCatID) + return nil, err + }, levelCat2Delete) + tasksch.HandleTask(task4Delete, task, true).Run() + _, err = task4Delete.GetResult(0) + } + } + } + cat2Delete = nil + } + return nil, err + }, []int{0, 1, 2, 3}) + tasksch.HandleTask(task, parentTask, true).Run() + if !isAsync { + _, err = task.GetResult(0) + hint = "1" + } else { + hint = task.ID + } + return hint, err +} + +func FullSyncVendorStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID int, vendorOrgCode string, isAsync, isContinueWhenError bool) (hint string, err error) { + multiStoreHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler) + if multiStoreHandler == nil { + return "", fmt.Errorf("vendorID:%d不是多门店平台", vendorID) + } + task := tasksch.NewParallelTask("FullSyncStoreSkuNew", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(false), ctx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + step := batchItemList[0].(int) + switch step { + case 0: + _, err = amendAndPruneVendorStuff(ctx, task, vendorID, vendorOrgCode, false, isContinueWhenError, AmendPruneAll, false) + case 1: + _, err = SyncCategories(ctx, task, []int{vendorID}, []string{vendorOrgCode}, nil, false) + case 2: + _, err = SyncSkus(ctx, task, []int{vendorID}, []string{vendorOrgCode}, nil, nil, false) + } + return retVal, err + }, []int{0, 1, 2}) + tasksch.HandleTask(task, parentTask, true).Run() + if !isAsync { + _, err = task.GetResult(0) + } else { + hint = task.GetID() + } return hint, err } diff --git a/business/jxstore/cms/sync_store.go b/business/jxstore/cms/sync_store.go index 8aac73b73..311b34ed3 100644 --- a/business/jxstore/cms/sync_store.go +++ b/business/jxstore/cms/sync_store.go @@ -36,7 +36,7 @@ func OpenRemoteStoreByJxStatus(ctx *jxcontext.Context, vendorIDs, storeIDs []int if handler, _ := partner.GetPurchasePlatformFromVendorID(storeMap.VendorID).(partner.IStoreHandler); handler != nil { storeDetail, err := dao.GetStoreDetail(db, storeMap.StoreID, storeMap.VendorID) if err == nil && storeDetail.Status == model.StoreStatusOpened { - if err = handler.UpdateStoreStatus(ctx, storeMap.StoreID, storeMap.VendorStoreID, model.StoreStatusOpened); err == nil { + if err = handler.UpdateStoreStatus(ctx, storeMap.VendorOrgCode, storeMap.StoreID, storeMap.VendorStoreID, model.StoreStatusOpened); err == nil { storeMap.Status = model.StoreStatusOpened dao.UpdateEntity(db, storeMap, model.FieldStatus) retVal = []int{1} diff --git a/business/jxstore/cms/sync_store_sku.go b/business/jxstore/cms/sync_store_sku.go index 66b986641..4be5d6d7e 100644 --- a/business/jxstore/cms/sync_store_sku.go +++ b/business/jxstore/cms/sync_store_sku.go @@ -80,14 +80,14 @@ func SyncStoreCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendo catInfo := batchItemList[0].(*dao.SkuStoreCatInfo) storeCatMap := &model.StoreSkuCategoryMap{} storeCatMap.ID = catInfo.MapID - if model.IsSyncStatusDelete(catInfo.StoreCatSyncStatus) { // 删除 - if model.IsSyncStatusDelete(catInfo.StoreCatSyncStatus) && !dao.IsVendorThingIDEmpty(catInfo.VendorCatID) { + if model.IsSyncStatusDelete(catInfo.CatSyncStatus) { // 删除 + if model.IsSyncStatusDelete(catInfo.CatSyncStatus) && !dao.IsVendorThingIDEmpty(catInfo.VendorCatID) { err = handler.DeleteStoreCategory(ctx, storeID, vendorStoreID, catInfo.VendorCatID, level) if err != nil && handler.IsErrCategoryNotExist(err) { err = nil } } - } else if model.IsSyncStatusNew(catInfo.StoreCatSyncStatus) { // 新增 + } else if model.IsSyncStatusNew(catInfo.CatSyncStatus) { // 新增 err = handler.CreateStoreCategory(ctx, storeID, vendorStoreID, catInfo) if err != nil && handler.IsErrCategoryExist(err) { if cat, err2 := handler.GetStoreCategory(ctx, storeID, vendorStoreID, catInfo.Name); err2 == nil { @@ -102,7 +102,7 @@ func SyncStoreCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendo updateFields = append(updateFields, model.FieldLastOperator) } } - } else if model.IsSyncStatusUpdate(catInfo.StoreCatSyncStatus) { // 修改 + } else if model.IsSyncStatusUpdate(catInfo.CatSyncStatus) { // 修改 if err = handler.UpdateStoreCategory(ctx, storeID, vendorStoreID, catInfo); err == nil { updateFields = append(updateFields, idFieldName) } @@ -163,7 +163,7 @@ func SyncStoreSkuNew2(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID return hint, err } -func FullSyncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID, storeID int, vendorStoreID string, isAsync, isContinueWhenError bool) (hint string, err error) { +func FullSyncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID, storeID int, vendorStoreID string, excludeSkuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { singleStoreHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler) task := tasksch.NewParallelTask("FullSyncStoreSkuNew", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { @@ -178,9 +178,9 @@ func FullSyncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, vendo } case 1: if singleStoreHandler != nil { - _, err = SyncStoreSkuNew(ctx, task, vendorID, storeID, vendorStoreID, nil, nil, nil, false, isContinueWhenError) + _, err = SyncStoreSkuNew(ctx, task, vendorID, storeID, vendorStoreID, nil, nil, excludeSkuIDs, false, isContinueWhenError) } else { - err = syncStoreSkuNew(ctx, task, true, vendorID, storeID, nil, nil, nil, false, isContinueWhenError) + err = syncStoreSkuNew(ctx, task, true, vendorID, storeID, nil, nil, excludeSkuIDs, false, isContinueWhenError) } } return retVal, err @@ -195,7 +195,7 @@ func FullSyncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, vendo } func isStoreSkuSyncNeedDelete(storeSku *dao.StoreSkuSyncInfo) bool { - return model.IsSyncStatusDelete(storeSku.StoreSkuSyncStatus) || storeSku.BindDeletedAt != utils.DefaultTimeValue || storeSku.BindID == 0 || storeSku.NameID == 0 + return model.IsSyncStatusDelete(storeSku.SkuSyncStatus) || storeSku.BindDeletedAt != utils.DefaultTimeValue || storeSku.BindID == 0 || storeSku.NameID == 0 } func storeSkuSyncInfo2Bare(inSku *dao.StoreSkuSyncInfo) (outSku *partner.StoreSkuInfo) { @@ -237,10 +237,10 @@ func sku2Update(vendorID int, sku *dao.StoreSkuSyncInfo, syncStatus int8) (item kvs := map[string]interface{}{} if syncStatus&(model.SyncFlagDeletedMask|model.SyncFlagNewMask|model.SyncFlagModifiedMask) != 0 { if model.IsSyncStatusNew(syncStatus) { - sku.StoreSkuSyncStatus = 0 + sku.SkuSyncStatus = 0 kvs[dao.GetVendorThingIDStructField(model.VendorNames[vendorID])] = utils.Str2Int64WithDefault(sku.VendorSkuID, 0) } else if model.IsSyncStatusDelete(syncStatus) { - sku.StoreSkuSyncStatus = 0 + sku.SkuSyncStatus = 0 if utils.IsTimeZero(sku.BindDeletedAt) && (sku.ID == 0 || sku.NameID == 0) { kvs[model.FieldDeletedAt] = time.Now() } @@ -248,18 +248,18 @@ func sku2Update(vendorID int, sku *dao.StoreSkuSyncInfo, syncStatus int8) (item kvs[dao.GetVendorThingIDStructField(model.VendorNames[vendorID])] = 0 } } else { - sku.StoreSkuSyncStatus = sku.StoreSkuSyncStatus & model.SyncFlagPriceMask + sku.SkuSyncStatus = sku.SkuSyncStatus & model.SyncFlagPriceMask } } else if syncStatus&model.SyncFlagStockMask != 0 { if isStoreSkuSyncNeedDelete(sku) { - sku.StoreSkuSyncStatus = 0 + sku.SkuSyncStatus = 0 } else { - sku.StoreSkuSyncStatus = sku.StoreSkuSyncStatus & (model.SyncFlagPriceMask | model.SyncFlagSaleMask) + sku.SkuSyncStatus = sku.SkuSyncStatus & (model.SyncFlagPriceMask | model.SyncFlagSaleMask) } } else { - sku.StoreSkuSyncStatus = sku.StoreSkuSyncStatus & ^syncStatus + sku.SkuSyncStatus = sku.SkuSyncStatus & ^syncStatus } - kvs[dao.GetSyncStatusStructField(model.VendorNames[vendorID])] = sku.StoreSkuSyncStatus + kvs[dao.GetSyncStatusStructField(model.VendorNames[vendorID])] = sku.SkuSyncStatus if sku.VendorPrice > 0 { kvs[dao.GetVendorPriceStructField(model.VendorNames[vendorID])] = sku.VendorPrice } @@ -351,10 +351,10 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo } else { updateItems = append(updateItems, sku2Update(vendorID, sku, model.SyncFlagDeletedMask)) } - } else if model.IsSyncStatusNew(sku.StoreSkuSyncStatus) { + } else if model.IsSyncStatusNew(sku.SkuSyncStatus) { calVendorPrice4StoreSku(sku, storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage)) if singleStoreHandler == nil { - sku.StoreSkuSyncStatus |= model.SyncFlagSaleMask | model.SyncFlagPriceMask + sku.SkuSyncStatus |= model.SyncFlagSaleMask | model.SyncFlagPriceMask bareSku = storeSkuSyncInfo2Bare(sku) stockList = append(stockList, bareSku) priceList = append(priceList, bareSku) @@ -366,7 +366,7 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo } else { if sku.MergedStatus == model.SkuStatusNormal { if dao.IsVendorThingIDEmpty(sku.VendorCatID) { - globals.SugarLogger.Warnf("syncStoreSkuNew 创建门店:%d商品:%d,但没有平台分类ID", sku.StoreID, sku.SkuID) + globals.SugarLogger.Warnf("syncStoreSkuNew 创建门店:%d商品:%d,但没有平台分类ID", storeID, sku.SkuID) } else { createList = append(createList, sku) } @@ -383,26 +383,26 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo } else { isAdded2Update := false // 修改商品信息时不改价(以免活动引起的失败),而用单独的改价来改 - if (model.IsSyncStatusUpdate(sku.StoreSkuSyncStatus) || (model.IsSyncStatusSeq(sku.StoreSkuSyncStatus) && reorderHandler == nil)) && singleStoreHandler != nil { + if (model.IsSyncStatusUpdate(sku.SkuSyncStatus) || (model.IsSyncStatusSeq(sku.SkuSyncStatus) && reorderHandler == nil)) && singleStoreHandler != nil { if dao.IsVendorThingIDEmpty(sku.VendorCatID) { - globals.SugarLogger.Warnf("syncStoreSkuNew 修改门店:%d商品:%d,但没有平台分类ID", sku.StoreID, sku.SkuID) + globals.SugarLogger.Warnf("syncStoreSkuNew 修改门店:%d商品:%d,但没有平台分类ID", storeID, sku.SkuID) } else { isAdded2Update = true updateList = append(updateList, calVendorPrice4StoreSku(sku, storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage))) } } - if model.IsSyncStatusPrice(sku.StoreSkuSyncStatus) { + if model.IsSyncStatusPrice(sku.SkuSyncStatus) { bareSku = storeSkuSyncInfo2Bare(calVendorPrice4StoreSku(sku, storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage))) priceList = append(priceList, bareSku) } if !isAdded2Update { - if model.IsSyncStatusUpdate(sku.StoreSkuSyncStatus) && singleStoreHandler == nil { // 正常就不应该进到这里 + if model.IsSyncStatusUpdate(sku.SkuSyncStatus) && singleStoreHandler == nil { // 正常就不应该进到这里 if bareSku == nil { bareSku = storeSkuSyncInfo2Bare(sku) } updateItems = append(updateItems, sku2Update(vendorID, sku, model.SyncFlagStockMask)) } - if model.IsSyncStatusSale(sku.StoreSkuSyncStatus) { + if model.IsSyncStatusSale(sku.SkuSyncStatus) { if bareSku == nil { bareSku = storeSkuSyncInfo2Bare(sku) } @@ -418,7 +418,7 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo } } } - isNeedReorder = model.IsSyncStatusSeq(sku.StoreSkuSyncStatus) + isNeedReorder = model.IsSyncStatusSeq(sku.SkuSyncStatus) } } if isNeedReorder && reorderHandler != nil && sku.VendorCatID != "" { @@ -523,7 +523,7 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo if len(list) > 0 { _, err = putils.FreeBatchStoreSkuInfo("更新门店商品库存", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { var failedList []*partner.StoreSkuInfoWithErr - failedList, err = storeSkuHandler.UpdateStoreSkusStock(ctx, storeID, vendorStoreID, batchedStoreSkuList) + failedList, err = storeSkuHandler.UpdateStoreSkusStock(ctx,storeDetail.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList) if len(failedList) > 0 { task.AddErrMsg(failedList) } @@ -547,7 +547,7 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo if len(statusList) > 0 { _, err = putils.FreeBatchStoreSkuInfo(name, func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { var failedList []*partner.StoreSkuInfoWithErr - failedList, err = storeSkuHandler.UpdateStoreSkusStatus(ctx, storeID, vendorStoreID, batchedStoreSkuList, status) + failedList, err = storeSkuHandler.UpdateStoreSkusStatus(ctx, storeDetail.VendorOrgCode,storeID, vendorStoreID, batchedStoreSkuList, status) if len(failedList) > 0 { task.AddErrMsg(failedList) } @@ -562,7 +562,7 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo if len(priceList) > 0 { _, err = putils.FreeBatchStoreSkuInfo("更新门店商品价格", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { var failedList []*partner.StoreSkuInfoWithErr - failedList, err = storeSkuHandler.UpdateStoreSkusPrice(ctx, storeID, vendorStoreID, batchedStoreSkuList) + failedList, err = storeSkuHandler.UpdateStoreSkusPrice(ctx, storeDetail.VendorOrgCode,storeID, vendorStoreID, batchedStoreSkuList) if len(failedList) > 0 { task.AddErrMsg(failedList) } @@ -632,6 +632,10 @@ func amendAndPruneStoreStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, v return "", fmt.Errorf("平台:%s不支持此操作", model.VendorChineseNames[vendorID]) } db := dao.GetDB() + storeDetail, err := dao.GetStoreDetail(db, storeID, vendorID) + if err != nil { + return "", err + } var sku2Delete []*partner.StoreSkuInfo var cat2Delete []*partner.BareCategoryInfo @@ -674,10 +678,10 @@ func amendAndPruneStoreStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, v if opType == AmendPruneOnlyAmend || opType == AmendPruneAll { for _, v := range localSkuList { - if !model.IsSyncStatusDelete(v.StoreSkuSyncStatus) && v.BindID != 0 { + if !model.IsSyncStatusDelete(v.SkuSyncStatus) && v.BindID != 0 { syncStatus := int8(0) if remoteSkuMap[v.VendorSkuID] == 0 { - if !model.IsSyncStatusNew(v.StoreSkuSyncStatus) { + if !model.IsSyncStatusNew(v.SkuSyncStatus) { syncStatus = model.SyncFlagNewMask } } else if isForceUpdate { @@ -688,7 +692,7 @@ func amendAndPruneStoreStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, v skuBind.ID = v.BindID skuBind.LastOperator = ctx.GetUserName() skuBind.UpdatedAt = time.Now() - dao.SetStoreSkuBindSyncStatus(skuBind, vendorID, syncStatus|v.StoreSkuSyncStatus) + dao.SetStoreSkuBindSyncStatus(skuBind, vendorID, syncStatus|v.SkuSyncStatus) dao.UpdateEntity(db, skuBind, dao.GetSyncStatusStructField(model.VendorNames[vendorID]), model.FieldLastOperator, model.FieldUpdatedAt) } } @@ -700,7 +704,7 @@ func amendAndPruneStoreStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, v _, err = putils.FreeBatchStoreSkuInfo("删除门店商品", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { if _, err = handler.DeleteStoreSkus(ctx, storeID, vendorStoreID, batchedStoreSkuList); err != nil { // 如果删除失败,尝试设置不可售,假定删除批处理SIZE小于等于设置门店商品可售批处理SIZE - handler.UpdateStoreSkusStatus(ctx, storeID, vendorStoreID, batchedStoreSkuList, model.SkuStatusDontSale) + handler.UpdateStoreSkusStatus(ctx, storeDetail.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList, model.SkuStatusDontSale) } return nil, 0, err }, ctx, task, sku2Delete, handler.GetStoreSkusBatchSize(partner.FuncDeleteStoreSkus), isContinueWhenError) @@ -724,13 +728,13 @@ func amendAndPruneStoreStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, v cat2Delete = checkRemoteCatExist(remoteCatMap, localCatMap, remoteCatList) for _, v := range localCatList { - if !model.IsSyncStatusDelete(v.StoreCatSyncStatus) && v.MapID != 0 { + if !model.IsSyncStatusDelete(v.CatSyncStatus) && v.MapID != 0 { syncStatus := int8(0) if remoteCatMap[v.VendorCatID] == 0 { - if !model.IsSyncStatusNew(v.StoreCatSyncStatus) { + if !model.IsSyncStatusNew(v.CatSyncStatus) { syncStatus = model.SyncFlagNewMask } - } else if isForceUpdate && !model.IsSyncStatusUpdate(v.StoreCatSyncStatus) { + } else if isForceUpdate && !model.IsSyncStatusUpdate(v.CatSyncStatus) { syncStatus = model.SyncFlagModifiedMask } if syncStatus != 0 { @@ -738,7 +742,7 @@ func amendAndPruneStoreStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, v catBind.ID = v.MapID catBind.LastOperator = ctx.GetUserName() catBind.UpdatedAt = time.Now() - dao.SetStoreCatMapSyncStatus(catBind, vendorID, syncStatus|v.StoreCatSyncStatus) + dao.SetStoreCatMapSyncStatus(catBind, vendorID, syncStatus|v.CatSyncStatus) dao.UpdateEntity(db, catBind, dao.GetSyncStatusStructField(model.VendorNames[vendorID]), model.FieldLastOperator, model.FieldUpdatedAt) } } diff --git a/business/jxstore/cms/user2.go b/business/jxstore/cms/user2.go index 3b0387b70..dd9b4a54f 100644 --- a/business/jxstore/cms/user2.go +++ b/business/jxstore/cms/user2.go @@ -8,6 +8,10 @@ import ( "sync" "time" + "git.rosy.net.cn/jx-callback/business/partner/purchase/jd" + + "git.rosy.net.cn/jx-callback/globals/api/apimanager" + "git.rosy.net.cn/baseapi" "git.rosy.net.cn/baseapi/platformapi/jdapi" "git.rosy.net.cn/jx-callback/business/jxutils/excel" @@ -814,82 +818,85 @@ func GetJdUsers(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint ) db := dao.GetDB() jdUsersStruct.userMap = jdUsersStruct.userMap[0:0] - //获取京东商城所有用户 - _, _, toatlPage, _ := api.JdAPI.PrivilegeSearchUser(1) - for i := 1; i <= toatlPage; i++ { - pageNoList = append(pageNoList, i) - } - storeMapList, err := dao.GetStoreMapsListWithoutDisabled(db, []int{model.VendorIDJD}, model.StoreStatusDisabled) - for _, v := range storeMapList { - jxVendorIDsMap[v.VendorStoreID] = utils.Int64ToStr(int64(v.StoreID)) - } taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { switch step { case 0: - taskFunc1 := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - pageNo := batchItemList[0].(int) - storeUserLists, _, _, err := api.JdAPI.PrivilegeSearchUser(pageNo) - retVal = storeUserLists - return retVal, err - } - taskParallel1 := tasksch.NewParallelTask("获取京东商城所有用户列表", tasksch.NewParallelConfig(), ctx, taskFunc1, pageNoList) - tasksch.HandleTask(taskParallel1, task, true).Run() - storeUserList, err = taskParallel1.GetResult(0) - case 1: - taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vv := batchItemList[0].(*jdapi.StoreUserInfo) - vendorStoreIDs, err := api.JdAPI.GetJdUserBindStoreIDs(vv.ID) - var vendorStoreIDsMap = make(map[string]string, len(vendorStoreIDs)) - var vendorStoreIDsResult []string - var roleNameStr string - for _, v := range vendorStoreIDs { - if jxVendorIDsMap[v] == "" { - continue - } - vendorStoreIDsMap[v] = jxVendorIDsMap[v] + //获取京东商城所有用户 + apiList := apimanager.CurAPIManager.GetAppOrgCodeList(model.VendorIDJD) + for _, v := range apiList { + _, _, toatlPage, _ := jd.GetAPI(v).PrivilegeSearchUser(1) + for i := 1; i <= toatlPage; i++ { + pageNoList = append(pageNoList, i) } - if vv.RoleNameStr != "" { - roleNameStr = strings.ReplaceAll(vv.RoleNameStr, " ", "") - if roleNameStr != jdapi.JdUserRoleJHYName && roleNameStr != jdapi.JdUserRolesName && roleNameStr != jdapi.JdUserNoRole { - api.JdAPI.UpdateJdUserRoles(int64(vv.ID), []string{jdapi.JdUserRoleJHYId}) - } + storeMapList, _ := dao.GetStoreMapsListWithoutDisabled(db, []int{model.VendorIDJD}, model.StoreStatusDisabled) + for _, v := range storeMapList { + jxVendorIDsMap[v.VendorStoreID] = utils.Int64ToStr(int64(v.StoreID)) } - if len(vendorStoreIDsMap) == 0 { - isManager, _ := api.JdAPI.IsJdManagerUser(int64(vv.ID)) - if isManager { - jdStruct := JdUserStruct{vv.LoginName, "商家管理员", vv.RoleNameStr, vv.LockStatus} - jdUsersStruct.AppendData(jdStruct) + taskFunc1 := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + pageNo := batchItemList[0].(int) + storeUserLists, _, _, err := jd.GetAPI(v).PrivilegeSearchUser(pageNo) + retVal = storeUserLists + return retVal, err + } + taskParallel1 := tasksch.NewParallelTask("获取京东商城所有用户列表", tasksch.NewParallelConfig(), ctx, taskFunc1, pageNoList) + tasksch.HandleTask(taskParallel1, task, true).Run() + storeUserList, err = taskParallel1.GetResult(0) + + taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + vv := batchItemList[0].(*jdapi.StoreUserInfo) + vendorStoreIDs, err := jd.GetAPI(v).GetJdUserBindStoreIDs(vv.ID) + var vendorStoreIDsMap = make(map[string]string, len(vendorStoreIDs)) + var vendorStoreIDsResult []string + var roleNameStr string + for _, v := range vendorStoreIDs { + if jxVendorIDsMap[v] == "" { + continue + } + vendorStoreIDsMap[v] = jxVendorIDsMap[v] + } + if vv.RoleNameStr != "" { + roleNameStr = strings.ReplaceAll(vv.RoleNameStr, " ", "") + if roleNameStr != jdapi.JdUserRoleJHYName && roleNameStr != jdapi.JdUserRolesName && roleNameStr != jdapi.JdUserNoRole { + jd.GetAPI(v).UpdateJdUserRoles(int64(vv.ID), []string{jdapi.JdUserRoleJHYId}) + } + } + if len(vendorStoreIDsMap) == 0 { + isManager, _ := jd.GetAPI(v).IsJdManagerUser(int64(vv.ID)) + if isManager { + jdStruct := JdUserStruct{vv.LoginName, "商家管理员", vv.RoleNameStr, vv.LockStatus} + jdUsersStruct.AppendData(jdStruct) + } else { + retVal = []int64{int64(vv.ID)} + } } else { - retVal = []int64{int64(vv.ID)} + for _, m := range vendorStoreIDsMap { + vendorStoreIDsResult = append(vendorStoreIDsResult, m) + } + sort.Strings(vendorStoreIDsResult[:]) + jdStruct := JdUserStruct{vv.LoginName, strings.Join(vendorStoreIDsResult, ","), vv.RoleNameStr, vv.LockStatus} + jdUsersStruct.AppendData(jdStruct) } - } else { - for _, m := range vendorStoreIDsMap { - vendorStoreIDsResult = append(vendorStoreIDsResult, m) - } - sort.Strings(vendorStoreIDsResult[:]) - jdStruct := JdUserStruct{vv.LoginName, strings.Join(vendorStoreIDsResult, ","), vv.RoleNameStr, vv.LockStatus} - jdUsersStruct.AppendData(jdStruct) + return retVal, err } - return retVal, err + taskParallel := tasksch.NewParallelTask("获取京东商城用户关联门店列表", tasksch.NewParallelConfig(), ctx, taskFunc, storeUserList) + tasksch.HandleTask(taskParallel, task, true).Run() + disabledIdList, err = taskParallel.GetResult(0) + + taskFunc2 := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + id := batchItemList[0].(int64) + jd.GetAPI(v).PrivilegeUpdateJdUserStatus(id, jdapi.JdUserStatusDisable) + return retVal, err + } + taskParallel2 := tasksch.NewParallelTask("禁用未关联活跃门店用户", tasksch.NewParallelConfig(), ctx, taskFunc2, disabledIdList) + tasksch.HandleTask(taskParallel2, task, true).Run() + _, err = taskParallel2.GetResult(0) } - taskParallel := tasksch.NewParallelTask("获取京东商城用户关联门店列表", tasksch.NewParallelConfig(), ctx, taskFunc, storeUserList) - tasksch.HandleTask(taskParallel, task, true).Run() - disabledIdList, err = taskParallel.GetResult(0) - case 2: - taskFunc2 := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - id := batchItemList[0].(int64) - api.JdAPI.PrivilegeUpdateJdUserStatus(id, jdapi.JdUserStatusDisable) - return retVal, err - } - taskParallel2 := tasksch.NewParallelTask("禁用未关联活跃门店用户", tasksch.NewParallelConfig(), ctx, taskFunc2, disabledIdList) - tasksch.HandleTask(taskParallel2, task, true).Run() - _, err = taskParallel2.GetResult(0) - case 3: + case 1: WriteToExcelJd(task, jdUsersStruct.userMap) } return result, err } - taskSeq := tasksch.NewSeqTask2("获取京东商城用户关联门店列表-序列任务", ctx, isContinueWhenError, taskSeqFunc, 4) + taskSeq := tasksch.NewSeqTask2("获取京东商城用户关联门店列表-序列任务", ctx, isContinueWhenError, taskSeqFunc, 2) tasksch.HandleTask(taskSeq, nil, true).Run() if !isAsync { _, err = taskSeq.GetResult(0) diff --git a/business/jxstore/initdata/initdata.go b/business/jxstore/initdata/initdata.go index 70d0b2ba9..5a30b28f7 100644 --- a/business/jxstore/initdata/initdata.go +++ b/business/jxstore/initdata/initdata.go @@ -5,8 +5,6 @@ import ( "git.rosy.net.cn/baseapi/platformapi/autonavi" "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/datares" "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" @@ -190,88 +188,88 @@ func InitVendorCategory(ctx *jxcontext.Context, vendorID int, isAsync bool) (hin } func UploadImg4Vendors(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) { - db := dao.GetDB() - rootTask := tasksch.NewSeqTask("合并SkuName图片至DataResource", ctx, - func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: // 计算SkuName中缺失的hashCode(注意是DescImg不是Img) - var skuNameList []*model.SkuName - if err = dao.GetRows(db, &skuNameList, ` - SELECT t1.* - FROM sku_name t1 - WHERE t1.desc_img <> '' AND t1.img_hash_code = '' - `); err == nil && len(skuNameList) > 0 { - calcTask := tasksch.NewParallelTask("UploadImg4Vendors calc hashCode", - tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(5), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - skuName := batchItemList[0].(*model.SkuName) - _, skuName.ImgHashCode, err = jxutils.DownloadFileByURL(skuName.DescImg) - if err == nil { - dao.UpdateEntity(db, skuName, "ImgHashCode") - } - return retVal, err - }, skuNameList) - tasksch.HandleTask(calcTask, task, false).Run() - _, err = calcTask.GetResult(0) - } - case 1: // 从SkuName添加缺失的图片至DataResource - _, err = dao.ExecuteSQL(db, ` - INSERT INTO data_resource(created_at, updated_at, last_operator, hash_code, - resource_type, name, main_url, ebai_url, qiniu_url, use_type) - SELECT t1.created_at, t1.created_at, t1.last_operator, t1.img_hash_code, - CASE - WHEN INSTR(t1.desc_img, ".jpg") > 0 OR INSTR(t1.desc_img, ".jpeg") > 0 THEN - 'image/jpeg' - WHEN INSTR(t1.desc_img, ".png") > 0 OR INSTR(t1.desc_img, ".peg") > 0 THEN - 'image/png' - WHEN INSTR(t1.desc_img, ".gif") THEN - 'image/gif' - ELSE - '' - END resource_type, - CONCAT(t1.name, '_desc'), desc_img main_url, t1.desc_img_ebai ebai_url, - IF(INSTR(t1.desc_img, "image.jxc4.com") > 0, t1.desc_img, '') qiniu_url, 2 - FROM sku_name t1 - JOIN ( - SELECT img_hash_code, MAX(id) id, COUNT(*) ct - FROM sku_name - WHERE img_hash_code <> '' AND desc_img <> '' - GROUP BY 1 - ) t3 ON t3.id = t1.id - LEFT JOIN data_resource t2 ON (t2.main_url <> '' AND t2.main_url = t1.desc_img) - WHERE t1.desc_img <> '' AND t1.img_hash_code <> '' AND t2.id IS NULL; - `) - case 2: // 统一SkuName中同hashCode,不同图片地址至同一地址 - _, err = dao.ExecuteSQL(db, ` - UPDATE sku_name t1 - JOIN data_resource t2 ON t2.hash_code = t1.img_hash_code AND t2.main_url <> '' - SET t1.desc_img = t2.main_url - WHERE t1.img_hash_code <> '' AND t1.desc_img <> t2.main_url; - `) - case 3: // 上传DataResource中缺失的平台图片 - dataResList, err2 := dao.GetNeedUploadDataResource(db) - if err = err2; err == nil && len(dataResList) > 0 { - uploadTask := tasksch.NewParallelTask("批量上传图片至平台", - tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(2), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - dataRes := batchItemList[0].(*model.DataResource) - _, err = datares.UploadImage2Vendors(ctx, task, dataRes, nil, false) - return nil, err - }, dataResList) - tasksch.HandleTask(uploadTask, task, true).Run() - _, err = uploadTask.GetResult(0) - } - } - return result, err - }, 4) - tasksch.HandleTask(rootTask, nil, true).Run() - if !isAsync { - if _, err = rootTask.GetResult(0); err == nil { - hint = "1" - } - } else { - hint = rootTask.ID - } + // db := dao.GetDB() + // rootTask := tasksch.NewSeqTask("合并SkuName图片至DataResource", ctx, + // func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + // switch step { + // case 0: // 计算SkuName中缺失的hashCode(注意是DescImg不是Img) + // var skuNameList []*model.SkuName + // if err = dao.GetRows(db, &skuNameList, ` + // SELECT t1.* + // FROM sku_name t1 + // WHERE t1.desc_img <> '' AND t1.img_hash_code = '' + // `); err == nil && len(skuNameList) > 0 { + // calcTask := tasksch.NewParallelTask("UploadImg4Vendors calc hashCode", + // tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(5), ctx, + // func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + // skuName := batchItemList[0].(*model.SkuName) + // _, skuName.ImgHashCode, err = jxutils.DownloadFileByURL(skuName.DescImg) + // if err == nil { + // dao.UpdateEntity(db, skuName, "ImgHashCode") + // } + // return retVal, err + // }, skuNameList) + // tasksch.HandleTask(calcTask, task, false).Run() + // _, err = calcTask.GetResult(0) + // } + // case 1: // 从SkuName添加缺失的图片至DataResource + // _, err = dao.ExecuteSQL(db, ` + // INSERT INTO data_resource(created_at, updated_at, last_operator, hash_code, + // resource_type, name, main_url, ebai_url, qiniu_url, use_type) + // SELECT t1.created_at, t1.created_at, t1.last_operator, t1.img_hash_code, + // CASE + // WHEN INSTR(t1.desc_img, ".jpg") > 0 OR INSTR(t1.desc_img, ".jpeg") > 0 THEN + // 'image/jpeg' + // WHEN INSTR(t1.desc_img, ".png") > 0 OR INSTR(t1.desc_img, ".peg") > 0 THEN + // 'image/png' + // WHEN INSTR(t1.desc_img, ".gif") THEN + // 'image/gif' + // ELSE + // '' + // END resource_type, + // CONCAT(t1.name, '_desc'), desc_img main_url, t1.desc_img_ebai ebai_url, + // IF(INSTR(t1.desc_img, "image.jxc4.com") > 0, t1.desc_img, '') qiniu_url, 2 + // FROM sku_name t1 + // JOIN ( + // SELECT img_hash_code, MAX(id) id, COUNT(*) ct + // FROM sku_name + // WHERE img_hash_code <> '' AND desc_img <> '' + // GROUP BY 1 + // ) t3 ON t3.id = t1.id + // LEFT JOIN data_resource t2 ON (t2.main_url <> '' AND t2.main_url = t1.desc_img) + // WHERE t1.desc_img <> '' AND t1.img_hash_code <> '' AND t2.id IS NULL; + // `) + // case 2: // 统一SkuName中同hashCode,不同图片地址至同一地址 + // _, err = dao.ExecuteSQL(db, ` + // UPDATE sku_name t1 + // JOIN data_resource t2 ON t2.hash_code = t1.img_hash_code AND t2.main_url <> '' + // SET t1.desc_img = t2.main_url + // WHERE t1.img_hash_code <> '' AND t1.desc_img <> t2.main_url; + // `) + // case 3: // 上传DataResource中缺失的平台图片 + // dataResList, err2 := dao.GetNeedUploadDataResource(db) + // if err = err2; err == nil && len(dataResList) > 0 { + // uploadTask := tasksch.NewParallelTask("批量上传图片至平台", + // tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(2), ctx, + // func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + // dataRes := batchItemList[0].(*model.DataResource) + // _, err = datares.UploadImage2Vendors(ctx, task, dataRes, nil, false) + // return nil, err + // }, dataResList) + // tasksch.HandleTask(uploadTask, task, true).Run() + // _, err = uploadTask.GetResult(0) + // } + // } + // return result, err + // }, 4) + // tasksch.HandleTask(rootTask, nil, true).Run() + // if !isAsync { + // if _, err = rootTask.GetResult(0); err == nil { + // hint = "1" + // } + // } else { + // hint = rootTask.ID + // } return hint, err } diff --git a/business/jxstore/misc/misc.go b/business/jxstore/misc/misc.go index 6b430e38f..62923b4b9 100644 --- a/business/jxstore/misc/misc.go +++ b/business/jxstore/misc/misc.go @@ -6,8 +6,11 @@ import ( "sync" "time" + "git.rosy.net.cn/jx-callback/business/jxstore/report" + "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" + "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/defsch" "git.rosy.net.cn/jx-callback/business/jxstore/act" "git.rosy.net.cn/jx-callback/business/jxstore/cms" "git.rosy.net.cn/jx-callback/business/jxutils" @@ -31,6 +34,9 @@ var ( dailyWorkTimeList = []string{ "20:30:00", } + createStorePriceTimeList = []string{ + "23:00:00", + } refreshPageActTimeList = []string{ "7:00:00", "8:00:00", @@ -106,6 +112,10 @@ func Init() { RefreshRealMobile(jxcontext.AdminCtx, model.VendorIDEBAI, time.Now().Add(-24*time.Hour), utils.DefaultTimeValue, false, true) }, 5*time.Second, 1*time.Hour) + ScheduleTimerFuncByInterval(func() { + defsch.FixedScheduler.ConfirmSelfTakeOrders(jxcontext.AdminCtx, nil, time.Now().Add(-48*time.Hour), time.Now().Add(-30*time.Minute), true, true) + }, 5*time.Second, 10*time.Minute) + ScheduleTimerFunc("auto enable remote store", func() { cms.EnableHaveRestStores(jxcontext.AdminCtx, false, true) cms.OpenRemoteStoreByJxStatus(jxcontext.AdminCtx, nil, nil, false, false, true) @@ -126,6 +136,12 @@ func Init() { ScheduleTimerFunc("ChangeStoreSkuSaleStatus", func() { cms.CurVendorSync.ChangeStoreSkuSaleStatus(jxcontext.AdminCtx, 0, true, true) }, ChangeStoreSkuSaleStatusList) + ScheduleTimerFunc("BeginSavePriceRefer", func() { + report.BeginSavePriceRefer(jxcontext.AdminCtx, nil, nil) + }, createStorePriceTimeList) + ScheduleTimerFunc("CreateStorePriceScore", func() { + cms.CreateStorePriceScore(jxcontext.AdminCtx, false) + }, openRemoteStoreTimeList) } ScheduleTimerFunc("AutoSaleStoreSku", func() { cms.AutoSaleStoreSku(jxcontext.AdminCtx, nil, false) @@ -144,12 +160,12 @@ func doDailyWork() { globals.SugarLogger.Debug("doDailyWork") cms.SyncStoresCourierInfo(jxcontext.AdminCtx, nil, false, true) netprinter.RebindAllPrinters(jxcontext.AdminCtx, false, true) - // cms.CurVendorSync.FullSyncStoresSkus(jxcontext.AdminCtx, dao.GetDB(), []int{model.VendorIDJD}, nil, false, true, true) syncFlag := model.SyncFlagPriceMask if (time.Now().Unix()/24*3600)%10 == 0 { syncFlag |= model.SyncFlagSaleMask } - cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, dao.GetDB(), []int{model.VendorIDJD}, nil, false, nil, []int{27379}, syncFlag, true, true) + // cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, dao.GetDB(), []int{model.VendorIDJD}, nil, false, nil, []int{27379}, syncFlag, true, true) + cms.CurVendorSync.FullSyncStoresSkus(jxcontext.AdminCtx, dao.GetDB(), []int{model.VendorIDJD}, nil, false, []int{27379}, true, true) SaveImportantTaskID(TaskNameSyncStoreSku, SpecialTaskID) taskID, _ := cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, dao.GetDB(), []int{model.VendorIDEBAI, model.VendorIDMTWM}, nil, false, nil, nil, syncFlag, true, true) diff --git a/business/jxstore/misc/misc2.go b/business/jxstore/misc/misc2.go index ed90d0ca4..c39f735d3 100644 --- a/business/jxstore/misc/misc2.go +++ b/business/jxstore/misc/misc2.go @@ -103,13 +103,13 @@ func (s *StoreListQueueData) TransferWaitQueueToProcessQueue() { } } -func AddOrDelExtraStoreOptime(ctx *jxcontext.Context, vendorID, storeID int, vendorStoreID string, storeInfo *model.Store, startOpStoreTime, endOpStoreTime int16, needAddTime bool) bool { +func AddOrDelExtraStoreOptime(ctx *jxcontext.Context, vendorID int, vendorOrgCode string, storeID int, vendorStoreID string, storeInfo *model.Store, startOpStoreTime, endOpStoreTime int16, needAddTime bool) bool { opTimeList := storeInfo.GetOpTimeList() if needAddTime { opTimeList = []int16{startOpStoreTime, endOpStoreTime} } handler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IStoreHandler) - return handler.UpdateStoreOpTime(ctx, storeID, vendorStoreID, opTimeList) == nil + return handler.UpdateStoreOpTime(ctx, vendorOrgCode, storeID, vendorStoreID, opTimeList) == nil } func GetStockValue(isStart bool) int { @@ -142,13 +142,13 @@ func SetSkuStock(isStart bool, storeSkuNameList []*partner.SkuNameInfo) { } } -func SetSpecialSkuStatus(ctx *jxcontext.Context, storeID, vendorID int, vendorStoreID string, storeSkuNameList []*partner.SkuNameInfo) { +func SetSpecialSkuStatus(ctx *jxcontext.Context, vendorID int, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuNameList []*partner.SkuNameInfo) { singleStoreHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler) for _, skuNameInfo := range storeSkuNameList { for _, skuInfo := range skuNameInfo.SkuList { if IsSpecialSku(skuNameInfo.Name) || IsSpecialSku(skuInfo.SkuName) { storeSkuList := []*partner.StoreSkuInfo{&skuInfo.StoreSkuInfo} - singleStoreHandler.UpdateStoreSkusStatus(ctx, storeID, vendorStoreID, storeSkuList, model.SkuStatusNormal) + singleStoreHandler.UpdateStoreSkusStatus(ctx, vendorOrgCode, storeID, vendorStoreID, storeSkuList, model.SkuStatusNormal) } } } @@ -180,7 +180,7 @@ func GetFilterStoreList(storeList []*cms.StoreExt, vendorMap, storeIDMap map[int } } for _, vendorStoreInfo := range storeInfo.StoreMaps { - vendorID := int(utils.MustInterface2Int64(vendorStoreInfo["vendorID"])) + vendorID := vendorStoreInfo.VendorID //filter for vendorID if len(vendorMap) > 0 { if _, ok := vendorMap[vendorID]; !ok { @@ -192,7 +192,7 @@ func GetFilterStoreList(storeList []*cms.StoreExt, vendorMap, storeIDMap map[int } temp := *storeInfo newStoreInfo := &temp - newStoreInfo.StoreMaps = []map[string]interface{}{vendorStoreInfo} + newStoreInfo.StoreMaps = []*model.StoreMap{vendorStoreInfo} outStoreList = append(outStoreList, newStoreInfo) } } @@ -223,9 +223,9 @@ func StartOrEndOpStoreEx(ctx *jxcontext.Context, isStart bool, startTime, endTim storeListValue := batchItemList[0].(*cms.StoreExt) storeID := storeListValue.ID for _, vendorListValue := range storeListValue.StoreMaps { - vendorID := int(utils.MustInterface2Int64(vendorListValue["vendorID"])) - startOpStoreTime := int16(utils.MustInterface2Int64(vendorListValue["fakeOpenStart"])) - endOpStoreTime := int16(utils.MustInterface2Int64(vendorListValue["fakeOpenStop"])) + vendorID := vendorListValue.VendorID + startOpStoreTime := vendorListValue.FakeOpenStart + endOpStoreTime := vendorListValue.FakeOpenStop //startOpStoreTime, endOpStoreTime := GetOpStoreTime(vendorID) if startTime != 0 && endTime != 0 { startOpStoreTime = startTime @@ -235,7 +235,7 @@ func StartOrEndOpStoreEx(ctx *jxcontext.Context, isStart bool, startTime, endTim if isStart && (startOpStoreTime == 0 || endOpStoreTime == 0) { continue } - vendorStoreID := utils.Interface2String(vendorListValue["vendorStoreID"]) + vendorStoreID := vendorListValue.VendorStoreID baseapi.SugarLogger.Debugf("StartOrEndOpStore storeID:%d vendorID:%d vendorStoreID:%s", storeID, vendorID, vendorStoreID) singleStoreHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler) storeSkuNameList, err := singleStoreHandler.GetStoreSkusFullInfo(ctx, task, storeID, vendorStoreID, nil) @@ -243,23 +243,23 @@ func StartOrEndOpStoreEx(ctx *jxcontext.Context, isStart bool, startTime, endTim baseapi.SugarLogger.Errorf("StartOrEndOpStore GetStoreSkusFullInfo error:%v storeID:%d vendorID:%d vendorStoreID:%s", err, storeID, vendorID, vendorStoreID) } else { SetSkuStock(isStart, storeSkuNameList) - SetSpecialSkuStatus(ctx, storeID, vendorID, vendorStoreID, storeSkuNameList) + SetSpecialSkuStatus(ctx, vendorID, vendorListValue.VendorOrgCode, storeID, vendorStoreID, storeSkuNameList) storeSkuList := putils.StoreSkuFullList2Bare(storeSkuNameList) if vendorID == model.VendorIDMTWM { storeSkuList = GetFilterStoreSkuList(storeSkuList) } if len(storeSkuList) > 0 { if !isStart { - AddOrDelExtraStoreOptime(ctx, vendorID, storeID, vendorStoreID, &storeListValue.Store, startOpStoreTime, endOpStoreTime, false) + AddOrDelExtraStoreOptime(ctx, vendorID, vendorListValue.VendorOrgCode, storeID, vendorStoreID, &storeListValue.Store, startOpStoreTime, endOpStoreTime, false) } _, err = putils.FreeBatchStoreSkuInfo("更新门店商品库存", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { - _, err = singleStoreHandler.UpdateStoreSkusStock(ctx, storeID, vendorStoreID, batchedStoreSkuList) + _, err = singleStoreHandler.UpdateStoreSkusStock(ctx, vendorListValue.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList) return nil, 0, err }, ctx, task, storeSkuList, singleStoreHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkusStock), true) if isStart { - AddOrDelExtraStoreOptime(ctx, vendorID, storeID, vendorStoreID, &storeListValue.Store, startOpStoreTime, endOpStoreTime, true) + AddOrDelExtraStoreOptime(ctx, vendorID, vendorListValue.VendorOrgCode, storeID, vendorStoreID, &storeListValue.Store, startOpStoreTime, endOpStoreTime, true) } } } @@ -339,8 +339,8 @@ func InitEx() { if err == nil { for _, storeInfo := range storeList { for _, vendorStoreInfo := range storeInfo.StoreMaps { - startOpStoreTime := int16(utils.MustInterface2Int64(vendorStoreInfo["fakeOpenStart"])) - endOpStoreTime := int16(utils.MustInterface2Int64(vendorStoreInfo["fakeOpenStop"])) + startOpStoreTime := vendorStoreInfo.FakeOpenStart + endOpStoreTime := vendorStoreInfo.FakeOpenStop if startOpStoreTime == 0 || endOpStoreTime == 0 { continue } diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index edb6b4ea2..214d9acd3 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -263,8 +263,8 @@ func ScoreStoreOpenTime(storeInfo *cms.StoreExt) { finalScore := 0 if isStoreOpen { for _, storeMap := range storeInfo.StoreMaps { - isSyncStoreSku := int(utils.MustInterface2Int64(storeMap["isSync"])) - vendorStoreStatus := int(utils.MustInterface2Int64(storeMap["status"])) + isSyncStoreSku := storeMap.IsSync + vendorStoreStatus := storeMap.Status isVendorStoreOpen := vendorStoreStatus == model.StoreStatusOpened opTimeList := storeInfo.GetOpTimeList() if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen && isSyncStoreSku != 0 { @@ -428,8 +428,8 @@ func ScoreFullVendor(storeInfo *cms.StoreExt) { isStoreOpen := storeStatus == model.StoreStatusOpened count := 0 for _, storeMap := range storeInfo.StoreMaps { - isSyncStoreSku := int(utils.MustInterface2Int64(storeMap["isSync"])) - vendorStoreStatus := int(utils.MustInterface2Int64(storeMap["status"])) + isSyncStoreSku := storeMap.IsSync + vendorStoreStatus := storeMap.Status isVendorStoreOpen := vendorStoreStatus == model.StoreStatusOpened opTimeList := storeInfo.GetOpTimeList() if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen && isSyncStoreSku != 0 { @@ -569,9 +569,9 @@ func GetFilterStoreListEx(storeList []*cms.StoreExt, storeIDMap map[int]int) (ou continue } } - var tempStoreMaps []map[string]interface{} + var tempStoreMaps []*model.StoreMap for _, vendorStoreInfo := range storeInfo.StoreMaps { - vendorID := int(utils.MustInterface2Int64(vendorStoreInfo["vendorID"])) + vendorID := vendorStoreInfo.VendorID if _, ok := fullVendorList[vendorID]; !ok { continue } diff --git a/business/jxstore/misc/store_sku_sales.go b/business/jxstore/misc/store_sku_sales.go index e4de9b4ac..ca0dfc7fe 100644 --- a/business/jxstore/misc/store_sku_sales.go +++ b/business/jxstore/misc/store_sku_sales.go @@ -74,7 +74,7 @@ func GetStoreSkuSalesInfo(ctx *jxcontext.Context, storeID int) (outStoreSkuSales } //得到当前门店商品数据 - storeSkuMapData := make(map[int]*cms.StoreSkuNameExt) + storeSkuMapData := make(map[int]*dao.StoreSkuNameExt) storeSkuData, err := cms.GetStoreSkus(ctx, storeID, citySkuIDs, true, "", true, false, map[string]interface{}{}, 0, -1) if err == nil { for _, value := range storeSkuData.SkuNames { diff --git a/business/jxstore/report/report.go b/business/jxstore/report/report.go index 0538ea1ab..f3120c702 100644 --- a/business/jxstore/report/report.go +++ b/business/jxstore/report/report.go @@ -4,9 +4,11 @@ import ( "errors" "fmt" "math" + "time" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" + "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model/dao" ) @@ -33,3 +35,48 @@ func GetStatisticsReportForAfsOrders(ctx *jxcontext.Context, storeIDs []int, fro statisticsReportForOrdersList, err = dao.GetGetStatisticsReportForAfsOrders(db, storeIDs, fromDateParm, toDateParm) return statisticsReportForOrdersList, err } + +func StatisticsReportForStoreSkusPrice(ctx *jxcontext.Context, cityCodes, skuIDs []int, snapDate string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { + var snapDateParam time.Time + db := dao.GetDB() + if snapDate != "" { + snapDateParam = utils.Str2Time(snapDate) + } + priceReferSnapshot, totalCount, err := dao.GetPriceReferSnapshot(db, cityCodes, skuIDs, snapDateParam, offset, pageSize) + pagedInfo = &model.PagedInfo{ + Data: priceReferSnapshot, + TotalCount: totalCount, + } + return +} + +func BeginSavePriceRefer(ctx *jxcontext.Context, cityCodes, skuIDs []int) (err error) { + db := dao.GetDB() + snapshotAt := utils.Time2Date(time.Now()) + priceReferSnapshot, err := dao.GetStatisticsReportForStoreSkusPrice(db, cityCodes, skuIDs) + if len(priceReferSnapshot) > 0 { + dao.Begin(db) + defer func() { + if r := recover(); r != nil || err != nil { + dao.Rollback(db) + if r != nil { + panic(r) + } + } + }() + priceReferSnapshotDeleteHis := &model.PriceReferSnapshot{SnapshotAt: snapshotAt.AddDate(0, -1, 0)} + priceReferSnapshotDelete := &model.PriceReferSnapshot{SnapshotAt: snapshotAt} + dao.DeleteEntity(db, priceReferSnapshotDeleteHis, "SnapshotAt") + dao.DeleteEntity(db, priceReferSnapshotDelete, "SnapshotAt") + for _, v := range priceReferSnapshot { + dao.WrapAddIDCULDEntity(v, ctx.GetUserName()) + v.SnapshotAt = snapshotAt + fmt.Println(v) + if err = dao.CreateEntity(db, v); err != nil { + return err + } + } + dao.Commit(db) + } + return err +} diff --git a/business/jxstore/tempop/tempop.go b/business/jxstore/tempop/tempop.go index 34ce3f737..e55bb1a69 100644 --- a/business/jxstore/tempop/tempop.go +++ b/business/jxstore/tempop/tempop.go @@ -4,10 +4,6 @@ import ( "bytes" "context" "fmt" - "image" - "image/jpeg" - "image/png" - "net/http" "regexp" "strings" "sync" @@ -631,7 +627,7 @@ func TransformJdSpu2Sku(ctx *jxcontext.Context, skuNameIDs []int, count int, isA return "", fmt.Errorf("待转换的skuName为空") } batchSize := 40 - rootTask := tasksch.NewSeqTask("TransformJdSpu2Sku", ctx, + rootTask := tasksch.NewSeqTask2("TransformJdSpu2Sku", ctx, isContinueWhenError, func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { var ( locker sync.Mutex @@ -1009,7 +1005,7 @@ func CreateConsumerFromOrders(ctx *jxcontext.Context, vendorIDs []int, fromDate, } } if order2 == nil && order.VendorID == model.VendorIDMTWM && time.Now().Sub(curDate) < 60*24*time.Hour { - order2, err = handler.GetOrder(order.VendorOrderID) + order2, err = handler.GetOrder(order.VendorOrgCode, order.VendorOrderID) } if order2 != nil { if order2.VendorUserID != "" && order.VendorUserID != order2.VendorUserID { @@ -1046,92 +1042,92 @@ func CreateConsumerFromOrders(ctx *jxcontext.Context, vendorIDs []int, fromDate, } func CheckImages(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) { - db := dao.GetDB() - rootTask := tasksch.NewSeqTask("检查图片的有效性", ctx, - func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: // 检查图片的格式与大小 - var imgList []*model.DataResource - if err = dao.GetRows(db, &imgList, ` - SELECT t1.* - FROM data_resource t1 - WHERE t1.use_type = 1 - `); err == nil && len(imgList) > 0 { - calcTask := tasksch.NewParallelTask("检查京西图片的有效性", - tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(5), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - dataRes := batchItemList[0].(*model.DataResource) - binaryData, hashCode, err2 := jxutils.DownloadFileByURL(dataRes.MainURL) - if err = err2; err == nil { - errMsg := "" - if hashCode != dataRes.HashCode { - errMsg = fmt.Sprintf("hashcode:%s", hashCode) - dataRes.HashCode = hashCode - } - resType := http.DetectContentType(binaryData) - if resType != dataRes.ResourceType { - errMsg += "," + resType - dataRes.ResourceType = resType - } - var img image.Image - if dataRes.ResourceType == "image/png" { - img, err = png.Decode(bytes.NewReader(binaryData)) - } else if dataRes.ResourceType == "image/jpeg" { - img, err = jpeg.Decode(bytes.NewReader(binaryData)) - } - if err == nil { - if img != nil { - if img.Bounds().Dx() != 800 || img.Bounds().Dy() != 800 { - errMsg += fmt.Sprintf(",size:%dx%d", img.Bounds().Dx(), img.Bounds().Dy()) - } - } - } else { - errMsg += "," + err.Error() - } - if errMsg != "" { - dataRes.Remark = errMsg - dao.UpdateEntity(dao.GetDB(), dataRes, "Remark", "ResourceType", "HashCode") - } - } - return retVal, err - }, imgList) - tasksch.HandleTask(calcTask, task, false).Run() - _, err = calcTask.GetResult(0) - } - case 1: // 检查京东商品图片 - skuNameInfo, err2 := cms.GetSkuNames(ctx, "", false, map[string]interface{}{}, 0, -1) - if err = err2; err == nil && len(skuNameInfo.SkuNames) > 0 { - calcTask := tasksch.NewParallelTask("检查京东图片的有效性", - tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(5), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - skuName := batchItemList[0].(*model.SkuNameExt) - for _, sku := range skuName.Skus { - if sku.JdID != 0 { - skuPageInfo, err2 := api.JdAPI.GetSkuPageInfo(sku.JdID) - if err = err2; err == nil && skuPageInfo.FixedStatus && len(skuPageInfo.Image) == 0 { - err = fmt.Errorf("skuName:%d, sku:%d, jdid:%d, 没有图片", skuName.ID, sku.ID, sku.JdID) - skuName.ImgHashCode = "np" - dao.UpdateEntity(dao.GetDB(), &skuName.SkuName, "ImgHashCode") - } - break - } - } - return retVal, err - }, skuNameInfo.SkuNames) - tasksch.HandleTask(calcTask, task, false).Run() - _, err = calcTask.GetResult(0) - } - } - return result, err - }, 2) - tasksch.HandleTask(rootTask, nil, true).Run() - if !isAsync { - if _, err = rootTask.GetResult(0); err == nil { - hint = "1" - } - } else { - hint = rootTask.ID - } + // db := dao.GetDB() + // rootTask := tasksch.NewSeqTask("检查图片的有效性", ctx, + // func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + // switch step { + // case 0: // 检查图片的格式与大小 + // var imgList []*model.DataResource + // if err = dao.GetRows(db, &imgList, ` + // SELECT t1.* + // FROM data_resource t1 + // WHERE t1.use_type = 1 + // `); err == nil && len(imgList) > 0 { + // calcTask := tasksch.NewParallelTask("检查京西图片的有效性", + // tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(5), ctx, + // func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + // dataRes := batchItemList[0].(*model.DataResource) + // binaryData, hashCode, err2 := jxutils.DownloadFileByURL(dataRes.MainURL) + // if err = err2; err == nil { + // errMsg := "" + // if hashCode != dataRes.HashCode { + // errMsg = fmt.Sprintf("hashcode:%s", hashCode) + // dataRes.HashCode = hashCode + // } + // resType := http.DetectContentType(binaryData) + // if resType != dataRes.ResourceType { + // errMsg += "," + resType + // dataRes.ResourceType = resType + // } + // var img image.Image + // if dataRes.ResourceType == "image/png" { + // img, err = png.Decode(bytes.NewReader(binaryData)) + // } else if dataRes.ResourceType == "image/jpeg" { + // img, err = jpeg.Decode(bytes.NewReader(binaryData)) + // } + // if err == nil { + // if img != nil { + // if img.Bounds().Dx() != 800 || img.Bounds().Dy() != 800 { + // errMsg += fmt.Sprintf(",size:%dx%d", img.Bounds().Dx(), img.Bounds().Dy()) + // } + // } + // } else { + // errMsg += "," + err.Error() + // } + // if errMsg != "" { + // dataRes.Remark = errMsg + // dao.UpdateEntity(dao.GetDB(), dataRes, "Remark", "ResourceType", "HashCode") + // } + // } + // return retVal, err + // }, imgList) + // tasksch.HandleTask(calcTask, task, false).Run() + // _, err = calcTask.GetResult(0) + // } + // case 1: // 检查京东商品图片 + // skuNameInfo, err2 := cms.GetSkuNames(ctx, "", false, map[string]interface{}{}, 0, -1) + // if err = err2; err == nil && len(skuNameInfo.SkuNames) > 0 { + // calcTask := tasksch.NewParallelTask("检查京东图片的有效性", + // tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(5), ctx, + // func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + // skuName := batchItemList[0].(*model.SkuNameExt) + // for _, sku := range skuName.Skus { + // if sku.JdID != 0 { + // skuPageInfo, err2 := api.JdAPI.GetSkuPageInfo(sku.JdID) + // if err = err2; err == nil && skuPageInfo.FixedStatus && len(skuPageInfo.Image) == 0 { + // err = fmt.Errorf("skuName:%d, sku:%d, jdid:%d, 没有图片", skuName.ID, sku.ID, sku.JdID) + // skuName.ImgHashCode = "np" + // dao.UpdateEntity(dao.GetDB(), &skuName.SkuName, "ImgHashCode") + // } + // break + // } + // } + // return retVal, err + // }, skuNameInfo.SkuNames) + // tasksch.HandleTask(calcTask, task, false).Run() + // _, err = calcTask.GetResult(0) + // } + // } + // return result, err + // }, 2) + // tasksch.HandleTask(rootTask, nil, true).Run() + // if !isAsync { + // if _, err = rootTask.GetResult(0); err == nil { + // hint = "1" + // } + // } else { + // hint = rootTask.ID + // } return hint, err } @@ -1206,7 +1202,7 @@ func FixMtwmCategory(ctx *jxcontext.Context, mtwmStoreIDs []int, isAsync, isCont name2CatMap[v.Name] = v } case 1: - storeIDs, err := mtwm.CurPurchaseHandler.GetAllStoresVendorID(ctx) + storeIDs, err := mtwm.CurPurchaseHandler.GetAllStoresVendorID(ctx, "") if err != nil { return nil, err } @@ -1377,16 +1373,18 @@ func BuildSkuFromEbaiStore(ctx *jxcontext.Context, baiduShopID int64, isAsync, i skuNameExt.Price = int(float32(skuNameExt.Price) * 500 / tmpSpecQuality) } } - mySku := &model.Sku{ - // CategoryID: - // NameID: - Comment: comment, - SpecQuality: specQuality, - SpecUnit: specUnit, - Weight: int(utils.Str2Int64(utils.Interface2String(sku["weight"]))), - Status: model.SkuStatusNormal, + mySku := &model.SkuWithVendor{ + Sku: &model.Sku{ + // CategoryID: + // NameID: + Comment: comment, + SpecQuality: specQuality, + SpecUnit: specUnit, + Weight: int(utils.Str2Int64(utils.Interface2String(sku["weight"]))), + Status: model.SkuStatusNormal, - LinkID: int(jxutils.StandardPrice2Int(utils.MustInterface2Float64(sku["sale_price"]))), // 临时传递价格用 + LinkID: int(jxutils.StandardPrice2Int(utils.MustInterface2Float64(sku["sale_price"]))), // 临时传递价格用 + }, } if sku["enabled"].(string) == "0" { mySku.Status = model.SkuStatusDontSale diff --git a/business/jxstore/yonghui/yonghui.go b/business/jxstore/yonghui/yonghui.go index 64d8769ac..f838d4b2c 100644 --- a/business/jxstore/yonghui/yonghui.go +++ b/business/jxstore/yonghui/yonghui.go @@ -9,7 +9,6 @@ import ( "strings" "sync" "time" - "unicode" "git.rosy.net.cn/baseapi" "git.rosy.net.cn/baseapi/utils" @@ -555,15 +554,6 @@ func GetWeiMobGoodsList(param *weimobapi.QueryGoodsListParam) (goodsList []*weim return goodsList, err } -func IsChineseChar(str string) bool { - for _, r := range str { - if unicode.Is(unicode.Scripts["Han"], r) { - return true - } - } - return false -} - func GetCellIntoMap(sheetParam *SheetParam, skuMap map[string]*ExcelParam, row []string, sheetName string, rowNum int) (errMsg string) { var ( skuID string @@ -613,10 +603,8 @@ func GetCellIntoMap(sheetParam *SheetParam, skuMap map[string]*ExcelParam, row [ } if rowNum >= sheetParam.SkuRow { if rowNum == sheetParam.SkuRow { - if IsChineseChar(skuID) { - if IsChineseChar(skuID) { - errMsg += fmt.Sprintf("sheet页:[%v],Excel排版发生变化!第[%v]行附近可能增加了一行,请确认!", sheetName, rowNum) - } + if cms.IsChineseChar(skuID) { + errMsg += fmt.Sprintf("sheet页:[%v],Excel排版发生变化!第[%v]行附近可能增加了一行,请确认!", sheetName, rowNum) } } if len(skuMap) > 0 { @@ -649,7 +637,7 @@ func GetCellIntoMap(sheetParam *SheetParam, skuMap map[string]*ExcelParam, row [ delete(skuMap, "") } else { for i := rowNum; i < sheetParam.SkuRow; i++ { - if !IsChineseChar(skuID) { + if !cms.IsChineseChar(skuID) { errMsg += fmt.Sprintf("sheet页:[%v],Excel排版发生变化!第[%v]行附近可能减少了一行,请确认!", sheetName, rowNum) } } @@ -863,7 +851,7 @@ func UpdateJxPriceByWeimob(ctx *jxcontext.Context, storeIDs []int, isAsync, isCo for _, v := range storeSkuBindInfoList { skuBindInfos = append(skuBindInfos, v.(*cms.StoreSkuBindInfo)) } - cms.UpdateStoresSkus(ctx, storeIDs, skuBindInfos, isAsync, isContinueWhenError) + cms.UpdateStoresSkus(ctx, storeIDs, skuBindInfos, false, isAsync, isContinueWhenError) case 2: WriteToExcel3(task, dataStoreSkusSuccess.dataStoreSkusSuccessList, dataFailed.dataFailedList) } diff --git a/business/jxutils/datares/datares.go b/business/jxutils/datares/datares.go index 7949b79cf..0019accf8 100644 --- a/business/jxutils/datares/datares.go +++ b/business/jxutils/datares/datares.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "image" + "image/gif" "image/jpeg" "image/png" "net/http" @@ -43,6 +44,8 @@ func Binary2Image(binaryData []byte, mimeType string) (img image.Image, outMimeT img, err = jpeg.Decode(bytes.NewReader(binaryData)) case model.MimeTypePng: img, err = png.Decode(bytes.NewReader(binaryData)) + case model.MimeTypeGif: + img, err = gif.Decode(bytes.NewReader(binaryData)) } return img, mimeType, err } @@ -108,8 +111,10 @@ func RegisterDataResource(ctx *jxcontext.Context, name, resourceURL, mimeType, h return dataRes, err } if imgType > 0 { - // 忽略上传错误 - UploadImage2Vendors(ctx, nil, dataRes, resBinary, isAsyncUpload2Vendor) + if globals.EnableStoreWrite { + // 忽略上传错误 + UploadImage2Vendors(ctx, nil, dataRes, resBinary, isAsyncUpload2Vendor) + } } return dataRes, err } @@ -173,7 +178,8 @@ func UploadImage2Vendors(ctx *jxcontext.Context, parentTask tasksch.ITask, dataR func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { vendorID := batchItemList[0].(int) if handler := partner.GetPurchasePlatformFromVendorID(vendorID); handler != nil { - imgHint, err2 := handler.UploadImg(ctx, dataRes.MainURL, imgData, imgName, int(dataRes.UseType)) + // TODO vendorOrgCode + imgHint, err2 := handler.UploadImg(ctx, "", dataRes.MainURL, imgData, imgName, int(dataRes.UseType)) if err = err2; err == nil { retVal = [][]interface{}{ []interface{}{ diff --git a/business/jxutils/jxutils_act_test.go b/business/jxutils/jxutils_act_test.go index 19b36010d..79d4d1577 100644 --- a/business/jxutils/jxutils_act_test.go +++ b/business/jxutils/jxutils_act_test.go @@ -14,6 +14,6 @@ func TestGetActStoreSku(t *testing.T) { if err != nil { t.Fatal(err) } - storeSkuMap := NewActStoreSkuMap(actStoreSkuList, false) + storeSkuMap := jxutils.NewActStoreSkuMap(actStoreSkuList, false) t.Log(storeSkuMap.GetActStoreSku(1, 2, 3)) } diff --git a/business/jxutils/jxutils_cms.go b/business/jxutils/jxutils_cms.go index 11449a847..e7d20815a 100644 --- a/business/jxutils/jxutils_cms.go +++ b/business/jxutils/jxutils_cms.go @@ -326,6 +326,13 @@ func CaculatePriceByPricePack(l model.PricePercentagePack, defPricePercentage, p return CaculateSkuVendorPrice(price, pricePercentage, priceAdd) } +func ConstrainPayPercentage(payPerCentage int) int { + if payPerCentage <= 50 { + payPerCentage = 70 + } + return payPerCentage +} + func IsSkuSpecial(specQuality float32, specUnit string) bool { return int(specQuality) == model.SpecialSpecQuality && (specUnit == model.SpecialSpecUnit || specUnit == model.SpecialSpecUnit2) } diff --git a/business/model/act.go b/business/model/act.go index c644314fd..b4bfeee86 100644 --- a/business/model/act.go +++ b/business/model/act.go @@ -78,8 +78,9 @@ func (*Act) TableUnique() [][]string { type ActMap struct { ModelIDCULD - ActID int `orm:"column(act_id)" json:"actID"` - VendorID int `orm:"column(vendor_id)" json:"vendorID"` + ActID int `orm:"column(act_id)" json:"actID"` + VendorID int `orm:"column(vendor_id)" json:"vendorID"` + VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"` SyncStatus int8 `orm:"default(2)" json:"syncStatus"` @@ -104,7 +105,8 @@ type Act2 struct { MapID int `orm:"column(map_id)"` Act - VendorID int `orm:"column(vendor_id)" json:"vendorID"` + VendorID int `orm:"column(vendor_id)" json:"vendorID"` + VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"` SyncStatus int8 `orm:"default(2)" json:"syncStatus"` diff --git a/business/model/common.go b/business/model/common.go index c539770f3..e5c3a1d10 100644 --- a/business/model/common.go +++ b/business/model/common.go @@ -9,12 +9,14 @@ const ( MimeTypeJpeg = "image/jpeg" MimeTypePng = "image/png" + MimeTypeGif = "image/gif" ) var ( ValidMimeTypes = map[string]int{ MimeTypeJpeg: 1, MimeTypePng: 1, + MimeTypeGif: 1, } ) diff --git a/business/model/dao/act.go b/business/model/dao/act.go index 4b524e839..02800b6a4 100644 --- a/business/model/dao/act.go +++ b/business/model/dao/act.go @@ -12,10 +12,11 @@ import ( ) type ActMapPureInfo struct { - VendorID int `orm:"column(vendor_id)" json:"vendorID"` - VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"` - SyncStatus int `orm:"default(2)" json:"syncStatus"` - Remark string `orm:"column(map_remark)" json:"remark"` + VendorID int `orm:"column(vendor_id)" json:"vendorID"` + VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 + VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"` + SyncStatus int `orm:"default(2)" json:"syncStatus"` + Remark string `orm:"column(map_remark)" json:"remark"` } type ActVendorInfo struct { @@ -41,7 +42,7 @@ func GetActVendorInfo(db *DaoDB, actID int, vendorIDs []int) (actMap map[int]*mo } sql := fmt.Sprintf(` SELECT t1.*, - t2.id map_id, t2.vendor_id, t2.vendor_act_id, t2.sync_status + t2.id map_id, t2.vendor_id, t2.vendor_org_code, t2.vendor_act_id, t2.sync_status FROM act t1 %s JOIN act_map t2 ON t2.act_id = t1.id AND t2.deleted_at = ?`, leftOrEmpty) sqlParams := []interface{}{ @@ -76,9 +77,13 @@ func GetActStoreSkuVendorList(db *DaoDB, actID int, vendorIDs, storeIDs, skuIDs pageSize = jxutils.FormalizePageSize(pageSize) leftOrEmpty := "" + jdVendorIDField := "t4.jd_id" if len(vendorIDs) == 1 && (vendorIDs[0] == -1 || vendorIDs[0] == model.VendorIDJX) { leftOrEmpty = "LEFT" } + if globals.IsUseThingMap { + jdVendorIDField = "t4m.vendor_thing_id" + } sql := fmt.Sprintf(` SELECT SQL_CALC_FOUND_ROWS t1.*, @@ -86,7 +91,7 @@ func GetActStoreSkuVendorList(db *DaoDB, actID int, vendorIDs, storeIDs, skuIDs t3.vendor_store_id, CASE t2.vendor_id WHEN 0 THEN - t4.jd_id + %s WHEN 1 THEN t5.mtwm_id WHEN 3 THEN @@ -98,7 +103,7 @@ func GetActStoreSkuVendorList(db *DaoDB, actID int, vendorIDs, storeIDs, skuIDs t6.name store_name, t7.name sku_name_name, t7.unit, t7.prefix FROM act_store_sku t1 - %s JOIN act_store_sku_map t2 ON t2.act_id = ? AND t2.bind_id = t1.id AND t2.deleted_at = ?`, leftOrEmpty) + %s JOIN act_store_sku_map t2 ON t2.act_id = ? AND t2.bind_id = t1.id AND t2.deleted_at = ?`, jdVendorIDField, leftOrEmpty) sqlParams := []interface{}{ actID, utils.DefaultTimeValue, @@ -110,14 +115,20 @@ func GetActStoreSkuVendorList(db *DaoDB, actID int, vendorIDs, storeIDs, skuIDs } sql += ` LEFT JOIN store_map t3 ON t3.store_id = t1.store_id AND t3.vendor_id = t2.vendor_id AND t3.deleted_at = ? - JOIN sku t4 ON t4.id = t1.sku_id + JOIN sku t4 ON t4.id = t1.sku_id` + sqlParams = append(sqlParams, utils.DefaultTimeValue) + if globals.IsUseThingMap { + sql += ` + LEFT JOIN thing_map t4m ON t4m.thing_id = t4.id AND t4m.thing_type = ? AND t4m.vendor_id = t2.vendor_id AND t4m.vendor_org_code = t3.vendor_org_code AND t4m.deleted_at = ?` + sqlParams = append(sqlParams, model.ThingTypeSku, utils.DefaultTimeValue) + } + sql += ` LEFT JOIN store_sku_bind t5 ON t5.sku_id = t1.sku_id AND t5.store_id = t1.store_id AND t5.deleted_at = ? LEFT JOIN store t6 ON t6.id = t1.store_id JOIN sku_name t7 ON t7.id = t4.name_id WHERE t1.act_id = ? ` sqlParams = append(sqlParams, - utils.DefaultTimeValue, utils.DefaultTimeValue, actID, ) @@ -307,7 +318,7 @@ func QueryActs(db *DaoDB, actID int, offset, pageSize int, syncStatus int, keywo sql = ` SELECT t1.*, - t2.id map_id, t2.vendor_id, t2.vendor_act_id, t2.sync_status, t2.remark map_remark + t2.id map_id, t2.vendor_id, t2.vendor_org_code, t2.vendor_act_id, t2.sync_status, t2.remark map_remark FROM act t1 LEFT JOIN act_map t2 ON t2.act_id = t1.id AND t2.deleted_at = ? WHERE t1.id IN (` + GenQuestionMarks(len(idList)) + `) diff --git a/business/model/dao/act_test.go b/business/model/dao/act_test.go index 1acee0c34..7d902cccb 100644 --- a/business/model/dao/act_test.go +++ b/business/model/dao/act_test.go @@ -44,3 +44,10 @@ func TestUpdateActStatusByTime(t *testing.T) { t.Fatal(err) } } + +func TestGetActStoreSkuVendorList(t *testing.T) { + _, _, err := GetActStoreSkuVendorList(GetDB(), 18440, nil, nil, nil, "", 0, 0) + if err != nil { + t.Fatal(err) + } +} diff --git a/business/model/dao/dao_order.go b/business/model/dao/dao_order.go index afc941ad4..ebccfdc9c 100644 --- a/business/model/dao/dao_order.go +++ b/business/model/dao/dao_order.go @@ -901,7 +901,7 @@ func GetOrders(db *DaoDB, ids []int64, isIncludeSku, isIncludeFake bool, fromDat ORDER BY IF(t1.status < ?, IF(t1.vendor_id = ?, 0, 1), 0), t1.order_created_at DESC` sqlParams = append(sqlParams, model.OrderStatusEndBegin, model.VendorIDJX) } else { - if isIncludeSku && userID == "" { + if isIncludeSku && userID == "" && len(ids) == 0 { sql += ` ORDER BY t1.id` } else { @@ -986,3 +986,32 @@ func GetMyOrderCountInfo(db *DaoDB, userID string, fromDate, toDate time.Time, s err = GetRows(db, &countInfo, sql, sqlParams...) return countInfo, err } + +func GetPendingFakeOrders(db *DaoDB, vendorIDs []int, orderCreatedAfter, orderCreatedBefore time.Time) (orderList []*model.GoodsOrder, err error) { + sql := ` + SELECT t1.* + FROM goods_order t1 + JOIN new_config t2 ON t2.type = ? AND t2.key = ? AND t2.deleted_at = ? + AND LOCATE(IF(t1.consignee_mobile2 <> '', t1.consignee_mobile2, t1.consignee_mobile), t2.value) > 0 + WHERE t1.order_created_at >= ? AND t1.order_created_at <= ? + AND t1.delivery_type = ? + AND t1.status >= ? AND t1.status < ? + ` + sqlParams := []interface{}{ + model.ConfigTypeSys, + model.ConfigSysFakeOrderMobiles, + utils.DefaultTimeValue, + orderCreatedAfter, + orderCreatedBefore, + model.OrderDeliveryTypeSelfTake, + model.OrderStatusAccepted, + model.OrderStatusEndBegin, + } + if len(vendorIDs) > 0 { + sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" + sqlParams = append(sqlParams, vendorIDs) + } + // globals.SugarLogger.Debug(sql) + err = GetRows(db, &orderList, sql, sqlParams...) + return orderList, err +} diff --git a/business/model/dao/dao_order_test.go b/business/model/dao/dao_order_test.go index 9d80b27a7..f1a1ee5ff 100644 --- a/business/model/dao/dao_order_test.go +++ b/business/model/dao/dao_order_test.go @@ -39,3 +39,11 @@ func TestGetStoreOrderSkuList(t *testing.T) { t.Log(utils.Format4Output(afsSkuList, false)) } + +func TestGetPendingFakeOrders(t *testing.T) { + orderList, err := GetPendingFakeOrders(GetDB(), nil, time.Now().Add(-48*time.Hour), time.Now().Add(-30*time.Minute)) + if err != nil { + t.Fatal(err) + } + t.Log(len(orderList)) +} diff --git a/business/model/dao/dao_user2.go b/business/model/dao/dao_user2.go index 51572c40d..3a4ee6b66 100644 --- a/business/model/dao/dao_user2.go +++ b/business/model/dao/dao_user2.go @@ -67,8 +67,8 @@ func GetUsers(db *DaoDB, userType int, keyword string, userIDs []string, userID2 } if keyword != "" { keywordLike := "%" + keyword + "%" - sql += " AND (t1.user_id2 LIKE ? OR t1.mobile LIKE ? OR t1.email LIKE ? OR t1.name LIKE ?)" - sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike) + sql += " AND (t1.user_id LIKE ? OR t1.user_id2 LIKE ? OR t1.mobile LIKE ? OR t1.email LIKE ? OR t1.name LIKE ?)" + sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike) } sql += " LIMIT ? OFFSET ?" sqlParams = append(sqlParams, pageSize, offset) diff --git a/business/model/dao/report.go b/business/model/dao/report.go index a668c5a4b..125b42a21 100644 --- a/business/model/dao/report.go +++ b/business/model/dao/report.go @@ -4,6 +4,7 @@ import ( "time" "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/model" ) @@ -33,6 +34,12 @@ type StatisticsReportForOrdersList struct { OperatorName2 string `json:"operatorName2"` } +type PriceReferSnapshotExt struct { + model.PriceReferSnapshot + CityName string `json:"cityName"` + SkuName string `json:"skuName"` +} + //查询统计订单信息 func GetStatisticsReportForOrders(db *DaoDB, storeIDs []int, fromDate time.Time, toDate time.Time) (statisticsReportForOrdersList []*StatisticsReportForOrdersList, err error) { sql := ` @@ -177,3 +184,102 @@ func GetGetStatisticsReportForAfsOrders(db *DaoDB, storeIDs []int, fromDate time } return nil, err } + +func GetStatisticsReportForStoreSkusPrice(db *DaoDB, cityCodes, skuIDs []int) (priceReferSnapshot []*model.PriceReferSnapshot, err error) { + sql := ` + SELECT b.city_code,a.sku_id, + MAX(a.price) max_price, + MIN(a.price) min_price, + ROUND(AVG(a.price)) avg_price, + ROUND(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT((a.price/IF(b.pay_percentage=0,100,b.pay_percentage))*100 ORDER BY (a.price/IF(b.pay_percentage=0,100,b.pay_percentage))*100),',',Count(1)/2),',',-1),2) mid_price, + MAX(a.jd_price) max_jd_price, + MIN(a.jd_price) min_jd_price, + ROUND(AVG(a.jd_price)) avg_jd_price, + ROUND(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(a.jd_price ORDER BY a.jd_price),',',Count(1)/2),',',-1),2) mid_jd_price, + MAX(a.ebai_price) max_ebai_price, + MIN(a.ebai_price) min_ebai_price, + ROUND(AVG(a.ebai_price)) avg_ebai_price, + ROUND(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(a.ebai_price ORDER BY a.ebai_price),',',Count(1)/2),',',-1),2) mid_ebai_price, + MAX(a.mtwm_price) max_mtwm_price, + MIN(a.mtwm_price) min_mtwm_price, + ROUND(AVG(a.mtwm_price)) avg_mtwm_price, + ROUND(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(a.mtwm_price ORDER BY a.mtwm_price),',',Count(1)/2),',',-1),2) mid_mtwm_price, + t1.max_sale_price, + t1.min_sale_price, + t1.avg_sale_price, + t1.max_vendor_price, + t1.min_vendor_price, + t1.avg_vendor_price + FROM store_sku_bind a + JOIN store b ON a.store_id = b.id AND b.deleted_at = ? + JOIN sku d ON a.sku_id = d.id AND d.deleted_at = ? + LEFT JOIN ( + SELECT SUM(t1.count),t1.sku_id,MAX(t1.sale_price) max_sale_price,MIN(t1.sale_price) min_sale_price,ROUND(AVG(t1.sale_price)) avg_sale_price,MAX(t1.vendor_price) max_vendor_price,MIN(t1.vendor_price) min_vendor_price,ROUND(AVG(t1.vendor_price)) avg_vendor_price + FROM order_sku t1 + WHERE t1.order_created_at BETWEEN ? AND NOW() + GROUP BY 2 + )t1 ON t1.sku_id = a.sku_id + WHERE a.deleted_at = ? + ` + sqlParams := []interface{}{ + utils.DefaultTimeValue, + utils.DefaultTimeValue, + time.Now().AddDate(0, -1, 0), + utils.DefaultTimeValue, + } + if len(skuIDs) > 0 { + sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" + sqlParams = append(sqlParams, skuIDs) + } + if len(cityCodes) > 0 { + sql += " AND b.city_code IN (" + GenQuestionMarks(len(cityCodes)) + ")" + sqlParams = append(sqlParams, cityCodes) + } + sql += " GROUP BY 1,2" + if err = GetRows(db, &priceReferSnapshot, sql, sqlParams...); err == nil { + return priceReferSnapshot, nil + } + return nil, err +} + +func GetPriceReferSnapshot(db *DaoDB, cityCodes, skuIDs []int, snapDate time.Time, offset, pageSize int) (priceReferSnapshot []*PriceReferSnapshotExt, totalCount int, err error) { + sql := ` + SELECT SQL_CALC_FOUND_ROWS a.*,b.name city_name + FROM price_refer_snapshot a + JOIN place b ON a.city_code = b.code + WHERE 1=1 + AND a.deleted_at = ? + ` + sqlParams := []interface{}{ + utils.DefaultTimeValue, + } + if len(skuIDs) > 0 { + sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" + sqlParams = append(sqlParams, skuIDs) + } + if len(cityCodes) > 0 { + sql += " AND a.city_code IN (" + GenQuestionMarks(len(cityCodes)) + ")" + sqlParams = append(sqlParams, cityCodes) + } + if !utils.IsTimeZero(snapDate) { + sql += " AND a.snapshot_at = ?" + sqlParams = append(sqlParams, snapDate) + } + sql += " LIMIT ? OFFSET ?" + sqlParams = append(sqlParams, pageSize, offset) + Begin(db) + defer Commit(db) + if err = GetRows(db, &priceReferSnapshot, sql, sqlParams...); err == nil { + totalCount = GetLastTotalRowCount(db) + } + for _, v := range priceReferSnapshot { + skuList, err2 := GetSkus(db, []int{v.SkuID}, nil, nil, nil) + err = err2 + if len(skuList) > 0 { + skuAndName := skuList[0] + jxSkuDetailName := jxutils.ComposeSkuName(skuAndName.Prefix, skuAndName.Name, skuAndName.Comment, skuAndName.Unit, skuAndName.SpecQuality, skuAndName.SpecUnit, 0) + v.SkuName = jxSkuDetailName + } + } + return priceReferSnapshot, totalCount, err +} diff --git a/business/model/dao/sku.go b/business/model/dao/sku.go index d48c657e2..3edd64d28 100644 --- a/business/model/dao/sku.go +++ b/business/model/dao/sku.go @@ -8,14 +8,14 @@ import ( "git.rosy.net.cn/jx-callback/globals" ) +type tStoreSkuSyncInfo2 struct { + StoreSkuSyncInfo + VendorPlaceCode string +} + type SkuCategoryWithVendor struct { - model.SkuCategory - - VendorID int `orm:"column(vendor_id)" json:"vendorID"` - VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 - - VendorCatID string `orm:"size(32);column(vendor_cat_id)" json:"vendorCatID"` - SyncStatus int8 `orm:"default(2)"` + *model.SkuCategory + MapList []*model.ThingMap `json:"mapList"` } func GetSellCities(db *DaoDB, nameID int, vendorID int) (cities []*model.Place, err error) { @@ -49,6 +49,26 @@ func DeleteSkuNamePlace(db *DaoDB, nameID int, placeCodes []int) (num int64, err return ExecuteSQL(db, sql, sqlParams...) } +func GetCategories(db *DaoDB, parentID int, catIDs []int) (cats []*model.SkuCategory, err error) { + sql := ` + SELECT t1.* + FROM sku_category t1 + WHERE t1.deleted_at = ?` + params := []interface{}{ + utils.DefaultTimeValue, + } + if parentID != -1 { + sql += " AND t1.parent_id = ?" + params = append(params, parentID) + } + if len(catIDs) > 0 { + sql += " AND t1.id (" + GenQuestionMarks(len(catIDs)) + ")" + params = append(params, catIDs) + } + sql += " ORDER BY t1.level, t1.seq" + return cats, GetRows(db, &cats, sql, params) +} + func GetSkus(db *DaoDB, skuIDs, nameIDs, statuss, catIDs []int) (skuList []*model.SkuAndName, err error) { sql := ` SELECT t1.*, t2.name, t2.unit, t2.prefix, t2.is_spu @@ -154,5 +174,148 @@ func SetSkuSyncStatus(db *DaoDB, vendorID int, skuIDs []int, syncStatus int) (nu return ExecuteSQL(db, sql, sqlParams...) } -// func GetSkuCategoryWithVendor(db *DaoDB, vendorIDs []int, appOrgCodes []string, catIDs []int) (num int64, err error) { -// } +// 多门店平台使用,当前只有京东 +func GetSkuCategoryWithVendor(db *DaoDB, vendorIDs []int, appOrgCodes []string, parentCatID int, catIDs []int, mustDirty bool) (catList []*SkuStoreCatInfo, err error) { + sql := ` + SELECT + t1m.vendor_id, t1m.vendor_org_code, + + t1m.id map_id, + t1.*, + t1m.vendor_thing_id vendor_cat_id, + t1m.sync_status cat_sync_status, + + t1pm.id parent_map_id, + t1p.name parent_cat_name, + t1pm.vendor_thing_id parent_vendor_cat_id, + t1pm.sync_status parent_cat_sync_status + FROM sku_category t1 + LEFT JOIN thing_map t1m ON t1m.thing_id = t1.id AND t1m.thing_type = ? AND t1m.deleted_at = ?` + sqlParams := []interface{}{ + model.ThingTypeCategory, + utils.DefaultTimeValue, + } + if len(vendorIDs) > 0 { + sql += " AND t1m.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" + sqlParams = append(sqlParams, vendorIDs) + } + if len(appOrgCodes) > 0 { + sql += " AND t1m.vendor_org_code IN (" + GenQuestionMarks(len(appOrgCodes)) + ")" + sqlParams = append(sqlParams, appOrgCodes) + } + sql += ` + LEFT JOIN sku_category t1p ON t1p.id = t1.parent_id + LEFT JOIN thing_map t1pm ON t1pm.thing_id = t1p.id AND t1pm.thing_type = ? AND t1m.deleted_at = ? + AND t1pm.vendor_id = t1m.vendor_id AND t1pm.vendor_org_code = t1m.vendor_org_code + WHERE 1 = 1 + ` + sqlParams = append(sqlParams, model.ThingTypeCategory, utils.DefaultTimeValue) + if mustDirty { + sql += " AND t1m.sync_status <> 0" + } else { + sql += " AND t1.deleted_at = ?" + sqlParams = append(sqlParams, utils.DefaultTimeValue) + } + if len(catIDs) > 0 { + sql += " AND t1.id IN (" + GenQuestionMarks(len(catIDs)) + ")" + sqlParams = append(sqlParams, catIDs) + } + if parentCatID >= 0 { + sql += " AND t1.parent_id = ?" + sqlParams = append(sqlParams, parentCatID) + } + sql += " ORDER BY t1.seq" + err = GetRows(db, &catList, sql, sqlParams...) + return catList, err +} + +// 多门店平台使用,当前只有京东 +func GetSkusWithVendor(db *DaoDB, vendorIDs []int, appOrgCodes []string, nameIDs, skuIDs []int, mustDirty bool) (skuList []*StoreSkuSyncInfo, err error) { + sql := ` + SELECT + t1m.vendor_id, t1m.vendor_org_code, + + t1m.id bind_id, + t1.*, + t1.id sku_id, + t1m.vendor_thing_id vendor_sku_id, + t1m.sync_status sku_sync_status, + + t2.price, + t2.price unit_price, + t2.prefix, + t2.name, + t2.unit, + t2.upc, + t2.is_global, + t2.status name_status, + IF(t11.resource_type IS NULL OR t11.resource_type <> ?, t2.img, '') img, + IF(t12.resource_type IS NULL OR t12.resource_type <> ?, t2.img2, '') img2, + t2.desc_img, + + t5.jd_code vendor_place_code, + + t3.jd_category_id vendor_vendor_cat_id, + + t3m.sync_status cat_sync_status, + t3m.vendor_thing_id vendor_cat_id + + FROM sku t1 + LEFT JOIN thing_map t1m ON t1m.thing_id = t1.id AND t1m.thing_type = ? AND t1m.deleted_at = ?` + sqlParams := []interface{}{ + model.MimeTypeGif, + model.MimeTypeGif, + model.ThingTypeSku, + utils.DefaultTimeValue, + } + if len(vendorIDs) > 0 { + sql += " AND t1m.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" + sqlParams = append(sqlParams, vendorIDs) + } + if len(appOrgCodes) > 0 { + sql += " AND t1m.vendor_org_code IN (" + GenQuestionMarks(len(appOrgCodes)) + ")" + sqlParams = append(sqlParams, appOrgCodes) + } + sql += ` + JOIN sku_name t2 ON t2.id = t1.name_id + LEFT JOIN sku_category t3 ON t3.id = t2.category_id + LEFT JOIN thing_map t3m ON t3m.thing_id = t3.id AND t3m.thing_type = ? AND t3m.deleted_at = ? + AND t3m.vendor_id = t1m.vendor_id AND t3m.vendor_org_code = t1m.vendor_org_code + LEFT JOIN sku_name_place_bind t4 ON t2.is_global = 0 AND t4.name_id = t1.name_id + LEFT JOIN place t5 ON t5.code = t4.place_code + LEFT JOIN data_resource t11 ON t11.main_url = t2.img + LEFT JOIN data_resource t12 ON t12.main_url = t2.img2 + WHERE 1 = 1 + ` + sqlParams = append(sqlParams, model.ThingTypeCategory, utils.DefaultTimeValue) + if mustDirty { + sql += " AND t1m.sync_status <> 0" + } else { + sql += " AND t1.deleted_at = ?" + sqlParams = append(sqlParams, utils.DefaultTimeValue) + } + if len(nameIDs) > 0 { + sql += " AND t1.name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")" + sqlParams = append(sqlParams, nameIDs) + } + if len(skuIDs) > 0 { + sql += " AND t1.id IN (" + GenQuestionMarks(len(skuIDs)) + ")" + sqlParams = append(sqlParams, skuIDs) + } + sql += " ORDER BY t1.seq" + + var list []*tStoreSkuSyncInfo2 + if err = GetRows(db, &list, sql, sqlParams...); err == nil { + skuMap := make(map[int]*StoreSkuSyncInfo) + for _, v := range list { + if skuMap[v.SkuID] == nil { + skuMap[v.SkuID] = &v.StoreSkuSyncInfo + skuList = append(skuList, &v.StoreSkuSyncInfo) + } + if !IsVendorThingIDEmpty(v.VendorPlaceCode) { + skuMap[v.SkuID].SellCities = append(skuMap[v.SkuID].SellCities, v.VendorPlaceCode) + } + } + } + return skuList, err +} diff --git a/business/model/dao/sku_test.go b/business/model/dao/sku_test.go new file mode 100644 index 000000000..50e7e45e0 --- /dev/null +++ b/business/model/dao/sku_test.go @@ -0,0 +1,16 @@ +package dao + +import ( + "testing" + + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/globals" +) + +func TestGetSkusWithVendor(t *testing.T) { + skuList, err := GetSkusWithVendor(GetDB(), nil, nil, []int{17368}, nil, true) + if err != nil { + t.Fatal(err) + } + globals.SugarLogger.Debug(utils.Format4Output(skuList, false)) +} diff --git a/business/model/dao/store.go b/business/model/dao/store.go index 18ec8da5a..08ac3f9ae 100644 --- a/business/model/dao/store.go +++ b/business/model/dao/store.go @@ -12,6 +12,8 @@ import ( type StoreDetail struct { model.Store + VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 + VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` VendorStatus int `json:"vendor_status"` // 取值同Store.Status DeliveryFee int `json:"deliveryFee"` @@ -32,7 +34,10 @@ type StoreDetail struct { DistrictName string `json:"districtName"` CityName string `json:"cityName"` - IsAutoOrder int8 `json:"isAutoOrder"` // 平台是否自动接单,-1:否,0:未知,1:是 + IsAutoOrder int8 `json:"isAutoOrder"` // 平台是否自动接单,-1:否,0:未知,1:是 + MarketManName string `json:"marketManName"` //市场负责人 + OperatorName string `json:"operatorName"` //运营负责人 + OperatorName2 string `json:"operatorName2"` } // 带快递门店信息的 @@ -54,6 +59,18 @@ type CityBrankBranch struct { PayeeBankCode string `orm:"size(8)" json:"payeeBankCode"` // 开户行代码 } +type StorePriceScore struct { + StoreID int `orm:"column(store_id)" json:"storeID"` + StoreName string `json:"storeName"` + StoreScore float64 `json:"storeScore"` + CityName string `json:"cityName"` +} + +type StorePriceScoreEx struct { + StorePriceScoreList []*StorePriceScore `json:"storePriceScoreList"` + TotalCount int `json:"totalCount"` +} + func (s *StoreDetail) GetPricePerentage(price int) (pricePercentage int) { return pricePercentage } @@ -66,13 +83,19 @@ func getStoreDetail(db *DaoDB, storeID, vendorID int, vendorStoreID string) (sto t3.value price_percentage_pack_str, t4.value freight_deduction_pack_str, district.name district_name, - city.name city_name + city.name city_name, + IF(mm.name <> '', mm.name, mm.user_id2) market_man_name, + IF(om.name <> '', om.name, om.user_id2) operator_name, + IF(om2.name <> '', om2.name, om2.user_id2) operator_name2 FROM store t1 LEFT JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? AND t2.deleted_at = ? LEFT JOIN place city ON city.code = t1.city_code LEFT JOIN place district ON district.code = t1.district_code LEFT JOIN new_config t3 ON t3.key = t2.price_percentage_pack AND t3.type = ? AND t3.deleted_at = ? LEFT JOIN new_config t4 ON t4.key = t2.freight_deduction_pack AND t4.type = ? AND t4.deleted_at = ? + LEFT JOIN user mm ON mm.mobile <> '' AND mm.mobile = t1.market_man_phone + LEFT JOIN user om ON om.mobile <> '' AND om.mobile = t1.operator_phone + LEFT JOIN user om2 ON om2.mobile <> '' AND om2.mobile = t1.operator_phone2 WHERE t1.deleted_at = ? ` sqlParams := []interface{}{ @@ -84,9 +107,9 @@ func getStoreDetail(db *DaoDB, storeID, vendorID int, vendorStoreID string) (sto utils.DefaultTimeValue, utils.DefaultTimeValue, } - if vendorID != model.VendorIDJX { - sql += " AND t2.id IS NOT NULL" - } + // if vendorID != model.VendorIDJX { + // sql += " AND t2.id IS NOT NULL" + // } if storeID > 0 { sql += " AND t1.id = ?" sqlParams = append(sqlParams, storeID) @@ -98,16 +121,16 @@ func getStoreDetail(db *DaoDB, storeID, vendorID int, vendorStoreID string) (sto if err = GetRow(db, &storeDetail, sql, sqlParams...); err == nil { storeDetail.PricePercentagePackObj = PricePercentagePack2Obj(storeDetail.PricePercentagePackStr) storeDetail.FreightDeductionPackObj = FreightDeductionPack2Obj(storeDetail.FreightDeductionPackStr) - if storeDetail.VendorStoreID == "" { - storeDetail.VendorStatus = storeDetail.Status - storeDetail.PricePercentage = model.DefVendorPricePercentage - storeDetail.AutoPickup = 1 - storeDetail.DeliveryType = model.StoreDeliveryTypeByStore - storeDetail.DeliveryCompetition = 1 - if vendorID == model.VendorIDJX { - storeDetail.IsSync = 1 - } - } + // if storeDetail.VendorStoreID == "" { + // storeDetail.VendorStatus = storeDetail.Status + // storeDetail.PricePercentage = model.DefVendorPricePercentage + // storeDetail.AutoPickup = 1 + // storeDetail.DeliveryType = model.StoreDeliveryTypeByStore + // storeDetail.DeliveryCompetition = 1 + // if vendorID == model.VendorIDJX { + // storeDetail.IsSync = 1 + // } + // } return storeDetail, nil } return nil, err @@ -460,3 +483,63 @@ func GetStoreMapsListWithoutDisabled(db *DaoDB, vendorIDs []int, status int) (st err = GetRows(db, &storeMapList, sql, sqlParams...) return storeMapList, err } + +func GetStorePriceScore(db *DaoDB, storeIDs []int, fromScore, toScore, sort int, snapDate time.Time, offset, pageSize int) (StorePriceScore []*StorePriceScore, totalCount int, err error) { + sql := ` + SELECT SQL_CALC_FOUND_ROWS a.store_id,score store_score,e.name city_name,b.name store_name + FROM store_price_score_snapshot a + JOIN store b ON b.id = a.store_id + JOIN place e ON e.code = b.city_code + WHERE 1=1 + ` + sqlParams := []interface{}{} + if fromScore != 0 && toScore != 0 { + sql += " AND a.score BETWEEN ? AND ?" + sqlParams = append(sqlParams, fromScore, toScore) + } + if len(storeIDs) > 0 { + sql += " AND a.store_id IN(" + GenQuestionMarks(len(storeIDs)) + ")" + sqlParams = append(sqlParams, storeIDs) + } + if !utils.IsTimeZero(snapDate) { + sql += " AND a.snapshot_at = ?" + sqlParams = append(sqlParams, snapDate) + } + if sort == 0 { + sql += " ORDER BY a.score" + } else { + sql += " ORDER BY a.score DESC" + } + sql += " LIMIT ? OFFSET ?" + sqlParams = append(sqlParams, pageSize, offset) + Begin(db) + defer Commit(db) + if err = GetRows(db, &StorePriceScore, sql, sqlParams...); err == nil { + totalCount = GetLastTotalRowCount(db) + } + return StorePriceScore, totalCount, err +} + +func GetStorePriceScoreSnapshot(db *DaoDB, snapDate time.Time) (storePriceScoreSnapshot []*model.StorePriceScoreSnapshot, err error) { + sql := ` + SELECT c.store_id,ROUND(count(c.price <= a.mid_price or NULL)/count(*)*100,2) score + FROM price_refer_snapshot a + JOIN store_sku_bind c ON c.sku_id = a.sku_id AND c.status = 1 AND c.deleted_at = ? + JOIN store d ON c.store_id = d.id AND d.city_code = a.city_code AND d.deleted_at = ? AND d.status != ? + WHERE 1=1 + ` + sqlParams := []interface{}{ + utils.DefaultTimeValue, + utils.DefaultTimeValue, + model.StoreStatusDisabled, + } + if !utils.IsTimeZero(snapDate) { + sql += " AND a.snapshot_at = ?" + sqlParams = append(sqlParams, snapDate) + } + sql += ` + GROUP BY c.store_id + ` + err = GetRows(db, &storePriceScoreSnapshot, sql, sqlParams...) + return storePriceScoreSnapshot, err +} diff --git a/business/model/dao/store_sku.go b/business/model/dao/store_sku.go index d1778ca30..e2c7c908f 100644 --- a/business/model/dao/store_sku.go +++ b/business/model/dao/store_sku.go @@ -6,37 +6,39 @@ import ( "strings" "time" - "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/model" + + "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/globals" ) var ( - // imgFieldMap = map[int]string{ - // model.VendorIDEBAI: "img_ebai", - // } dataResFieldMap = map[int]string{ model.VendorIDMTWM: "mtwm_url", model.VendorIDEBAI: "ebai_url", } - // descImgFieldMap = map[int]string{ - // model.VendorIDEBAI: "desc_img_ebai", - // } ) type SkuStoreCatInfo struct { - model.SkuCategory - MapID int `orm:"column(map_id)"` // 这个主要用于判断是否有store_sku_category_map - VendorCatID string `orm:"column(vendor_cat_id)"` - StoreCatSyncStatus int8 + VendorID int `orm:"column(vendor_id)" json:"vendorID"` + VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 + MapID int `orm:"column(map_id)"` // 这个主要用于判断是否有store_sku_category_map + model.SkuCategory + VendorCatID string `orm:"column(vendor_cat_id)"` + CatSyncStatus int8 + + ParentMapID int `orm:"column(parent_map_id)"` // 这个主要用于判断是否有父store_sku_category_map ParentCatName string - ParentMapID int `orm:"column(parent_map_id)"` // 这个主要用于判断是否有父store_sku_category_map ParentVendorCatID string `orm:"column(parent_vendor_cat_id)"` ParentCatSyncStatus int8 } type StoreSkuSyncInfo struct { + VendorID int `orm:"column(vendor_id)" json:"vendorID"` + VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 + // 平台无关的store sku信息 BindID int `orm:"column(bind_id)"` // 换名的原因是与Sku.ID同名区别 StoreID int `orm:"column(store_id)"` @@ -46,20 +48,23 @@ type StoreSkuSyncInfo struct { UnitPrice int64 // 平台相关的store sku信息 - StoreSkuStatus int - StoreSkuSyncStatus int8 - VendorSkuID string `orm:"column(vendor_sku_id)"` - BindDeletedAt time.Time `orm:"type(datetime)" json:"bindDeletedAt"` + StoreSkuStatus int + SkuSyncStatus int8 + VendorSkuID string `orm:"column(vendor_sku_id)"` + BindDeletedAt time.Time `orm:"type(datetime)" json:"bindDeletedAt"` model.Sku // sku_name - Prefix string - NameID int `orm:"column(name_id)"` - VendorNameID string `orm:"column(vendor_name_id)"` + Prefix string + // NameID int `orm:"column(name_id)"` + VendorNameID string `orm:"column(vendor_name_id)"` // 暂时无用 Name string Unit string Upc string + IsGlobal int8 `orm:"default(1)" json:"isGlobal"` // 是否是全部(全国)可见,如果否的话,可见性由SkuPlace决定 + NameStatus int + SellCities []string // 平台相关的图片信息 Img string @@ -68,18 +73,13 @@ type StoreSkuSyncInfo struct { VendorVendorCatID int64 `orm:"column(vendor_vendor_cat_id)"` // 平台商品分类(叶子结点) - // 饿百也只需要给出叶子结点了 - // https://open-be.ele.me/dev/notice?id=275 - // VendorVendorCatID2 int64 `orm:"column(vendor_vendor_cat_id2)"` // 平台商品分类上一级 - // VendorVendorCatID3 int64 `orm:"column(vendor_vendor_cat_id3)"` // 平台商品分类再上一级 - // sku的商家分类信息 - SkuStoreCatSyncStatus int8 - SkuVendorCatID string `orm:"column(sku_vendor_cat_id)"` + SkuCatSyncStatus int8 + SkuVendorCatID string `orm:"column(sku_vendor_cat_id)"` // sku_name的商家分类信息 - StoreCatSyncStatus int8 - VendorCatID string `orm:"column(vendor_cat_id)"` + CatSyncStatus int8 + VendorCatID string `orm:"column(vendor_cat_id)"` VendorPrice int64 MergedStatus int @@ -111,13 +111,87 @@ type StoreSkuNameInfo struct { UnitPrice int64 } +// GetStoreSkus用 +type StoreSkuNameExt struct { + StoreID int `orm:"column(store_id)" json:"storeID"` + StoreName string `json:"storeName"` + SkuID int `orm:"column(sku_id)" json:"skuID"` + model.SkuName + PayPercentage int `json:"-"` + UnitPrice int `json:"unitPrice"` + Skus []*StoreSkuExt `orm:"-" json:"skus,omitempty"` + SkusStr string `json:"-"` + + PendingOpType int8 `json:"pendingOpType"` // 取值同 StoreOpRequest.Type + PendingUnitPrice int `json:"pendingUnitPrice"` // 这个是待审核的价格申请 +} + +// GetStoreSkus用 +type StoreSkuNamesInfo struct { + TotalCount int `json:"totalCount"` + SkuNames []*StoreSkuNameExt `json:"skuNames"` +} + +type StoreSkuExt struct { + NameID int `orm:"column(name_id)" json:"nameID"` + SkuID int `orm:"column(sku_id)" json:"id"` + Comment string `orm:"size(255)" json:"comment"` + SkuCategoryID int `orm:"column(sku_category_id)" json:"categoryID"` + SkuSpecQuality float32 `json:"specQuality"` + SkuSpecUnit string `orm:"size(8)" json:"specUnit"` // 质量或容量 + Weight int `json:"weight"` // 重量/质量,单位为克,当相应的SkuName的SpecUnit为g或kg时,必须等于SpecQuality + JdID string `orm:"column(sku_jd_id);null;index" json:"jdID"` + SkuStatus int `json:"status"` + + BindCreatedAt time.Time `orm:"auto_now_add;type(datetime)" json:"createdAt"` + BindUpdatedAt time.Time `orm:"auto_now;type(datetime)" json:"updatedAt"` + BindLastOperator string `orm:"size(32)" json:"lastOperator"` // 最后操作员 + BindDeletedAt time.Time `orm:"type(datetime)" json:"deletedAt"` + SubStoreID int `orm:"column(sub_store_id)" json:"subStoreID"` + BindPrice int `json:"price"` // 单位为分,不用int64的原因是这里不需要累加 + UnitPrice int `json:"unitPrice"` // 这个是一斤的门店商品价,放在这里的原因是避免额外增加一张store sku_name表,逻辑上要保证同一SKU NAME中的所有SKU这个字段的数据一致 + StoreSkuStatus int `json:"storeSkuStatus"` + + EbaiID string `orm:"column(ebai_id);index" json:"ebaiID"` + MtwmID string `orm:"column(mtwm_id)" json:"mtwmID"` // 这个也不是必须的,只是为了DAO取数据语句一致 + // WscID string `orm:"column(wsc_id);index" json:"wscID"` // 表示微盟skuId + // WscID2 string `orm:"column(wsc_id2);index" json:"wscID2"` // 表示微盟goodsId + + JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"` + EbaiSyncStatus int8 `orm:"default(2)" json:"ebaiSyncStatus"` + MtwmSyncStatus int8 `orm:"default(2)" json:"mtwmSyncStatus"` + // WscSyncStatus int8 `orm:"default(2)" json:"wscSyncStatus"` + + JdPrice int `json:"jdPrice"` + EbaiPrice int `json:"ebaiPrice"` + MtwmPrice int `json:"mtwmPrice"` + JxPrice int `json:"jxPrice"` + + AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"` + + ActPrice int `json:"actPrice"` + ActID int `orm:"column(act_id)" json:"actID"` + ActType int `orm:"column(act_type)" json:"actType"` + + EarningPrice int `json:"earningPrice"` + EarningActID int `orm:"column(earning_act_id)" json:"earningActID"` + + RealEarningPrice int `json:"realEarningPrice"` + + StatusSaleBegin int16 `json:"statusSaleBegin"` //商品可售时间范围 + StatusSaleEnd int16 `json:"statusSaleEnd"` + + Count int `json:"count"` + Times int `json:"times"` +} + // todo 应该通过需要同步的skuid来驱动同步分类,而不是当前这种分开的逻辑 // 单门店模式厂商适用 // 从store_sku_bind中,得到所有依赖的商家分类信息 func GetSkusCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level int) (cats []*SkuStoreCatInfo, err error) { sql := ` SELECT DISTINCT t4.*, - t5.id map_id, t5.%s_id vendor_cat_id, t5.%s_sync_status store_cat_sync_status, + t5.id map_id, t5.%s_id vendor_cat_id, t5.%s_sync_status cat_sync_status, t4p.name parent_cat_name, t5p.id parent_map_id, t5p.%s_id parent_vendor_cat_id, t5p.%s_sync_status parent_cat_sync_status FROM store_sku_bind t1 @@ -172,7 +246,7 @@ func GetStoreCategories(db *DaoDB, vendorID, storeID int, level int, mustDirty b fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) sql := ` SELECT t4.*, - t5.id map_id, t5.%s_id vendor_cat_id, t5.%s_sync_status store_cat_sync_status, + t5.id map_id, t5.%s_id vendor_cat_id, t5.%s_sync_status cat_sync_status, t4p.name parent_cat_name, t5p.id parent_map_id, t5p.%s_id parent_vendor_cat_id, t5p.%s_sync_status parent_cat_sync_status FROM store_sku_category_map t5 @@ -208,6 +282,120 @@ func GetDirtyStoreCategories(db *DaoDB, vendorID, storeID int, level int) (cats // 以store_sku_bind为基础来做同步,正常情况下使用 // 单多门店模式厂商通用 func GetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty bool) (skus []*StoreSkuSyncInfo, err error) { + if !globals.IsUseThingMap { + return oldGetStoreSkus2(db, vendorID, storeID, skuIDs, mustDirty) + } + return newGetStoreSkus2(db, vendorID, storeID, skuIDs, mustDirty) +} + +func newGetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty bool) (skus []*StoreSkuSyncInfo, err error) { + if vendorID < 0 { + panic("vendorID<0") + } + isSingleStorePF := model.MultiStoresVendorMap[vendorID] != 1 + fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) + skuVendorIDField := fmt.Sprintf("t1.%s_id", fieldPrefix) + if !isSingleStorePF { + skuVendorIDField = "t2m.vendor_thing_id" + } + sql := ` + SELECT + t14.vendor_id, t14.vendor_org_code, + t1.id bind_id, t1.sku_id, t1.price, t1.unit_price, t1.status store_sku_status, + %s vendor_sku_id, t1.%s_sync_status sku_sync_status, t1.%s_price vendor_price, + t1.store_id, t1.deleted_at bind_deleted_at,t1.status_sale_begin,t1.status_sale_end, + t2.*, + t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc, + IF(t11.%s <> '', t11.%s, t3.img) img, + IF(t12.%s <> '', t12.%s, t3.img2) img2, + t13.%s desc_img, + t4.%s_category_id vendor_vendor_cat_id` + fmtParams := []interface{}{ + skuVendorIDField, fieldPrefix, fieldPrefix, + GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), + GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), + GetDataResFieldName(vendorID), + fieldPrefix, + } + if isSingleStorePF { + sql += `, + t5.%s_sync_status cat_sync_status, t5.%s_id vendor_cat_id, + t5sku.%s_sync_status sku_cat_sync_status, t5sku.%s_id sku_vendor_cat_id` + fmtParams = append(fmtParams, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix) + } else { + sql += `, + t4m.vendor_thing_id vendor_cat_id, + t5skum.vendor_thing_id sku_vendor_cat_id` + } + sql += ` + FROM store_sku_bind t1 + LEFT JOIN store_map t14 ON t14.store_id = t1.store_id AND t14.vendor_id = ? AND t14.deleted_at = ? + LEFT JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ? AND t2.status = ? + LEFT JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ? AND t3.status = ? + LEFT JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ? + LEFT JOIN data_resource t11 ON t11.main_url = t3.img + LEFT JOIN data_resource t12 ON t12.main_url = t3.img2 + LEFT JOIN data_resource t13 ON t13.main_url = t3.desc_img + ` + sqlParams := []interface{}{ + vendorID, utils.DefaultTimeValue, + utils.DefaultTimeValue, model.SkuStatusNormal, + utils.DefaultTimeValue, model.SkuStatusNormal, + utils.DefaultTimeValue, + } + if isSingleStorePF { + sql += ` + LEFT JOIN store_sku_category_map t5 ON t4.id = t5.category_id AND t5.store_id = t1.store_id AND t5.deleted_at = ? + LEFT JOIN store_sku_category_map t5sku ON t2.category_id = t5sku.category_id AND t5sku.store_id = t1.store_id AND t5sku.deleted_at = ?` + sqlParams = append(sqlParams, utils.DefaultTimeValue, utils.DefaultTimeValue) + } else { + sql += ` + LEFT JOIN sku_category t5sku ON t5sku.id = t2.category_id + LEFT JOIN thing_map t2m ON t2m.thing_id = t1.sku_id AND t2m.vendor_org_code = t14.vendor_org_code AND t2m.thing_type = ? AND t2m.vendor_id = ? AND t2m.deleted_at = ? + LEFT JOIN thing_map t4m ON t4m.thing_id = t3.category_id AND t4m.vendor_org_code = t14.vendor_org_code AND t4m.thing_type = ? AND t4m.vendor_id = ? AND t4m.deleted_at = ? + LEFT JOIN thing_map t5skum ON t5skum.thing_id = t5sku.id AND t5skum.vendor_org_code = t14.vendor_org_code AND t5skum.thing_type = ? AND t5skum.vendor_id = ? AND t5skum.deleted_at = ? + ` + sqlParams = append(sqlParams, + model.ThingTypeSku, vendorID, utils.DefaultTimeValue, + model.ThingTypeCategory, vendorID, utils.DefaultTimeValue, + model.ThingTypeCategory, vendorID, utils.DefaultTimeValue) + } + sql += " WHERE 1 = 1" + if storeID > 0 { + sql += " AND t1.store_id = ?" + sqlParams = append(sqlParams, storeID) + } + if mustDirty { + sql += " AND (t1.%s_sync_status <> 0 OR (%s <> %s AND t3.id IS NULL))" + fmtParams = append(fmtParams, fieldPrefix, skuVendorIDField) + if isSingleStorePF { + fmtParams = append(fmtParams, "0") + } else { + fmtParams = append(fmtParams, "''") + } + } else { + sql += " AND t1.deleted_at = ?" + sqlParams = append(sqlParams, utils.DefaultTimeValue) + } + if len(skuIDs) > 0 { + sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" + sqlParams = append(sqlParams, skuIDs) + } + // 多门店平台没有成功创建的商品,不直接过滤,让上层同步时报错 + // if !isSingleStorePF { + // sql += " AND t2.%s_id <> 0" + // fmtParams = append(fmtParams, fieldPrefix) + // } + sql = fmt.Sprintf(sql, fmtParams...) + sql += " ORDER BY t1.price" + // globals.SugarLogger.Debug(sql) + if err = GetRows(db, &skus, sql, sqlParams...); err != nil { + return nil, err + } + return skus, err +} + +func oldGetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty bool) (skus []*StoreSkuSyncInfo, err error) { if vendorID < 0 { panic("vendorID<0") } @@ -219,7 +407,7 @@ func GetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty boo fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) sql := ` SELECT t1.id bind_id, t1.sku_id, t1.price, t1.unit_price, t1.status store_sku_status, - %s.%s_id vendor_sku_id, t1.%s_sync_status store_sku_sync_status, t1.%s_price vendor_price, + %s.%s_id vendor_sku_id, t1.%s_sync_status sku_sync_status, t1.%s_price vendor_price, t1.store_id, t1.deleted_at bind_deleted_at,t1.status_sale_begin,t1.status_sale_end, t2.*, t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc, @@ -236,8 +424,8 @@ func GetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty boo } if isSingleStorePF { sql += `, - t5.%s_sync_status store_cat_sync_status, t5.%s_id vendor_cat_id, - t5sku.%s_sync_status sku_store_cat_sync_status, t5sku.%s_id sku_vendor_cat_id` + t5.%s_sync_status cat_sync_status, t5.%s_id vendor_cat_id, + t5sku.%s_sync_status sku_cat_sync_status, t5sku.%s_id sku_vendor_cat_id` fmtParams = append(fmtParams, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix) } else { sql += `, @@ -307,19 +495,82 @@ func GetStoreSkus(db *DaoDB, vendorID, storeID int, skuIDs []int) (skus []*Store // 以sku为基础来做全同步, // 多门店模式厂商适用 func GetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSyncInfo, err error) { + if !globals.IsUseThingMap { + return oldGetFullStoreSkus(db, vendorID, storeID) + } + return newGetFullStoreSkus(db, vendorID, storeID) +} + +func newGetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSyncInfo, err error) { globals.SugarLogger.Debugf("GetFullStoreSkus, storeID:%d, vendorID:%d", storeID, vendorID) sql := ` - SELECT t1.id bind_id, t1.price, t1.unit_price, t1.status store_sku_status, t2.%s_id vendor_sku_id, - t1.%s_sync_status store_sku_sync_status, t1.store_id, t1.deleted_at bind_deleted_at, - t2.*, t2.id sku_id, + SELECT t1.id bind_id, t1.price, t1.unit_price, t1.status store_sku_status, + t1.%s_sync_status sku_sync_status, t1.store_id, t1.deleted_at bind_deleted_at, + t2.*, t2.id sku_id, t2m.vendor_thing_id vendor_sku_id, t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc, IF(t11.%s <> '', t11.%s, t3.img) img, IF(t12.%s <> '', t12.%s, t3.img2) img2, t13.%s desc_img, t4.%s_category_id vendor_vendor_cat_id, - t4.%s_sync_status store_cat_sync_status, t4.%s_id vendor_cat_id, - t5sku.%s_sync_status sku_store_cat_sync_status, t5sku.%s_id sku_vendor_cat_id + t4m.sync_status cat_sync_status, t4m.vendor_thing_id vendor_cat_id, + t5skum.sync_status sku_cat_sync_status, t5skum.vendor_thing_id sku_vendor_cat_id + FROM sku t2 + LEFT JOIN store_sku_bind t1 ON t1.sku_id = t2.id AND t1.store_id = ? AND t1.deleted_at = ? + LEFT JOIN store_map sm ON sm.store_id = t1.store_id AND sm.vendor_id = ? AND sm.deleted_at = ? + LEFT JOIN thing_map t2m ON t2m.thing_id = t2.id AND t2m.vendor_org_code = sm.vendor_org_code AND t2m.thing_type = ? AND t2m.vendor_id = ? AND t2m.deleted_at = ? + JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ? AND t3.status = ? + JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ? + LEFT JOIN thing_map t4m ON t4m.thing_id = t3.category_id AND t4m.vendor_org_code = sm.vendor_org_code AND t4m.thing_type = ? AND t4m.vendor_id = ? AND t4m.deleted_at = ? + LEFT JOIN sku_category t5sku ON t2.category_id = t5sku.id + LEFT JOIN thing_map t5skum ON t5skum.thing_id = t2.category_id AND t5skum.vendor_org_code = sm.vendor_org_code AND t5skum.thing_type = ? AND t5skum.vendor_id = ? AND t5skum.deleted_at = ? + LEFT JOIN data_resource t11 ON t11.main_url = t3.img + LEFT JOIN data_resource t12 ON t12.main_url = t3.img2 + LEFT JOIN data_resource t13 ON t13.main_url = t3.desc_img + WHERE t2.deleted_at = ? AND t2.status = ? AND t2m.vendor_thing_id <> '' + ORDER BY t1.price DESC` + sqlParams := []interface{}{ + storeID, + utils.DefaultTimeValue, + vendorID, utils.DefaultTimeValue, + model.ThingTypeSku, vendorID, utils.DefaultTimeValue, + utils.DefaultTimeValue, + model.SkuStatusNormal, + utils.DefaultTimeValue, + model.ThingTypeCategory, vendorID, utils.DefaultTimeValue, + model.ThingTypeCategory, vendorID, utils.DefaultTimeValue, + utils.DefaultTimeValue, + model.SkuStatusNormal, + } + fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) + sql = fmt.Sprintf(sql, + fieldPrefix, + GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), + GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), + GetDataResFieldName(vendorID), + fieldPrefix) + // globals.SugarLogger.Debug(sql) + // globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false)) + if err = GetRows(db, &skus, sql, sqlParams...); err != nil { + return nil, err + } + return skus, err +} + +func oldGetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSyncInfo, err error) { + globals.SugarLogger.Debugf("GetFullStoreSkus, storeID:%d, vendorID:%d", storeID, vendorID) + + sql := ` + SELECT t1.id bind_id, t1.price, t1.unit_price, t1.status store_sku_status, + t1.%s_sync_status sku_sync_status, t1.store_id, t1.deleted_at bind_deleted_at, + t2.*, t2.id sku_id, t2.%s_id vendor_sku_id, + t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc, + IF(t11.%s <> '', t11.%s, t3.img) img, + IF(t12.%s <> '', t12.%s, t3.img2) img2, + t13.%s desc_img, + t4.%s_category_id vendor_vendor_cat_id, + t4.%s_sync_status cat_sync_status, t4.%s_id vendor_cat_id, + t5sku.%s_sync_status sku_cat_sync_status, t5sku.%s_id sku_vendor_cat_id FROM sku t2 LEFT JOIN store_sku_bind t1 ON t1.sku_id = t2.id AND t1.store_id = ? AND t1.deleted_at = ? JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ? AND t3.status = ? @@ -644,13 +895,15 @@ func UpdateStoreSkuBindSyncStatus(db *DaoDB, vendorIDs []int, storeID int) (num func GetStoreSkusByNameIDs(db *DaoDB, storeIDs []int, nameID int) (skuList []*StoreSkuSyncInfo, err error) { sql := ` SELECT a.*,c.unit,c.name - FROM store_sku_bind a + FROM store_sku_bind a JOIN sku b ON a.sku_id = b.id JOIN sku_name c ON b.name_id = c.id WHERE b.name_id = ? + AND a.deleted_at = ? ` sqlParams := []interface{}{ nameID, + utils.DefaultTimeValue, } if len(storeIDs) > 0 { sql += " AND a.store_id in (" + GenQuestionMarks(len(storeIDs)) + ")" @@ -662,34 +915,157 @@ func GetStoreSkusByNameIDs(db *DaoDB, storeIDs []int, nameID int) (skuList []*St return skuList, err } -func GetTopSkusByStoreIDs(db *DaoDB, storeIDs []int) (skuAndName []*model.SkuAndName, err error) { +func GetTopSkusByStoreIDs(db *DaoDB, storeIDs []int) (storeSkuNameExt []*StoreSkuNameExt, err error) { sql := ` - SELECT * + SELECT t2.id sku_id,t3.*,t1.store_id,t1.store_name FROM( - SELECT SUM(b.count) count,b.sku_id + SELECT SUM(b.count) count,c.id,a.store_id,d.name store_name FROM goods_order a - JOIN order_sku b ON a.vendor_order_id = b.vendor_order_id + JOIN order_sku b ON a.vendor_order_id = b.vendor_order_id AND a.vendor_id = b.vendor_id JOIN sku c ON b.sku_id = c.id AND c.deleted_at = ? + JOIN sku_name t1 ON t1.id = c.name_id AND t1.deleted_at = ? + STRAIGHT_JOIN store_sku_bind t4 ON t4.store_id = IF(a.store_id = 0,a.jx_store_id,a.store_id) AND t4.sku_id = b.sku_id AND t4.status = ? AND t4.deleted_at = ? + JOIN store d ON d.id = a.store_id WHERE 1=1 + AND a.order_created_at BETWEEN ? and NOW() ` sqlParams := []interface{}{ utils.DefaultTimeValue, + utils.DefaultTimeValue, + model.SkuStatusNormal, + utils.DefaultTimeValue, + time.Now().AddDate(0, -1, 0), } if len(storeIDs) > 0 { - sql += " AND a.store_id in(" + GenQuestionMarks(len(storeIDs)) + ")" + sql += " AND a.store_id IN(" + GenQuestionMarks(len(storeIDs)) + ")" sqlParams = append(sqlParams, storeIDs) } sql += ` AND b.sale_price > ? - GROUP BY b.sku_id)t1 - JOIN sku t2 ON t1.sku_id = t2.id - JOIN sku_name t3 ON t2.name_id = t3.id + GROUP BY 2,3,4)t1 + JOIN sku t2 ON t2.id = t1.id + JOIN sku_name t3 ON t3.id = t2.name_id ORDER BY t1.count DESC LIMIT ? ` sqlParams = append(sqlParams, 100, 30) - err = GetRows(db, &skuAndName, sql, sqlParams...) - return skuAndName, err + err = GetRows(db, &storeSkuNameExt, sql, sqlParams...) + var skuNamesInfo = &StoreSkuNamesInfo{ + SkuNames: storeSkuNameExt, + } + for _, v := range storeSkuNameExt { + var skus []*StoreSkuExt + sql2 := ` + SELECT a.id sku_id,a.*,t4.created_at bind_created_at, t4.updated_at bind_updated_at, t4.last_operator bind_last_operator, t4.deleted_at bind_deleted_at, + t4.sub_store_id, t4.price bind_price, IF(t4.unit_price IS NOT NULL, t4.unit_price, t1.price) unit_price, t4.status store_sku_status, t4.auto_sale_at, + t4.ebai_id, t4.mtwm_id, + t4.ebai_sync_status, t4.mtwm_sync_status, + t4.jd_price, t4.ebai_price, t4.mtwm_price, t4.jx_price + FROM sku a + JOIN sku_name t1 ON a.name_id = t1.id AND t1.deleted_at = ? + JOIN store_sku_bind t4 ON t4.sku_id = a.id AND t4.deleted_at = ? + WHERE a.id = ? + AND a.deleted_at = ? + ` + sqlParams2 := []interface{}{ + utils.DefaultTimeValue, + utils.DefaultTimeValue, + v.SkuID, + utils.DefaultTimeValue, + } + if len(storeIDs) > 0 { + sql2 += " AND t4.store_id IN(" + GenQuestionMarks(len(storeIDs)) + ")" + sqlParams2 = append(sqlParams2, storeIDs) + } + err = GetRows(db, &skus, sql2, sqlParams2...) + v.Skus = skus + err = UpdateActPrice4StoreSkuNameNew(db, storeIDs, []int{v.SkuID}, skuNamesInfo, -1) + } + return storeSkuNameExt, err +} + +func GetTopCategorysByStoreIDs(db *DaoDB, storeIDs []int) (skuCategory []*model.SkuCategory, err error) { + sql := ` + SELECT DISTINCT t5.* FROM( + SELECT d.* + FROM ( + SELECT t3.*,t1.count + FROM( + SELECT SUM(b.count) count,d.category_id + FROM goods_order a + JOIN order_sku b ON a.vendor_order_id = b.vendor_order_id + JOIN sku c ON b.sku_id = c.id AND c.deleted_at = ? + JOIN sku_name d ON d.id = c.name_id AND d.deleted_at = ? + JOIN store e ON e.id = a.store_id + JOIN (SELECT city_code FROM store WHERE 1=1 + ` + sqlParams := []interface{}{ + utils.DefaultTimeValue, + utils.DefaultTimeValue, + } + if len(storeIDs) > 0 { + sql += " AND id IN(" + GenQuestionMarks(len(storeIDs)) + ")" + sqlParams = append(sqlParams, storeIDs) + } + + sql += ` + )t6 ON t6.city_code = e.city_code + WHERE 1=1 + AND a.order_created_at BETWEEN ? and NOW() + AND b.sale_price > ? + GROUP BY d.category_id)t1 + JOIN sku_category t3 ON t1.category_id = t3.id + AND t3.level = ? + AND t3.deleted_at = ? + ORDER BY t1.count DESC)t4 + JOIN sku_category d ON d.id = t4.parent_id + AND d.level = ? + Order by t4.count DESC)t5 + LIMIT ? + ` + sqlParams = append(sqlParams, time.Now().AddDate(0, -1, 0), 100, 2, utils.DefaultTimeValue, 1, 10) + err = GetRows(db, &skuCategory, sql, sqlParams...) + return skuCategory, err +} + +func RefershStoreSkusMidPrice(db *DaoDB, storeIDs []int) (count int64, err error) { + sql := ` + UPDATE store_sku_bind a + JOIN store d ON d.id = a.store_id + JOIN price_refer_snapshot b ON a.sku_id = b.sku_id AND b.snapshot_at = ? AND d.city_code = b.city_code + SET a.price = (b.mid_price*IF(d.pay_percentage=0,100,d.pay_percentage))/100 + WHERE 1=1 + ` + sqlParams := []interface{}{ + utils.Time2Date(time.Now().AddDate(0, 0, -1)), + } + if len(storeIDs) > 0 { + sql += " AND a.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" + sqlParams = append(sqlParams, storeIDs) + } + sql += ` + AND (a.price/IF(d.pay_percentage=0,100,d.pay_percentage))*100 > b.mid_price + AND a.deleted_at = ? + AND a.status = ? + ` + sqlParams = append(sqlParams, utils.DefaultTimeValue, model.SkuStatusNormal) + return ExecuteSQL(db, sql, sqlParams) +} + +func GetStoreSkuNamePrice(db *DaoDB) (storeSkuNamePriceList []*model.StoreSkuNamePrice, err error) { + sql := ` + SELECT * + FROM store_sku_name_price + WHERE deleted_at = ? + ` + sqlParams := []interface{}{ + utils.DefaultTimeValue, + } + err = GetRows(db, &storeSkuNamePriceList, sql, sqlParams...) + if err != nil { + return nil, err + } + return storeSkuNamePriceList, err } func SetStoreSkuBindVendorPrice(storeSkuBind *model.StoreSkuBind, vendorID int, vendorPrice int) { @@ -750,3 +1126,45 @@ func SetStoreCatMapSyncStatus(storeCatMap *model.StoreSkuCategoryMap, vendorID i storeCatMap.EbaiSyncStatus = syncStatus } } + +// skuIDs为空,会导致性能极低,所以要skuIDs必须有值 +func UpdateActPrice4StoreSkuNameNew(db *DaoDB, storeIDs, skuIDs []int, skuNamesInfo *StoreSkuNamesInfo, actVendorID int) (err error) { + if len(skuIDs) == 0 { + return nil + } + var vendorIDs []int + if actVendorID >= 0 { + vendorIDs = []int{actVendorID} + } + actStoreSkuList, err := GetEffectiveActStoreSkuInfo(db, 0, vendorIDs, storeIDs, skuIDs, time.Now(), time.Now()) + if err != nil { + globals.SugarLogger.Errorf("updateActPrice4StoreSkuNameNew can not get sku promotion info for error:%v", err) + return err + } + actStoreSkuMap4Act := jxutils.NewActStoreSkuMap(actStoreSkuList, true) + actStoreSkuMap4EarningPrice := jxutils.NewActStoreSkuMap(actStoreSkuList, false) + + for _, skuName := range skuNamesInfo.SkuNames { + if len(skuName.Skus) > 0 { + for _, v := range skuName.Skus { + if actStoreSku := actStoreSkuMap4Act.GetActStoreSku(skuName.StoreID, v.SkuID, -1); actStoreSku != nil { + v.ActPrice = int(actStoreSku.ActualActPrice) + v.ActID = actStoreSku.ActID + v.ActType = actStoreSku.Type + } + if actStoreSku := actStoreSkuMap4EarningPrice.GetActStoreSku(skuName.StoreID, v.SkuID, -1); actStoreSku != nil { + v.EarningPrice = int(actStoreSku.EarningPrice) + v.EarningActID = actStoreSku.ActID + } + + v.RealEarningPrice = v.EarningPrice + if v.RealEarningPrice == 0 { + v.RealEarningPrice = int(jxutils.CaculateSkuEarningPrice(int64(v.BindPrice), int64(v.BindPrice), skuName.PayPercentage)) + } + } + } else { + skuName.UnitPrice = skuName.Price + } + } + return err +} diff --git a/business/model/dao/thing_map.go b/business/model/dao/thing_map.go new file mode 100644 index 000000000..59ce42b1c --- /dev/null +++ b/business/model/dao/thing_map.go @@ -0,0 +1,88 @@ +package dao + +import "git.rosy.net.cn/jx-callback/business/model" + +import "git.rosy.net.cn/baseapi/utils" + +import "git.rosy.net.cn/jx-callback/globals" + +func GetThingMapList(db *DaoDB, thingType int, vendorIDs, thingIDs []int) (cats []*model.ThingMap, err error) { + sql := ` + SELECT t1.* + FROM thing_map t1 + WHERE t1.deleted_at = ? AND t1.thing_type = ? + ` + sqlParams := []interface{}{ + utils.DefaultTimeValue, + thingType, + } + if len(thingIDs) > 0 { // 必须要指定ID + sql += " AND t1.thing_id IN (" + GenQuestionMarks(len(thingIDs)) + ")" + sqlParams = append(sqlParams, thingIDs) + err = GetRows(db, &cats, sql, sqlParams...) + } + return cats, err +} + +func GetThingMapMap(db *DaoDB, thingType int, vendorIDs, thingIDs []int) (thingMapMap map[int64][]*model.ThingMap, err error) { + thingMapList, err := GetThingMapList(db, thingType, vendorIDs, thingIDs) + if err == nil { + thingMapMap = make(map[int64][]*model.ThingMap) + for _, thingMap := range thingMapList { + thingMapMap[thingMap.ThingID] = append(thingMapMap[thingMap.ThingID], thingMap) + } + } + return thingMapMap, err +} + +func SetThingMapSyncStatus(db *DaoDB, vendorIDs []int, vendorOrgCodes []string, thingType int, thingIDs []int, syncStatus int8) (num int64, err error) { + sql := ` + UPDATE thing_map t1 + SET t1.sync_status |= ? + WHERE t1.deleted_at = ? AND t1.thing_type = ? + ` + sqlParams := []interface{}{ + syncStatus, + utils.DefaultTimeValue, + thingType, + } + if len(vendorIDs) > 0 { + sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" + sqlParams = append(sqlParams, vendorIDs) + } + if len(vendorOrgCodes) > 0 { + sql += " AND t1.vendor_org_code IN (" + GenQuestionMarks(len(vendorOrgCodes)) + ")" + sqlParams = append(sqlParams, vendorOrgCodes) + } + if len(thingIDs) > 0 { + sql += " AND t1.thing_id IN (" + GenQuestionMarks(len(thingIDs)) + ")" + sqlParams = append(sqlParams, thingIDs) + } + num, err = ExecuteSQL(db, sql, sqlParams...) + return num, err +} + +func SetSkuNameSyncStatus(db *DaoDB, vendorIDs []int, vendorOrgCodes []string, nameIDs []int, syncStatus int8) (num int64, err error) { + if globals.IsUseThingMap { + skuIDs, err2 := GetSkuIDByNames(db, nameIDs) + if err = err2; err == nil { + num, err = SetThingMapSyncStatus(db, vendorIDs, vendorOrgCodes, model.ThingTypeSku, skuIDs, syncStatus) + } + } else { + sql := ` + UPDATE sku t1 + SET t1.jd_sync_status = t1.jd_sync_status | ? + WHERE t1.deleted_at = ? + ` + sqlParams := []interface{}{ + syncStatus, + utils.DefaultTimeValue, + } + if len(nameIDs) > 0 { + sql += " AND t1.name_id IN(" + GenQuestionMarks(len(nameIDs)) + ")" + sqlParams = append(sqlParams, nameIDs) + } + num, err = ExecuteSQL(db, sql, sqlParams...) + } + return num, err +} diff --git a/business/model/error_code.go b/business/model/error_code.go index 3afb079f1..70a49bcea 100644 --- a/business/model/error_code.go +++ b/business/model/error_code.go @@ -6,6 +6,7 @@ const ( ErrorCodeIgnore = "ignore" ErrCodeSuccess = "0" + ErrCodePoint = "1" ErrCodeGeneralFailed = "-1" ErrCodeTokenIsInvalid = "-2" ErrCodeUserNotExist = "-3" diff --git a/business/model/order.go b/business/model/order.go index 36ed06e1d..96624d07f 100644 --- a/business/model/order.go +++ b/business/model/order.go @@ -100,6 +100,7 @@ type GoodsOrder struct { InvoiceTitle string `orm:"size(64)" json:"invoiceTitle"` // 发票抬头 InvoiceTaxerID string `orm:"size(32);column(invoice_taxer_id)" json:"invoiceTaxerID"` // 发票纳税人识别码 InvoiceEmail string `orm:"size(64)" json:"invoiceEmail"` // 发票邮箱 + VendorOrgCode string `orm:"size(64)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 // 以下只是用于传递数据 OriginalData string `orm:"-" json:"-"` @@ -179,6 +180,8 @@ type Waybill struct { ModelTimeInfo `json:"-"` OriginalData string `orm:"type(text)" json:"-"` Remark string `orm:"-" json:"-"` // 用于传递remark + + VendorOrgCode string `orm:"size(64)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 } func (w *Waybill) TableUnique() [][]string { @@ -321,7 +324,7 @@ type OrderPayRefund struct { RefundID string `orm:"column(refund_id);unique;size(48)" json:"refundID"` VendorRefundID string `orm:"column(vendor_refund_id);unique;size(48)" json:"vendorRefundID"` - AfsOrderID string `orm:"column(afs_order_id);index;size(48)" json:"afsOrderID"` + AfsOrderID string `orm:"column(afs_order_id);index;size(48)" json:"afsOrderID"` // AfsOrderID与RefundID的区别? VendorOrderID string `orm:"column(vendor_order_id);index;size(48)" json:"vendorOrderID"` VendorID int `orm:"column(vendor_id)" json:"vendorID"` TransactionID string `orm:"column(transaction_id);index;size(48)" json:"transactionID"` diff --git a/business/model/order_financial.go b/business/model/order_financial.go index 8e064d56f..2fd772fa1 100644 --- a/business/model/order_financial.go +++ b/business/model/order_financial.go @@ -105,7 +105,8 @@ type AfsOrder struct { RefundMoney int64 `json:"refundMoney"` // 平台扣款总额 1 RefundMoneyByCal int64 `json:"refundMoneyByCal"` // 平台扣款总额-通过公式计算平台扣除京西的金额M // JxSkuMoney int64 `json:"jxSkuMoney"` // 京西补贴金额,现阶段是平台扣京西多少钱,京西扣商家多少钱,暂不考虑撤回京西补贴 - Skus []*OrderSkuFinancial `orm:"-" json:"skus"` + Skus []*OrderSkuFinancial `orm:"-" json:"skus"` + VendorOrgCode string `orm:"size(64)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 } func (o *AfsOrder) TableUnique() [][]string { diff --git a/business/model/sku.go b/business/model/sku.go index 8015321be..e2e51cf03 100644 --- a/business/model/sku.go +++ b/business/model/sku.go @@ -18,6 +18,11 @@ const ( SkuStatusNormal = 1 ) +const ( + CategoryStatusDisabled = 0 + CategoryStatusEnable = 1 +) + var ( SpecUnitNames = []string{ "g", @@ -140,9 +145,10 @@ type SkuCategory struct { // ElmCategoryID int64 `orm:"column(elm_category_id)" json:"elmCategoryID"` // 这个是指对应的饿了么商品类别 // WscCategoryID int64 `orm:"column(wsc_category_id)" json:"wscCategoryID"` // 这个是指对应的美团外卖商品类别 - - JdID int64 `orm:"column(jd_id)" json:"jdID"` // 这个是指商家自己的商品类别在京东平台上的ID - JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"` + Status int8 `orm:"default(1)" json:"status"` //分类状态,0表示禁用,1表示启用 + Img string `orm:"size(512)" json:"img"` //分类图片 + JdID int64 `orm:"column(jd_id)" json:"jdID"` // 这个是指商家自己的商品类别在京东平台上的ID + JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"` } func (*SkuCategory) TableUnique() [][]string { @@ -173,13 +179,13 @@ type SkuName struct { SpecUnit string `orm:"size(8)" json:"-"` // 为份必然为克,这个主要作用只是用于确保SkuName的唯一性 Price int `json:"price"` // 单位为分,标准价,不为份的就为实际标准价,为份的为每市斤价,实际还要乘质量。todo 为份的确定必须有质量 - Img string `orm:"size(512)" json:"img"` - Img2 string `orm:"size(512)" json:"img2"` // 第二张图片 - ImgEbai string `orm:"size(255)" json:"imgEbai"` // 饿百图片地址 - ImgHashCode string `orm:"size(255);index" json:"img_hash_code"` + Img string `orm:"size(512)" json:"img"` + Img2 string `orm:"size(512)" json:"img2"` // 第二张图片 + // ImgEbai string `orm:"size(255)" json:"imgEbai"` // 饿百图片地址 + // ImgHashCode string `orm:"size(255);index" json:"img_hash_code"` - DescImg string `orm:"size(255)" json:"descImg"` // 商品详情图片描述 - DescImgEbai string `orm:"size(255)" json:"descImgEbai"` // 饿百的商品详情图片描述RTF + DescImg string `orm:"size(255)" json:"descImg"` // 商品详情图片描述 + // DescImgEbai string `orm:"size(255)" json:"descImgEbai"` // 饿百的商品详情图片描述RTF Upc string `orm:"size(20);index"` Status int `orm:"default(1)" json:"status"` // skuname状态,取值同sku.Status @@ -223,12 +229,6 @@ type SkuAndName struct { IsSpu int } -// func (*Sku) TableUnique() [][]string { -// return [][]string{ -// []string{"JdID", "DeletedAt"}, -// } -// } - func (*Sku) TableUnique() [][]string { return [][]string{ []string{"NameID", "SpecQuality", "SpecUnit", "DeletedAt"}, @@ -248,10 +248,15 @@ func (*SkuNamePlaceBind) TableUnique() [][]string { } } +type SkuWithVendor struct { + *Sku + MapList []*ThingMap `json:"mapList"` +} + type SkuNameExt struct { SkuName - Skus []*Sku `orm:"-" json:"skus"` - SkusStr string `json:"-"` + Skus []*SkuWithVendor `orm:"-" json:"skus"` + SkusStr string `json:"-"` Places []int `orm:"-" json:"places"` PlacesStr string `json:"-"` diff --git a/business/model/store.go b/business/model/store.go index 0250028f4..80f5ff000 100644 --- a/business/model/store.go +++ b/business/model/store.go @@ -373,6 +373,8 @@ type StoreMap struct { StoreID int `orm:"column(store_id)" json:"storeID"` VendorID int `orm:"column(vendor_id)" json:"vendorID"` + VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 + VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` Status int `json:"status"` // 取值同Store.Status StoreName string `orm:"size(255)" json:"storeName"` // 平台门店的名字 @@ -422,9 +424,91 @@ func (*StoreCourierMap) TableUnique() [][]string { } } +type PriceReferSnapshot struct { + ModelIDCULD + SnapshotAt time.Time `orm:"type(datetime)" json:"snapshotAt"` // 这个不同于CreatedAt,SnapshotAt是逻辑上的时间,CreatedAt是实际存储的时间 + CityCode int `json:"cityCode"` + SkuID int `orm:"column(sku_id)" json:"skuId"` + MaxPrice int `json:"maxPrice"` + MinPrice int `json:"minPrice"` + AvgPrice int `json:"avgPrice"` + MidPrice int `json:"midPrice"` + MaxJdPrice int `json:"maxJdPrice"` + MinJdPrice int `json:"minJdPrice"` + AvgJdPrice int `json:"avgJdPrice"` + MidJdPrice int `json:"midJdPrice"` + MaxEbaiPrice int `json:"maxEbaiPrice"` + MinEbaiPrice int `json:"minEbaiPrice"` + AvgEbaiPrice int `json:"avgEbaiPrice"` + MidEbaiPrice int `json:"midEbaiPrice"` + MaxMtwmPrice int `json:"maxMtwmPrice"` + MinMtwmPrice int `json:"minMtwmPrice"` + AvgMtwmPrice int `json:"avgMtwmPrice"` + MidMtwmPrice int `json:"midMtwmPrice"` + MaxSalePrice int `json:"maxSalePrice"` + MinSalePrice int `json:"minSalePrice"` + AvgSalePrice int `json:"avgSalePrice"` + MaxVendorPrice int `json:"maxVendorPrice"` + MinVendorPrice int `json:"minVendorPrice"` + AvgVendorPrice int `json:"avgVendorPrice"` +} + +func (*PriceReferSnapshot) TableUnique() [][]string { + return [][]string{ + []string{"CityCode", "SkuID", "SnapshotAt"}, + } +} + +func (*PriceReferSnapshot) TableIndex() [][]string { + return [][]string{ + []string{"SnapshotAt"}, + } +} + +type StorePriceScoreSnapshot struct { + ModelIDCULD + SnapshotAt time.Time `orm:"type(datetime)" json:"snapshotAt"` // 这个不同于CreatedAt,SnapshotAt是逻辑上的时间,CreatedAt是实际存储的时间 + StoreID int `orm:"column(store_id)" json:"storeID"` + Score float64 `json:"score"` +} + +func (*StorePriceScoreSnapshot) TableUnique() [][]string { + return [][]string{ + []string{"StoreID", "Score", "SnapshotAt"}, + } +} + +func (*StorePriceScoreSnapshot) TableIndex() [][]string { + return [][]string{ + []string{"SnapshotAt"}, + } +} + +type StoreSkuNamePrice struct { + ModelIDCULD + OutSkuID string `orm:"column(out_sku_id)" json:"outSkuID"` + Name string `json:"name"` + Price int `json:"price"` + Unit string `json:"unit"` + NameIDGroup string `orm:"column(name_id_group)" json:"nameIDGroup"` +} + +func (*StoreSkuNamePrice) TableUnique() [][]string { + return [][]string{ + []string{"OutSkuID", "Price", "NameIDGroup"}, + } +} + +func (*StoreSkuNamePrice) TableIndex() [][]string { + return [][]string{ + []string{"OutSkuID"}, + } +} + type VendorStoreSnapshot struct { ModelIDCULD + VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 StoreID int `orm:"column(store_id)" json:"storeID"` VendorID int `orm:"column(vendor_id)" json:"vendorID"` VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` diff --git a/business/model/sync_map.go b/business/model/sync_map.go index 2577356df..5ca1dcbae 100644 --- a/business/model/sync_map.go +++ b/business/model/sync_map.go @@ -14,13 +14,15 @@ type ThingMap struct { VendorID int `orm:"column(vendor_id)" json:"vendorID"` VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 - VendorThingID string `orm:"size(32);column(vendor_thing_id)" json:"vendorThingID"` - SyncStatus int8 `orm:"default(2)"` + VendorThingID string `orm:"size(32);column(vendor_thing_id);index" json:"vendorThingID"` + SyncStatus int8 `orm:"default(2)" json:"syncStatus"` + + Remark string `orm:"size(255)" json:"remark"` } func (*ThingMap) TableUnique() [][]string { return [][]string{ []string{"ThingID", "ThingType", "VendorID", "VendorOrgCode", "DeletedAt"}, - []string{"VendorThingID", "ThingType", "VendorID", "VendorOrgCode", "DeletedAt"}, + // []string{"VendorThingID", "ThingType", "VendorID", "VendorOrgCode", "DeletedAt"}, } } diff --git a/business/partner/partner.go b/business/partner/partner.go index 8af7d7564..f9146c15d 100644 --- a/business/partner/partner.go +++ b/business/partner/partner.go @@ -88,7 +88,7 @@ type IOrderManager interface { OnOrderNew(order *model.GoodsOrder, orderStatus *model.OrderStatus) (err error) OnOrderAdjust(order *model.GoodsOrder, orderStatus *model.OrderStatus) (err error) - OnOrderStatusChanged(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) @@ -141,14 +141,14 @@ type IPurchasePlatformHandler interface { //////// // Store - ReadStore(ctx *jxcontext.Context, vendorStoreID string) (store *dao.StoreDetail, err error) + ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (store *dao.StoreDetail, err error) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) - GetStoreStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string) (storeStatus int, err error) - UpdateStoreCustomID(ctx *jxcontext.Context, vendorStoreID string, storeID int64) (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, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) + UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) } // db *dao.DaoDB, @@ -161,15 +161,24 @@ type IMultipleStoresHandler interface { 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) - ReadSku(vendorSkuID string) (skuNameExt *model.SkuNameExt, 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, skuID int, vendorSkuID, skuName string) (skuNameList []*SkuNameInfo, err error) + GetSkus(ctx *jxcontext.Context, vendorOrgCode string, skuID int, vendorSkuID string) (skuNameList []*SkuNameInfo, err error) } type ISingleStoreHandler interface { diff --git a/business/partner/partner_order.go b/business/partner/partner_order.go index 442a87ce3..42065ab7d 100644 --- a/business/partner/partner_order.go +++ b/business/partner/partner_order.go @@ -12,7 +12,7 @@ type OrderPhoneNumberInfo struct { type IPurchasePlatformOrderHandler interface { Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) - GetOrder(vendorOrderID string) (order *model.GoodsOrder, err error) + GetOrder(vendorOrgCode, vendorOrderID string) (order *model.GoodsOrder, err error) GetStatusActionTimeout(order *model.GoodsOrder, statusType, status int) (params *StatusActionParams) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) @@ -38,7 +38,7 @@ type IPurchasePlatformOrderHandler interface { GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) - ReplyOrderComment(ctx *jxcontext.Context, orderComment *model.OrderComment, replyComment string) (err error) + ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) diff --git a/business/partner/partner_store.go b/business/partner/partner_store.go index 2a0b3b994..f7292476c 100644 --- a/business/partner/partner_store.go +++ b/business/partner/partner_store.go @@ -6,12 +6,12 @@ import ( ) type IStoreHandler interface { - GetAllStoresVendorID(ctx *jxcontext.Context) (vendorStoreIDs []string, err error) + GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) - EnableAutoAcceptOrder(ctx *jxcontext.Context, storeID int, vendorStoreID string, isSetEnable bool) (err error) - UpdateStoreStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string, status int) (err error) + EnableAutoAcceptOrder(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, isSetEnable bool) (err error) + UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) // opTime格式为整数1130代表11:30 - UpdateStoreOpTime(ctx *jxcontext.Context, storeID int, vendorStoreID string, opTimeList []int16) (err error) + UpdateStoreOpTime(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, opTimeList []int16) (err error) } // 同步资质信息至平台 diff --git a/business/partner/partner_store_sku.go b/business/partner/partner_store_sku.go index 9333b0705..f3f61a19c 100644 --- a/business/partner/partner_store_sku.go +++ b/business/partner/partner_store_sku.go @@ -133,13 +133,13 @@ type BareCategoryInfo struct { type IPurchasePlatformStoreSkuHandler interface { GetStoreSkusBatchSize(funcID int) int - ListOrders(ctx *jxcontext.Context, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) + ListOrders(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) // 此接口要求实现为不限制批处理大小的 - GetStoreSkusBareInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*StoreSkuInfo) (outStoreSkuList []*StoreSkuInfo, err error) - UpdateStoreSkusStock(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (failedList []*StoreSkuInfoWithErr, err error) - UpdateStoreSkusStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo, status int) (failedList []*StoreSkuInfoWithErr, err error) - UpdateStoreSkusPrice(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (failedList []*StoreSkuInfoWithErr, err error) + GetStoreSkusBareInfo(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*StoreSkuInfo) (outStoreSkuList []*StoreSkuInfo, err error) + UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (failedList []*StoreSkuInfoWithErr, err error) + UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo, status int) (failedList []*StoreSkuInfoWithErr, err error) + UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (failedList []*StoreSkuInfoWithErr, err error) } type ISingleStoreStoreSkuHandler interface { diff --git a/business/partner/purchase/ebai/act_page.go b/business/partner/purchase/ebai/act_page.go index c0fe778d2..4327faf40 100644 --- a/business/partner/purchase/ebai/act_page.go +++ b/business/partner/purchase/ebai/act_page.go @@ -84,8 +84,9 @@ func (c *PurchaseHandler) GetPageActList(ctx *jxcontext.Context, createdFrom tim VendorMask: model.GetVendorMask(model.VendorIDEBAI), LimitCount: 1, }, - VendorID: model.VendorIDEBAI, - VendorActID: ebaiAct.ActivityID, + VendorID: model.VendorIDEBAI, + VendorOrgCode: api.EbaiAPI.GetSource(), + VendorActID: ebaiAct.ActivityID, } actList = append(actList, act) } diff --git a/business/partner/purchase/ebai/ebai.go b/business/partner/purchase/ebai/ebai.go index c5cd5fe05..3a222d025 100644 --- a/business/partner/purchase/ebai/ebai.go +++ b/business/partner/purchase/ebai/ebai.go @@ -39,9 +39,12 @@ func New() (obj *PurchaseHandler) { } func EbaiBusStatus2JxStatus(ebaiStatus int) int { - if ebaiStatus == ebaiapi.ShopBusStatusHaveRest || ebaiStatus == ebaiapi.ShopBusStatusSuspended { + if ebaiStatus == ebaiapi.ShopBusStatusHaveRest { return model.StoreStatusClosed } + if ebaiStatus == ebaiapi.ShopBusStatusSuspended { + return model.StoreStatusDisabled + } return model.StoreStatusOpened } @@ -49,7 +52,7 @@ func (p *PurchaseHandler) GetVendorID() int { return model.VendorIDEBAI } -func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { +func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { globals.SugarLogger.Debugf("ebai UploadImg imgURL:%s, imgName:%s, imgType:%d", imgURL, imgName, imgType) if globals.EnableEbaiStoreWrite { if imgType == model.ImgTypeMain { diff --git a/business/partner/purchase/ebai/order.go b/business/partner/purchase/ebai/order.go index e891e83fa..83f53d018 100644 --- a/business/partner/purchase/ebai/order.go +++ b/business/partner/purchase/ebai/order.go @@ -78,7 +78,7 @@ func (p *PurchaseHandler) getStatusFromVendorStatus(vendorStatus string) int { return model.OrderStatusUnknown } -func (p *PurchaseHandler) GetOrder(vendorOrderID string) (order *model.GoodsOrder, err error) { +func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID string) (order *model.GoodsOrder, err error) { order, _, err = p.getOrder(vendorOrderID) return order, err } @@ -208,6 +208,8 @@ func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo InvoiceTitle: utils.Interface2String(orderMap["invoice_title"]), InvoiceTaxerID: utils.Interface2String(orderMap["taxer_id"]), InvoiceEmail: jxutils.GetOneEmailFromStr(utils.Interface2String(orderMap["remark"])), + + VendorOrgCode: utils.Interface2String(result["source"]), } if utils.IsTimeZero(order.PickDeadline) && !utils.IsTimeZero(order.StatusTime) { order.PickDeadline = order.StatusTime.Add(pickupOrderDelay) // 饿百要求在5分钟内拣货,不然订单会被取消 @@ -425,7 +427,7 @@ func (c *PurchaseHandler) onOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaiapi. if status.Status == model.OrderStatusFinished { if order, err2 := partner.CurOrderManager.LoadOrder(status.VendorOrderID, status.VendorID); err2 == nil { if order.TotalShopMoney == 0 { - if order2, err2 := c.GetOrder(status.VendorOrderID); err2 == nil { + if order2, err2 := c.GetOrder(msg.Source, status.VendorOrderID); err2 == nil { order.TotalShopMoney = order2.TotalShopMoney order.PmSubsidyMoney = order2.PmSubsidyMoney partner.CurOrderManager.UpdateOrderFields(order, []string{"TotalShopMoney", "PmSubsidyMoney"}) @@ -433,7 +435,7 @@ func (c *PurchaseHandler) onOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaiapi. } } } - err = partner.CurOrderManager.OnOrderStatusChanged(status) + err = partner.CurOrderManager.OnOrderStatusChanged(msg.Source, status) } } retVal = api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, nil) @@ -612,7 +614,7 @@ func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.Goods return err } -func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) { +func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) { if utils.IsTimeZero(queryDate) { return nil, fmt.Errorf("queryDate必须指定") } @@ -620,7 +622,7 @@ func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, parentTask tasksch. toDate := fromDate.Add(24*time.Hour - 1) var vendorStoreIDs []string if vendorStoreID == "" { - vendorStoreIDs, err = c.GetAllStoresVendorID(ctx) + vendorStoreIDs, err = c.GetAllStoresVendorID(ctx, "") if err != nil { return nil, err } diff --git a/business/partner/purchase/ebai/order_afs.go b/business/partner/purchase/ebai/order_afs.go index eb499879e..fac74a1ea 100644 --- a/business/partner/purchase/ebai/order_afs.go +++ b/business/partner/purchase/ebai/order_afs.go @@ -73,6 +73,7 @@ func (c *PurchaseHandler) onAfsOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaia ReasonImgList: utils.LimitUTF8StringLen(strings.Join(partRefundData.Photos, ","), 1024), RefundType: model.AfsTypePartRefund, + VendorOrgCode: msg.Source, // FreightUserMoney: afsInfo.OrderFreightMoney, // AfsFreightMoney: afsInfo.AfsFreight, // BoxMoney: afsInfo.PackagingMoney, diff --git a/business/partner/purchase/ebai/order_comment.go b/business/partner/purchase/ebai/order_comment.go index 8a49a1e5c..eef56da63 100644 --- a/business/partner/purchase/ebai/order_comment.go +++ b/business/partner/purchase/ebai/order_comment.go @@ -92,7 +92,7 @@ func (c *PurchaseHandler) RefreshComment(fromTime, toTime time.Time) (err error) return err } -func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, orderComment *model.OrderComment, replyComment string) (err error) { +func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string,orderComment *model.OrderComment, replyComment string) (err error) { if orderComment.VendorStoreID != "" && orderComment.UserCommentID != "" { if globals.EnableEbaiStoreWrite { err = api.EbaiAPI.OrderRatesReply("", utils.Str2Int64(orderComment.VendorStoreID), orderComment.UserCommentID, replyComment) diff --git a/business/partner/purchase/ebai/order_test.go b/business/partner/purchase/ebai/order_test.go index 2349cfadc..239b3d356 100644 --- a/business/partner/purchase/ebai/order_test.go +++ b/business/partner/purchase/ebai/order_test.go @@ -18,7 +18,7 @@ func TestGetOrder4PartRefund(t *testing.T) { } func TestListOrders(t *testing.T) { - order, err := CurPurchaseHandler.ListOrders(jxcontext.AdminCtx, nil, utils.GetCurDate(), "") + order, err := CurPurchaseHandler.ListOrders(jxcontext.AdminCtx, "", nil, utils.GetCurDate(), "") if err != nil { t.Fatal(err.Error()) } else { diff --git a/business/partner/purchase/ebai/store.go b/business/partner/purchase/ebai/store.go index d76a5c13e..31022b65e 100644 --- a/business/partner/purchase/ebai/store.go +++ b/business/partner/purchase/ebai/store.go @@ -24,6 +24,7 @@ const ( type tEbaiStoreInfo struct { model.Store + VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 VendorStoreID string `orm:"column(vendor_store_id)"` RealLastOperator string EbaiStoreStatus int @@ -79,7 +80,7 @@ func getCoordintate(data interface{}) float64 { return utils.MustInterface2Float64(data) } -func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorStoreID string) (*dao.StoreDetail, error) { +func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (*dao.StoreDetail, error) { baiduShopID := utils.Str2Int64WithDefault(vendorStoreID, 0) if baiduShopID == 0 { return nil, fmt.Errorf("饿百门店ID:%s非法,应该是一个整数", vendorStoreID) @@ -121,6 +122,7 @@ func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorStoreID string db := dao.GetDB() if city, err2 := dao.GetPlaceByName(db, utils.Interface2String(result["city"]), model.PlaceLevelCity, 0); err2 == nil { retVal.CityCode = city.Code + retVal.CityName = utils.Interface2String(result["city"]) districtName := utils.Interface2String(result["county"]) if retVal.CityCode != 0 && districtName != "" { if district, err2 := dao.GetPlaceByName(db, utils.Interface2String(result["county"]), model.PlaceLevelDistrict, city.Code); err2 == nil { @@ -136,6 +138,7 @@ func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorStoreID string } } } + retVal.VendorStoreID = vendorStoreID retVal.ID = int(utils.Str2Int64WithDefault(utils.Interface2String(result["shop_id"]), 0)) retVal.DeliveryRangeType = model.DeliveryRangeTypePolygon retVal.DeliveryRange = EbaiDeliveryRegion2Jx(result["delivery_region"]) @@ -150,7 +153,9 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin var stores []*tEbaiStoreInfo sql := ` - SELECT t1.*, t2.status ebai_store_status, t2.vendor_store_id, + SELECT + t1.*, + t2.status ebai_store_status, t2.vendor_store_id, t2.vendor_org_code, IF(t1.updated_at > t2.updated_at, t1.last_operator, t2.last_operator) real_last_operator, t2.sync_status FROM store t1 JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? AND (t2.deleted_at = ?) @@ -165,7 +170,7 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin if store.SyncStatus&model.SyncFlagDeletedMask == 0 { shopID = store.ID } - store2, err2 := p.ReadStore(jxcontext.AdminCtx, store.VendorStoreID) + store2, err2 := p.ReadStore(jxcontext.AdminCtx, store.VendorOrgCode, store.VendorStoreID) // globals.SugarLogger.Debugf("ebai UpdateStore2 store2:%s, err2:%v", utils.Format4Output(store2, true), err2) if err = err2; err == nil { if store2.ID == store.ID { @@ -174,7 +179,7 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin } if err == nil { if shopID > 0 { - err = p.UpdateStoreCustomID(jxcontext.AdminCtx, store.VendorStoreID, int64(shopID)) + err = p.UpdateStoreCustomID(jxcontext.AdminCtx, "", store.VendorStoreID, int64(shopID)) } else if shopID == 0 { // todo remove out shop id } @@ -410,7 +415,7 @@ func genStoreMapFromStore(store *tEbaiStoreInfo) map[string]interface{} { return params } -func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string) (storeStatus int, err error) { +func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) { ebaiStatus, err := api.EbaiAPI.ShopBusStatusGet("", utils.Str2Int64(vendorStoreID), ebaiapi.PlatformFlagElm) if err == nil { storeStatus = EbaiBusStatus2JxStatus(ebaiStatus) @@ -425,7 +430,7 @@ func (c *PurchaseHandler) onShopMsgPush(msg *ebaiapi.CallbackMsg) (response *eba storeStatus := model.StoreStatusOpened switch utils.Interface2String(msg.Body["msg_type"]) { case "online", "offline": - storeStatus, err = c.GetStoreStatus(jxcontext.AdminCtx, storeID, vendorStoreID) + storeStatus, err = c.GetStoreStatus(jxcontext.AdminCtx, "", storeID, vendorStoreID) case "shop_open", "shop_pause", "shop_close": if int(utils.ForceInterface2Int64(msg.Body["business_ele"])) == 1 { storeStatus = model.StoreStatusOpened @@ -447,12 +452,12 @@ func (c *PurchaseHandler) GetShopHealthInfo(vendorShopID string) (shopHealthInfo return shopHealthInfo, err } -func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, storeID int, vendorStoreID string, isSetEnable bool) (err error) { +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, storeID int, vendorStoreID string, status int) (err error) { - store, err := c.ReadStore(ctx, vendorStoreID) +func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) { + store, err := c.ReadStore(ctx, vendorOrgCode, vendorStoreID) if err != nil { return err } @@ -478,7 +483,7 @@ func (c *PurchaseHandler) updateStoreStatus(userName string, storeID int, vendor return err } -func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, storeID int, vendorStoreID string, opTimeList []int16) (err error) { +func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, opTimeList []int16) (err error) { params := map[string]interface{}{ ebaiapi.KeyBaiduShopID: vendorStoreID, } @@ -489,7 +494,7 @@ func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, storeID int, return err } -func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context) (vendorStoreIDs []string, err error) { +func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) { shopList, err := api.EbaiAPI.ShopList(ebaiapi.SysStatusAll) if err == nil && len(shopList) > 0 { vendorStoreIDs = make([]string, len(shopList)) @@ -500,9 +505,34 @@ func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context) (vendorSt return vendorStoreIDs, err } -func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorStoreID string, storeID int64) (err error) { +func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode string, vendorStoreID string, storeID int64) (err error) { if globals.EnableJdStoreWrite { err = api.EbaiAPI.ShopIDBatchUpdate([]string{vendorStoreID}, []string{utils.Int64ToStr(storeID)}) } return err } + +func (c *PurchaseHandler) GetShopListByPage(status, proxy_business_state int) (shopList []*ebaiapi.ShopList, err error) { + var ( + pageCount = 500 + pageNum = 1 + ) + for { + shopListPage, _, err2 := api.EbaiAPI.GetShopListByPage(status, proxy_business_state, pageCount, pageNum) + err = err2 + shopList = append(shopList, shopListPage...) + if len(shopList) < pageCount { + break + } + pageNum++ + } + return shopList, err +} + +func (c *PurchaseHandler) GetShopIDsByPage() (vendorStoreIDs []string, err error) { + shopList, err := c.GetShopListByPage(ebaiapi.ShopStatusOnLine, ebaiapi.ProxyBusinessState) + for _, v := range shopList { + vendorStoreIDs = append(vendorStoreIDs, v.Wid) + } + return vendorStoreIDs, err +} diff --git a/business/partner/purchase/ebai/store_sku2.go b/business/partner/purchase/ebai/store_sku2.go index f6e60ee80..469fcb748 100644 --- a/business/partner/purchase/ebai/store_sku2.go +++ b/business/partner/purchase/ebai/store_sku2.go @@ -172,7 +172,7 @@ func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, v return failedList, err } -func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) { +func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (successList []*partner.StoreSkuInfo, err error) { vendorSkuIDs := partner.BareStoreSkuInfoList(storeSkuList).GetVendorSkuIDIntList() if globals.EnableEbaiStoreWrite { var opResult *ebaiapi.BatchOpResult @@ -214,7 +214,7 @@ func StoreSkuInfoList2Ebai(storeSkuList []*partner.StoreSkuInfo) (outList ebaiap return outList } -func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { +func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { if globals.EnableEbaiStoreWrite { if len(storeSkuList) > 1 { opResult, err2 := api.EbaiAPI.SkuPriceUpdateBatch(ctx.GetTrackInfo(), utils.Int2Str(storeID), StoreSkuInfoList2Ebai(storeSkuList), ebaiapi.SkuIDTypeSkuID) @@ -231,7 +231,7 @@ func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, storeID i return failedList, err } -func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { +func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { if globals.EnableEbaiStoreWrite { if len(storeSkuList) > 1 { opResult, err2 := api.EbaiAPI.SkuStockUpdateBatch(ctx.GetTrackInfo(), utils.Int2Str(storeID), StoreSkuInfoList2Ebai(storeSkuList), ebaiapi.SkuIDTypeSkuID) @@ -272,10 +272,10 @@ func genSkuParamsFromStoreSkuInfo2(storeSku *dao.StoreSkuSyncInfo, isCreate bool if storeSku.DescImg != "" { params["rtf"] = storeSku.DescImg } - if isCreate /*storeSku.StoreSkuSyncStatus&(model.SyncFlagPriceMask| model.SyncFlagNewMask) != 0 */ { + if isCreate /*storeSku.SkuSyncStatus&(model.SyncFlagPriceMask| model.SyncFlagNewMask) != 0 */ { params["sale_price"] = storeSku.VendorPrice } - if storeSku.StoreSkuSyncStatus&(model.SyncFlagSaleMask|model.SyncFlagNewMask) != 0 { + if storeSku.SkuSyncStatus&(model.SyncFlagSaleMask|model.SyncFlagNewMask) != 0 { params["status"] = jxSkuStatus2Ebai(storeSku.MergedStatus) } // todo 饿百如果给的UPC是空要报错,但如果我要删除UPC怎么弄? diff --git a/business/partner/purchase/ebai/store_sku2_test.go b/business/partner/purchase/ebai/store_sku2_test.go index 7eac8e1fb..93e652bb2 100644 --- a/business/partner/purchase/ebai/store_sku2_test.go +++ b/business/partner/purchase/ebai/store_sku2_test.go @@ -23,7 +23,7 @@ func TestGetStoreSkusFullInfo(t *testing.T) { } func TestGetStoreSkusBareInfo(t *testing.T) { - storeSkuList, err := CurPurchaseHandler.GetStoreSkusBareInfo(jxcontext.AdminCtx, nil, testShopID, testShopBaiduID, nil) + storeSkuList, err := CurPurchaseHandler.GetStoreSkusBareInfo(jxcontext.AdminCtx, "", nil, testShopID, testShopBaiduID, nil) if err != nil { t.Fatal(err.Error()) } diff --git a/business/partner/purchase/ebai/store_test.go b/business/partner/purchase/ebai/store_test.go index c26fc7088..c24f5ba3b 100644 --- a/business/partner/purchase/ebai/store_test.go +++ b/business/partner/purchase/ebai/store_test.go @@ -10,7 +10,7 @@ import ( ) func TestReadStore(t *testing.T) { - result, err := CurPurchaseHandler.ReadStore(jxcontext.AdminCtx, testShopBaiduID) + result, err := CurPurchaseHandler.ReadStore(jxcontext.AdminCtx, "", testShopBaiduID) if err != nil { t.Fatal(err.Error()) } diff --git a/business/partner/purchase/ebai/waybill.go b/business/partner/purchase/ebai/waybill.go index 0d7564fdd..8a8f551ba 100644 --- a/business/partner/purchase/ebai/waybill.go +++ b/business/partner/purchase/ebai/waybill.go @@ -73,6 +73,8 @@ func (c *PurchaseHandler) callbackMsg2Waybill(msg *ebaiapi.CallbackMsg) (retVal Status: c.GetWaybillStatusFromVendorStatus(vendorStatus), VendorStatus: vendorStatus, StatusTime: utils.Timestamp2Time(msg.Timestamp), + + VendorOrgCode: msg.Source, } return retVal } diff --git a/business/partner/purchase/elm/elm.go b/business/partner/purchase/elm/elm.go index f4deb0341..d2cbf40c6 100644 --- a/business/partner/purchase/elm/elm.go +++ b/business/partner/purchase/elm/elm.go @@ -92,7 +92,7 @@ func (c *PurchaseHandler) OnCallbackMsg(msg *elmapi.CallbackMsg) (retVal *elmapi return retVal } -func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { +func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { return imgHint, err } diff --git a/business/partner/purchase/elm/order.go b/business/partner/purchase/elm/order.go index 935956d9f..41f2130a5 100644 --- a/business/partner/purchase/elm/order.go +++ b/business/partner/purchase/elm/order.go @@ -96,13 +96,13 @@ func (c *PurchaseHandler) onOrderStatusMsg(msg *elmapi.CallbackOrderStatusMsg) ( globals.SugarLogger.Warnf("onOrderStatusMsg elm msg:%v not handled", msg) return elmapi.SuccessResponse } - err := partner.CurOrderManager.OnOrderStatusChanged(status) + err := partner.CurOrderManager.OnOrderStatusChanged("", status) // 直接跳到拣货完成 if msg.MsgType == elmapi.MsgTypeOrderAccepted { status.Status = model.OrderStatusFinishedPickup status.VendorStatus = fakePickedUp - err = partner.CurOrderManager.OnOrderStatusChanged(status) + err = partner.CurOrderManager.OnOrderStatusChanged("", status) } // if globals.HandleLegacyJxOrder && err == nil { // c.legacyElmOrderStatusChanged(status) @@ -123,7 +123,7 @@ func (c *PurchaseHandler) onOrderCancelRefundMsg(msg *elmapi.CallbackOrderCancel return elmapi.Err2CallbackResponse(partner.CurOrderManager.OnOrderStatusChanged(status), status.VendorStatus) } -func (c *PurchaseHandler) GetOrder(orderID string) (order *model.GoodsOrder, err error) { +func (c *PurchaseHandler) GetOrder(vendorOrgCode, orderID string) (order *model.GoodsOrder, err error) { result, err := api.ElmAPI.GetOrder(orderID) if err == nil { order = c.Map2Order(result) @@ -200,7 +200,7 @@ func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo // func (c *PurchaseHandler) onOrderNew(msg map[string]interface{}) (response *elmapi.CallbackResponse) { // todo 这里应该可以直接用msg里的内容,而不用再次去查 - order, err := c.GetOrder(msg["orderId"].(string)) + order, err := c.GetOrder("", msg["orderId"].(string)) if err == nil { order.VendorStatus = c.stateAndType2Str(order.VendorStatus, elmapi.MsgTypeOrderValid) err = partner.CurOrderManager.OnOrderNew(order, nil) diff --git a/business/partner/purchase/elm/order_comment.go b/business/partner/purchase/elm/order_comment.go index adff37f0e..18cba44d6 100644 --- a/business/partner/purchase/elm/order_comment.go +++ b/business/partner/purchase/elm/order_comment.go @@ -5,6 +5,6 @@ import ( "git.rosy.net.cn/jx-callback/business/model" ) -func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, orderComment *model.OrderComment, replyComment string) (err error) { +func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) { return err } diff --git a/business/partner/purchase/elm/order_test.go b/business/partner/purchase/elm/order_test.go index 7c0e294a9..1a3f7b704 100644 --- a/business/partner/purchase/elm/order_test.go +++ b/business/partner/purchase/elm/order_test.go @@ -13,7 +13,7 @@ func init() { func TestGetOrder(t *testing.T) { orderID := "3025427524410871880" - order, err := new(PurchaseHandler).GetOrder(orderID) + order, err := new(PurchaseHandler).GetOrder("", orderID) if err != nil { t.Fatal(err.Error()) } diff --git a/business/partner/purchase/elm/store.go b/business/partner/purchase/elm/store.go index 7ee357328..ff863d62a 100644 --- a/business/partner/purchase/elm/store.go +++ b/business/partner/purchase/elm/store.go @@ -8,7 +8,7 @@ import ( "git.rosy.net.cn/jx-callback/business/model/dao" ) -func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorStoreID string) (*dao.StoreDetail, error) { +func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode string, vendorStoreID string) (*dao.StoreDetail, error) { return nil, errors.New("饿了么还没实现") } @@ -20,6 +20,6 @@ func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask return hint, err } -func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string) (storeStatus int, err error) { +func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) { return storeStatus, err } diff --git a/business/partner/purchase/jd/act.go b/business/partner/purchase/jd/act.go index b5377b58c..613ce32d2 100644 --- a/business/partner/purchase/jd/act.go +++ b/business/partner/purchase/jd/act.go @@ -65,12 +65,12 @@ func jdSkuActStatus2Jx(jdActState int) int { return jdSkuActStatusMap[jdActState] } -func CreatePromotionInfos(promotionType int, name string, beginDate, endDate time.Time, outInfoId, advertising, traceId string) (infoId int64, err error) { +func CreatePromotionInfos(vendorOrgCode string, promotionType int, name string, beginDate, endDate time.Time, outInfoId, advertising, traceId string) (infoId int64, err error) { if globals.EnableJdStoreWrite { if promotionType == model.ActSkuDirectDown { - infoId, err = getAPI("").CreatePromotionInfosSingle(name, beginDate, endDate, outInfoId, advertising, traceId) + infoId, err = getAPI(vendorOrgCode).CreatePromotionInfosSingle(name, beginDate, endDate, outInfoId, advertising, traceId) } else { - infoId, err = getAPI("").CreatePromotionInfosLimitTime(name, beginDate, endDate, outInfoId, advertising, traceId) + infoId, err = getAPI(vendorOrgCode).CreatePromotionInfosLimitTime(name, beginDate, endDate, outInfoId, advertising, traceId) } } else { infoId = jxutils.GenFakeID() @@ -81,26 +81,26 @@ func CreatePromotionInfos(promotionType int, name string, beginDate, endDate tim return infoId, err } -func CreatePromotionRules(promotionType int, infoId int64, outInfoId string, limitDevice, limitPin, limitCount, limitDaily int, traceId string) (err error) { +func CreatePromotionRules(vendorOrgCode string, promotionType int, infoId int64, outInfoId string, limitDevice, limitPin, limitCount, limitDaily int, traceId string) (err error) { if globals.EnableJdStoreWrite { if promotionType == model.ActSkuDirectDown { - err = getAPI("").CreatePromotionRulesSingle(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily, traceId) + err = getAPI(vendorOrgCode).CreatePromotionRulesSingle(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily, traceId) } else { - err = getAPI("").CreatePromotionRulesLimitTime(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily, traceId) + err = getAPI(vendorOrgCode).CreatePromotionRulesLimitTime(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily, traceId) } } return err } -func CreatePromotionSku(promotionType int, infoId int64, outInfoId string, skus []*jdapi.PromotionSku, traceId string) (skusResult []*jdapi.PromotionSku, err error) { +func CreatePromotionSku(vendorOrgCode string, promotionType int, infoId int64, outInfoId string, skus []*jdapi.PromotionSku, traceId string) (skusResult []*jdapi.PromotionSku, err error) { if globals.EnableJdStoreWrite { for _, batchSkus := range splitPromotionSku(skus, jdapi.MaxPromotionSkuCount) { var tmpSkusResult []*jdapi.PromotionSku var tmpErr error if promotionType == model.ActSkuDirectDown { - tmpSkusResult, tmpErr = getAPI("").CreatePromotionSkuSingle(infoId, outInfoId, batchSkus, traceId) + tmpSkusResult, tmpErr = getAPI(vendorOrgCode).CreatePromotionSkuSingle(infoId, outInfoId, batchSkus, traceId) } else { - tmpSkusResult, tmpErr = getAPI("").CreatePromotionSkuLimitTime(infoId, outInfoId, batchSkus, traceId) + tmpSkusResult, tmpErr = getAPI(vendorOrgCode).CreatePromotionSkuLimitTime(infoId, outInfoId, batchSkus, traceId) } if err = tmpErr; err != nil { break @@ -111,14 +111,14 @@ func CreatePromotionSku(promotionType int, infoId int64, outInfoId string, skus return skusResult, err } -func CancelPromotionSku(promotionType int, infoId int64, outInfoId string, skus []*jdapi.PromotionSku, traceId string) (err error) { +func CancelPromotionSku(vendorOrgCode string, promotionType int, infoId int64, outInfoId string, skus []*jdapi.PromotionSku, traceId string) (err error) { if globals.EnableJdStoreWrite { for _, batchSkus := range splitPromotionSku(skus, jdapi.MaxPromotionSkuCount) { var tmpErr error if promotionType == model.ActSkuDirectDown { - tmpErr = getAPI("").CancelPromotionSkuSingle(infoId, outInfoId, batchSkus, traceId) + tmpErr = getAPI(vendorOrgCode).CancelPromotionSkuSingle(infoId, outInfoId, batchSkus, traceId) } else { - tmpErr = getAPI("").CancelPromotionSkuLimitTime(infoId, outInfoId, batchSkus, traceId) + tmpErr = getAPI(vendorOrgCode).CancelPromotionSkuLimitTime(infoId, outInfoId, batchSkus, traceId) } if err = tmpErr; err != nil { break @@ -128,45 +128,45 @@ func CancelPromotionSku(promotionType int, infoId int64, outInfoId string, skus return err } -func ConfirmPromotion(promotionType int, infoId int64, outInfoId, traceId string) (err error) { +func ConfirmPromotion(vendorOrgCode string, promotionType int, infoId int64, outInfoId, traceId string) (err error) { if globals.EnableJdStoreWrite { if promotionType == model.ActSkuDirectDown { - return getAPI("").ConfirmPromotionSingle(infoId, outInfoId, traceId) + return getAPI(vendorOrgCode).ConfirmPromotionSingle(infoId, outInfoId, traceId) } else { - return getAPI("").ConfirmPromotionLimitTime(infoId, outInfoId, traceId) + return getAPI(vendorOrgCode).ConfirmPromotionLimitTime(infoId, outInfoId, traceId) } } return err } -func CancelPromotion(promotionType int, infoId int64, outInfoId, traceId string) (err error) { +func CancelPromotion(vendorOrgCode string, promotionType int, infoId int64, outInfoId, traceId string) (err error) { if globals.EnableJdStoreWrite { if promotionType == model.ActSkuDirectDown { - err = getAPI("").CancelPromotionSingle(infoId, outInfoId, traceId) + err = getAPI(vendorOrgCode).CancelPromotionSingle(infoId, outInfoId, traceId) } else { - err = getAPI("").CancelPromotionLimitTime(infoId, outInfoId, traceId) + err = getAPI(vendorOrgCode).CancelPromotionLimitTime(infoId, outInfoId, traceId) } } return err } -func AdjustPromotionTime(promotionType int, infoId int64, outInfoId string, endDate time.Time, traceId string) (err error) { +func AdjustPromotionTime(vendorOrgCode string, promotionType int, infoId int64, outInfoId string, endDate time.Time, traceId string) (err error) { if globals.EnableJdStoreWrite { if promotionType == model.ActSkuDirectDown { - err = getAPI("").AdjustPromotionTimeSingle(infoId, outInfoId, endDate, traceId) + err = getAPI(vendorOrgCode).AdjustPromotionTimeSingle(infoId, outInfoId, endDate, traceId) } else { - err = getAPI("").AdjustPromotionTimeLimitTime(infoId, outInfoId, endDate, traceId) + err = getAPI(vendorOrgCode).AdjustPromotionTimeLimitTime(infoId, outInfoId, endDate, traceId) } } return err } -func AdjustPromotionSku(promotionType int, infoId int64, outInfoId string, skus []*jdapi.PromotionSku, traceId string) (skusResult []*jdapi.PromotionSku, err error) { +func AdjustPromotionSku(vendorOrgCode string, promotionType int, infoId int64, outInfoId string, skus []*jdapi.PromotionSku, traceId string) (skusResult []*jdapi.PromotionSku, err error) { if globals.EnableJdStoreWrite { if promotionType == model.ActSkuDirectDown { - skusResult, err = getAPI("").AdjustPromotionSkuSingle(infoId, outInfoId, skus, traceId) + skusResult, err = getAPI(vendorOrgCode).AdjustPromotionSkuSingle(infoId, outInfoId, skus, traceId) } else { - skusResult, err = getAPI("").AdjustPromotionSkuLimitTime(infoId, outInfoId, skus, traceId) + skusResult, err = getAPI(vendorOrgCode).AdjustPromotionSkuLimitTime(infoId, outInfoId, skus, traceId) } } return skusResult, err @@ -194,12 +194,12 @@ func createSkuAct(ctx *jxcontext.Context, act *model.Act2, actStoreSku []*model. if act.VendorActID == "" { outInfoID = utils.Int2Str(act.ID) } - infoID, err2 := CreatePromotionInfos(act.Type, act.GetRealActName(), act.BeginAt, act.EndAt, outInfoID, act.Advertising, traceInfo) + infoID, err2 := CreatePromotionInfos(act.VendorOrgCode, act.Type, act.GetRealActName(), act.BeginAt, act.EndAt, outInfoID, act.Advertising, traceInfo) if err = err2; err == nil { vendorActID = utils.Int64ToStr(infoID) - if err = CreatePromotionRules(act.Type, infoID, "", act.LimitUser, act.LimitUser, act.LimitCount, 1, traceInfo); err == nil { - if _, err = CreatePromotionSku(act.Type, infoID, utils.Int2Str(act.ID), storeSku2Jd(actStoreSku, model.IsSyncStatusNeedCreate), traceInfo); err == nil { - if err = ConfirmPromotion(act.Type, infoID, "", traceInfo); err == nil { + if err = CreatePromotionRules(act.VendorOrgCode, act.Type, infoID, "", act.LimitUser, act.LimitUser, act.LimitCount, 1, traceInfo); err == nil { + if _, err = CreatePromotionSku(act.VendorOrgCode, act.Type, infoID, utils.Int2Str(act.ID), storeSku2Jd(actStoreSku, model.IsSyncStatusNeedCreate), traceInfo); err == nil { + if err = ConfirmPromotion(act.VendorOrgCode, act.Type, infoID, "", traceInfo); err == nil { for _, v := range actStoreSku { v.VendorActID = vendorActID } @@ -207,24 +207,24 @@ func createSkuAct(ctx *jxcontext.Context, act *model.Act2, actStoreSku []*model. } } if err != nil { - CancelPromotion(act.Type, infoID, "", traceInfo) + CancelPromotion(act.VendorOrgCode, act.Type, infoID, "", traceInfo) } } return vendorActID, err } -func cancelSkuActSkus(ctx *jxcontext.Context, actType int, vendorActID string, actStoreSku []*model.ActStoreSku2) (err error) { +func cancelSkuActSkus(ctx *jxcontext.Context, vendorOrgCode string, actType int, vendorActID string, actStoreSku []*model.ActStoreSku2) (err error) { if vendorActID != "" { if skuList := storeSku2Jd(actStoreSku, model.IsSyncStatusNeedDelete); len(skuList) > 0 { - err = CancelPromotionSku(actType, utils.Str2Int64(vendorActID), "", skuList, ctx.GetTrackInfo()) + err = CancelPromotionSku(vendorOrgCode, actType, utils.Str2Int64(vendorActID), "", skuList, ctx.GetTrackInfo()) } } return err } -func cancelSkuAct(ctx *jxcontext.Context, actType int, vendorActID string) (err error) { +func cancelSkuAct(ctx *jxcontext.Context, vendorOrgCode string, actType int, vendorActID string) (err error) { if vendorActID != "" { - err = CancelPromotion(actType, utils.Str2Int64(vendorActID), "", ctx.GetTrackInfo()) + err = CancelPromotion(vendorOrgCode, actType, utils.Str2Int64(vendorActID), "", ctx.GetTrackInfo()) } return err } @@ -256,7 +256,7 @@ func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITa if model.IsSyncStatusDelete(act.SyncStatus) { for vendorActID := range vendorActInfoMap { if vendorActID != "" { - if err = cancelSkuAct(ctx, act.Type, vendorActID); err != nil { + if err = cancelSkuAct(ctx, act.VendorOrgCode, act.Type, vendorActID); err != nil { return err } } @@ -287,9 +287,9 @@ func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITa if vendorActID != "" { if len(vendorActInfoMap[vendorActID]) == len(deleteActInfoMap[vendorActID]) { // todo 如果这个取消导致了整活动被取消的话,怎么设置京西活动的状态 - err = cancelSkuAct(ctx, act.Type, vendorActID) + err = cancelSkuAct(ctx, act.VendorOrgCode, act.Type, vendorActID) } else { - err = cancelSkuActSkus(ctx, act.Type, vendorActID, deleteActInfoMap[vendorActID]) + err = cancelSkuActSkus(ctx, act.VendorOrgCode, act.Type, vendorActID, deleteActInfoMap[vendorActID]) } if err != nil { return err @@ -325,7 +325,7 @@ func (c *PurchaseHandler) onActMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.C if _, ok := actMap.Load(intPromotionID); !ok { utils.CallFuncAsync(func() { if !partner.CurActManager.IsVendorActExist(jxcontext.AdminCtx, promotionID, model.VendorIDJD) { - act, actStoreSkuList, err := getActFromJD(promotionID) + act, actStoreSkuList, err := getActFromJD(appKey2OrgCode(msg.AppKey), promotionID) if err == nil && len(actStoreSkuList) > 0 { _, err = partner.CurActManager.CreateActFromVendor(jxcontext.AdminCtx, act, actStoreSkuList) } @@ -341,8 +341,8 @@ func (c *PurchaseHandler) onActMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.C return retVal } -func getActFromJD(promotionID string) (act *model.Act2, actStoreSkuList []*model.ActStoreSku2, err error) { - result, err := getAPI("").QueryPromotionInfo(utils.Str2Int64(promotionID)) +func getActFromJD(vendorOrgCode, promotionID string) (act *model.Act2, actStoreSkuList []*model.ActStoreSku2, err error) { + result, err := getAPI(vendorOrgCode).QueryPromotionInfo(utils.Str2Int64(promotionID)) if err == nil && len(result.SkuResultList) > 0 { act = &model.Act2{ Act: model.Act{ @@ -357,8 +357,9 @@ func getActFromJD(promotionID string) (act *model.Act2, actStoreSkuList []*model LimitDaily: result.SkuResultList[0].LimitDaily, LimitCount: 1, }, - VendorID: model.VendorIDJD, - VendorActID: promotionID, + VendorID: model.VendorIDJD, + VendorOrgCode: vendorOrgCode, + VendorActID: promotionID, } if utils.IsTimeZero(act.BeginAt) { act.BeginAt = result.BeginTime.GoTime() diff --git a/business/partner/purchase/jd/callback.go b/business/partner/purchase/jd/callback.go index 0b29cd921..9a4b0bf16 100644 --- a/business/partner/purchase/jd/callback.go +++ b/business/partner/purchase/jd/callback.go @@ -6,21 +6,21 @@ import ( func OnOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { if CurPurchaseHandler != nil { - retVal = CurPurchaseHandler.OnOrderMsg(msg) + retVal = CurPurchaseHandler.OnOrderMsg(appKey2OrgCode(msg.AppKey), msg) } return retVal } func OnWaybillMsg(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) { if CurPurchaseHandler != nil { - retVal = CurPurchaseHandler.OnWaybillMsg(msg) + retVal = CurPurchaseHandler.OnWaybillMsg(appKey2OrgCode(msg.AppKey), msg) } return retVal } func OnStoreMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { if CurPurchaseHandler != nil { - retVal = CurPurchaseHandler.OnStoreMsg(msg) + retVal = CurPurchaseHandler.OnStoreMsg(appKey2OrgCode(msg.AppKey), msg) } return retVal } diff --git a/business/partner/purchase/jd/financial.go b/business/partner/purchase/jd/financial.go index f95121baa..45037f159 100644 --- a/business/partner/purchase/jd/financial.go +++ b/business/partner/purchase/jd/financial.go @@ -18,13 +18,14 @@ func (p *PurchaseHandler) OnFinancialMsg(msg *jdapi.CallbackOrderMsg) (retVal *j // 京东正向/退款订单类型处理--存储 func (p *PurchaseHandler) onFinancialMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { var err error + a := GetAPIByAppKey(msg.AppKey) // if msg.StatusID == jdapi.OrderStatusPayFinishedSettle || msg.StatusID == jdapi.OrderStatusTipChanged || msg.StatusID == jdapi.OrderStatusSwitch2SelfSettle { // 如果是正向单 if msg.StatusID == jdapi.OrderStatusPayFinishedSettle || msg.StatusID == jdapi.OrderStatusTipChanged || msg.StatusID == jdapi.OrderStatusAdjustSettle || msg.StatusID == jdapi.OrderStatusSwitch2SelfSettle { // 如果是正向单 order, err2 := partner.CurOrderManager.LoadOrder(msg.BillID, model.VendorIDJD) if err = err2; err == nil { - orderData, err2 := getAPI("").QuerySingleOrder(msg.BillID) + orderData, err2 := a.QuerySingleOrder(msg.BillID) if err = err2; err == nil { - orderFinancial, err2 := CurPurchaseHandler.OrderDetail2Financial(orderData, false, order) + orderFinancial, err2 := CurPurchaseHandler.OrderDetail2Financial(a, orderData, false, order) if err = err2; err == nil { if msg.StatusID == jdapi.OrderStatusPayFinishedSettle { err = partner.CurOrderManager.SaveOrderFinancialInfo(orderFinancial, partner.CreatedPeration) @@ -37,7 +38,7 @@ func (p *PurchaseHandler) onFinancialMsg(msg *jdapi.CallbackOrderMsg) (retVal *j err = nil } } else if msg.StatusID == jdapi.AfsServiceStateRefundSuccess || msg.StatusID == jdapi.AfsServiceStateReturnGoodsSuccess { // 如果是退款单 - orderData, err2 := getAPI("").GetAfsService(msg.BillID) + orderData, err2 := a.GetAfsService(msg.BillID) if err = err2; err == nil { err = partner.CurOrderManager.SaveAfsOrderFinancialInfo(CurPurchaseHandler.AfsOrderDetail2Financial(orderData)) } @@ -46,7 +47,7 @@ func (p *PurchaseHandler) onFinancialMsg(msg *jdapi.CallbackOrderMsg) (retVal *j } // 处理京东正向订单信息 -func (p *PurchaseHandler) OrderDetail2Financial(orderData map[string]interface{}, isFromOrderDetail bool, order *model.GoodsOrder) (orderFinancial *model.OrderFinancial, err error) { +func (p *PurchaseHandler) OrderDetail2Financial(a *jdapi.API, orderData map[string]interface{}, isFromOrderDetail bool, order *model.GoodsOrder) (orderFinancial *model.OrderFinancial, err error) { orderFinancial = &model.OrderFinancial{ VendorID: model.VendorIDJD, VendorOrderID: utils.Int64ToStr(utils.MustInterface2Int64(orderData["orderId"])), @@ -149,9 +150,9 @@ func (p *PurchaseHandler) OrderDetail2Financial(orderData map[string]interface{} } } } - globals.SugarLogger.Debug(utils.Format4Output(orderFinancial.Discounts, false)) + // globals.SugarLogger.Debug(utils.Format4Output(orderFinancial.Discounts, false)) } - order1, err2 := getAPI("").OrderShoudSettlementService(orderFinancial.VendorOrderID) + order1, err2 := a.OrderShoudSettlementService(orderFinancial.VendorOrderID) if err = err2; err == nil { orderFinancial.ShopMoney = utils.Interface2Int64WithDefault(order1["settlementAmount"], 0) orderFinancial.PmMoney += utils.Interface2Int64WithDefault(order1["goodsCommission"], 0) @@ -160,10 +161,6 @@ func (p *PurchaseHandler) OrderDetail2Financial(orderData map[string]interface{} orderFinancial.PmMoney += utils.Interface2Int64WithDefault(order1["guaranteedCommission"], 0) orderFinancial.PmSkuSubsidyMoney = utils.Interface2Int64WithDefault(order1["platSkuGoodsDiscountMoney"], 0) orderFinancial.PmSubsidyMoney = utils.Interface2Int64WithDefault(order1["platOrderGoodsDiscountMoney"], 0) + orderFinancial.PmSkuSubsidyMoney - } else { - if !isFromOrderDetail { - // globals.SugarLogger.Warnf("jd OrderDetail2Financial, orderID:%s is not found from getAPI("").OrderShoudSettlementService, err:%v", orderFinancial.VendorOrderID, err) - } } return orderFinancial, err } @@ -182,6 +179,7 @@ func (p *PurchaseHandler) AfsOrderDetail2Financial(orderData map[string]interfac BoxMoney: utils.MustInterface2Int64(orderData["packagingMoney"]), TongchengFreightMoney: utils.MustInterface2Int64(orderData["tongchengFreightMoney"]), SkuBoxMoney: utils.MustInterface2Int64(orderData["mealBoxMoney"]), + VendorOrgCode: utils.Interface2String(orderData["venderId"]), } order, err := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID) if err == nil { @@ -230,10 +228,10 @@ func (p *PurchaseHandler) AfsOrderDetail2Financial(orderData map[string]interfac return afsOrder } -func (p *PurchaseHandler) OnOrderDetail(orderDetail map[string]interface{}, peration string) (err error) { +func (p *PurchaseHandler) OnOrderDetail(a *jdapi.API, orderDetail map[string]interface{}, peration string) (err error) { order, err := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(utils.MustInterface2Int64(orderDetail["orderId"])), model.VendorIDJD) if err == nil { - orderFinancial, err2 := CurPurchaseHandler.OrderDetail2Financial(orderDetail, true, order) + orderFinancial, err2 := CurPurchaseHandler.OrderDetail2Financial(a, orderDetail, true, order) if err = err2; err == nil { err = partner.CurOrderManager.SaveOrderFinancialInfo(orderFinancial, peration) } diff --git a/business/partner/purchase/jd/jd.go b/business/partner/purchase/jd/jd.go index 7e5e7740d..33f85cc61 100644 --- a/business/partner/purchase/jd/jd.go +++ b/business/partner/purchase/jd/jd.go @@ -26,14 +26,30 @@ func getAPI(appOrgCode string) (apiObj *jdapi.API) { return partner.CurAPIManager.GetAPI(model.VendorIDJD, appOrgCode).(*jdapi.API) } -func GetAPIByToken(token string) (apiObj *jdapi.API) { - if token == "" { +func GetAPI(appOrgCode string) (apiObj *jdapi.API) { + return getAPI(appOrgCode) +} + +func appKey2OrgCode(appKey string) (vendorOrgCode string) { + apiList := partner.CurAPIManager.GetAppOrgCodeList(model.VendorIDJD) + for _, v := range apiList { + jdAPI := partner.CurAPIManager.GetAPI(model.VendorIDJD, v).(*jdapi.API) + if jdAPI.GetAppKey() == appKey { + vendorOrgCode = v + break + } + } + return vendorOrgCode +} + +func GetAPIByAppKey(appKey string) (apiObj *jdapi.API) { + if appKey == "" { apiObj = getAPI("") } else { apiList := partner.CurAPIManager.GetAppOrgCodeList(model.VendorIDJD) for _, v := range apiList { jdAPI := partner.CurAPIManager.GetAPI(model.VendorIDJD, v).(*jdapi.API) - if jdAPI.GetToken() == token { + if jdAPI.GetAppKey() == appKey { apiObj = jdAPI break } @@ -75,6 +91,6 @@ func JxStoreStatus2JdStatus(status int) (yn, closeStatus int) { } } -func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { +func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { return imgHint, err } diff --git a/business/partner/purchase/jd/order.go b/business/partner/purchase/jd/order.go index f923c12ba..dc658c7a9 100644 --- a/business/partner/purchase/jd/order.go +++ b/business/partner/purchase/jd/order.go @@ -44,19 +44,19 @@ var ( selfTakeCodeReg = regexp.MustCompile(`等待用户凭提货码(\d+)于`) ) -func (c *PurchaseHandler) OnOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { +func (c *PurchaseHandler) OnOrderMsg(vendorOrgCode string, msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { jxutils.CallMsgHandler(func() { - retVal = c.onOrderMsg(msg) + retVal = c.onOrderMsg(vendorOrgCode, msg) }, jxutils.ComposeUniversalOrderID(msg.BillID, model.VendorIDJD)) return retVal } -func (c *PurchaseHandler) updateOrderFinancialInfo(orderID string) (err error) { +func (c *PurchaseHandler) updateOrderFinancialInfo(a *jdapi.API, orderID string) (err error) { order := &model.GoodsOrder{ VendorOrderID: orderID, VendorID: model.VendorIDJD, } - orderSettlement, err := getAPI("").OrderShoudSettlementService2(orderID) + orderSettlement, err := a.OrderShoudSettlementService2(orderID) if err == nil { if orderSettlement != nil { updateOrderBySettleMent(order, orderSettlement) @@ -66,7 +66,8 @@ func (c *PurchaseHandler) updateOrderFinancialInfo(orderID string) (err error) { return err } -func (c *PurchaseHandler) onOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { +func (c *PurchaseHandler) onOrderMsg(vendorOrgCode string, msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { + a := getAPI(vendorOrgCode) status := c.callbackMsg2Status(msg) if jdapi.StatusIDNewOrder == msg.StatusID { status.Status = model.OrderStatusNew // 因为京东将事件32000与状态32000混用,事件32000可能是新订单,也可能是已接单,统一当成新订单处理 @@ -76,22 +77,22 @@ func (c *PurchaseHandler) onOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi } if msg.MsgURL == jdapi.CallbackMsgOrderAccounting { retVal = c.OnFinancialMsg(msg) - retVal = jdapi.Err2CallbackResponse(c.updateOrderFinancialInfo(msg.BillID), status.VendorStatus) + retVal = jdapi.Err2CallbackResponse(c.updateOrderFinancialInfo(a, msg.BillID), status.VendorStatus) } else if msg.MsgURL == jdapi.CallbackMsgAfterSaleBillStatus { - retVal = c.OnAfsOrderMsg(msg) + retVal = c.OnAfsOrderMsg(a, msg) } else { // 新订单事件,与订单状态有点冲突 if jdapi.StatusIDNewOrder == msg.StatusID { - retVal = c.onOrderNew(msg, status) + retVal = c.onOrderNew(a, msg, status) } else if jdapi.OrderStatusAdjust == msg.StatusID { - retVal = c.onOrderAdjust(msg, status) + retVal = c.onOrderAdjust(a, msg, status) } else { if msg.StatusID == jdapi.OrderStatusAddComment || msg.StatusID == jdapi.OrderStatusModifyComment { utils.CallFuncAsync(func() { - c.onOrderComment2(msg) + c.onOrderComment2(a, msg) }) } - err := partner.CurOrderManager.OnOrderStatusChanged(status) + err := partner.CurOrderManager.OnOrderStatusChanged(vendorOrgCode, status) // if globals.HandleLegacyJxOrder && err == nil { // c.legacyJdOrderStatusChanged(status) // } @@ -109,7 +110,7 @@ func updateOrderBySettleMent(order *model.GoodsOrder, orderSettlement *jdapi.Ord } } -func (c *PurchaseHandler) getOrder(orderID string) (order *model.GoodsOrder, orderMap map[string]interface{}, err error) { +func (c *PurchaseHandler) getOrder(a *jdapi.API, orderID string) (order *model.GoodsOrder, orderMap map[string]interface{}, err error) { globals.SugarLogger.Debugf("jd getOrder orderID:%s", orderID) var ( realMobile string @@ -120,16 +121,16 @@ func (c *PurchaseHandler) getOrder(orderID string) (order *model.GoodsOrder, ord taskIndex := batchItemList[0].(int) switch taskIndex { case 0: - orderMap, err = getAPI("").QuerySingleOrder(orderID) + orderMap, err = a.QuerySingleOrder(orderID) if err == nil { order = c.Map2Order(orderMap) - realMobile, _ = getAPI("").GetRealMobile4Order(orderID, order.VendorStoreID) + realMobile, _ = a.GetRealMobile4Order(orderID, order.VendorStoreID) if realMobile != "" { order.ConsigneeMobile2 = jxutils.FormalizeMobile(realMobile) } } case 1: - orderSettlement, _ = getAPI("").OrderShoudSettlementService2(orderID) + orderSettlement, _ = a.OrderShoudSettlementService2(orderID) } return nil, err }, []int{0, 1}) @@ -141,8 +142,8 @@ func (c *PurchaseHandler) getOrder(orderID string) (order *model.GoodsOrder, ord return order, orderMap, err } -func (c *PurchaseHandler) GetOrder(orderID string) (order *model.GoodsOrder, err error) { - order, _, err = c.getOrder(orderID) +func (c *PurchaseHandler) GetOrder(vendorOrgCode, orderID string) (order *model.GoodsOrder, err error) { + order, _, err = c.getOrder(getAPI(vendorOrgCode), orderID) return order, err } @@ -178,6 +179,7 @@ func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo ActualPayPrice: utils.MustInterface2Int64(result["orderBuyerPayableMoney"]), DistanceFreightMoney: utils.Interface2Int64WithDefault(result["merchantPaymentDistanceFreightMoney"], 0), DeliveryType: deliveryTypeMap[int(utils.Str2Int64WithDefault(utils.Interface2String(result["deliveryCarrierNo"]), 0))], + VendorOrgCode: utils.Interface2String(result["orgCode"]), } if orderInvoice, ok := result["orderInvoice"].(map[string]interface{}); ok && orderInvoice != nil { order.InvoiceTitle = utils.Interface2String(orderInvoice["invoiceTitle"]) @@ -240,27 +242,27 @@ func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo } // -func (c *PurchaseHandler) onOrderNew(msg *jdapi.CallbackOrderMsg, orderStatus *model.OrderStatus) (response *jdapi.CallbackResponse) { +func (c *PurchaseHandler) onOrderNew(a *jdapi.API, msg *jdapi.CallbackOrderMsg, orderStatus *model.OrderStatus) (response *jdapi.CallbackResponse) { globals.SugarLogger.Debugf("onOrderNew orderID:%s", msg.BillID) - order, orderMap, err := c.getOrder(msg.BillID) + order, orderMap, err := c.getOrder(a, msg.BillID) if err == nil { globals.SugarLogger.Debugf("onOrderNew2 orderID:%s", msg.BillID) if err = partner.CurOrderManager.OnOrderNew(order, orderStatus); err == nil { utils.CallFuncAsync(func() { - c.OnOrderDetail(orderMap, partner.CreatedPeration) + c.OnOrderDetail(a, orderMap, partner.CreatedPeration) }) } } return jdapi.Err2CallbackResponse(err, "jd onOrderNew") } -func (c *PurchaseHandler) onOrderAdjust(msg *jdapi.CallbackOrderMsg, orderStatus *model.OrderStatus) *jdapi.CallbackResponse { - order, orderMap, err := c.getOrder(msg.BillID) +func (c *PurchaseHandler) onOrderAdjust(a *jdapi.API, msg *jdapi.CallbackOrderMsg, orderStatus *model.OrderStatus) *jdapi.CallbackResponse { + order, orderMap, err := c.getOrder(a, msg.BillID) if err == nil { err = partner.CurOrderManager.OnOrderAdjust(order, orderStatus) if err == nil { utils.CallFuncAsync(func() { - c.OnOrderDetail(orderMap, partner.UpdatedPeration) + c.OnOrderDetail(a, orderMap, partner.UpdatedPeration) }) } } @@ -284,9 +286,10 @@ func (c *PurchaseHandler) callbackMsg2Status(msg *jdapi.CallbackOrderMsg) *model func (c *PurchaseHandler) postFakeMsg(vendorOrderID, vendorStatus string) { msg := &jdapi.CallbackOrderMsg{ - BillID: vendorOrderID, - StatusID: vendorStatus, - Timestamp: utils.Time2Str(time.Now()), + CallbackMsg: &jdapi.CallbackMsg{}, + BillID: vendorOrderID, + StatusID: vendorStatus, + Timestamp: utils.Time2Str(time.Now()), } utils.CallFuncAsync(func() { OnOrderMsg(msg) @@ -303,8 +306,8 @@ func (c *PurchaseHandler) getStatusFromVendorStatus(vendorStatus string) int { func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) { globals.SugarLogger.Debugf("jd AcceptOrRefuseOrder orderID:%s, isAcceptIt:%t", order.VendorOrderID, isAcceptIt) - if globals.EnableStoreWrite { - err = getAPI("").OrderAcceptOperate(order.VendorOrderID, isAcceptIt, userName) + if globals.EnableJdStoreWrite { + err = getAPI(order.VendorOrgCode).OrderAcceptOperate(order.VendorOrderID, isAcceptIt, userName) if isAcceptIt && err == nil { c.postFakeMsg(order.VendorOrderID, jdapi.StatusIDWaitOutStore) } @@ -322,7 +325,7 @@ func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptI func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) { globals.SugarLogger.Debugf("jd PickupGoods orderID:%s, isSelfDelivery:%t", order.VendorOrderID, isSelfDelivery) if !isSelfDelivery && globals.EnableJdStoreWrite { - _, err = getAPI("").OrderJDZBDelivery(order.VendorOrderID, userName) + _, err = getAPI(order.VendorOrgCode).OrderJDZBDelivery(order.VendorOrderID, userName) } else { c.postFakeMsg(order.VendorOrderID, jdapi.OrderStatusFinishedPickup) } @@ -331,21 +334,21 @@ func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bo func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) { if globals.EnableJdStoreWrite { - err = getAPI("").ReceiveFailedAudit(order.VendorOrderID, isAcceptIt, ctx.GetUserName(), "") + err = getAPI(order.VendorOrgCode).ReceiveFailedAudit(order.VendorOrderID, isAcceptIt, ctx.GetUserName(), "") } return err } func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 拣货失败后再次招唤平台配送 if globals.EnableJdStoreWrite { - err = getAPI("").UrgeDispatching(order.VendorOrderID, ctx.GetUserName()) + err = getAPI(order.VendorOrgCode).UrgeDispatching(order.VendorOrderID, ctx.GetUserName()) } return err } func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 投递失败后确认收到退货 if globals.EnableJdStoreWrite { - err = getAPI("").ConfirmReceiveGoods(order.VendorOrderID) + err = getAPI(order.VendorOrgCode).ConfirmReceiveGoods(order.VendorOrderID) } return err } @@ -353,11 +356,11 @@ func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *mod func (c *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) { globals.SugarLogger.Debugf("jd Swtich2SelfDeliver orderID:%s", order.VendorOrderID) if globals.EnableJdStoreWrite { - _, err = getAPI("").ModifySellerDelivery(order.VendorOrderID, userName) + _, err = getAPI(order.VendorOrgCode).ModifySellerDelivery(order.VendorOrderID, userName) if err != nil { if errWithCode, ok := err.(*utils.ErrorWithCode); ok && errWithCode.Level() == 1 { globals.SugarLogger.Infof("Swtich2SelfDeliver failed with error:%v try get current status", err) - if order2, err2 := c.GetOrder(order.VendorOrderID); err2 == nil { + if order2, err2 := c.GetOrder(order.VendorOrgCode, order.VendorOrderID); err2 == nil { var mapData map[string]interface{} if err2 = utils.UnmarshalUseNumber([]byte(order2.OriginalData), &mapData); err2 == nil { if utils.Interface2String(mapData["deliveryCarrierNo"]) == "2938" { // 当前已经是自送状态了 @@ -374,7 +377,7 @@ func (c *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName s func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) { globals.SugarLogger.Debugf("jd Swtich2SelfDelivered orderID:%s", order.VendorOrderID) if globals.EnableJdStoreWrite { - _, err = getAPI("").DeliveryEndOrder(order.VendorOrderID, userName) + _, err = getAPI(order.VendorOrgCode).DeliveryEndOrder(order.VendorOrderID, userName) } return err } @@ -382,7 +385,7 @@ func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) { globals.SugarLogger.Debugf("jd SelfDeliverDelivering orderID:%s", order.VendorOrderID) if globals.EnableJdStoreWrite { - _, err = getAPI("").OrderSerllerDelivery(order.VendorOrderID, userName) + _, err = getAPI(order.VendorOrgCode).OrderSerllerDelivery(order.VendorOrderID, userName) } return err } @@ -397,13 +400,13 @@ func (c *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName } func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) { - mobile, err = getAPI("").GetRealMobile4Order(order.VendorOrderID, order.VendorStoreID) + mobile, err = getAPI(order.VendorOrgCode).GetRealMobile4Order(order.VendorOrderID, order.VendorStoreID) return mobile, err } func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) { if globals.EnableJdStoreWrite { - err = getAPI("").OrderCancelOperate(order.VendorOrderID, isAgree, ctx.GetUserName(), reason) + err = getAPI(order.VendorOrgCode).OrderCancelOperate(order.VendorOrderID, isAgree, ctx.GetUserName(), reason) } return err } @@ -411,7 +414,7 @@ func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *mod func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { if globals.EnableJdStoreWrite { err1 := c.Swtich2SelfDeliver(order, ctx.GetUserName()) - if err = getAPI("").CancelAndRefund(order.VendorOrderID, ctx.GetUserName(), reason); err != nil { + if err = getAPI(order.VendorOrgCode).CancelAndRefund(order.VendorOrderID, ctx.GetUserName(), reason); err != nil { if err1 != nil { err = fmt.Errorf("取消订单失败,京东取消订单是要先转为自送再处理,转自送失败:%v", err1) } @@ -430,12 +433,12 @@ func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.Goods }) } if globals.EnableJdStoreWrite { - err = getAPI("").AdjustOrder(order.VendorOrderID, ctx.GetUserName(), reason, oaosAdjustDTOList) + err = getAPI(order.VendorOrgCode).AdjustOrder(order.VendorOrderID, ctx.GetUserName(), reason, oaosAdjustDTOList) } return err } -func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) { +func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) { if utils.IsTimeZero(queryDate) { return nil, fmt.Errorf("queryDate必须指定") } @@ -449,7 +452,7 @@ func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, parentTask tasksch. if vendorStoreID != "" { queryParam.DeliveryStationNo = vendorStoreID } - orderList, _, err := getAPI("").OrderQuery2(queryParam) + orderList, _, err := getAPI(vendorOrgCode).OrderQuery2(queryParam) if err == nil { vendorOrderIDs = make([]string, len(orderList)) for k, v := range orderList { @@ -460,12 +463,13 @@ func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, parentTask tasksch. } func (c *PurchaseHandler) UpdateWaybillTip(ctx *jxcontext.Context, order *model.GoodsOrder, tipFee int64) (err error) { - orderInfo, err := getAPI("").QuerySingleOrder2(order.VendorOrderID) + a := getAPI(order.VendorOrgCode) + orderInfo, err := a.QuerySingleOrder2(order.VendorOrderID) if err == nil { tip2Add := int(tipFee) - orderInfo.Tips if tip2Add != 0 { if globals.EnableJdStoreWrite { - err = getAPI("").OrderAddTips(order.VendorOrderID, tip2Add, ctx.GetUserName()) + err = a.OrderAddTips(order.VendorOrderID, tip2Add, ctx.GetUserName()) } } } @@ -473,7 +477,7 @@ func (c *PurchaseHandler) UpdateWaybillTip(ctx *jxcontext.Context, order *model. } func (c *PurchaseHandler) GetWaybillTip(ctx *jxcontext.Context, order *model.GoodsOrder) (tipFee int64, err error) { - orderInfo, err := getAPI("").QuerySingleOrder2(order.VendorOrderID) + orderInfo, err := getAPI(order.VendorOrgCode).QuerySingleOrder2(order.VendorOrderID) if err == nil { tipFee = int64(orderInfo.Tips) } @@ -482,13 +486,13 @@ func (c *PurchaseHandler) GetWaybillTip(ctx *jxcontext.Context, order *model.Goo func (c *PurchaseHandler) AddWaybillTip(ctx *jxcontext.Context, order *model.GoodsOrder, tipFee2Add int64) (err error) { if globals.EnableJdStoreWrite { - err = getAPI("").OrderAddTips(order.VendorOrderID, int(tipFee2Add), ctx.GetUserName()) + err = getAPI(order.VendorOrgCode).OrderAddTips(order.VendorOrderID, int(tipFee2Add), ctx.GetUserName()) } return err } -func (c *PurchaseHandler) GetSelfTakeCode(ctx *jxcontext.Context, vendorOrderID string) (selfTakeCode string, err error) { - orderTrackList, err := getAPI("").GetByOrderNoForOaos(vendorOrderID) +func (c *PurchaseHandler) GetSelfTakeCode(ctx *jxcontext.Context, order *model.GoodsOrder) (selfTakeCode string, err error) { + orderTrackList, err := getAPI(order.VendorOrgCode).GetByOrderNoForOaos(order.VendorOrderID) if err == nil { for _, v := range orderTrackList { if v.TagCode == 180 { @@ -503,9 +507,9 @@ func (c *PurchaseHandler) GetSelfTakeCode(ctx *jxcontext.Context, vendorOrderID return selfTakeCode, err } -func (c *PurchaseHandler) ConfirmSelfTake(ctx *jxcontext.Context, vendorOrderID, selfTakeCode string) (err error) { +func (c *PurchaseHandler) ConfirmSelfTake(ctx *jxcontext.Context, order *model.GoodsOrder, selfTakeCode string) (err error) { if globals.EnableJdStoreWrite { - err = getAPI("").CheckSelfPickCode(selfTakeCode, vendorOrderID, ctx.GetUserName()) + err = getAPI(order.VendorOrgCode).CheckSelfPickCode(selfTakeCode, order.VendorOrderID, ctx.GetUserName()) } return err } diff --git a/business/partner/purchase/jd/order_afs.go b/business/partner/purchase/jd/order_afs.go index e3ecc3803..b89bc58e4 100644 --- a/business/partner/purchase/jd/order_afs.go +++ b/business/partner/purchase/jd/order_afs.go @@ -58,15 +58,15 @@ var ( } ) -func (c *PurchaseHandler) OnAfsOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { +func (c *PurchaseHandler) OnAfsOrderMsg(a *jdapi.API, msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { jxutils.CallMsgHandlerAsync(func() { - retVal = c.onAfsOrderMsg(msg) + retVal = c.onAfsOrderMsg(a, msg) }, jxutils.ComposeUniversalOrderID(msg.BillID, model.VendorIDJD)) return retVal } -func (c *PurchaseHandler) onAfsOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { - afsInfo, err := getAPI("").GetAfsService2(msg.BillID) +func (c *PurchaseHandler) onAfsOrderMsg(a *jdapi.API, msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { + afsInfo, err := a.GetAfsService2(msg.BillID) if err == nil { status := c.callbackAfsMsg2Status(msg, afsInfo) if partner.CurOrderManager.GetStatusDuplicatedCount(status) > 0 { @@ -141,6 +141,7 @@ func (c *PurchaseHandler) buildAfsOrder(afsInfo *jdapi.AfsServiceResponse) (afsO ReasonImgList: utils.LimitUTF8StringLen(jdapi.ProcessQuestionPic(afsInfo.QuestionPic), 1024), VendorAppealType: afsInfo.ApplyDeal, AppealType: c.convertAfsAppealType(afsInfo.ApplyDeal), + VendorOrgCode: afsInfo.VenderID, } afsOrder.Status = c.GetAfsStatusFromVendorStatus(afsOrder.VendorStatus) @@ -181,7 +182,7 @@ func (c *PurchaseHandler) buildAfsOrder(afsInfo *jdapi.AfsServiceResponse) (afsO // 审核售后单申请 func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) { if globals.EnableJdStoreWrite { - err = getAPI("").AfsOpenApprove(order.AfsOrderID, afsApproveTypeMap[approveType], reason, ctx.GetUserName()) + err = getAPI(order.VendorOrgCode).AfsOpenApprove(order.AfsOrderID, afsApproveTypeMap[approveType], reason, ctx.GetUserName()) } return err } @@ -189,7 +190,7 @@ func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *mod // 确认收到退货 func (c *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) { if globals.EnableJdStoreWrite { - err = getAPI("").ConfirmReceipt(order.AfsOrderID, ctx.GetUserName()) + err = getAPI(order.VendorOrgCode).ConfirmReceipt(order.AfsOrderID, ctx.GetUserName()) } return err } @@ -217,7 +218,7 @@ func (c *PurchaseHandler) RefundOrder(ctx *jxcontext.Context, order *model.Goods // 发起部分退款 func (c *PurchaseHandler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) { if globals.EnableJdStoreWrite { - _, err = getAPI("").AfsSubmit(order.VendorOrderID, ctx.GetUserName(), utils.Int2Str(jdapi.AfsReasonWrongPurchase), reason, "", order.ConsigneeName, order.ConsigneeMobile, order.ConsigneeAddress, orderSkus2AfsSkus(refundSkuList)) + _, err = getAPI(order.VendorOrgCode).AfsSubmit(order.VendorOrderID, ctx.GetUserName(), utils.Int2Str(jdapi.AfsReasonWrongPurchase), reason, "", order.ConsigneeName, order.ConsigneeMobile, order.ConsigneeAddress, orderSkus2AfsSkus(refundSkuList)) } return err } diff --git a/business/partner/purchase/jd/order_comment.go b/business/partner/purchase/jd/order_comment.go index a6ee7962e..ab77a1e2f 100644 --- a/business/partner/purchase/jd/order_comment.go +++ b/business/partner/purchase/jd/order_comment.go @@ -13,9 +13,9 @@ const ( JDDJ_BAD_COMMENTS_MAX_MODIFY_TIME = 72 // 小时 ) -func (c *PurchaseHandler) onOrderComment2(msg *jdapi.CallbackOrderMsg) (err error) { +func (c *PurchaseHandler) onOrderComment2(a *jdapi.API, msg *jdapi.CallbackOrderMsg) (err error) { intOrderID := utils.Str2Int64(msg.BillID) - result, err := getAPI("").GetCommentByOrderId2(intOrderID) + result, err := a.GetCommentByOrderId2(intOrderID) if err == nil { globals.SugarLogger.Debugf("onOrderComment comment:%s", utils.Format4Output(result, true)) orderCommend := &model.OrderComment{ @@ -43,9 +43,9 @@ func (c *PurchaseHandler) onOrderComment2(msg *jdapi.CallbackOrderMsg) (err erro return err } -func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, orderComment *model.OrderComment, replyComment string) (err error) { +func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) { if globals.EnableJdStoreWrite { - err = getAPI("").OrgReplyComment(utils.Str2Int64(orderComment.VendorOrderID), orderComment.VendorStoreID, replyComment, ctx.GetUserName()) + err = getAPI(vendorOrgCode).OrgReplyComment(utils.Str2Int64(orderComment.VendorOrderID), orderComment.VendorStoreID, replyComment, ctx.GetUserName()) } return err } diff --git a/business/partner/purchase/jd/order_test.go b/business/partner/purchase/jd/order_test.go index c82bc71ed..5703907bf 100644 --- a/business/partner/purchase/jd/order_test.go +++ b/business/partner/purchase/jd/order_test.go @@ -26,14 +26,14 @@ func TestSwitch2SelfDeliver(t *testing.T) { } func TestGetOrder(t *testing.T) { - _, err := CurPurchaseHandler.GetOrder("815536199000222") + _, err := CurPurchaseHandler.GetOrder("", "815536199000222") if err != nil { t.Fatal(err.Error()) } } func TestListOrders(t *testing.T) { - result, err := CurPurchaseHandler.ListOrders(jxcontext.AdminCtx, nil, time.Now(), "") + result, err := CurPurchaseHandler.ListOrders(jxcontext.AdminCtx, "", nil, time.Now(), "") if err != nil { t.Fatal(err.Error()) } @@ -41,7 +41,11 @@ func TestListOrders(t *testing.T) { } func TestGetSelfTakeCode(t *testing.T) { - selfTakeCode, err := CurPurchaseHandler.GetSelfTakeCode(jxcontext.AdminCtx, "921160248000222") + order, err := partner.CurOrderManager.LoadOrder("921160248000222", model.VendorIDJD) + if err != nil { + t.Fatal(err) + } + selfTakeCode, err := CurPurchaseHandler.GetSelfTakeCode(jxcontext.AdminCtx, order) if err != nil { t.Fatal(err.Error()) } diff --git a/business/partner/purchase/jd/sku.go b/business/partner/purchase/jd/sku.go index 6b78f8b5a..214aea54b 100644 --- a/business/partner/purchase/jd/sku.go +++ b/business/partner/purchase/jd/sku.go @@ -9,20 +9,9 @@ import ( "git.rosy.net.cn/baseapi/platformapi/jdapi" "git.rosy.net.cn/baseapi/utils" "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" - "github.com/astaxie/beego" -) - -const ( - DefBrandID = 35247 - - DefJdCategoryID = 20362 - DefJdCategoryID4Jxgy = 22410 // 其他国产水果 ) type tSkuInfoExt struct { @@ -39,13 +28,6 @@ var ( } ) -func getDefJdCategoryID() int { - if beego.BConfig.RunMode == "jxgy" { - return DefJdCategoryID4Jxgy - } - return DefJdCategoryID -} - func (p *PurchaseHandler) CreateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) { var jdPid int64 if cat.ParentID != 0 { @@ -57,66 +39,28 @@ func (p *PurchaseHandler) CreateCategory(db *dao.DaoDB, cat *model.SkuCategory, return err } } - if globals.EnableStoreWrite { + if globals.EnableJdStoreWrite { result, err2 := getAPI("").AddShopCategory(jdPid, cat.Name, int(cat.Level), cat.Seq, userName) if err = err2; err == nil { if jdID := utils.Str2Int64WithDefault(result, 0); jdID != 0 { cat.JdID = jdID } } + } else { + cat.JdID = jxutils.GenFakeID() } return err } -func jdCat2Jx(jdCat *jdapi.CategoryInfo) (jxCat *partner.BareCategoryInfo) { - return &partner.BareCategoryInfo{ - VendorCatID: utils.Int64ToStr(jdCat.Id), - Level: jdCat.Level, - Name: jdCat.Name, - Seq: jdCat.Sort, - } -} - -func (p *PurchaseHandler) GetAllCategories(ctx *jxcontext.Context, vendorOrgCode string) (cats []*partner.BareCategoryInfo, err error) { - result, err := getAPI(vendorOrgCode).QueryCategoriesByOrgCode() - if err == nil { - catMap := make(map[int64]*partner.BareCategoryInfo) - level := 1 - for { - processedCount := 0 - for _, jdCat := range result { - if jdCat.Level == level { - processedCount++ - jxCat := jdCat2Jx(jdCat) - if level == 1 { - cats = append(cats, jxCat) - } else { - parentCat := catMap[jdCat.ParentId] - if parentCat != nil { - parentCat.Children = append(parentCat.Children, jxCat) - } - } - catMap[jdCat.Id] = jxCat - } - } - if processedCount == 0 { - break - } - level++ - } - } - return cats, err -} - func (p *PurchaseHandler) UpdateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error { - if globals.EnableStoreWrite { + if globals.EnableJdStoreWrite { return getAPI("").UpdateShopCategory(cat.JdID, cat.Name) } return nil } func (p *PurchaseHandler) DeleteCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error { - if globals.EnableStoreWrite { + if globals.EnableJdStoreWrite { return getAPI("").DelShopCategory(cat.JdID) } return nil @@ -142,7 +86,7 @@ func (p *PurchaseHandler) ReorderCategories(db *dao.DaoDB, parentCatID int, user for k, v := range cats { jdCatIDs[k] = v.JdID } - if globals.EnableStoreWrite { + if globals.EnableJdStoreWrite { err = getAPI("").ChangeShopCategoryOrder(parentJDID, jdCatIDs) } } @@ -215,7 +159,7 @@ func (p *PurchaseHandler) cuSku(db *dao.DaoDB, sku *model.Sku, handler func(skuE func (p *PurchaseHandler) CreateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) { return p.cuSku(db, sku, func(skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (vendorSkuID string, err error) { if skuExt.IsSpu == 0 { - if globals.EnableStoreWrite { + if globals.EnableJdStoreWrite { vendorSkuID, err = getAPI("").AddSku(utils.Int2Str(sku.ID), skuExt.JdCategoryID, shopCategories, skuExt.BrandID, skuName, price, jxutils.IntWeight2Float(sku.Weight), jxutils.BatchString2Slice(skuExt.Img, skuExt.Img2), jxStatus2jdStatus(sku.Status), true, addParams) if err != nil { if jdSkuID := jdapi.GetJdSkuIDFromError(err); jdSkuID > 0 { @@ -223,6 +167,8 @@ func (p *PurchaseHandler) CreateSku(db *dao.DaoDB, sku *model.Sku, userName stri err = nil } } + } else { + vendorSkuID = utils.Int64ToStr(jxutils.GenFakeID()) } } else { vendorSkuID, err = p.syncSkuNameAsSpu(db, sku, skuExt, price, skuName, shopCategories, addParams) @@ -231,74 +177,77 @@ func (p *PurchaseHandler) CreateSku(db *dao.DaoDB, sku *model.Sku, userName stri }) } -func (p *PurchaseHandler) ReadSku(vendorSkuID string) (skuNameExt *model.SkuNameExt, err error) { - jdSkuID := utils.Str2Int64(vendorSkuID) - skuList, _, err := getAPI("").QuerySkuInfos(&jdapi.QuerySkuParam{ - SkuID: jdSkuID, - }) - if err == nil { - if len(skuList) >= 1 { - skuNameExt = &model.SkuNameExt{} - if imgList, err2 := getAPI("").QueryListBySkuIds(&jdapi.QueryListBySkuIdsParam{ - SkuIDs: []int64{jdSkuID}, - }); err2 == nil && len(imgList) > 0 { - skuNameExt.Img = imgList[0].SourceImgURL - } - sku := skuList[0] - prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(sku.SkuName) - if name == "" { - name = sku.SkuName - unit = "份" - specUnit = "g" - } - skuNameExt.Prefix = prefix - skuNameExt.Name = name - skuNameExt.Unit = unit - skuNameExt.Price = sku.SkuPrice - skuNameExt.Skus = []*model.Sku{ - &model.Sku{ - SpecQuality: specQuality, - SpecUnit: specUnit, - Weight: jxutils.FloatWeight2Int(float32(sku.Weight)), - JdID: sku.SkuID, - Status: jdStatus2jxStatus(sku.FixedStatus), - Comment: comment, - }, - } - skuNameExt.Skus[0].ID = int(utils.Str2Int64(sku.OutSkuID)) +// func (p *PurchaseHandler) ReadSku(ctx *jxcontext.Context, vendorOrgCode, vendorSkuID string) (skuNameExt *model.SkuNameExt, err error) { +// jdSkuID := utils.Str2Int64(vendorSkuID) +// a := getAPI(vendorOrgCode) +// skuList, _, err := a.QuerySkuInfos(&jdapi.QuerySkuParam{ +// SkuID: jdSkuID, +// }) +// if err == nil { +// if len(skuList) >= 1 { +// skuNameExt = &model.SkuNameExt{} +// if imgList, err2 := a.QueryListBySkuIds(&jdapi.QueryListBySkuIdsParam{ +// SkuIDs: []int64{jdSkuID}, +// }); err2 == nil && len(imgList) > 0 { +// skuNameExt.Img = imgList[0].SourceImgURL +// } +// sku := skuList[0] +// prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(sku.SkuName) +// if name == "" { +// name = sku.SkuName +// unit = "份" +// specUnit = "g" +// } +// skuNameExt.Prefix = prefix +// skuNameExt.Name = name +// skuNameExt.Unit = unit +// skuNameExt.Price = sku.SkuPrice +// skuNameExt.Skus = []*model.SkuWithVendor{ +// &model.SkuWithVendor{ +// Sku: &model.Sku{ +// SpecQuality: specQuality, +// SpecUnit: specUnit, +// Weight: jxutils.FloatWeight2Int(float32(sku.Weight)), +// JdID: sku.SkuID, +// Status: jdStatus2jxStatus(sku.FixedStatus), +// Comment: comment, +// }, +// }, +// } +// skuNameExt.Skus[0].ID = int(utils.Str2Int64(sku.OutSkuID)) - db := dao.GetDB() - shopCategories := sku.ShopCategories - if len(shopCategories) > 0 { - skuCat := &model.SkuCategory{} - skuCat.JdID = shopCategories[0] - if dao.GetEntity(db, skuCat, "JdID") == nil { - skuNameExt.CategoryID = skuCat.ID - } - } - sellCities := sku.SellCities - for _, v := range sellCities { - if v == 0 { - skuNameExt.IsGlobal = 1 - } - } - if len(sellCities) == 0 || skuNameExt.IsGlobal == 1 { - skuNameExt.IsGlobal = 1 - } else { - var places []*model.Place - if err = dao.GetRows(db, &places, "SELECT * FROM place WHERE jd_code IN ("+dao.GenQuestionMarks(len(sellCities))+") AND level = 2", sellCities); err == nil { - skuNameExt.Places = make([]int, len(places)) - for k, v := range places { - skuNameExt.Places[k] = v.Code - } - } - } - } else { - err = partner.ErrCanNotFindItem - } - } - return skuNameExt, err -} +// db := dao.GetDB() +// shopCategories := sku.ShopCategories +// if len(shopCategories) > 0 { +// skuCat := &model.SkuCategory{} +// skuCat.JdID = shopCategories[0] +// if dao.GetEntity(db, skuCat, "JdID") == nil { +// skuNameExt.CategoryID = skuCat.ID +// } +// } +// sellCities := sku.SellCities +// for _, v := range sellCities { +// if v == 0 { +// skuNameExt.IsGlobal = 1 +// } +// } +// if len(sellCities) == 0 || skuNameExt.IsGlobal == 1 { +// skuNameExt.IsGlobal = 1 +// } else { +// var places []*model.Place +// if err = dao.GetRows(db, &places, "SELECT * FROM place WHERE jd_code IN ("+dao.GenQuestionMarks(len(sellCities))+") AND level = 2", sellCities); err == nil { +// skuNameExt.Places = make([]int, len(places)) +// for k, v := range places { +// skuNameExt.Places[k] = v.Code +// } +// } +// } +// } else { +// err = partner.ErrCanNotFindItem +// } +// } +// return skuNameExt, err +// } func (p *PurchaseHandler) UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) { return p.cuSku(db, sku, func(skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (vendorSkuID string, err error) { @@ -311,7 +260,7 @@ func (p *PurchaseHandler) UpdateSku(db *dao.DaoDB, sku *model.Sku, userName stri params[jdapi.KeyImages] = jxutils.BatchString2Slice(skuExt.Img, skuExt.Img2) params[jdapi.KeyFixedStatus] = jxStatus2jdStatus(sku.Status) if skuExt.IsSpu == 0 { - if globals.EnableStoreWrite { + if globals.EnableJdStoreWrite { vendorSkuID, err = getAPI("").UpdateSku(utils.Int2Str(sku.ID), params) } } else { @@ -335,7 +284,7 @@ func (p *PurchaseHandler) DeleteSku(db *dao.DaoDB, sku *model.Sku, userName stri err = dao.GetRow(db, &skuExt, sql, sku.ID) if err == nil { if skuExt.IsSpu == 0 { - if globals.EnableStoreWrite { + if globals.EnableJdStoreWrite { _, err = getAPI("").UpdateSku(utils.Int2Str(sku.ID), params) } } else { @@ -345,57 +294,57 @@ func (p *PurchaseHandler) DeleteSku(db *dao.DaoDB, sku *model.Sku, userName stri return err } -func (p *PurchaseHandler) RefreshAllSkusID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) { - globals.SugarLogger.Debugf("jd RefreshAllSkusID") +// func (p *PurchaseHandler) RefreshAllSkusID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) { +// globals.SugarLogger.Debugf("jd RefreshAllSkusID") - db := dao.GetDB() - var skuPairs []*jdapi.SkuIDPair - const stepCount = 2 +// db := dao.GetDB() +// var skuPairs []*jdapi.SkuIDPair +// const stepCount = 2 - rootTask := tasksch.NewSeqTask("jd RefreshAllSkusID", ctx, - func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - err = dao.GetRows(db, &skuPairs, ` - SELECT t1.id out_sku_id, t1.jd_id sku_id - FROM sku t1 - WHERE t1.deleted_at = ? - `, utils.DefaultTimeValue) - default: - taskName := "RefreshAllSkusID update id" - if step != stepCount-1 { - taskName = "RefreshAllSkusID update uuid" - } - task1 := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true).SetBatchSize(jdapi.MaxBatchSize4BatchUpdateOutSkuId), ctx, - func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - skuPairs := make([]*jdapi.SkuIDPair, len(batchItemList)) - for k, v := range batchItemList { - pair := v.(*jdapi.SkuIDPair) - skuPairs[k] = &jdapi.SkuIDPair{ - SkuId: pair.SkuId, - OutSkuId: pair.OutSkuId, - } - if step != stepCount-1 { - skuPairs[k].OutSkuId = utils.GetUUID() - } - } - globals.SugarLogger.Debug(utils.Format4Output(skuPairs, false)) - if globals.EnableStoreWrite { - _, err = getAPI("").BatchUpdateOutSkuId(skuPairs) - } - return nil, err - }, skuPairs) - rootTask.AddChild(task1).Run() - _, err = task1.GetResult(0) - } - return nil, err - }, stepCount) - tasksch.HandleTask(rootTask, parentTask, false).Run() - if !isAsync { - _, err = rootTask.GetResult(0) - } - return rootTask.ID, err -} +// rootTask := tasksch.NewSeqTask("jd RefreshAllSkusID", ctx, +// func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { +// switch step { +// case 0: +// err = dao.GetRows(db, &skuPairs, ` +// SELECT t1.id out_sku_id, t1.jd_id sku_id +// FROM sku t1 +// WHERE t1.deleted_at = ? +// `, utils.DefaultTimeValue) +// default: +// taskName := "RefreshAllSkusID update id" +// if step != stepCount-1 { +// taskName = "RefreshAllSkusID update uuid" +// } +// task1 := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true).SetBatchSize(jdapi.MaxBatchSize4BatchUpdateOutSkuId), ctx, +// func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { +// skuPairs := make([]*jdapi.SkuIDPair, len(batchItemList)) +// for k, v := range batchItemList { +// pair := v.(*jdapi.SkuIDPair) +// skuPairs[k] = &jdapi.SkuIDPair{ +// SkuId: pair.SkuId, +// OutSkuId: pair.OutSkuId, +// } +// if step != stepCount-1 { +// skuPairs[k].OutSkuId = utils.GetUUID() +// } +// } +// globals.SugarLogger.Debug(utils.Format4Output(skuPairs, false)) +// if globals.EnableJdStoreWrite { +// _, err = getAPI("").BatchUpdateOutSkuId(skuPairs) +// } +// return nil, err +// }, skuPairs) +// rootTask.AddChild(task1).Run() +// _, err = task1.GetResult(0) +// } +// return nil, err +// }, stepCount) +// tasksch.HandleTask(rootTask, parentTask, false).Run() +// if !isAsync { +// _, err = rootTask.GetResult(0) +// } +// return rootTask.ID, err +// } func splitAddParams(addParams map[string]interface{}) (spuAddParams, skuAddParams map[string]interface{}) { if addParams != nil { @@ -420,7 +369,7 @@ func (p *PurchaseHandler) syncSkuNameAsSpu(db *dao.DaoDB, sku *model.Sku, skuExt globals.SugarLogger.Debugf("syncSkuNameAsSpu1 sku.id=%d, bareSkuName:%s, skuName:%s, skuNameJdID:%d", sku.ID, skuExt.Name, skuName, skuNameJdID) spuAddParams, skuAddParams := splitAddParams(addParams) if !jxutils.IsEmptyID(skuNameJdID) && sku.JdSyncStatus&model.SyncFlagDeletedMask != 0 { // 删除SKU - if globals.EnableStoreWrite { + if globals.EnableJdStoreWrite { err = getAPI("").UpdateSkuBaseInfo(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted)) } } @@ -440,14 +389,14 @@ func (p *PurchaseHandler) syncSkuNameAsSpu(db *dao.DaoDB, sku *model.Sku, skuExt } if count.Ct <= 1 && sku.JdSyncStatus&model.SyncFlagDeletedMask != 0 { // 1就是最后删的那个 updateFields = append(updateFields, model.FieldJdSyncStatus) - if globals.EnableStoreWrite { + if globals.EnableJdStoreWrite { if err = getAPI("").UpdateSpu(utils.Int2Str(skuExt.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusOffline)); err == nil { err = getAPI("").UpdateSpu(utils.Int2Str(skuExt.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted)) } } } } else if skuExt.JdSyncStatus&model.SyncFlagNewMask != 0 && jxutils.IsEmptyID(skuNameJdID) { - if globals.EnableStoreWrite { + if globals.EnableJdStoreWrite { spuName := jxutils.ComposeSpuName(skuExt.Prefix, skuExt.Name, 0) skus := []map[string]interface{}{ map[string]interface{}{ @@ -462,7 +411,7 @@ func (p *PurchaseHandler) syncSkuNameAsSpu(db *dao.DaoDB, sku *model.Sku, skuExt } skus[0] = utils.MergeMaps(skus[0], skuAddParams) updateFields = append(updateFields, model.FieldJdSyncStatus) - if globals.EnableStoreWrite { + if globals.EnableJdStoreWrite { vendorSpuID, skuPairs, err2 := getAPI("").AddSpu(utils.Int2Str(skuExt.ID), skuExt.JdCategoryID, shopCategories, skuExt.BrandID, spuName, []string{skuExt.Img}, jxStatus2jdStatus(skuExt.Status), spuAddParams, skus) if err = err2; err == nil { skuExt.JdID = vendorSpuID @@ -483,7 +432,7 @@ func (p *PurchaseHandler) syncSkuNameAsSpu(db *dao.DaoDB, sku *model.Sku, skuExt jdapi.KeyFixedStatus: jxStatus2jdStatus(skuExt.Status), }, spuAddParams) updateFields = append(updateFields, model.FieldJdSyncStatus) - if globals.EnableStoreWrite { + if globals.EnableJdStoreWrite { err = getAPI("").UpdateSpu(utils.Int2Str(skuExt.ID), params) } } @@ -497,7 +446,7 @@ func (p *PurchaseHandler) syncSkuNameAsSpu(db *dao.DaoDB, sku *model.Sku, skuExt } if err == nil && !jxutils.IsEmptyID(skuNameJdID) { if sku.JdSyncStatus&model.SyncFlagNewMask != 0 { // 非首次新增SKU - if globals.EnableStoreWrite { + if globals.EnableJdStoreWrite { vendorSkuID2, err2 := getAPI("").AppendSku(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), skuName, price, jxutils.IntWeight2Float(sku.Weight), []string{skuExt.Img}, jxStatus2jdStatus(sku.Status), true, composeSkuSpec(sku.SpecQuality, sku.SpecUnit, skuExt.Unit), skuAddParams) if err = err2; err == nil { vendorSkuID = utils.Int64ToStr(vendorSkuID2) @@ -510,7 +459,7 @@ func (p *PurchaseHandler) syncSkuNameAsSpu(db *dao.DaoDB, sku *model.Sku, skuExt params[jdapi.KeyFixedStatus] = jxStatus2jdStatus(sku.Status) params[jdapi.KeyWeight] = jxutils.IntWeight2Float(sku.Weight) params[jdapi.KeySkuPrice] = price - if globals.EnableStoreWrite { + if globals.EnableJdStoreWrite { err = getAPI("").UpdateSkuBaseInfo(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), utils.MergeMaps(params, skuAddParams)) if sku.JdSyncStatus&model.SyncFlagSpecMask != 0 { skuIndex := sku.SkuIndex @@ -541,189 +490,3 @@ func composeSkuSpec(specQuality float32, specUnit, unit string) string { } return value } - -func jdStatus2jxStatus(jdStatus int) (jxStatus int) { - switch jdStatus { - case jdapi.SkuFixedStatusOnline: - jxStatus = model.SkuStatusNormal - case jdapi.SkuFixedStatusOffline: - jxStatus = model.SkuStatusDontSale - case jdapi.SkuFixedStatusDeleted: - jxStatus = model.SkuStatusDeleted - } - return jxStatus -} - -func jxStatus2jdStatus(jxStatus int) (jdStatus int) { - switch jxStatus { - case model.SkuStatusNormal: - jdStatus = jdapi.SkuFixedStatusOnline - case model.SkuStatusDontSale: - jdStatus = jdapi.SkuFixedStatusOffline - case model.SkuStatusDeleted: - jdStatus = jdapi.SkuFixedStatusDeleted - } - return jdStatus -} - -func (p *PurchaseHandler) getVendorCategories(level int, pid int64) (vendorCats []*model.SkuVendorCategory, err error) { - cats, err := getAPI("").QueryChildCategoriesForOP(pid) - if err != nil { - return nil, err - } - for _, v := range cats { - if v.Status == 1 { - cat := &model.SkuVendorCategory{ - VendorID: model.VendorIDJD, - Name: v.Name, - Level: level, - VendorCategoryID: utils.Int64ToStr(v.Id), - } - if level > 1 { - cat.ParentID = utils.Int64ToStr(v.ParentId) - if level == 3 { - cat.IsLeaf = 1 - } - } - vendorCats = append(vendorCats, cat) - if level < 3 { - childVendorCats, err2 := p.getVendorCategories(level+1, v.Id) - if err2 == nil && len(childVendorCats) > 0 { - vendorCats = append(vendorCats, childVendorCats...) - } else { - cat.IsLeaf = 1 - } - } - } - } - return vendorCats, nil -} - -func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) { - vendorCats, err = p.getVendorCategories(1, 0) - return vendorCats, err -} - -func (p *PurchaseHandler) GetSkus(ctx *jxcontext.Context, skuID int, vendorSkuID, skuName string) (skuNameList []*partner.SkuNameInfo, err error) { - param := &jdapi.QuerySkuParam{ - SkuID: utils.Str2Int64WithDefault(vendorSkuID, 0), - SkuName: skuName, - IsFilterDel: jdapi.IsFilterDelTrue, - PageNo: 1, - PageSize: jdapi.MaxSkuIDsCount4QueryListBySkuIds, // 为了同时取图,这个值不要大于jdapi.MaxSkuIDsCount4QueryListBySkuIds - } - for { - skuList, _, err2 := getAPI("").QuerySkuInfos(param) - if err = err2; err != nil { - return nil, err - } - if len(skuList) > 0 { - batchSkuNameList := make([]*partner.SkuNameInfo, len(skuList)) - for k, v := range skuList { - batchSkuNameList[k] = vendorSku2Jx(v) - } - setSkuNameListPic(batchSkuNameList) - skuNameList = append(skuNameList, batchSkuNameList...) - } - if len(skuList) < param.PageSize { - break - } - param.PageNo++ - } - return skuNameList, err -} - -func setSkuNameListPic(skuNameList []*partner.SkuNameInfo) []*partner.SkuNameInfo { - jdSkuIDs := make([]int64, len(skuNameList)) - for k, v := range skuNameList { - jdSkuIDs[k] = utils.Str2Int64(v.SkuList[0].VendorSkuID) - } - - imgMap := make(map[int64]*jdapi.ImgHandleQueryResult) - if imgList, err2 := getAPI("").QueryListBySkuIds(&jdapi.QueryListBySkuIdsParam{ - SkuIDs: jdSkuIDs, - }); err2 == nil { - for _, v := range imgList { - if v.ImgType == jdapi.ImgTypeMain { - imgResult := imgMap[v.SkuID] - if imgResult == nil || imgResult.IsMain < v.IsMain { - imgMap[v.SkuID] = v - } - } - } - } - - // 使用扒页面方式获取商品图片 - if false { - var leftJdSkuIDs []int64 - for _, v := range jdSkuIDs { - if imgMap[v] == nil { - leftJdSkuIDs = append(leftJdSkuIDs, v) - } - } - task := tasksch.NewParallelTask("jd setSkuNameListPic", nil, jxcontext.AdminCtx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - jdSkuID := batchItemList[0].(int64) - imgList, err := getAPI("").GetSkuPageImageInfo(jdSkuID) - if err == nil && len(imgList) > 0 { - retVal = [][]string{ - []string{utils.Int64ToStr(jdSkuID), imgList[0].Big}, - } - } - return retVal, err - }, leftJdSkuIDs) - task.Run() - if resultList, err := task.GetResult(0); err == nil { - for _, v := range resultList { - strList := v.([]string) - imgMap[utils.Str2Int64(strList[0])] = &jdapi.ImgHandleQueryResult{ - SourceImgURL: strList[1], - } - } - } - } - - // 设置商品图片 - for _, v := range skuNameList { - if imgResult := imgMap[utils.Str2Int64(v.SkuList[0].VendorSkuID)]; imgResult != nil { - v.PictureList = []string{imgResult.SourceImgURL} - } - } - return skuNameList -} - -func vendorSku2Jx(vendorSku *jdapi.SkuMain) (skuName *partner.SkuNameInfo) { - prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(vendorSku.SkuName) - weight := int(vendorSku.Weight * 1000) - if weight <= 0 { - weight = jxutils.FormatSkuWeight(specQuality, specUnit) - } - skuID := int(utils.Str2Int64WithDefault(vendorSku.OutSkuID, 0)) - vendorSkuID := utils.Int64ToStr(vendorSku.SkuID) - skuName = &partner.SkuNameInfo{ - NameID: skuID, - VendorNameID: vendorSkuID, - VendorCatIDList: []string{utils.Int64ToStr(vendorSku.CategoryID)}, - - Prefix: prefix, - Name: name, - Unit: unit, - SkuList: []*partner.SkuInfo{ - &partner.SkuInfo{ - StoreSkuInfo: partner.StoreSkuInfo{ - VendorSkuID: vendorSkuID, - SkuID: skuID, - - VendorPrice: int64(vendorSku.SkuPrice), - Status: jdStatus2jxStatus(vendorSku.FixedStatus), - }, - SkuName: vendorSku.SkuName, - Comment: comment, - SpecQuality: float64(specQuality), - SpecUnit: specUnit, - Weight: weight, - }, - }, - } - return skuName -} diff --git a/business/partner/purchase/jd/sku2.go b/business/partner/purchase/jd/sku2.go new file mode 100644 index 000000000..5529bb772 --- /dev/null +++ b/business/partner/purchase/jd/sku2.go @@ -0,0 +1,359 @@ +package jd + +import ( + "fmt" + + "git.rosy.net.cn/baseapi/platformapi/jdapi" + "git.rosy.net.cn/baseapi/utils" + "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" + "github.com/astaxie/beego" +) + +const ( + DefBrandID = 35247 + + DefJdCategoryID = 20362 + DefJdCategoryID4Jxgy = 22410 // 其他国产水果 +) + +func getDefJdCategoryID() int { + if beego.BConfig.RunMode == "jxgy" { + return DefJdCategoryID4Jxgy + } + return DefJdCategoryID +} + +func jdCat2Jx(jdCat *jdapi.CategoryInfo) (jxCat *partner.BareCategoryInfo) { + return &partner.BareCategoryInfo{ + VendorCatID: utils.Int64ToStr(jdCat.Id), + Level: jdCat.Level, + Name: jdCat.Name, + Seq: jdCat.Sort, + } +} + +func (p *PurchaseHandler) GetAllCategories(ctx *jxcontext.Context, vendorOrgCode string) (cats []*partner.BareCategoryInfo, err error) { + result, err := getAPI(vendorOrgCode).QueryCategoriesByOrgCode() + if err == nil { + catMap := make(map[int64]*partner.BareCategoryInfo) + level := 1 + for { + processedCount := 0 + for _, jdCat := range result { + if jdCat.Level == level { + processedCount++ + jxCat := jdCat2Jx(jdCat) + if level == 1 { + cats = append(cats, jxCat) + } else { + parentCat := catMap[jdCat.ParentId] + if parentCat != nil { + parentCat.Children = append(parentCat.Children, jxCat) + } + } + catMap[jdCat.Id] = jxCat + } + } + if processedCount == 0 { + break + } + level++ + } + } + return cats, err +} + +func (p *PurchaseHandler) CreateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error) { + globals.SugarLogger.Debugf("CreateCategory2 cat:%s", utils.Format4Output(cat, true)) + parentID := int64(0) + if cat.Level != 1 { + parentID = utils.Str2Int64(cat.ParentVendorCatID) + } + if globals.EnableJdStoreWrite { + result, err2 := getAPI(cat.VendorOrgCode).AddShopCategory(parentID, cat.Name, int(cat.Level), cat.Seq, ctx.GetUserName()) + if err = err2; err == nil { + if jdID := utils.Str2Int64WithDefault(result, 0); jdID != 0 { + cat.VendorCatID = utils.Int64ToStr(jdID) + } + } + } else { + cat.VendorCatID = utils.Int64ToStr(jxutils.GenFakeID()) + } + return err +} + +func (p *PurchaseHandler) UpdateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error) { + globals.SugarLogger.Debugf("UpdateCategory2 cat:%s", utils.Format4Output(cat, true)) + if globals.EnableJdStoreWrite { + err = getAPI(cat.VendorOrgCode).UpdateShopCategory(utils.Str2Int64(cat.VendorCatID), cat.Name) + } + return err +} + +func (p *PurchaseHandler) DeleteCategory2(ctx *jxcontext.Context, vendorOrgCode, vendorCatID string) (err error) { + globals.SugarLogger.Debugf("DeleteCategory2 vendorOrgCode:%s, vendorCatID:%s", vendorOrgCode, vendorCatID) + if globals.EnableJdStoreWrite { + err = getAPI(vendorOrgCode).DelShopCategory(utils.Str2Int64(vendorCatID)) + } + return err +} + +func (p *PurchaseHandler) ReorderCategories2(ctx *jxcontext.Context, vendorOrgCode, vendorParentCatID string, vendorCatIDList []string) (err error) { + if globals.EnableJdStoreWrite { + err = getAPI(vendorOrgCode).ChangeShopCategoryOrder(utils.Str2Int64(vendorParentCatID), utils.StringSlice2Int64(vendorCatIDList)) + } + return err +} + +func (p *PurchaseHandler) getVendorCategories(level int, pid int64) (vendorCats []*model.SkuVendorCategory, err error) { + // 得到平台的分类,不需要指定分账号 + cats, err := getAPI("").QueryChildCategoriesForOP(pid) + if err != nil { + return nil, err + } + for _, v := range cats { + if v.Status == 1 { + cat := &model.SkuVendorCategory{ + VendorID: model.VendorIDJD, + Name: v.Name, + Level: level, + VendorCategoryID: utils.Int64ToStr(v.Id), + } + if level > 1 { + cat.ParentID = utils.Int64ToStr(v.ParentId) + if level == 3 { + cat.IsLeaf = 1 + } + } + vendorCats = append(vendorCats, cat) + if level < 3 { + childVendorCats, err2 := p.getVendorCategories(level+1, v.Id) + if err2 == nil && len(childVendorCats) > 0 { + vendorCats = append(vendorCats, childVendorCats...) + } else { + cat.IsLeaf = 1 + } + } + } + } + return vendorCats, nil +} + +func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) { + vendorCats, err = p.getVendorCategories(1, 0) + return vendorCats, err +} + +func skuInfo2Param(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (param *jdapi.OpSkuParam) { + param = &jdapi.OpSkuParam{ + TraceID: ctx.GetTrackInfo(), + OutSkuID: utils.Int2Str(sku.SkuID), + ShopCategories: []int64{utils.Str2Int64(sku.VendorCatID)}, + CategoryID: sku.VendorVendorCatID, + BrandID: DefBrandID, + SkuName: utils.LimitUTF8StringLen(sku.SkuName, jdapi.MaxSkuNameCharCount), + SkuPrice: int(sku.Price), + Weight: float64(jxutils.IntWeight2Float(sku.Weight)), + FixedStatus: jxStatus2jdStatus(sku.MergedStatus), + IsSale: jdapi.IsSaleNo, // todo ? + + Upc: sku.Upc, + Images: jxutils.BatchString2Slice(sku.Img, sku.Img2), + } + if param.CategoryID == 0 { + param.CategoryID = int64(getDefJdCategoryID()) + } + if sku.IsGlobal == 0 && len(sku.SellCities) > 0 { + param.SellCities = utils.StringSlice2Int64(sku.SellCities) + } + if sku.DescImg != "" { + param.ProductDesc = fmt.Sprintf(`一张图片`, sku.DescImg) + } + return param +} + +func (p *PurchaseHandler) CreateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error) { + globals.SugarLogger.Debugf("CreateSku2 sku:%s", utils.Format4Output(sku, true)) + param := skuInfo2Param(ctx, sku) + if globals.EnableJdStoreWrite { + sku.VendorSkuID, err = getAPI(sku.VendorOrgCode).AddSku2(param) + } else { + sku.VendorSkuID = utils.Int64ToStr(jxutils.GenFakeID()) + } + return err +} + +func (p *PurchaseHandler) UpdateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error) { + globals.SugarLogger.Debugf("UpdateSku2 sku:%s", utils.Format4Output(sku, true)) + param := skuInfo2Param(ctx, sku) + if globals.EnableJdStoreWrite { + _, err = getAPI(sku.VendorOrgCode).UpdateSku2(param) + } + return err +} + +func (p *PurchaseHandler) DeleteSku2(ctx *jxcontext.Context, vendorOrgCode string, sku *partner.StoreSkuInfo) (err error) { + globals.SugarLogger.Debugf("DeleteSku2 vendorOrgCode:%s, sku:%s", vendorOrgCode, utils.Format4Output(sku, true)) + param := &jdapi.OpSkuParam{ + TraceID: ctx.GetTrackInfo(), + OutSkuID: utils.Int2Str(sku.SkuID), + FixedStatus: jdapi.SkuFixedStatusDeleted, + } + if globals.EnableJdStoreWrite { + _, err = getAPI(vendorOrgCode).UpdateSku2(param) + } + return err +} + +func (p *PurchaseHandler) GetSkus(ctx *jxcontext.Context, vendorOrgCode string, skuID int, vendorSkuID string) (skuNameList []*partner.SkuNameInfo, err error) { + param := &jdapi.QuerySkuParam{ + SkuID: utils.Str2Int64WithDefault(vendorSkuID, 0), + IsFilterDel: jdapi.IsFilterDelTrue, + PageNo: 1, + PageSize: jdapi.MaxSkuIDsCount4QueryListBySkuIds, // 为了同时取图,这个值不要大于jdapi.MaxSkuIDsCount4QueryListBySkuIds + } + for { + skuList, _, err2 := getAPI(vendorOrgCode).QuerySkuInfos(param) + if err = err2; err != nil { + return nil, err + } + if len(skuList) > 0 { + batchSkuNameList := make([]*partner.SkuNameInfo, len(skuList)) + for k, v := range skuList { + batchSkuNameList[k] = vendorSku2Jx(v) + } + setSkuNameListPic(vendorOrgCode, batchSkuNameList) + skuNameList = append(skuNameList, batchSkuNameList...) + } + if len(skuList) < param.PageSize { + break + } + param.PageNo++ + } + return skuNameList, err +} + +func setSkuNameListPic(vendorOrgCode string, skuNameList []*partner.SkuNameInfo) []*partner.SkuNameInfo { + jdSkuIDs := make([]int64, len(skuNameList)) + for k, v := range skuNameList { + jdSkuIDs[k] = utils.Str2Int64(v.SkuList[0].VendorSkuID) + } + + imgMap := make(map[int64]*jdapi.ImgHandleQueryResult) + if imgList, err2 := getAPI(vendorOrgCode).QueryListBySkuIds(&jdapi.QueryListBySkuIdsParam{ + SkuIDs: jdSkuIDs, + }); err2 == nil { + for _, v := range imgList { + if v.ImgType == jdapi.ImgTypeMain { + imgResult := imgMap[v.SkuID] + if imgResult == nil || imgResult.IsMain < v.IsMain { + imgMap[v.SkuID] = v + } + } + } + } + + // 使用扒页面方式获取商品图片 + if false { + var leftJdSkuIDs []int64 + for _, v := range jdSkuIDs { + if imgMap[v] == nil { + leftJdSkuIDs = append(leftJdSkuIDs, v) + } + } + task := tasksch.NewParallelTask("jd setSkuNameListPic", nil, jxcontext.AdminCtx, + func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + jdSkuID := batchItemList[0].(int64) + imgList, err := getAPI(vendorOrgCode).GetSkuPageImageInfo(jdSkuID) + if err == nil && len(imgList) > 0 { + retVal = [][]string{ + []string{utils.Int64ToStr(jdSkuID), imgList[0].Big}, + } + } + return retVal, err + }, leftJdSkuIDs) + task.Run() + if resultList, err := task.GetResult(0); err == nil { + for _, v := range resultList { + strList := v.([]string) + imgMap[utils.Str2Int64(strList[0])] = &jdapi.ImgHandleQueryResult{ + SourceImgURL: strList[1], + } + } + } + } + + // 设置商品图片 + for _, v := range skuNameList { + if imgResult := imgMap[utils.Str2Int64(v.SkuList[0].VendorSkuID)]; imgResult != nil { + v.PictureList = []string{imgResult.SourceImgURL} + } + } + return skuNameList +} + +func vendorSku2Jx(vendorSku *jdapi.SkuMain) (skuName *partner.SkuNameInfo) { + prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(vendorSku.SkuName) + weight := int(vendorSku.Weight * 1000) + if weight <= 0 { + weight = jxutils.FormatSkuWeight(specQuality, specUnit) + } + skuID := int(utils.Str2Int64WithDefault(vendorSku.OutSkuID, 0)) + vendorSkuID := utils.Int64ToStr(vendorSku.SkuID) + skuName = &partner.SkuNameInfo{ + NameID: skuID, + VendorNameID: vendorSkuID, + VendorCatIDList: []string{utils.Int64ToStr(vendorSku.CategoryID)}, + + Prefix: prefix, + Name: name, + Unit: unit, + SkuList: []*partner.SkuInfo{ + &partner.SkuInfo{ + StoreSkuInfo: partner.StoreSkuInfo{ + VendorSkuID: vendorSkuID, + SkuID: skuID, + + VendorPrice: int64(vendorSku.SkuPrice), + Status: jdStatus2jxStatus(vendorSku.FixedStatus), + }, + SkuName: vendorSku.SkuName, + Comment: comment, + SpecQuality: float64(specQuality), + SpecUnit: specUnit, + Weight: weight, + }, + }, + } + return skuName +} + +func jdStatus2jxStatus(jdStatus int) (jxStatus int) { + switch jdStatus { + case jdapi.SkuFixedStatusOnline: + jxStatus = model.SkuStatusNormal + case jdapi.SkuFixedStatusOffline: + jxStatus = model.SkuStatusDontSale + case jdapi.SkuFixedStatusDeleted: + jxStatus = model.SkuStatusDeleted + } + return jxStatus +} + +func jxStatus2jdStatus(jxStatus int) (jdStatus int) { + switch jxStatus { + case model.SkuStatusNormal: + jdStatus = jdapi.SkuFixedStatusOnline + case model.SkuStatusDontSale: + jdStatus = jdapi.SkuFixedStatusOffline + case model.SkuStatusDeleted: + jdStatus = jdapi.SkuFixedStatusDeleted + } + return jdStatus +} diff --git a/business/partner/purchase/jd/sku_test.go b/business/partner/purchase/jd/sku_test.go index bbb28661b..26a23090e 100644 --- a/business/partner/purchase/jd/sku_test.go +++ b/business/partner/purchase/jd/sku_test.go @@ -45,17 +45,17 @@ func TestGetAllCategories(t *testing.T) { t.Log(utils.Format4Output(result, false)) } -func TestReadSku(t *testing.T) { - skuName, err := CurPurchaseHandler.ReadSku("2005582952") - t.Log(utils.Format4Output(skuName, false)) - if err != nil { - t.Fatal(err.Error()) - } - if skuName.Name != "味事达酱香鲜特级酿造酱油" || skuName.Skus[0].SpecUnit != "ml" { - t.Fatal("ReadSku return data wrong") - t.Log(string(utils.MustMarshal(skuName))) - } -} +// func TestReadSku(t *testing.T) { +// skuName, err := CurPurchaseHandler.ReadSku(jxcontext.AdminCtx, "", "2005582952") +// t.Log(utils.Format4Output(skuName, false)) +// if err != nil { +// t.Fatal(err.Error()) +// } +// if skuName.Name != "味事达酱香鲜特级酿造酱油" || skuName.Skus[0].SpecUnit != "ml" { +// t.Fatal("ReadSku return data wrong") +// t.Log(string(utils.MustMarshal(skuName))) +// } +// } func TestGetVendorCategories(t *testing.T) { catList, err := CurPurchaseHandler.GetVendorCategories(jxcontext.AdminCtx) @@ -66,7 +66,7 @@ func TestGetVendorCategories(t *testing.T) { } func TestGetSkus(t *testing.T) { - skuNameList, err := CurPurchaseHandler.GetSkus(jxcontext.AdminCtx, 0, "2023747677", "") + skuNameList, err := CurPurchaseHandler.GetSkus(jxcontext.AdminCtx, "", 0, "2023747677") t.Log(utils.Format4Output(skuNameList, false)) t.Log(len(skuNameList)) if err != nil { diff --git a/business/partner/purchase/jd/store.go b/business/partner/purchase/jd/store.go index 43c54fa2c..fc88d91cd 100644 --- a/business/partner/purchase/jd/store.go +++ b/business/partner/purchase/jd/store.go @@ -26,6 +26,7 @@ const ( type tJdStoreInfo struct { model.Store + VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 FreightDeductionPack string `orm:"size(32)" json:"freightDeductionPack"` // @@ -37,8 +38,15 @@ type tJdStoreInfo struct { SyncStatus int } -func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorStoreID string) (*dao.StoreDetail, error) { - result, err := getAPI("").GetStoreInfoByStationNo2(vendorStoreID) +var ( + specialDistrictMap = map[int]int{ + 13989: 310032, + } +) + +func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (*dao.StoreDetail, error) { + a := getAPI(vendorOrgCode) + result, err := a.GetStoreInfoByStationNo2(vendorStoreID) if err == nil { retVal := &dao.StoreDetail{ Store: model.Store{ @@ -74,6 +82,7 @@ func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorStoreID string if cityCode != 0 { if city, err2 := dao.GetPlaceByJdCode(db, cityCode); err2 == nil { retVal.CityCode = city.Code + retVal.CityName = utils.Interface2String(result.CityName) districtName := result.CountyName // 京东的市区号码与通用数据完全无法关联,只有通过名字来关联 if retVal.CityCode != 0 && districtName != "" { if district, err2 := dao.GetPlaceByName(db, districtName, 3, city.Code); err2 == nil { @@ -90,9 +99,9 @@ func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorStoreID string } } } - + retVal.VendorStoreID = vendorStoreID retVal.ID = int(utils.Str2Int64WithDefault(result.OutSystemID, 0)) - deliveryRange, err2 := getAPI("").GetDeliveryRangeByStationNo2(vendorStoreID) + deliveryRange, err2 := a.GetDeliveryRangeByStationNo2(vendorStoreID) if err = err2; err == nil { retVal.DeliveryRangeType = int8(deliveryRange.DeliveryRangeType) if retVal.DeliveryRangeType == model.DeliveryRangeTypePolygon { @@ -110,9 +119,11 @@ func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorStoreID string func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) { var stores []*tJdStoreInfo sql := ` - SELECT t1.*, city.jd_code jd_city_code, district.jd_code jd_district_code, - t2.status jd_store_status, t2.vendor_store_id, IF(t1.updated_at > t2.updated_at, t1.last_operator, t2.last_operator) real_last_operator, - t2.sync_status, t2.freight_deduction_pack + SELECT + t1.*, city.jd_code jd_city_code, district.jd_code jd_district_code, + t2.status jd_store_status, t2.vendor_store_id, IF(t1.updated_at > t2.updated_at, t1.last_operator, + t2.last_operator) real_last_operator, + t2.sync_status, t2.freight_deduction_pack, t2.vendor_org_code FROM store t1 JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? AND (t2.deleted_at = ?) LEFT JOIN place city ON t1.city_code = city.code @@ -122,6 +133,7 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin ` if err = dao.GetRows(db, &stores, sql, model.VendorIDJD, utils.DefaultTimeValue, storeID); err == nil { for _, store := range stores { + a := getAPI(store.VendorOrgCode) storeParams := &jdapi.OpStoreParams{ StationNo: store.VendorStoreID, Operator: userName, @@ -154,6 +166,11 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin storeParams.DeliveryRangeRadius = int(utils.Str2Int64WithDefault(store.DeliveryRange, 0)) } } + if specialDistrictMap[storeParams.County] != 0 { + storeParams.City = storeParams.County + storeParams.County = specialDistrictMap[storeParams.County] + } + modifyCloseStatus := false if store.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagDeletedMask|model.SyncFlagStoreStatus) != 0 { modifyCloseStatus = true @@ -163,7 +180,7 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin globals.SugarLogger.Debug(utils.Format4Output(storeParams, false)) errList := errlist.New() if globals.EnableJdStoreWrite { - errList.AddErr(getAPI("").UpdateStoreInfo4Open2(storeParams, modifyCloseStatus)) + errList.AddErr(a.UpdateStoreInfo4Open2(storeParams, modifyCloseStatus)) } if store.FreightDeductionPack != "" { storeDetail, err2 := dao.GetStoreDetail(db, store.ID, model.VendorIDJD) @@ -196,7 +213,7 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin freightParams.IsFullFree = len(freightParams.FreeFreightInfoList) > 0 globals.SugarLogger.Debug(utils.Format4Output(freightParams, false)) if globals.EnableJdStoreWrite { - errList.AddErr(getAPI("").UpdateStoreFreightConfigNew(freightParams)) + errList.AddErr(a.UpdateStoreFreightConfigNew(freightParams)) } } } @@ -239,7 +256,7 @@ func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask storeParams.OutSystemID = store.VendorStoreID } if globals.EnableJdStoreWrite { - err = getAPI("").UpdateStoreInfo4Open2(storeParams, false) + err = getAPI(store.VendorOrgCode).UpdateStoreInfo4Open2(storeParams, false) } return nil, err }, stores) @@ -265,8 +282,8 @@ func JdDeliveryType2Jx(deliveryType int) int8 { return scheduler.StoreDeliveryTypeByPlatform } -func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string) (storeStatus int, err error) { - result, err := getAPI("").GetStoreInfoByStationNo2(vendorStoreID) +func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) { + result, err := getAPI(vendorOrgCode).GetStoreInfoByStationNo2(vendorStoreID) if err == nil { storeStatus = JdStoreStatus2JxStatus(int(result.Yn), result.CloseStatus) } @@ -274,7 +291,7 @@ func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, storeID int, ve } // 当前京东的storeCrud消息不会在门店状态改变时发送,所以意义不大,先放在这里 -func (c *PurchaseHandler) OnStoreMsg(msg *jdapi.CallbackOrderMsg) (response *jdapi.CallbackResponse) { +func (c *PurchaseHandler) OnStoreMsg(vendorOrgCode string, msg *jdapi.CallbackOrderMsg) (response *jdapi.CallbackResponse) { var err error // if msg.StatusID == jdapi.StatusIDUpdateStore { // var storeStatus int @@ -291,15 +308,15 @@ func (c *PurchaseHandler) OnStoreMsg(msg *jdapi.CallbackOrderMsg) (response *jda return jdapi.Err2CallbackResponse(err, "") } -func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, storeID int, vendorStoreID string, isSetEnable bool) (err error) { - _, err = getAPI("").UpdateStoreConfig4Open(vendorStoreID, isSetEnable) +func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, isSetEnable bool) (err error) { + _, err = getAPI(vendorOrgCode).UpdateStoreConfig4Open(vendorStoreID, isSetEnable) return err } -func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string, status int) (err error) { +func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) { _, closeStatus := JxStoreStatus2JdStatus(status) if globals.EnableJdStoreWrite { - err = getAPI("").UpdateStoreInfo4Open2(&jdapi.OpStoreParams{ + err = getAPI(vendorOrgCode).UpdateStoreInfo4Open2(&jdapi.OpStoreParams{ StationNo: vendorStoreID, Operator: ctx.GetUserName(), CloseStatus: closeStatus, @@ -331,26 +348,30 @@ func fillOpTimeParams(params *jdapi.OpStoreParams, opTimeList []int16) { } } -func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, storeID int, vendorStoreID string, opTimeList []int16) (err error) { +func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, opTimeList []int16) (err error) { params := &jdapi.OpStoreParams{ StationNo: vendorStoreID, Operator: ctx.GetUserName(), } fillOpTimeParams(params, opTimeList) if globals.EnableJdStoreWrite { - err = getAPI("").UpdateStoreInfo4Open2(params, false) + err = getAPI(vendorOrgCode).UpdateStoreInfo4Open2(params, false) } return err } -func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context) (vendorStoreIDs []string, err error) { - vendorStoreIDs, err = getAPI("").GetStationsByVenderId() +func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) { + vendorStoreIDs, err = getAPI(vendorOrgCode).GetStationsByVenderId() return vendorStoreIDs, err } -func (c *PurchaseHandler) storeUploadImgByURL(inImgURL string) (imgURL string, err error) { +func (c *PurchaseHandler) storeUploadImgByURL(vendorOrgCode, inImgURL string) (imgURL string, err error) { if globals.EnableJdStoreWrite { - imgURL, err = api.JdPageAPI.StoreUploadImgByURL(inImgURL) + if vendorOrgCode == globals.JdOrgCode { + imgURL, err = api.JdPageAPI.StoreUploadImgByURL(inImgURL) + } else { + imgURL, err = getAPI(vendorOrgCode).StoreUploadImgByURL(inImgURL) + } } else { imgURL = utils.GetUUID() } @@ -378,7 +399,7 @@ func (c *PurchaseHandler) SyncQualify(ctx *jxcontext.Context, storeDetail *dao.S if err != nil { return err } - licenceURL, err := c.storeUploadImgByURL(storeDetail.Licence) + licenceURL, err := c.storeUploadImgByURL(storeDetail.VendorOrgCode, storeDetail.Licence) if err != nil { return err } @@ -400,7 +421,7 @@ func (c *PurchaseHandler) SyncQualify(ctx *jxcontext.Context, storeDetail *dao.S Scope: licenceDetail.Scope, }) - idFrondURL, err := c.storeUploadImgByURL(storeDetail.IDCardFront) + idFrondURL, err := c.storeUploadImgByURL(storeDetail.VendorOrgCode, storeDetail.IDCardFront) if err != nil { return addStoreInfo2Err(err, storeDetail.ID) } @@ -434,7 +455,7 @@ func (c *PurchaseHandler) SyncQualify(ctx *jxcontext.Context, storeDetail *dao.S qualifyList = append(qualifyList, addInfo) } if storeDetail.IDExpire == "" { - idBackURL, err := c.storeUploadImgByURL(storeDetail.IDCardBack) + idBackURL, err := c.storeUploadImgByURL(storeDetail.VendorOrgCode, storeDetail.IDCardBack) if err != nil { return addStoreInfo2Err(err, storeDetail.ID) } @@ -453,9 +474,9 @@ func (c *PurchaseHandler) SyncQualify(ctx *jxcontext.Context, storeDetail *dao.S return addStoreInfo2Err(err, storeDetail.ID) } -func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorStoreID string, storeID int64) (err error) { +func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string, storeID int64) (err error) { if globals.EnableJdStoreWrite { - err = getAPI("").UpdateStoreInfo4Open2( + err = getAPI(vendorOrgCode).UpdateStoreInfo4Open2( &jdapi.OpStoreParams{ StationNo: vendorStoreID, Operator: ctx.GetUserName(), diff --git a/business/partner/purchase/jd/store_sku2.go b/business/partner/purchase/jd/store_sku2.go index ef9fd0c32..1688fb913 100644 --- a/business/partner/purchase/jd/store_sku2.go +++ b/business/partner/purchase/jd/store_sku2.go @@ -20,7 +20,7 @@ func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) { return batchSize } -func (p *PurchaseHandler) getStoreSkusBareInfoLimitSize(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.StoreSkuInfo) (outStoreSkuList []*partner.StoreSkuInfo, err error) { +func (p *PurchaseHandler) getStoreSkusBareInfoLimitSize(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.StoreSkuInfo) (outStoreSkuList []*partner.StoreSkuInfo, err error) { var batchSkuInfoList []*jdapi.BaseStockCenterRequest batchSkuList := partner.BareStoreSkuInfoList(inStoreSkuList).GetVendorSkuIDIntList() for _, v := range inStoreSkuList { @@ -38,9 +38,9 @@ func (p *PurchaseHandler) getStoreSkusBareInfoLimitSize(ctx *jxcontext.Context, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { subTaskID := batchItemList[0].(int) if subTaskID == 0 { - stockInfo, err = getAPI("").QueryOpenUseable(batchSkuInfoList) + stockInfo, err = getAPI(vendorOrgCode).QueryOpenUseable(batchSkuInfoList) } else { - priceInfo, err = getAPI("").GetStationInfoList(vendorStoreID, batchSkuList) + priceInfo, err = getAPI(vendorOrgCode).GetStationInfoList(vendorStoreID, batchSkuList) } return nil, err }, []int{0, 1}) @@ -65,9 +65,9 @@ func (p *PurchaseHandler) getStoreSkusBareInfoLimitSize(ctx *jxcontext.Context, return outStoreSkuList, err } -func (p *PurchaseHandler) GetStoreSkusBareInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.StoreSkuInfo) (outStoreSkuList []*partner.StoreSkuInfo, err error) { +func (p *PurchaseHandler) GetStoreSkusBareInfo(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.StoreSkuInfo) (outStoreSkuList []*partner.StoreSkuInfo, err error) { result, err := putils.FreeBatchStoreSkuInfo("获取门店商品信息", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { - list, err := p.getStoreSkusBareInfoLimitSize(ctx, task, storeID, vendorStoreID, batchedStoreSkuList) + list, err := p.getStoreSkusBareInfoLimitSize(ctx, vendorOrgCode, task, storeID, vendorStoreID, batchedStoreSkuList) if err == nil { result = list } @@ -110,7 +110,7 @@ func getStrOutSkuIDs(l []*jdapi.StoreSkuBatchUpdateResponse, isSuccess bool) (ou return outSkuIDs } -func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) { +func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (successList []*partner.StoreSkuInfo, err error) { var skuVendibilityList []*jdapi.StockVendibility jdStatus := jxStoreSkuStatus2Jd(status) for _, v := range storeSkuList { @@ -120,7 +120,7 @@ func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, storeID }) } if globals.EnableJdStoreWrite { - responseList, err2 := getAPI("").BatchUpdateVendibility(ctx.GetTrackInfo(), "", vendorStoreID, skuVendibilityList, ctx.GetUserName()) + responseList, err2 := getAPI(vendorOrgCode).BatchUpdateVendibility(ctx.GetTrackInfo(), "", vendorStoreID, skuVendibilityList, ctx.GetUserName()) if err = err2; isErrPartialFailed(err) { failedList = putils.SelectStoreSkuListByResponseList(storeSkuList, responseList, storeID, model.VendorIDJD, "更新商品状态") // successList = putils.UnselectStoreSkuListBySkuIDs(storeSkuList, utils.StringSlice2Int(getStrOutSkuIDs(responseList, false))) @@ -129,10 +129,10 @@ func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, storeID return failedList, err } -func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { +func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { if len(storeSkuList) == 1 { if globals.EnableJdStoreWrite { - _, err = getAPI("").UpdateStationPrice(ctx.GetTrackInfo(), utils.Str2Int64WithDefault(storeSkuList[0].VendorSkuID, 0), vendorStoreID, int(storeSkuList[0].VendorPrice)) + _, err = getAPI(vendorOrgCode).UpdateStationPrice(ctx.GetTrackInfo(), utils.Str2Int64WithDefault(storeSkuList[0].VendorSkuID, 0), vendorStoreID, int(storeSkuList[0].VendorPrice)) failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorIDJD, "更新商品价格") } } else { @@ -144,7 +144,7 @@ func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, storeID i }) } if globals.EnableJdStoreWrite { - responseList, err2 := getAPI("").UpdateVendorStationPrice(ctx.GetTrackInfo(), "", vendorStoreID, skuPriceInfoList) + responseList, err2 := getAPI(vendorOrgCode).UpdateVendorStationPrice(ctx.GetTrackInfo(), "", vendorStoreID, skuPriceInfoList) if err = err2; isErrPartialFailed(err) { failedList = putils.SelectStoreSkuListByResponseList(storeSkuList, responseList, storeID, model.VendorIDJD, "更新商品价格") } @@ -153,10 +153,10 @@ func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, storeID i return failedList, err } -func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { +func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { if len(storeSkuList) == 1 { if globals.EnableJdStoreWrite { - err = getAPI("").UpdateCurrentQty(ctx.GetTrackInfo(), vendorStoreID, utils.Str2Int64WithDefault(storeSkuList[0].VendorSkuID, 0), storeSkuList[0].Stock) + err = getAPI(vendorOrgCode).UpdateCurrentQty(ctx.GetTrackInfo(), vendorStoreID, utils.Str2Int64WithDefault(storeSkuList[0].VendorSkuID, 0), storeSkuList[0].Stock) failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorIDJD, "更新商品库存") } } else { @@ -168,7 +168,7 @@ func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, storeID i }) } if globals.EnableJdStoreWrite { - responseList, err2 := getAPI("").BatchUpdateCurrentQtys(ctx.GetTrackInfo(), "", vendorStoreID, skuStockList, ctx.GetUserName()) + responseList, err2 := getAPI(vendorOrgCode).BatchUpdateCurrentQtys(ctx.GetTrackInfo(), "", vendorStoreID, skuStockList, ctx.GetUserName()) if err = err2; isErrPartialFailed(err) { failedList = putils.SelectStoreSkuListByResponseList(storeSkuList, responseList, storeID, model.VendorIDJD, "更新商品库存") // successList = putils.UnselectStoreSkuListBySkuIDs(storeSkuList, utils.StringSlice2Int(getStrOutSkuIDs(responseList, false))) @@ -178,7 +178,7 @@ func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, storeID i return failedList, err } -func (p *PurchaseHandler) SyncStoreProducts(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { +func (p *PurchaseHandler) SyncStoreProducts(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { globals.SugarLogger.Debugf("jd SyncStoreProducts, storeID:%d", storeID) db := dao.GetDB() storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJD) @@ -194,7 +194,7 @@ func (p *PurchaseHandler) SyncStoreProducts(ctx *jxcontext.Context, parentTask t storeSku := batchItemList[0].(*dao.StoreSkuSyncInfo) if storeSku.VendorSkuID != "" && storeSku.StoreSkuStatus == model.SkuStatusNormal { if globals.EnableJdStoreWrite { - synchronized, err2 := getAPI("").SyncProduct(storeDetail.VendorStoreID, storeSku.VendorSkuID) + synchronized, err2 := getAPI(vendorOrgCode).SyncProduct(storeDetail.VendorStoreID, storeSku.VendorSkuID) if err = err2; err == nil && synchronized { retVal = []int{1} } diff --git a/business/partner/purchase/jd/store_sku2_test.go b/business/partner/purchase/jd/store_sku2_test.go index a33571a08..82d780ba4 100644 --- a/business/partner/purchase/jd/store_sku2_test.go +++ b/business/partner/purchase/jd/store_sku2_test.go @@ -19,13 +19,13 @@ func TestGetStoreSkusBareInfo(t *testing.T) { // for i := 0; i < 30-1; i++ { // list = append(list, list[0]) // } - skuNameList, err := CurPurchaseHandler.GetSkus(jxcontext.AdminCtx, 0, "", "") + skuNameList, err := CurPurchaseHandler.GetSkus(jxcontext.AdminCtx, "", 0, "") if err != nil { t.Fatal(err) } list := putils.StoreSkuFullList2Bare(skuNameList) - storeSkuList, err := CurPurchaseHandler.GetStoreSkusBareInfo(jxcontext.AdminCtx, nil, 2, "11053496", list) + storeSkuList, err := CurPurchaseHandler.GetStoreSkusBareInfo(jxcontext.AdminCtx, "", nil, 2, "11053496", list) if err != nil { t.Fatal(err.Error()) } diff --git a/business/partner/purchase/jd/store_test.go b/business/partner/purchase/jd/store_test.go index ae173c9c2..255a03d90 100644 --- a/business/partner/purchase/jd/store_test.go +++ b/business/partner/purchase/jd/store_test.go @@ -17,7 +17,7 @@ const ( ) func TestReadStore(t *testing.T) { - result, err := new(PurchaseHandler).ReadStore(jxcontext.AdminCtx, TestJdStoreNo) + result, err := new(PurchaseHandler).ReadStore(jxcontext.AdminCtx, "", TestJdStoreNo) if err != nil { t.Fatal(err.Error()) } @@ -26,7 +26,7 @@ func TestReadStore(t *testing.T) { func TestUpdateStore(t *testing.T) { handler := new(PurchaseHandler) - result, err := handler.ReadStore(jxcontext.AdminCtx, TestJdStoreNo) + result, err := handler.ReadStore(jxcontext.AdminCtx, "", TestJdStoreNo) // result := &model.Store{} // result.ID = 100164 @@ -43,7 +43,7 @@ func TestUpdateStore(t *testing.T) { } // same - result, err = handler.ReadStore(jxcontext.AdminCtx, TestJdStoreNo) + result, err = handler.ReadStore(jxcontext.AdminCtx, "", TestJdStoreNo) if result.Name != newName { t.Fatalf("result is not same, desired newName:%s, newName:%s", newName, result.Name) } diff --git a/business/partner/purchase/jd/waybill.go b/business/partner/purchase/jd/waybill.go index 36805ff44..521c2a2c9 100644 --- a/business/partner/purchase/jd/waybill.go +++ b/business/partner/purchase/jd/waybill.go @@ -8,21 +8,21 @@ import ( "git.rosy.net.cn/jx-callback/business/partner" ) -func (c *PurchaseHandler) OnWaybillMsg(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) { +func (c *PurchaseHandler) OnWaybillMsg(vendorOrgCode string, msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) { jxutils.CallMsgHandler(func() { - retVal = c.onWaybillMsg(msg) + retVal = c.onWaybillMsg(vendorOrgCode, msg) }, jxutils.ComposeUniversalOrderID(msg.OrderID, model.VendorIDJD)) return retVal } -func (c *PurchaseHandler) onWaybillMsg(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) { +func (c *PurchaseHandler) onWaybillMsg(vendorOrgCode string, msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) { order := c.callbackMsg2Waybill(msg) switch msg.DeliveryStatus { case jdapi.DeliveryStatusWait4Grap: order.Status = model.WaybillStatusNew case jdapi.DeliveryStatusAccepted, jdapi.DeliveryStatusCourierChaged: // 将更换配送员也当成接单消息 // todo 性能问题,暂时取消调用 - // if result, err := getAPI("").QuerySingleOrder(msg.OrderID); err == nil { + // if result, err := getAPI(vendorOrgCode).QuerySingleOrder(msg.OrderID); err == nil { // // 默认配送费=订单应付运费(orderReceivableFreight) // //订单应付运费为未优惠前应付运费(满免优惠,运费优惠券,VIP免基础运费,用户小费)ps:用户小费是用户给配送员的小费 // order.DesiredFee = utils.Interface2Int64WithDefault(result["orderReceivableFreight"], 0) + @@ -63,6 +63,8 @@ func (c *PurchaseHandler) callbackMsg2Waybill(msg *jdapi.CallbackDeliveryStatusM VendorStatus: msg.DeliveryStatus, StatusTime: utils.Str2Time(msg.DeliveryStatusTime), Remark: msg.Remark, + + VendorOrgCode: appKey2OrgCode(msg.AppKey), } return retVal } diff --git a/business/partner/purchase/jx/jx.go b/business/partner/purchase/jx/jx.go index 42636c0dc..24dc7beeb 100644 --- a/business/partner/purchase/jx/jx.go +++ b/business/partner/purchase/jx/jx.go @@ -29,6 +29,6 @@ func (c *PurchaseHandler) GetVendorID() int { return model.VendorIDJX } -func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { +func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { return imgHint, err } diff --git a/business/partner/purchase/jx/localjx/order.go b/business/partner/purchase/jx/localjx/order.go index d774d4cca..640ec7d39 100644 --- a/business/partner/purchase/jx/localjx/order.go +++ b/business/partner/purchase/jx/localjx/order.go @@ -153,7 +153,7 @@ func CreateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64, order, err2 := jxOrder2GoodsOrder(ctx, outJxOrder, deliveryAddress) if err = err2; err == nil { order.Status = model.OrderStatusCreated - partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order)) + callNewOrder(order) } } return outJxOrder, err @@ -232,8 +232,9 @@ func OnPayFinished(orderPay *model.OrderPay) (err error) { db := dao.GetDB() dao.UpdateEntity(db, orderPay) order.Status = model.OrderStatusNew + order.VendorStatus = utils.Int2Str(model.OrderStatusNew) order.StatusTime = *orderPay.PayFinishedAt - err = partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order)) + err = callNewOrder(order) } return err } @@ -256,8 +257,8 @@ func GenOrderNo(ctx *jxcontext.Context) (orderNo int64) { func GenRefundID(order *model.GoodsOrder) (refundID int64) { const suffix = 100000 - orderID := utils.Str2Int64(order.VendorOrderID) * suffix - orderID += int64(time.Now().Sub(order.OrderFinishedAt) / time.Minute) + refundID = utils.Str2Int64(order.VendorOrderID) * suffix + refundID += int64(time.Now().Sub(order.OrderFinishedAt) / time.Minute) return refundID } @@ -314,7 +315,7 @@ func generateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64 } deliveryAddress = addressList[0] if distance := jxutils.Point2StoreDistance(deliveryAddress.Lng, deliveryAddress.Lat, storeDetail.Lng, storeDetail.Lat, storeDetail.DeliveryRangeType, storeDetail.DeliveryRange); distance == 0 { - return nil, nil, fmt.Errorf("送货地址:%s不在门店%s的配送范围", deliveryAddress.DetailAddress, storeDetail.Name) + return nil, nil, fmt.Errorf("当前送货地址不在门店%s的配送范围", storeDetail.Name) } // 营业状态及时间检查 @@ -339,94 +340,91 @@ func generateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64 return nil, nil, fmt.Errorf("门店:%s不在营业时间范围", storeDetail.Name) } - skus := formalizeSkus(jxOrder.Skus) - if len(skus) == 0 { - return nil, nil, fmt.Errorf("商品列表为空") - } - var skuIDs []int - for _, v := range skus { - skuIDs = append(skuIDs, v.SkuID) - } - - // storeSkuList, err := dao.GetStoresSkusInfo(db, []int{jxOrder.StoreID}, skuIDs) - // if err != nil { - // return nil, nil, err - // } - // storeSkuMap := make(map[int]*model.StoreSkuBind) - // for _, v := range storeSkuList { - // storeSkuMap[v.SkuID] = v - // } - storeSkuInfo, err := cms.GetStoreSkus(ctx, jxOrder.StoreID, skuIDs, true, "", true, false, map[string]interface{}{ - "actVendorID": model.VendorIDJX, - }, 0, model.UnlimitedPageSize) - if err != nil { - return nil, nil, err - } - storeSkuMap := make(map[int]*cms.StoreSkuExt) - for _, v1 := range storeSkuInfo.SkuNames { - for _, v2 := range v1.Skus { - storeSkuMap[v2.SkuID] = v2 - } - } - - skuList, err := dao.GetSkus(db, skuIDs, nil, nil, nil) - if err != nil { - return nil, nil, err - } - skuMap := make(map[int]*model.SkuAndName) - for _, v := range skuList { - skuMap[v.ID] = v - } - outJxOrder2 := *jxOrder outJxOrder2.Skus = nil outJxOrder2.OrderPrice = 0 outJxOrder2.Weight = 0 outJxOrder = &outJxOrder2 outJxOrder.StoreName = storeDetail.Name - for _, v := range skus { - if storeSkuBind := storeSkuMap[v.SkuID]; storeSkuBind != nil { - if sku := skuMap[v.SkuID]; sku != nil { - jxSku := &JxSkuInfo{ - SkuID: v.SkuID, - Price: int64(storeSkuBind.JxPrice), - Count: v.Count, - SalePrice: int64(storeSkuBind.JxPrice), // todo 考虑活动价 - Weight: sku.Weight, - Name: jxutils.ComposeSkuName(sku.Prefix, sku.Name, sku.Comment, sku.Unit, sku.SpecQuality, sku.SpecUnit, 0), - } - if storeSkuBind.ActPrice != 0 && storeSkuBind.ActPrice < storeSkuBind.JxPrice { - jxSku.SalePrice = int64(storeSkuBind.ActPrice) - jxSku.Count = 1 - outJxOrder.Skus = append(outJxOrder.Skus, jxSku) - outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice - outJxOrder.Weight += jxSku.Count * jxSku.Weight - if v.Count-1 > 0 { - jxSku2 := *jxSku - jxSku2.SalePrice = jxSku.Price - jxSku2.Count = v.Count - 1 + skus := formalizeSkus(jxOrder.Skus) + // 允许空商品列表(一般用于测试配送地址,门店信息是否合适) + if len(skus) > 0 { + var skuIDs []int + for _, v := range skus { + skuIDs = append(skuIDs, v.SkuID) + } + storeSkuInfo, err := cms.GetStoreSkus(ctx, jxOrder.StoreID, skuIDs, true, "", true, false, map[string]interface{}{ + "actVendorID": model.VendorIDJX, + }, 0, model.UnlimitedPageSize) + if err != nil { + return nil, nil, err + } + storeSkuMap := make(map[int]*dao.StoreSkuExt) + for _, v1 := range storeSkuInfo.SkuNames { + for _, v2 := range v1.Skus { + storeSkuMap[v2.SkuID] = v2 + } + } - jxSku = &jxSku2 - } else { - jxSku = nil + skuList, err := dao.GetSkus(db, skuIDs, nil, nil, nil) + if err != nil { + return nil, nil, err + } + skuMap := make(map[int]*model.SkuAndName) + for _, v := range skuList { + skuMap[v.ID] = v + } + + for _, v := range skus { + if storeSkuBind := storeSkuMap[v.SkuID]; storeSkuBind != nil { + if sku := skuMap[v.SkuID]; sku != nil { + jxSku := &JxSkuInfo{ + SkuID: v.SkuID, + Price: int64(storeSkuBind.JxPrice), + Count: v.Count, + SalePrice: int64(storeSkuBind.JxPrice), // todo 考虑活动价 + Weight: sku.Weight, + Name: jxutils.ComposeSkuName(sku.Prefix, sku.Name, sku.Comment, sku.Unit, sku.SpecQuality, sku.SpecUnit, 0), + } + if storeSkuBind.ActPrice != 0 && storeSkuBind.ActPrice < storeSkuBind.JxPrice { + jxSku.SalePrice = int64(storeSkuBind.ActPrice) + jxSku.Count = 1 + + outJxOrder.Skus = append(outJxOrder.Skus, jxSku) + outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice + outJxOrder.Weight += jxSku.Count * jxSku.Weight + if v.Count-1 > 0 { + jxSku2 := *jxSku + jxSku2.SalePrice = jxSku.Price + jxSku2.Count = v.Count - 1 + + jxSku = &jxSku2 + } else { + jxSku = nil + } + } + if jxSku != nil { + outJxOrder.Skus = append(outJxOrder.Skus, jxSku) + outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice + outJxOrder.Weight += jxSku.Count * jxSku.Weight } - } - if jxSku != nil { - outJxOrder.Skus = append(outJxOrder.Skus, jxSku) - outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice - outJxOrder.Weight += jxSku.Count * jxSku.Weight } } } - } - sort.Sort(JxSkuInfoList(outJxOrder.Skus)) - if outJxOrder.FreightPrice, _, err = delivery.CalculateDeliveryFee(dao.GetDB(), jxOrder.StoreID, "", - jxutils.StandardCoordinate2Int(deliveryAddress.Lng), jxutils.StandardCoordinate2Int(deliveryAddress.Lat), - model.CoordinateTypeMars, outJxOrder.Weight, checkTime); err == nil { + sort.Sort(JxSkuInfoList(outJxOrder.Skus)) + outJxOrder.FreightPrice, _, err = delivery.CalculateDeliveryFee(dao.GetDB(), jxOrder.StoreID, "", + jxutils.StandardCoordinate2Int(deliveryAddress.Lng), jxutils.StandardCoordinate2Int(deliveryAddress.Lat), + model.CoordinateTypeMars, outJxOrder.Weight, checkTime) + } else { outJxOrder.FreightPrice = 0 + } + if err == nil { outJxOrder.TotalPrice = outJxOrder.OrderPrice + outJxOrder.FreightPrice outJxOrder.ActualPayPrice = outJxOrder.TotalPrice + } else { + outJxOrder = nil + deliveryAddress = nil } return outJxOrder, deliveryAddress, err } @@ -514,9 +512,11 @@ func CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) if orderPay.Status == model.PayStatusYes { refundID := utils.Int64ToStr(GenRefundID(order)) orderPayRefund, err2 := refundOrderByWX(ctx, orderPay, refundID) - if err = err2; err == nil { + if err2 == nil { dao.WrapAddIDCULDEntity(orderPayRefund, ctx.GetUserName()) - errList.AddErr(dao.CreateEntity(dao.GetDB(), orderPay)) + errList.AddErr(dao.CreateEntity(dao.GetDB(), orderPayRefund)) + } else { + errList.AddErr(err2) } } else { orderPay.Status = model.PayStatusCanceled @@ -524,7 +524,9 @@ func CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) errList.AddErr(err2) } } - errList.AddErr(changeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, reason)) + if errList.GetErrListAsOne() == nil { + errList.AddErr(changeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, reason)) + } err = errList.GetErrListAsOne() } } else { @@ -533,6 +535,14 @@ func CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) return err } +// todo 消息用异步可能导致丢失,单同步又有重入相关的问题 +func callNewOrder(order *model.GoodsOrder) (err error) { + jxutils.CallMsgHandlerAsync(func() { + err = partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order)) + }, jxutils.ComposeUniversalOrderID(order.VendorOrderID, model.VendorIDJX)) + return err +} + func changeOrderStatus(vendorOrderID string, status int, remark string) (err error) { orderStatus := &model.OrderStatus{ VendorOrderID: vendorOrderID, @@ -545,7 +555,10 @@ func changeOrderStatus(vendorOrderID string, status int, remark string) (err err StatusTime: time.Now(), Remark: remark, } - return partner.CurOrderManager.OnOrderStatusChanged(orderStatus) + jxutils.CallMsgHandlerAsync(func() { + err = partner.CurOrderManager.OnOrderStatusChanged("", orderStatus) + }, jxutils.ComposeUniversalOrderID(vendorOrderID, model.VendorIDJX)) + return err } func GetOrderPay(ctx *jxcontext.Context, vendorOrderID string) (payList []*model.OrderPay, err error) { diff --git a/business/partner/purchase/jx/order.go b/business/partner/purchase/jx/order.go index 1a31217f3..5bd3086bc 100644 --- a/business/partner/purchase/jx/order.go +++ b/business/partner/purchase/jx/order.go @@ -15,7 +15,7 @@ func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo return order } -func (c *PurchaseHandler) GetOrder(orderID string) (order *model.GoodsOrder, err error) { +func (c *PurchaseHandler) GetOrder(vendorOrgCode, orderID string) (order *model.GoodsOrder, err error) { return order, err } @@ -102,7 +102,7 @@ func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.Goods return err } -func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) { +func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) { return vendorOrderIDs, err } diff --git a/business/partner/purchase/jx/order_comment.go b/business/partner/purchase/jx/order_comment.go index e417ab618..20553a214 100644 --- a/business/partner/purchase/jx/order_comment.go +++ b/business/partner/purchase/jx/order_comment.go @@ -5,6 +5,6 @@ import ( "git.rosy.net.cn/jx-callback/business/model" ) -func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, orderComment *model.OrderComment, replyComment string) (err error) { +func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) { return err } diff --git a/business/partner/purchase/jx/phpjx/order.go b/business/partner/purchase/jx/phpjx/order.go index fa079d957..c4dd0b068 100644 --- a/business/partner/purchase/jx/phpjx/order.go +++ b/business/partner/purchase/jx/phpjx/order.go @@ -41,7 +41,7 @@ func onOrderMsg(msg *CallbackMsg) (retVal, errCode string, err error) { } } else { status := callbackMsg2Status(msg) - err = partner.CurOrderManager.OnOrderStatusChanged(status) + err = partner.CurOrderManager.OnOrderStatusChanged("", status) } return retVal, errCode, err } diff --git a/business/partner/purchase/jx/phpjx/order_afs.go b/business/partner/purchase/jx/phpjx/order_afs.go index bb604c9aa..2e2fbd109 100644 --- a/business/partner/purchase/jx/phpjx/order_afs.go +++ b/business/partner/purchase/jx/phpjx/order_afs.go @@ -101,7 +101,7 @@ func onAfsOrderMsg(msg *CallbackMsg) (err error) { err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, status) } } else { - err = partner.CurOrderManager.OnOrderStatusChanged(status) + err = partner.CurOrderManager.OnOrderStatusChanged("", status) } return err } diff --git a/business/partner/purchase/jx/sku.go b/business/partner/purchase/jx/sku.go index 00a6ad887..7673a1423 100644 --- a/business/partner/purchase/jx/sku.go +++ b/business/partner/purchase/jx/sku.go @@ -4,7 +4,6 @@ package jx import ( "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" @@ -30,13 +29,29 @@ func (p *PurchaseHandler) ReorderCategories(db *dao.DaoDB, parentCatID int, user return err } +func (p *PurchaseHandler) CreateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error) { + return err +} + +func (p *PurchaseHandler) UpdateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error) { + return err +} + +func (p *PurchaseHandler) DeleteCategory2(ctx *jxcontext.Context, vendorOrgCode, vendorCatID string) (err error) { + return err +} + +func (p *PurchaseHandler) ReorderCategories2(ctx *jxcontext.Context, vendorOrgCode, vendorParentCatID string, vendorCatIDList []string) (err error) { + return err +} + func (p *PurchaseHandler) CreateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) { return err } -func (p *PurchaseHandler) ReadSku(vendorSkuID string) (skuNameExt *model.SkuNameExt, err error) { - return skuNameExt, err -} +// func (p *PurchaseHandler) ReadSku(ctx *jxcontext.Context, vendorOrgCode, vendorSkuID string) (skuNameExt *model.SkuNameExt, err error) { +// return skuNameExt, err +// } func (p *PurchaseHandler) UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) { return err @@ -46,14 +61,22 @@ func (p *PurchaseHandler) DeleteSku(db *dao.DaoDB, sku *model.Sku, userName stri return err } -func (p *PurchaseHandler) RefreshAllSkusID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) { - return hint, err +func (p *PurchaseHandler) CreateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error) { + return err +} + +func (p *PurchaseHandler) UpdateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error) { + return err +} + +func (p *PurchaseHandler) DeleteSku2(ctx *jxcontext.Context, vendorOrgCode string, sku *partner.StoreSkuInfo) (err error) { + return err } func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) { return vendorCats, err } -func (p *PurchaseHandler) GetSkus(ctx *jxcontext.Context, skuID int, vendorSkuID, skuName string) (skuNameList []*partner.SkuNameInfo, err error) { +func (p *PurchaseHandler) GetSkus(ctx *jxcontext.Context, vendorOrgCode string, skuID int, vendorSkuID string) (skuNameList []*partner.SkuNameInfo, err error) { return skuNameList, err } diff --git a/business/partner/purchase/jx/store.go b/business/partner/purchase/jx/store.go index 9b75beae0..c5b1c17d5 100644 --- a/business/partner/purchase/jx/store.go +++ b/business/partner/purchase/jx/store.go @@ -6,7 +6,7 @@ import ( "git.rosy.net.cn/jx-callback/business/model/dao" ) -func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorStoreID string) (storeDetail *dao.StoreDetail, err error) { +func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (storeDetail *dao.StoreDetail, err error) { return storeDetail, err } @@ -19,26 +19,26 @@ func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask return hint, err } -func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string) (storeStatus int, err error) { +func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) { return storeStatus, err } -func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, storeID int, vendorStoreID string, isSetEnable bool) (err error) { +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, storeID int, vendorStoreID string, status int) (err error) { +func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) { return err } -func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, storeID int, vendorStoreID string, opTimeList []int16) (err error) { +func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, opTimeList []int16) (err error) { return err } -func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context) (vendorStoreIDs []string, err error) { +func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) { return vendorStoreIDs, err } -func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorStoreID string, storeID int64) (err error) { +func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string, storeID int64) (err error) { return err } diff --git a/business/partner/purchase/jx/store_sku2.go b/business/partner/purchase/jx/store_sku2.go index c6a1ef6d3..14ddf5d9b 100644 --- a/business/partner/purchase/jx/store_sku2.go +++ b/business/partner/purchase/jx/store_sku2.go @@ -11,18 +11,18 @@ func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) { return batchSize } -func (p *PurchaseHandler) GetStoreSkusBareInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.StoreSkuInfo) (outStoreSkuList []*partner.StoreSkuInfo, err error) { +func (p *PurchaseHandler) GetStoreSkusBareInfo(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.StoreSkuInfo) (outStoreSkuList []*partner.StoreSkuInfo, err error) { return outStoreSkuList, err } -func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (successList []*partner.StoreSkuInfo, err error) { +func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (successList []*partner.StoreSkuInfo, err error) { return successList, err } -func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { +func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { return successList, err } -func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { +func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { return successList, err } diff --git a/business/partner/purchase/mtwm/mtwm.go b/business/partner/purchase/mtwm/mtwm.go index 54b9468cb..09bce7a52 100644 --- a/business/partner/purchase/mtwm/mtwm.go +++ b/business/partner/purchase/mtwm/mtwm.go @@ -168,7 +168,7 @@ func skuStatusJX2Mtwm(status int) int { return mtwmapi.SellStatusOffline } -func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { +func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { globals.SugarLogger.Debugf("mtwm UploadImg imgURL:%s, imgName:%s", imgURL, imgName) poiCode4UploadImg := p.getUploadImgPoiCode() if poiCode4UploadImg == "" { diff --git a/business/partner/purchase/mtwm/order.go b/business/partner/purchase/mtwm/order.go index f55f8be1b..9cc8fe70d 100644 --- a/business/partner/purchase/mtwm/order.go +++ b/business/partner/purchase/mtwm/order.go @@ -30,6 +30,8 @@ const ( fakeRefuseUserApplyCancel = "fake_refuse_user_apply_cancel" fakeUserUndoApplyCancel = "fake_user_undo_apply_cancel" fakeOrderAdjustFinished = "fake_order_adjust_finished" + + keyVendorOrgCode = "vendorOrgCode" ) const ( @@ -83,16 +85,17 @@ func (p *PurchaseHandler) getStatusFromVendorStatus(vendorStatus string) int { return model.OrderStatusUnknown } -func (p *PurchaseHandler) getOrder(vendorOrderID string) (order *model.GoodsOrder, orderMap map[string]interface{}, err error) { +func (p *PurchaseHandler) getOrder(vendorOrgCode, vendorOrderID string) (order *model.GoodsOrder, orderMap map[string]interface{}, err error) { result, err := api.MtwmAPI.OrderGetOrderDetail(utils.Str2Int64(vendorOrderID), true) if err == nil { + result[keyVendorOrgCode] = vendorOrgCode order = p.Map2Order(result) } return order, result, err } -func (p *PurchaseHandler) GetOrder(vendorOrderID string) (order *model.GoodsOrder, err error) { - order, _, err = p.getOrder(vendorOrderID) +func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID string) (order *model.GoodsOrder, err error) { + order, _, err = p.getOrder(vendorOrgCode, vendorOrderID) return order, err } @@ -128,6 +131,8 @@ func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo InvoiceTitle: utils.Interface2String(result["invoice_title"]), InvoiceTaxerID: utils.Interface2String(result["taxpayer_id"]), InvoiceEmail: jxutils.GetOneEmailFromStr(utils.Interface2String(result["caution"])), + + VendorOrgCode: utils.Interface2String(result[keyVendorOrgCode]), } pickType := int(utils.Interface2Int64WithDefault(result["pick_type"], 0)) if pickType == mtwmapi.OrderPickTypeSelf { @@ -289,7 +294,7 @@ func (c *PurchaseHandler) onOrderMsg(msg *mtwmapi.CallbackMsg) (response *mtwmap return nil } if msg.Cmd == mtwmapi.MsgTypeNewOrder { - order, orderMap, err2 := c.getOrder(GetOrderIDFromMsg(msg)) + order, orderMap, err2 := c.getOrder(msg.AppID, GetOrderIDFromMsg(msg)) if err = err2; err == nil { err = partner.CurOrderManager.OnOrderNew(order, c.callbackMsg2Status(msg)) if err == nil { @@ -306,7 +311,7 @@ func (c *PurchaseHandler) onOrderMsg(msg *mtwmapi.CallbackMsg) (response *mtwmap if status != nil { if status.Status == model.OrderStatusAdjust { var order *model.GoodsOrder - if order, err = c.GetOrder(GetOrderIDFromMsg(msg)); err == nil { + if order, err = c.GetOrder(msg.AppID, GetOrderIDFromMsg(msg)); err == nil { skuList, err2 := getRefundSkuDetailList(msg) if err = err2; err == nil { var removedSkuList []*model.OrderSku @@ -331,7 +336,7 @@ func (c *PurchaseHandler) onOrderMsg(msg *mtwmapi.CallbackMsg) (response *mtwmap } }) } - err = partner.CurOrderManager.OnOrderStatusChanged(status) + err = partner.CurOrderManager.OnOrderStatusChanged(msg.AppID, status) if err == nil && msg.Cmd == mtwmapi.MsgTypeOrderFinished { utils.CallFuncAsync(func() { orderMap, err := api.MtwmAPI.OrderGetOrderDetail(utils.Str2Int64(GetOrderIDFromMsg(msg)), true) @@ -568,7 +573,7 @@ func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.Goods return err } -func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) { +func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) { if utils.IsTimeZero(queryDate) { return nil, fmt.Errorf("queryDate必须指定") } @@ -576,7 +581,7 @@ func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, parentTask tasksch. var vendorStoreIDs []string if vendorStoreID == "" { - vendorStoreIDs, err = c.GetAllStoresVendorID(ctx) + vendorStoreIDs, err = c.GetAllStoresVendorID(ctx, "") if err != nil { return nil, err } diff --git a/business/partner/purchase/mtwm/order_afs.go b/business/partner/purchase/mtwm/order_afs.go index be41a9301..0aaaaf1f0 100644 --- a/business/partner/purchase/mtwm/order_afs.go +++ b/business/partner/purchase/mtwm/order_afs.go @@ -93,6 +93,7 @@ func (c *PurchaseHandler) onAfsOrderMsg(msg *mtwmapi.CallbackMsg) (retVal *mtwma ReasonImgList: utils.LimitUTF8StringLen(strings.Join(refundData.PictureList, ","), 1024), RefundType: model.AfsTypePartRefund, + VendorOrgCode: msg.AppID, // FreightUserMoney: afsInfo.OrderFreightMoney, // AfsFreightMoney: afsInfo.AfsFreight, // BoxMoney: afsInfo.PackagingMoney, diff --git a/business/partner/purchase/mtwm/order_comment.go b/business/partner/purchase/mtwm/order_comment.go index f68ab3e2d..4d3056ea5 100644 --- a/business/partner/purchase/mtwm/order_comment.go +++ b/business/partner/purchase/mtwm/order_comment.go @@ -103,7 +103,7 @@ func (c *PurchaseHandler) RefreshComment(fromTime, toTime time.Time) (err error) return err } -func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, orderComment *model.OrderComment, replyComment string) (err error) { +func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) { globals.SugarLogger.Debugf("mtwm ReplyOrderComment, orderComment:%s, replyComment:%s", utils.Format4Output(orderComment, true), replyComment) if globals.EnableMtwmStoreWrite { err = api.MtwmAPI.CommentAddReply(orderComment.VendorStoreID, utils.Str2Int64(orderComment.UserCommentID), replyComment) diff --git a/business/partner/purchase/mtwm/order_test.go b/business/partner/purchase/mtwm/order_test.go index 8e313ed81..b5a3cac58 100644 --- a/business/partner/purchase/mtwm/order_test.go +++ b/business/partner/purchase/mtwm/order_test.go @@ -11,7 +11,7 @@ import ( ) func TestGetOrder(t *testing.T) { - result, err := CurPurchaseHandler.GetOrder("33437032333978492") + result, err := CurPurchaseHandler.GetOrder("", "33437032333978492") if err != nil { t.Fatal(err) } @@ -19,7 +19,7 @@ func TestGetOrder(t *testing.T) { } func TestListOrders(t *testing.T) { - result, err := CurPurchaseHandler.ListOrders(jxcontext.AdminCtx, nil, time.Now(), "4626746") + result, err := CurPurchaseHandler.ListOrders(jxcontext.AdminCtx, "", nil, time.Now(), "4626746") if err != nil { t.Fatal(err) } diff --git a/business/partner/purchase/mtwm/store.go b/business/partner/purchase/mtwm/store.go index 7f43095f0..05de4e943 100644 --- a/business/partner/purchase/mtwm/store.go +++ b/business/partner/purchase/mtwm/store.go @@ -40,7 +40,7 @@ type tEbaiStoreInfo struct { DistrictID int `orm:"column(district_id)"` } -func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorStoreID string) (retVal *dao.StoreDetail, err error) { +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)) @@ -68,10 +68,12 @@ func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorStoreID string lat := jxutils.IntCoordinate2Standard(retVal.Lat) db := dao.GetDB() retVal.DistrictCode = api.AutonaviAPI.GetCoordinateDistrictCode(lng, lat) - if district, err := dao.GetPlaceByCode(db, retVal.DistrictCode); err == nil { - retVal.CityCode = district.ParentCode - } + 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{} @@ -135,7 +137,7 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin // 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, storeID, storeDetail.VendorStoreID, mergedStoreStatus) + // err = p.UpdateStoreStatus(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID, mergedStoreStatus) // } else { // err = nil // } @@ -143,9 +145,9 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin // errList.AddErr(err) // } if storeDetail.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreStatus) != 0 { - errList.AddErr(p.UpdateStoreStatus(jxcontext.AdminCtx, storeID, storeDetail.VendorStoreID, mergedStoreStatus)) + errList.AddErr(p.UpdateStoreStatus(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID, mergedStoreStatus)) } - errList.AddErr(p.UpdateStoreOpTime(jxcontext.AdminCtx, storeID, storeDetail.VendorStoreID, storeDetail.GetOpTimeList())) + errList.AddErr(p.UpdateStoreOpTime(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID, storeDetail.GetOpTimeList())) return errList.GetErrListAsOne() } @@ -165,7 +167,7 @@ func (p *PurchaseHandler) onStoreStatusChanged(msg *mtwmapi.CallbackMsg) (respon } else if poiStatus == mtwmapi.MsgPoiStatusOffline { storeStatus = model.StoreStatusDisabled } else { - storeStatus, err = p.GetStoreStatus(jxcontext.AdminCtx, 0, vendorStoreID) + storeStatus, err = p.GetStoreStatus(jxcontext.AdminCtx, "", 0, vendorStoreID) } if err == nil { err = partner.CurStoreManager.OnStoreStatusChanged(vendorStoreID, model.VendorIDMTWM, storeStatus) @@ -174,7 +176,7 @@ func (p *PurchaseHandler) onStoreStatusChanged(msg *mtwmapi.CallbackMsg) (respon return response } -func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string) (storeStatus int, err error) { +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 @@ -182,11 +184,11 @@ func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, storeID int, ve return 0, err } -func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, storeID int, vendorStoreID string, isSetEnable bool) (err error) { +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, storeID int, vendorStoreID string, status int) (err error) { +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 { @@ -255,7 +257,7 @@ func constrainOpTimeList(opTimeList, validOpTimeList []int16) (newOpTimeList []i return newOpTimeList } -func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, storeID int, vendorStoreID string, opTimeList []int16) (err error) { +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) @@ -272,11 +274,11 @@ func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, storeID int, return err } -func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context) (vendorStoreIDs []string, err error) { +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, vendorStoreID string, storeID int64) (err error) { +func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string, storeID int64) (err error) { return err } diff --git a/business/partner/purchase/mtwm/store_sku2.go b/business/partner/purchase/mtwm/store_sku2.go index 97d5e98ea..3b33f2c9b 100644 --- a/business/partner/purchase/mtwm/store_sku2.go +++ b/business/partner/purchase/mtwm/store_sku2.go @@ -113,7 +113,7 @@ func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID in subCatName := "" subCatCode := 0 - if storeCat.StoreCatSyncStatus&model.SyncFlagNewMask == 0 { + if storeCat.CatSyncStatus&model.SyncFlagNewMask == 0 { // 修改一级分类 originName = storeCat.VendorCatID } @@ -124,7 +124,7 @@ func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID in catCode = storeCat.ParentID subCatName = storeCat.Name subCatCode = storeCat.ID - if storeCat.StoreCatSyncStatus&model.SyncFlagNewMask == 0 { + if storeCat.CatSyncStatus&model.SyncFlagNewMask == 0 { // 修改二级分类 originName = storeCat.VendorCatID catName = storeCat.Name @@ -151,9 +151,9 @@ func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID in Sequence: storeCat.Seq, } err = api.MtwmAPI.RetailCatUpdate(vendorStoreID, catName, param4Update) - if storeCat.StoreCatSyncStatus&model.SyncFlagNewMask == 0 && // 修改分类名,但分类不存在 + if storeCat.CatSyncStatus&model.SyncFlagNewMask == 0 && // 修改分类名,但分类不存在 p.IsErrCategoryNotExist(err) && originName != "" { - storeCat.StoreCatSyncStatus |= model.SyncFlagNewMask + storeCat.CatSyncStatus |= model.SyncFlagNewMask err = p.CreateStoreCategory(ctx, storeID, vendorStoreID, storeCat) } } @@ -242,7 +242,7 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI syncType = "更新商品" } for i, storeSku := range storeSkuList { - isNeedUpdatePrice := isCreate //storeSku.StoreSkuSyncStatus&( model.SyncFlagPriceMask| model.SyncFlagNewMask) != 0 + isNeedUpdatePrice := isCreate //storeSku.SkuSyncStatus&( model.SyncFlagPriceMask| model.SyncFlagNewMask) != 0 foodData := make(map[string]interface{}) foodDataList[i] = foodData foodData[mtwmapi.KeyAppFoodCode] = utils.Int2Str(storeSku.SkuID) @@ -373,7 +373,7 @@ func storeSku2Mtwm(storeSkuList []*partner.StoreSkuInfo, updateType int) (skuLis return skuList } -func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) { +func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (successList []*partner.StoreSkuInfo, err error) { skuList := storeSku2Mtwm(storeSkuList, updateTypeStatus) mtwmStatus := skuStatusJX2Mtwm(status) if globals.EnableMtwmStoreWrite { @@ -388,7 +388,7 @@ func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, storeID return failedList, err } -func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { +func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { priceList := storeSku2Mtwm(storeSkuList, updateTypePrice) if globals.EnableMtwmStoreWrite { failedFoodList, err2 := api.MtwmAPI.RetailSkuPrice(ctx.GetTrackInfo(), vendorStoreID, priceList) @@ -401,7 +401,7 @@ func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, storeID i return failedList, err } -func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { +func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { stockList := storeSku2Mtwm(storeSkuList, updateTypeStock) if globals.EnableMtwmStoreWrite { failedFoodList, err2 := api.MtwmAPI.RetailSkuStock(ctx.GetTrackInfo(), vendorStoreID, stockList) diff --git a/business/partner/purchase/mtwm/store_sku2_test.go b/business/partner/purchase/mtwm/store_sku2_test.go index 884c24955..095fbe242 100644 --- a/business/partner/purchase/mtwm/store_sku2_test.go +++ b/business/partner/purchase/mtwm/store_sku2_test.go @@ -19,7 +19,7 @@ func TestGetStoreSkusFullInfo(t *testing.T) { } func TestGetStoreSkusBareInfo(t *testing.T) { - storeSkuList, err := CurPurchaseHandler.GetStoreSkusBareInfo(jxcontext.AdminCtx, nil, 2, "2523687", []*partner.StoreSkuInfo{ + storeSkuList, err := CurPurchaseHandler.GetStoreSkusBareInfo(jxcontext.AdminCtx, "", nil, 2, "2523687", []*partner.StoreSkuInfo{ &partner.StoreSkuInfo{ SkuID: 969, }, diff --git a/business/partner/purchase/mtwm/store_test.go b/business/partner/purchase/mtwm/store_test.go index 9ae1e40aa..daecbef8f 100644 --- a/business/partner/purchase/mtwm/store_test.go +++ b/business/partner/purchase/mtwm/store_test.go @@ -11,7 +11,7 @@ import ( ) func TestReadStore(t *testing.T) { - store, err := CurPurchaseHandler.ReadStore(jxcontext.AdminCtx, "4351018") + store, err := CurPurchaseHandler.ReadStore(jxcontext.AdminCtx, "", "4351018") if err != nil { t.Fatal(err) } diff --git a/business/partner/purchase/mtwm/waybill.go b/business/partner/purchase/mtwm/waybill.go index 4c44081a6..432e02db4 100644 --- a/business/partner/purchase/mtwm/waybill.go +++ b/business/partner/purchase/mtwm/waybill.go @@ -49,6 +49,8 @@ func (c *PurchaseHandler) callbackMsg2Waybill(msg *mtwmapi.CallbackMsg) (retVal Status: c.GetWaybillStatusFromVendorStatus(vendorStatus), StatusTime: getTimeFromTimestamp(utils.Str2Int64(msg.FormData.Get("time"))), Remark: "", + + VendorOrgCode: msg.AppID, } return retVal } diff --git a/business/partner/purchase/weimob/wsc/order.go b/business/partner/purchase/weimob/wsc/order.go index 57416ab9e..0e5967048 100644 --- a/business/partner/purchase/weimob/wsc/order.go +++ b/business/partner/purchase/weimob/wsc/order.go @@ -54,7 +54,7 @@ func (p *PurchaseHandler) onOrderMsg(msg *weimobapi.CallbackMsg) (response *weim order.StatusTime = msg.StatusTime err = partner.CurOrderManager.OnOrderNew(order, status) } else { - err = partner.CurOrderManager.OnOrderStatusChanged(status) + err = partner.CurOrderManager.OnOrderStatusChanged("", status) } } } @@ -98,7 +98,7 @@ func (p *PurchaseHandler) getStatusFromVendorStatus(vendorStatus string) int { return model.OrderStatusUnknown } -func (p *PurchaseHandler) GetOrder(vendorOrderID string) (order *model.GoodsOrder, err error) { +func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID string) (order *model.GoodsOrder, err error) { globals.SugarLogger.Debugf("wsc GetOrder orderID:%s", vendorOrderID) result, err := api.WeimobAPI.QueryOrderDetail(utils.Str2Int64(vendorOrderID), false) if err != nil { diff --git a/business/partner/purchase/weimob/wsc/order_comment.go b/business/partner/purchase/weimob/wsc/order_comment.go index 334562e53..6dce36b84 100644 --- a/business/partner/purchase/weimob/wsc/order_comment.go +++ b/business/partner/purchase/weimob/wsc/order_comment.go @@ -5,6 +5,6 @@ import ( "git.rosy.net.cn/jx-callback/business/model" ) -func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, orderComment *model.OrderComment, replyComment string) (err error) { +func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) { return err } diff --git a/business/partner/purchase/weimob/wsc/store.go b/business/partner/purchase/weimob/wsc/store.go index df548f76d..28bf44197 100644 --- a/business/partner/purchase/weimob/wsc/store.go +++ b/business/partner/purchase/weimob/wsc/store.go @@ -8,7 +8,7 @@ import ( "git.rosy.net.cn/jx-callback/business/model/dao" ) -func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorStoreID string) (*dao.StoreDetail, error) { +func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (*dao.StoreDetail, error) { return nil, errors.New("微盟微商城还没实现") } @@ -20,6 +20,6 @@ func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask return hint, err } -func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string) (storeStatus int, err error) { +func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) { return 0, err } diff --git a/business/partner/purchase/weimob/wsc/wsc.go b/business/partner/purchase/weimob/wsc/wsc.go index dc85a07a2..457b53a5b 100644 --- a/business/partner/purchase/weimob/wsc/wsc.go +++ b/business/partner/purchase/weimob/wsc/wsc.go @@ -68,7 +68,7 @@ func vendorCategoryID2String(catID int64) string { return "" } -func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { +func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { if globals.EnableWscStoreWrite { imgHint, err = api.WeimobAPI.UploadImg(imgData, imgName) } diff --git a/business/partner/putils/store_sku.go b/business/partner/putils/store_sku.go index ec57c16c3..893295781 100644 --- a/business/partner/putils/store_sku.go +++ b/business/partner/putils/store_sku.go @@ -81,7 +81,7 @@ func flatCatList(catList []*partner.BareCategoryInfo) (flattedCatList []*partner return flattedCatList } -func (p *DefSingleStorePlatform) GetStoreSkusBareInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.StoreSkuInfo) (outStoreSkuList []*partner.StoreSkuInfo, err error) { +func (p *DefSingleStorePlatform) GetStoreSkusBareInfo(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.StoreSkuInfo) (outStoreSkuList []*partner.StoreSkuInfo, err error) { resultList, err := FreeBatchStoreSkuInfo("获取门店商品信息", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { result, err = p.GetStoreSkusFullInfo(ctx, parentTask, storeID, vendorStoreID, batchedStoreSkuList) return result, successCount, err diff --git a/conf/app.conf b/conf/app.conf index c347eea59..166136d97 100644 --- a/conf/app.conf +++ b/conf/app.conf @@ -59,6 +59,8 @@ backstageHost = "http://www.jxc4.com" wxBackstageHost = "http://wx.jxc4.com" jdStorePageCookie = "OPJQMA7B3FTKCAUGO7FHCH5NMBGAWGGXYRNLEHYYZNGNPNIBCAM4IOEPG3NT3RIA44G5C3535Q5LGG4F4SR4AZVLGYKYTKFJJKEAOXENVBL5VXNILRP3GLNVVWA26XZ3VGSYOHA72RICMVZS3G53DTEH3LYUCSS54VI6WPOAGGDK532VYPEWWVCXUFRWENWDI4PEKM7SXBZ5BJO6DBLLERUA74YR2CVCGP4WUROCAHAMXKJ2VBGHTZYRL2DHR3BMXAHCTBAHYQLL24K5YI2PULRJL2UGAVD7VFRMEYTOXYHWCYVDXJ6HYFIPWIN3ULLXDDLN2ICON4GRK" +jd2StorePageCookie = "CK5GE5MR2UIOBOZC7BBZLLSI7MVDWPEQ4BRJTJQ2OP3ZFKYDDYTHXLZR3RDCQD6WXIWTDOSXTP3AQEC2D3ZS24VYF7PTTKKUKN7G4XBQS3QOBGUDNLQNEY7CLSNLWZCC7LNI6GZOWOOEN72AWG53MMCURHIQRBG7CGEGVIZQNRKV2NAWXHUA2REY6NP2B3GHPO6S4H35ST5KQXRJWL5LJSIWZHXGPYA3OGPRNAHBLVVNTQE6OL2RPMHQYNXCFMU5QQERDWPFLIWKB7W4GI7GHKLYDY" + ebaiStorePageCookieWMUSS = "B0AAFQCAAAGbhkuMCsvcyYBDkkyAxBGIBlgXAQYVwc7VwYZFkx2HDoPSmo5eV1femopWgJRawhgAALG04cg1RUmhUakBbJRdgPS0tNEhnQhNRewwuWwYYBDEFPCQSDXV5YWA6PAVRHUJ9SnVGMThYAjNjLw9pRxIbS04-XFo05AQgBl%7ERLA33vWcR73gEAKZ" ebaiStorePageCookieWMSTOKEN = "gAALgNAAAGfBI5YEBHSQdZY1InIS8CVQU9aBU1f3VLWVQqKHAAAc5LnRLZ1QLLx0S5IuzCSX8ZQ7oUwAAUr-GEm9JpRc9AQAAsLkLHHXzuhh2lZkbyrcAAAWBESKg3ZA" mtpsStoreToken = "M0p9VatZSeSHfrosD5IViAVl73IcA8mlcuHIV5sG6Zpv83a7JE0wY3t26aEhrrs_MR5gtLSFF1UIkt8HAjaXow" @@ -97,18 +99,26 @@ zhongwuAppSecret = "29435497822f52f3cf659c65da548a79" getWeixinTokenKey = "c928ed0d-87a3-441a-8517-f92f0167296f" storeName = "京西菜市" +useThingMap = true + [dev] -jdToken = "df97f334-f7d8-4b36-9664-5784d8ae0baf" -jdAppKey = "06692746f7224695ad4788ce340bc854" -jdSecret = "d6b42a35a7414a5490d811654d745c84" +jdOrgCode = "320406" +jdToken = "77e703b7-7997-441b-a12a-2e522efb117a" +jdAppKey = "1dba76d40cac446ca500c0391a0b6c9d" +jdSecret = "a88d031a1e7b462cb1579f12e97fe7f4" + +jd2OrgCode = "349454" +jd2Token = "29e0e567-c475-433a-aff0-37176ee8d8a7" +jd2AppKey = "7fb947624ff847ae94ff2f068cc99652" +jd2Secret = "1097abd7ef09427099b4922784af123a" elmIsProd = false elmToken = "2d2b583447b04b6bba5a6f3faed3559b" elmAppKey = "RwT214gAsS" elmSecret = "56afff4b9ebd8a7eb532d18fa33f17be57f9b9db" -ebaiSource = "62923" -ebaiSecret = "aa4cdc6c1108486b" +ebaiSource = "34665" +ebaiSecret = "c3db75b754ea2d89" mtpsAppKey = "25e816550bc9484480642f19a95f13fd" mtpsSecret = "r4$HqrKx9~=7?2Jfo,$Z~a7%~k!Au&pEdI2)oPJvSbH2ao@2N0[8wSIvtuumh_J^" @@ -129,10 +139,16 @@ getYLYTokenURL = "http://www.jxc4.com/v2/sys/GetYLYToken" [prod] EnableDocs = false +jdOrgCode = "320406" jdToken = "77e703b7-7997-441b-a12a-2e522efb117a" jdAppKey = "1dba76d40cac446ca500c0391a0b6c9d" jdSecret = "a88d031a1e7b462cb1579f12e97fe7f4" +jd2OrgCode = "349454" +jd2Token = "29e0e567-c475-433a-aff0-37176ee8d8a7" +jd2AppKey = "7fb947624ff847ae94ff2f068cc99652" +jd2Secret = "1097abd7ef09427099b4922784af123a" + elmIsProd = true elmToken = "" elmAppKey = "KLRDcOZGrk" @@ -178,6 +194,7 @@ EnableDocs = false dbConnectStr = "root:WebServer@1@tcp(127.0.0.1:3306)/jxgy?charset=utf8mb4&loc=Local&parseTime=true" +jdOrgCode = "339032" jdToken = "84541069-fbe2-424b-b625-9b2ba1d4c9e6" jdAppKey = "5d5577a2506f41b8b4ec520ba83490f5" jdSecret = "0b01b9eeb15b41dab1c3d05d95c17a26" @@ -229,68 +246,9 @@ getYLYTokenURL = "http://www.jxc4.com/v2/sys/GetYLYToken" storeName = "京西果园" -[jd] -httpport = 8089 -EnableDocs = false - -dbConnectStr = "root:WebServer@1@tcp(127.0.0.1:3306)/jd?charset=utf8mb4&loc=Local&parseTime=true" - -jdToken = "84541069-fbe2-424b-b625-9b2ba1d4c9e6" -jdAppKey = "5d5577a2506f41b8b4ec520ba83490f5" -jdSecret = "0b01b9eeb15b41dab1c3d05d95c17a26" -jdStorePageCookie = "YDYCWYUGKSROMV3MKJQIFINJ5CLPYH6IRVFUMFJD3JI6VQKHX3YPHTWDIDBNMCBUKSY3P7SKAHHKR7PHQDSFRXZEWXA4XOUTALIQDGDYIEUCMDPWSYGDVT42DJ27CD27QKCR3UN7KF7EPIHGPR7GCRTBD6NFNB5MFIV6EPYE6RGXH6K2VN6O67WVPV5PLGYFIAKGHFCQNCPB4GL5IIBN4ARWFQ23OEMGXQRC77UCFGE7JOWTZG2KLEWZL5JBAVSZUYFDYFEFHXZNSJPWMFCADAJTUQ" - -disableEbai = true -# ebaiSource = "35957" -# ebaiSecret = "10013fbb7c2ddad7" -# ebaiStorePageCookieWMUSS = "YBAABKPRplPSpTCX4YSUAvSg8dSjYpIwF3FzBsGEw7agNbNT90GnwfbAYdBU5cjRX%7EjwAAMxhrUGEheAUicBtSXDIeGB0hclFgZ2tcBlhhIlwwfRBHaV8pClctLEhIfSR6HDwXPC5nHBVTeBsrWjwHCjoXUCN1eS1NBKLzB9E9WREwhfALlGMDAJsPmAwAAO" -# ebaiStorePageCookieWMSTOKEN = "gAAA4OkFSZBsOayRIAnRqd24YRRVvWgRFE2w2CGtjKlAIsYg1sNHEIQlwsBKLzB5sulw9nVQAA0tyyFu-F2xVbAQAAi6OrHIFNnBwgJlQdmb8AAHssrx9_zgABBgAABQ" - -disableMtwm = true -# mtwmAppID = "4123" -# mtwmSecret = "df2c88338b85f830cebce2a9eab56628" -# mtwmCallbackURL = "http://callback-jxgy.jxc4.com" - -enableStoreWrite = true -enableJdStoreWrite = true -# enableEbaiStoreWrite = true -# enableMtwmStoreWrite = true - -disableMtps = true -# mtpsAppKey = "3c0a05d464c247c19d7ec13accc78605" -# mtpsSecret = "b1M}9?:sTbsB[OF2gNORnN(|(iy9rB8(`7]|[wGLnbmt`evfM>E:A90DjHAW:UPE" - -dadaIsProd = true -dadaCallbackURL = "http://callback-jd.jxc4.com/dadadelivery/msg" -dadaSourceID = "6660" - -weixinAppID = "wx2bb99eb5d2c9b82c" -weixinSecret = "6bbbed1443cc062c20a015a64c07a531" - -weixinMiniAppID = "wx2d6949f724b2541d" -weixinMiniSecret = "11f3c380551c4683c149990b004d6df9" - -wxpayNotifyURL = "http://callback-jd.jxc4.com/wxpay/msg/" - -backstageHost = "http://www-jd.jxc4.com" -wxBackstageHost = "http://wx-jd.jxc4.com" - -# dingdingAgentID = 258707199 -# dingdingAppKey = "dingtozhutfr98qgwc7d" -# dingdingSecret = "7EJ0HDbkxQri-O2RSaYUu7_ZwvvMKtRVHT8cpyfvIvK6A9n9HRwPNCNRJFuEDeT_" - -# dingdingQRCodeAppKey = "dingoaw990o1jm9jswvwib" -# dingdingQRCodeSecret = "N9dyC9qB84sauQPs4_JYrILMsG5Krqm9-PSSVJ8t9hb87rrHiFUirISxGF5G57RV" - -dingdingCallbackURL = "http://callback-jd.jxc4.com/dingding/msg" - -getWeixinTokenURL = "http://www.jxc4.com/v2/sys/GetWXToken" -getYLYTokenURL = "http://www.jxc4.com/v2/sys/GetYLYToken" - -storeName = "京西京东" - [test] -jdToken = "df97f334-f7d8-4b36-9664-5784d8ae0baf" +jdOrgCode = "82029" +jdToken = "594ab45a-9a73-4a43-82b0-a64cbd55d883" jdAppKey = "06692746f7224695ad4788ce340bc854" jdSecret = "d6b42a35a7414a5490d811654d745c84" @@ -318,7 +276,8 @@ dbConnectStr = "root:WebServer@1@tcp(127.0.0.1:3306)/jxd_dev_0?charset=utf8mb4&l httpport = 8088 # xiaan -jdToken = "df97f334-f7d8-4b36-9664-5784d8ae0baf" +jdOrgCode = "82029" +jdToken = "594ab45a-9a73-4a43-82b0-a64cbd55d883" jdAppKey = "06692746f7224695ad4788ce340bc854" jdSecret = "d6b42a35a7414a5490d811654d745c84" jdStorePageCookie = "5EOCZRXVCRXBTYD5EPV6FOXRCQWFFQO75FRMJ3BAKZ5JXY6XTJECMWXK5OZIPLZTUWZKZKXHXA6I7G3WMIKSWOHZIHRLNE5FZY3NBD6G5IMBOYHMJSJR3RF4TMZB2JEW2DF755YPFUSA6BMWI3KNLT3I4EAP2Z4JA6ZWAA34MNQX5P6LOI4EGG76QJU3G3VW7QFE6BAVAONMKBEHKNXNZGX3RQF7PHXDXSPJSY5XQEGM7IV2L7LKIG3M2D6QVSPEGQW4NV7SZ4TX32D2XQA7PIX46M" @@ -355,10 +314,16 @@ enableElmStoreWrite = false enableMtwmStoreWrite = false enableWscStoreWrite = false +jdOrgCode = "320406" jdToken = "77e703b7-7997-441b-a12a-2e522efb117a" jdAppKey = "1dba76d40cac446ca500c0391a0b6c9d" jdSecret = "a88d031a1e7b462cb1579f12e97fe7f4" +jd2OrgCode = "349454" +jd2Token = "29e0e567-c475-433a-aff0-37176ee8d8a7" +jd2AppKey = "7fb947624ff847ae94ff2f068cc99652" +jd2Secret = "1097abd7ef09427099b4922784af123a" + elmIsProd = true elmToken = "" elmAppKey = "KLRDcOZGrk" diff --git a/controllers/act.go b/controllers/act.go index 9163a28fb..d1f88fb30 100644 --- a/controllers/act.go +++ b/controllers/act.go @@ -68,6 +68,7 @@ func (c *ActController) PreCreateAct() { // @Param name formData string true "活动名,必须唯一(所以名子上最好带上日期)" // @Param type formData int true "活动类型,3:直降,4:秒杀(美团当前不支持秒杀)" // @Param vendorIDs formData string true "厂商ID,当前只支持,京东:0,京西(用于记录活动信息):99" +// @Param vendorOrgCode formData string false "厂商内组织代码" // @Param beginAt formData string true "开始日期" // @Param endAt formData string true "结束日期" // @Param pricePercentage formData int true "活动价格比例" @@ -104,7 +105,7 @@ func (c *ActController) CreateAct() { Advertising: params.Advertising, Remark: params.Remark, } - retVal, err = act.CreateAct(params.Ctx, actObj, vendorIDs, nil, actStoreSkuList, params.IsAsync) + retVal, err = act.CreateAct(params.Ctx, actObj, vendorIDs, params.VendorOrgCode, nil, actStoreSkuList, params.IsAsync) } } return retVal, "", err diff --git a/controllers/cms.go b/controllers/cms.go index 3d73e6e06..2e9b700fa 100644 --- a/controllers/cms.go +++ b/controllers/cms.go @@ -9,6 +9,7 @@ import ( "git.rosy.net.cn/jx-callback/business/jxutils/datares" "git.rosy.net.cn/jx-callback/business/msghub" "git.rosy.net.cn/jx-callback/globals/api" + "git.rosy.net.cn/jx-callback/globals/api/apimanager" "github.com/astaxie/beego" ) @@ -330,3 +331,16 @@ func (c *CmsController) GetCityBankBranches() { return retVal, "", err }) } + +// @Title 得到平台的账号信息 +// @Description 得到平台的账号信息 +// @Param token header string true "认证token" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /GetVendorOrgCodeInfo [get] +func (c *CmsController) GetVendorOrgCodeInfo() { + c.callGetVendorOrgCodeInfo(func(params *tCmsGetVendorOrgCodeInfoParams) (retVal interface{}, errCode string, err error) { + retVal = apimanager.GetVendorOrgCodeMap(params.Ctx) + return retVal, "", err + }) +} diff --git a/controllers/cms_sku.go b/controllers/cms_sku.go index 164d6df80..5a501f55d 100644 --- a/controllers/cms_sku.go +++ b/controllers/cms_sku.go @@ -291,20 +291,21 @@ func (c *SkuController) DeleteSkuNamePlace() { }) } -// @Title 远程查询厂商SKU信息 -// @Description 远程查询厂商SKU信息,这个是实时调用API远程查询(不推荐使用) -// @Param token header string true "认证token" -// @Param vendorSkuID query string true "sku ID" -// @Param vendorID query int true "门店所属的厂商ID" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /GetVendorSku [get] -func (c *SkuController) GetVendorSku() { - c.callGetVendorSku(func(params *tSkuGetVendorSkuParams) (retVal interface{}, errCode string, err error) { - retVal, err = cms.GetVendorSku(params.Ctx, params.VendorID, params.VendorSkuID) - return retVal, "", err - }) -} +// // @Title 远程查询厂商SKU信息 +// // @Description 远程查询厂商SKU信息,这个是实时调用API远程查询(不推荐使用) +// // @Param token header string true "认证token" +// // @Param vendorSkuID query string true "sku ID" +// // @Param vendorID query int true "门店所属的厂商ID" +// // @Param vendorOrgCode query string false "厂商内组织代码" +// // @Success 200 {object} controllers.CallResult +// // @Failure 200 {object} controllers.CallResult +// // @router /GetVendorSku [get] +// func (c *SkuController) GetVendorSku() { +// c.callGetVendorSku(func(params *tSkuGetVendorSkuParams) (retVal interface{}, errCode string, err error) { +// retVal, err = cms.GetVendorSku(params.Ctx, params.VendorID, params.VendorOrgCode, params.VendorSkuID) +// return retVal, "", err +// }) +// } // @Title 同步商家SKU // @Description 同步商家SKU diff --git a/controllers/cms_store.go b/controllers/cms_store.go index d11275fbc..b9b340768 100644 --- a/controllers/cms_store.go +++ b/controllers/cms_store.go @@ -29,7 +29,7 @@ type StoreController struct { // @Param tel query string false "电话" // @Param statuss query string false "门店状态列表[-1,0,1],(-1:禁用;0:休息,关店;1:正常开店),缺省不限制" // @Param vendorStoreCond query string false "查询关联门店的条件(如果此字段没有设置,vendorStoreConds无效),and:与,or:或,指的是vendorStoreConds里的条件间的关系,这组条件与其它条件都是与的关系" -// @Param vendorStoreConds query string false "为厂商条件对象{vendorID: cond},注意vendorID是字符串形式,cond,-1:没有关联,0:不限定,1:有关联,缺省为0" +// @Param vendorStoreConds query string false "为厂商条件对象{vendorID: cond},注意vendorID是字符串形式,cond,-1:没有关联,0:不限定,1:有关联,缺省为0,其它值表示vendorOrgCode" // @Param courierStoreCond query string false "查询关联门店的条件(如果此字段没有设置,courierStoreConds无效),and:与,or:或,指的是courierStoreConds里的条件间的关系,这组条件与其它条件都是与的关系" // @Param courierStoreConds query string false "为厂商条件对象{vendorID: cond},注意vendorID是字符串形式,cond,-1:没有关联,0:不限定,1:有关联,缺省为0" // @Param mapLongitude query string false "地图中心经度" @@ -60,12 +60,13 @@ func (c *StoreController) GetStores() { // @Param token header string true "认证token" // @Param vendorStoreID query string true "门店ID" // @Param vendorID query int true "门店所属的厂商ID" +// @Param vendorOrgCode query string false "厂商内组织代码" // @Success 200 {object} controllers.CallResult // @Failure 200 {object} controllers.CallResult // @router /GetVendorStore [get] func (c *StoreController) GetVendorStore() { c.callGetVendorStore(func(params *tStoreGetVendorStoreParams) (retVal interface{}, errCode string, err error) { - retVal, err = cms.GetVendorStore(params.Ctx, params.VendorStoreID, params.VendorID) + retVal, err = cms.GetVendorStore(params.Ctx, params.VendorID, params.VendorOrgCode, params.VendorStoreID) return retVal, "", err }) } @@ -176,6 +177,7 @@ func (c *StoreController) UpdateStoreVendorMap() { // @Param token header string true "认证token" // @Param storeID formData int true "门店ID,payload中的相应字段会被忽略" // @Param vendorID formData int true "厂商ID,payload中的相应字段会被忽略" +// @Param vendorOrgCode formData string false "厂商内组织代码" // @Param payload formData string true "json数据,storeMap对象({'vendorStoreID':'11732425','autoPickup':1,'deliveryCompetition':1, 'pricePercentage':100})" // @Success 200 {object} controllers.CallResult // @Failure 200 {object} controllers.CallResult @@ -184,7 +186,7 @@ func (c *StoreController) AddStoreVendorMap() { c.callAddStoreVendorMap(func(params *tStoreAddStoreVendorMapParams) (retVal interface{}, errCode string, err error) { storeMap := &model.StoreMap{} if err = utils.UnmarshalUseNumber([]byte(params.Payload), storeMap); err == nil { - retVal, err = cms.AddStoreVendorMap(params.Ctx, nil, params.StoreID, params.VendorID, storeMap) + retVal, err = cms.AddStoreVendorMap(params.Ctx, nil, params.VendorID, params.VendorOrgCode, params.StoreID, storeMap) } return retVal, "", err }) @@ -551,6 +553,7 @@ func (c *StoreController) GetStoreListByLocation() { // @Title 老格恢复拓店进度 // @Description 老格恢复拓店进度 // @Param token header string true "认证token" +// @Param vendorOrgCode formData string false "厂商内组织代码" // @Success 200 {object} controllers.CallResult // @Failure 200 {object} controllers.CallResult // @router /JdStoreInfoCoordinateRecover [post] @@ -558,7 +561,63 @@ func (c *StoreController) JdStoreInfoCoordinateRecover() { c.callJdStoreInfoCoordinateRecover(func(params *tStoreJdStoreInfoCoordinateRecoverParams) (retVal interface{}, errCode string, err error) { r := c.Ctx.Request files := r.MultipartForm.File["userfiles"] - err = cms.JdStoreInfoCoordinateRecover(params.Ctx, files) + err = cms.JdStoreInfoCoordinateRecover(params.Ctx, params.VendorOrgCode, files) + return retVal, "", err + }) +} + +// @Title 导出平台门店信息 +// @Description 导出平台门店信息 +// @Param token header string true "认证token" +// @Param vendorIDs formData string true "平台ID列表" +// @Param isAsync formData bool false "是否异步操作" +// @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /GetVendorStoreInfo [post] +func (c *StoreController) GetVendorStoreInfo() { + var vendorIDList []int + c.callGetVendorStoreInfo(func(params *tStoreGetVendorStoreInfoParams) (retVal interface{}, errCode string, err error) { + if err = jxutils.Strings2Objs(params.VendorIDs, &vendorIDList); err == nil { + retVal, err = cms.GetVendorStoreInfo(params.Ctx, vendorIDList, params.IsAsync, params.IsContinueWhenError) + } + return retVal, "", err + }) +} + +// @Title 查询门店价格评分 +// @Description 查询门店价格评分 +// @Param token header string true "认证token" +// @Param storeIDs formData string false "门店列表" +// @Param snapDate formData string true "时间,默认前一天(格式2006-01-02" +// @Param fromScore formData int false "分数范围开始 默认0" +// @Param toScore formData int false "分数范围结束 默认100" +// @Param sort formData int false "排序,默认降序,0为降序,1为升序" +// @Param offset formData int false "门店列表起始序号(以0开始,缺省为0)" +// @Param pageSize formData int false "门店列表页大小(缺省为50,-1表示全部)" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /GetStorePriceScore [post] +func (c *StoreController) GetStorePriceScore() { + var storeIDList []int + c.callGetStorePriceScore(func(params *tStoreGetStorePriceScoreParams) (retVal interface{}, errCode string, err error) { + if jxutils.Strings2Objs(params.StoreIDs, &storeIDList); err == nil { + retVal, err = cms.GetStorePriceScore(params.Ctx, storeIDList, params.FromScore, params.ToScore, params.Sort, params.SnapDate, params.Offset, params.PageSize) + } + return retVal, "", err + }) +} + +// @Title 生成门店价格分数表 +// @Description 生成门店价格分数表 +// @Param token header string true "认证token" +// @Param forRefresh formData bool true "是否是刷新中位价重新生成分数表" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /CreateStorePriceScore [post] +func (c *StoreController) CreateStorePriceScore() { + c.callCreateStorePriceScore(func(params *tStoreCreateStorePriceScoreParams) (retVal interface{}, errCode string, err error) { + err = cms.CreateStorePriceScore(params.Ctx, params.ForRefresh) return retVal, "", err }) } diff --git a/controllers/cms_store_sku.go b/controllers/cms_store_sku.go index 0a6857dc7..59fd3b635 100644 --- a/controllers/cms_store_sku.go +++ b/controllers/cms_store_sku.go @@ -28,7 +28,6 @@ type StoreSkuController struct { // @Param prefix query string false "商品前缀(不要求完全一致)" // @Param categoryID query int false "商品所属类别ID" // @Param unit query string false "商品单位" -// @Param jdID query int false "商品京东ID" // @Param fromStatus query int false "查询起始状态(0:不可售,1:可售)" // @Param toStatus query int false "查询结束状态(0:不可售,1:可售)" // @Param stFromTime query string false "统计SKU开始时间" @@ -69,7 +68,6 @@ func (c *StoreSkuController) GetStoreSkus() { // @Param prefix query string false "商品前缀(不要求完全一致)" // @Param categoryID query int false "商品所属类别ID" // @Param unit query string false "商品单位" -// @Param jdID query int false "商品京东ID" // @Param fromStatus query int false "查询起始状态(0:不可售,1:可售)" // @Param toStatus query int false "查询结束状态(0:不可售,1:可售)" // @Param stFromTime query string false "统计SKU开始时间" @@ -206,6 +204,7 @@ func (c *StoreSkuController) SyncStoresSkus() { // @Param token header string true "认证token" // @Param storeIDs formData string true "门店ID列表" // @Param payload formData string true "json数据,StoreSkuBindInfo对象数组" +// @Param isScale formData bool false "是否按门店结算比例缩放" // @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" // @Param isAsync formData bool false "是否异步操作" // @Success 200 {object} controllers.CallResult @@ -218,7 +217,7 @@ func (c *StoreSkuController) UpdateStoresSkus() { if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.Payload, &skuBindInfos); err != nil { return retVal, "", err } - retVal, err = cms.UpdateStoresSkus(params.Ctx, storeIDs, skuBindInfos, params.IsAsync, params.IsContinueWhenError) + retVal, err = cms.UpdateStoresSkus(params.Ctx, storeIDs, skuBindInfos, params.IsScale, params.IsAsync, params.IsContinueWhenError) return retVal, "", err }) } @@ -247,17 +246,25 @@ func (c *StoreSkuController) UpdateStoresSkusByBind() { // @Description 拷贝门店SKU信息(此函数当前只是本地数据操作,要同步到远端需要调用SyncStoresSkus) // @Param token header string true "认证token" // @Param fromStoreID formData int true "源门店ID" -// @Param toStoreID formData int true "目标门店ID" +// @Param toStoreID formData int false "目标门店ID" +// @Param toStoreIDs formData string false "目标门店ID列表" // @Param copyMode formData string true "拷贝模式,fresh:目标门店数据全部清除后拷贝,update:确保指定的源数据全部拷贝,已有的忽略" // @Param pricePercentage formData int false "价格调整百分比,缺省为100%" // @Param categoryIDs formData string false "json数据,skuName所属的类别,[1,2,3]" // @Param skuIDs formData string false "json数据,skuID列表,[1,2,3]" +// @Param isScale formData bool false "是否按门店结算比例缩放" // @Success 200 {object} controllers.CallResult // @Failure 200 {object} controllers.CallResult // @router /CopyStoreSkus [post] func (c *StoreSkuController) CopyStoreSkus() { c.callCopyStoreSkus(func(params *tStoreSkuCopyStoreSkusParams) (retVal interface{}, errCode string, err error) { - retVal, err = cms.CopyStoreSkus(params.Ctx, params.FromStoreID, params.ToStoreID, params.CopyMode, params.MapData, params.Ctx.GetUserName()) + var toStoreIDs []int + if err = jxutils.Strings2Objs(params.ToStoreIDs, &toStoreIDs); err == nil { + if params.ToStoreID > 0 { + toStoreIDs = append(toStoreIDs, params.ToStoreID) + } + retVal, err = cms.CopyStoreSkus(params.Ctx, params.FromStoreID, toStoreIDs, params.CopyMode, params.IsScale, params.MapData, params.Ctx.GetUserName()) + } return retVal, "", err }) } @@ -441,7 +448,7 @@ func (c *StoreSkuController) GetMissingStoreSkuFromOrder() { // @Title 根据门店信息查找推荐商品(按销量) // @Description 根据门店信息查找推荐商品(按销量) -// @Param token header string true "认证token" +// @Param token header string false "认证token" // @Param storeIDs query string true "门店列表" // @Success 200 {object} controllers.CallResult // @Failure 200 {object} controllers.CallResult @@ -455,3 +462,58 @@ func (c *StoreSkuController) GetTopSkusByStoreIDs() { return retVal, "", err }) } + +// @Title 根据门店信息查找推荐分类(按商品销量) +// @Description 根据门店信息查找推荐分类(按商品销量) +// @Param token header string false "认证token" +// @Param storeIDs query string true "门店列表" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /GetTopCategorysByStoreIDs [get] +func (c *StoreSkuController) GetTopCategorysByStoreIDs() { + var storeIDList []int + c.callGetTopCategorysByStoreIDs(func(params *tStoreSkuGetTopCategorysByStoreIDsParams) (retVal interface{}, errCode string, err error) { + if jxutils.Strings2Objs(params.StoreIDs, &storeIDList); err == nil { + retVal, err = cms.GetTopCategorysByStoreIDs(params.Ctx, storeIDList) + } + return retVal, "", err + }) +} + +// @Title 根据门店刷新中位价 +// @Description 根据门店刷新中位价 +// @Param token header string true "认证token" +// @Param storeIDs query string true "门店列表" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /RefershStoreSkusMidPrice [put] +func (c *StoreSkuController) RefershStoreSkusMidPrice() { + var storeIDList []int + c.callRefershStoreSkusMidPrice(func(params *tStoreSkuRefershStoreSkusMidPriceParams) (retVal interface{}, errCode string, err error) { + if jxutils.Strings2Objs(params.StoreIDs, &storeIDList); err == nil { + err = cms.RefershStoreSkusMidPrice(params.Ctx, storeIDList) + } + return retVal, "", err + }) +} + +// @Title 根据Excel刷新京西门店商品价 +// @Description 根据Excel刷新京西门店商品价 +// @Param token header string true "认证token" +// @Param storeIDs formData string true "门店列表" +// @Param isAsync formData bool true "是否异步,缺省是同步" +// @Param isContinueWhenError formData bool true "单个同步失败是否继续,缺省false" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /RefreshJxPriceByExcel [post] +func (c *StoreSkuController) RefreshJxPriceByExcel() { + var storeIDList []int + c.callRefreshJxPriceByExcel(func(params *tStoreSkuRefreshJxPriceByExcelParams) (retVal interface{}, errCode string, err error) { + if jxutils.Strings2Objs(params.StoreIDs, &storeIDList); err == nil { + r := c.Ctx.Request + files := r.MultipartForm.File["userfiles"] + retVal, err = cms.RefreshJxPriceByExcel(params.Ctx, storeIDList, files, params.IsAsync, params.IsContinueWhenError) + } + return retVal, "", err + }) +} diff --git a/controllers/cms_sync.go b/controllers/cms_sync.go index 687264cb2..fd0dd2524 100644 --- a/controllers/cms_sync.go +++ b/controllers/cms_sync.go @@ -4,7 +4,9 @@ import ( "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxstore/cms" "git.rosy.net.cn/jx-callback/business/jxutils" + "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model/dao" + "git.rosy.net.cn/jx-callback/globals" "github.com/astaxie/beego" ) @@ -87,16 +89,16 @@ func (c *SyncController) RefreshAllStoresID() { // @Success 200 {object} controllers.CallResult // @Failure 200 {object} controllers.CallResult // @router /RefreshAllSkusID [put] -func (c *SyncController) RefreshAllSkusID() { - // c.callRefreshAllSkusID(func(params *tSyncRefreshAllSkusIDParams) (retVal interface{}, errCode string, err error) { - // var vendorIDs, storeIDs []int - // if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.VendorIDs, &vendorIDs); err != nil { - // return retVal, "", err - // } - // retVal, err = cms.CurVendorSync.RefreshAllSkusID(params.Ctx, params.IsAsync, vendorIDs, storeIDs) - // return retVal, "", err - // }) -} +// func (c *SyncController) RefreshAllSkusID() { +// c.callRefreshAllSkusID(func(params *tSyncRefreshAllSkusIDParams) (retVal interface{}, errCode string, err error) { +// var vendorIDs, storeIDs []int +// if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.VendorIDs, &vendorIDs); err != nil { +// return retVal, "", err +// } +// retVal, err = cms.CurVendorSync.RefreshAllSkusID(params.Ctx, params.IsAsync, vendorIDs, storeIDs) +// return retVal, "", err +// }) +// } // @Title 全新初始化商家商品信息 // @Description 全新初始化商家商品信息(!!!此操作会先清除平台上已有的商品及分类信息),此操作只适用于单门店模式平台 @@ -115,7 +117,7 @@ func (c *SyncController) FullSyncStoresSkus() { if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.VendorIDs, &vendorIDs); err != nil { return retVal, "", err } - retVal, err = cms.CurVendorSync.FullSyncStoresSkus(params.Ctx, db, vendorIDs, storeIDs, true, params.IsAsync, params.IsContinueWhenError) + retVal, err = cms.CurVendorSync.FullSyncStoresSkus(params.Ctx, db, vendorIDs, storeIDs, true, nil, params.IsAsync, params.IsContinueWhenError) return retVal, "", err }) } @@ -142,21 +144,61 @@ func (c *SyncController) DeleteRemoteStoreSkus() { }) } -// @Title 同步SkuName(多门店平台) -// @Description 同步SkuName(多门店平台) +// @Title 同步商家分类(多门店平台) +// @Description 同步商家分类(多门店平台) // @Param token header string true "认证token" -// @Param nameIDs formData string false "name ID列表" +// @Param vendorID formData int false "平台ID(京东0 美团1 饿百3)" +// @Param vendorOrgCode formData string false "平台账号" // @Param isForce formData bool false "是否强制(设置修改标志)" // @Param isAsync formData bool false "是否异步" // @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" // @Success 200 {object} controllers.CallResult // @Failure 200 {object} controllers.CallResult -// @router /SyncSkuNames [put] +// @router /SyncCategories [post] +func (c *SyncController) SyncCategories() { + c.callSyncCategories(func(params *tSyncSyncCategoriesParams) (retVal interface{}, errCode string, err error) { + var vendorIDs []int + if params.MapData["vendorID"] != nil { + vendorIDs = append(vendorIDs, params.VendorID) + } + vendorOrgCodes := jxutils.BatchString2Slice(params.VendorOrgCode) + if params.IsForce { + dao.SetThingMapSyncStatus(dao.GetDB(), vendorIDs, vendorOrgCodes, model.ThingTypeCategory, nil, model.SyncFlagModifiedMask) + } + retVal, err = cms.SyncCategories(params.Ctx, nil, vendorIDs, vendorOrgCodes, nil, params.IsAsync) + return retVal, "", err + }) +} + +// @Title 同步SkuName(多门店平台) +// @Description 同步SkuName(多门店平台) +// @Param token header string true "认证token" +// @Param nameIDs formData string false "name ID列表" +// @Param isForce formData bool false "是否强制(设置修改标志)" +// @Param vendorID formData int false "平台ID(京东0 美团1 饿百3)" +// @Param vendorOrgCode formData string false "平台账号" +// @Param isAsync formData bool false "是否异步" +// @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /SyncSkuNames [put,post] func (c *SyncController) SyncSkuNames() { c.callSyncSkuNames(func(params *tSyncSyncSkuNamesParams) (retVal interface{}, errCode string, err error) { var nameIDs []int if err = jxutils.Strings2Objs(params.NameIDs, &nameIDs); err == nil { - retVal, err = cms.CurVendorSync.SyncSkuNames(params.Ctx, nameIDs, params.IsForce, params.IsAsync, params.IsContinueWhenError) + if globals.IsUseThingMap { + var vendorIDs []int + if params.MapData["vendorID"] != nil { + vendorIDs = append(vendorIDs, params.VendorID) + } + vendorOrgCodes := jxutils.BatchString2Slice(params.VendorOrgCode) + if params.IsForce { + dao.SetSkuNameSyncStatus(dao.GetDB(), vendorIDs, vendorOrgCodes, nameIDs, model.SyncFlagModifiedMask) + } + retVal, err = cms.SyncSkus(params.Ctx, nil, vendorIDs, vendorOrgCodes, nameIDs, nil, params.IsAsync) + } else { + retVal, err = cms.CurVendorSync.SyncSkuNames(params.Ctx, nameIDs, params.IsForce, params.IsAsync, params.IsContinueWhenError) + } } return retVal, "", err }) @@ -201,3 +243,20 @@ func (c *SyncController) AddCreateFlagForJxStoreSku() { return retVal, "", err }) } + +// @Title 初始化多门店平台商品库(及商家分类) +// @Description 初始化多门店平台商品库(及商家分类) +// @Param token header string true "认证token" +// @Param vendorID formData int true "平台ID(京东0 美团1 饿百3)" +// @Param vendorOrgCode formData string true "平台账号" +// @Param isAsync formData bool false "是否异步操作" +// @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /FullSyncVendorStuff [post] +func (c *SyncController) FullSyncVendorStuff() { + c.callFullSyncVendorStuff(func(params *tSyncFullSyncVendorStuffParams) (retVal interface{}, errCode string, err error) { + retVal, err = cms.FullSyncVendorStuff(params.Ctx, nil, params.VendorID, params.VendorOrgCode, params.IsAsync, params.IsContinueWhenError) + return retVal, "", err + }) +} diff --git a/controllers/jd_callback.go b/controllers/jd_callback.go index 60c39a6c4..73819c55f 100644 --- a/controllers/jd_callback.go +++ b/controllers/jd_callback.go @@ -5,7 +5,6 @@ import ( "fmt" "io/ioutil" "net/http" - "net/url" "git.rosy.net.cn/baseapi/platformapi/jdapi" "git.rosy.net.cn/baseapi/utils" @@ -20,13 +19,16 @@ type DjswController struct { beego.Controller } -func (c *DjswController) handleMsg(isNeedDecode bool, handler func(*jdapi.API, url.Values, string) *jdapi.CallbackResponse) (callbackResponse *jdapi.CallbackResponse) { - values, token, msgURL, callbackResponse := jdapi.GetCallbackMsg(getUsefulRequest(c.Ctx), isNeedDecode) +func (c *DjswController) handleMsg(isNeedDecode bool, handler func(*jdapi.API, interface{}) *jdapi.CallbackResponse) (callbackResponse *jdapi.CallbackResponse) { + callbackMsg, mapData, callbackResponse := jdapi.GetCallbackMsg2(getUsefulRequest(c.Ctx)) + globals.SugarLogger.Debug(utils.Format4Output(callbackMsg, true)) if callbackResponse == nil { - if jdAPI := jd.GetAPIByToken(token); jdAPI != nil { - callbackResponse = handler(jdAPI, values, msgURL) + if jdAPI := jd.GetAPIByAppKey(callbackMsg.AppKey); jdAPI != nil { + if callbackResponse = jdAPI.CheckCallbackValidation2(mapData, callbackMsg.Sign); callbackResponse == nil { + callbackResponse = handler(jdAPI, callbackMsg.Param) + } } else { - callbackResponse = jdapi.Err2CallbackResponse(fmt.Errorf("没有匹配的token,非法请求"), "") + callbackResponse = jdapi.Err2CallbackResponse(fmt.Errorf("没有匹配的appKey,非法请求"), "") } } return callbackResponse @@ -34,11 +36,8 @@ func (c *DjswController) handleMsg(isNeedDecode bool, handler func(*jdapi.API, u func (c *DjswController) orderStatus(isCancelOrder bool) { if c.Ctx.Input.Method() == http.MethodPost { - callbackResponse := c.handleMsg(isCancelOrder, func(a *jdapi.API, values url.Values, msgURL string) (callbackResponse *jdapi.CallbackResponse) { - obj, callbackResponse := a.GetOrderCallbackMsg(values, msgURL) - if callbackResponse == nil { - callbackResponse = jd.OnOrderMsg(obj) - } + callbackResponse := c.handleMsg(isCancelOrder, func(a *jdapi.API, obj interface{}) (callbackResponse *jdapi.CallbackResponse) { + callbackResponse = jd.OnOrderMsg(obj.(*jdapi.CallbackOrderMsg)) return callbackResponse }) c.Data["json"] = c.transferResponse("orderStatus", callbackResponse) @@ -90,11 +89,8 @@ func (c *DjswController) ApplyCancelOrder() { func (c *DjswController) PushDeliveryStatus() { if c.Ctx.Input.Method() == http.MethodPost { - callbackResponse := c.handleMsg(true, func(a *jdapi.API, values url.Values, msgURL string) (callbackResponse *jdapi.CallbackResponse) { - obj, callbackResponse := a.GetOrderDeliveryCallbackMsg(values, msgURL) - if callbackResponse == nil { - callbackResponse = jd.OnWaybillMsg(obj) - } + callbackResponse := c.handleMsg(true, func(a *jdapi.API, obj interface{}) (callbackResponse *jdapi.CallbackResponse) { + callbackResponse = jd.OnWaybillMsg(obj.(*jdapi.CallbackDeliveryStatusMsg)) return callbackResponse }) c.Data["json"] = c.transferResponse("PushDeliveryStatus", callbackResponse) @@ -120,11 +116,7 @@ func (c *DjswController) Token() { func (c *DjswController) StockIsHave() { // globals.SugarLogger.Info(string(c.Ctx.Input.RequestBody)) if c.Ctx.Input.Method() == http.MethodPost { - callbackResponse := c.handleMsg(true, func(a *jdapi.API, values url.Values, msgURL string) (callbackResponse *jdapi.CallbackResponse) { - _, callbackResponse = a.GetStoreStockCallbackMsg(values, msgURL) - if callbackResponse == nil { - // globals.SugarLogger.Debugf("StockIsHave, obj:%s", utils.Format4Output(obj, false)) - } + callbackResponse := c.handleMsg(true, func(a *jdapi.API, obj interface{}) (callbackResponse *jdapi.CallbackResponse) { return callbackResponse }) c.Data["json"] = c.transferResponse("StockIsHave", callbackResponse) @@ -136,11 +128,8 @@ func (c *DjswController) StockIsHave() { func (c *DjswController) SinglePromoteCreate() { if c.Ctx.Input.Method() == http.MethodPost { - callbackResponse := c.handleMsg(false, func(a *jdapi.API, values url.Values, msgURL string) (callbackResponse *jdapi.CallbackResponse) { - obj, callbackResponse := a.GetOrderCallbackMsg(values, msgURL) - if callbackResponse == nil { - callbackResponse = jd.OnActMsg(obj) - } + callbackResponse := c.handleMsg(false, func(a *jdapi.API, obj interface{}) (callbackResponse *jdapi.CallbackResponse) { + callbackResponse = jd.OnActMsg(obj.(*jdapi.CallbackOrderMsg)) return callbackResponse }) c.Data["json"] = c.transferResponse("SinglePromoteCreate", callbackResponse) @@ -152,11 +141,8 @@ func (c *DjswController) SinglePromoteCreate() { func (c *DjswController) StoreCrud() { if c.Ctx.Input.Method() == http.MethodPost { - callbackResponse := c.handleMsg(false, func(a *jdapi.API, values url.Values, msgURL string) (callbackResponse *jdapi.CallbackResponse) { - obj, callbackResponse := a.GetOrderCallbackMsg(values, msgURL) - if callbackResponse == nil { - callbackResponse = jd.OnStoreMsg(obj) - } + callbackResponse := c.handleMsg(false, func(a *jdapi.API, obj interface{}) (callbackResponse *jdapi.CallbackResponse) { + callbackResponse = jd.OnStoreMsg(obj.(*jdapi.CallbackOrderMsg)) return callbackResponse }) c.Data["json"] = c.transferResponse("StoreCrud", callbackResponse) @@ -218,3 +204,7 @@ func (c *DjswController) nullOperation() { c.Data["json"] = c.transferResponse("nullOperation", nil) c.ServeJSON() } + +func (c *DjswController) UpdateSku() { + c.nullOperation() +} diff --git a/controllers/jx_order.go b/controllers/jx_order.go index 0d9ca9227..964fc08a4 100644 --- a/controllers/jx_order.go +++ b/controllers/jx_order.go @@ -759,9 +759,9 @@ func (c *OrderController) RefreshHistoryOrdersEarningPrice() { c.callRefreshHistoryOrdersEarningPrice(func(params *tOrderRefreshHistoryOrdersEarningPriceParams) (retVal interface{}, errCode string, err error) { var vendorIDList []int if err = jxutils.Strings2Objs(params.VendorIDs, &vendorIDList); err == nil { - retVal, err = orderman.FixedOrderManager.RefreshHistoryOrdersEarningPrice(params.Ctx, params.VendorOrderID, params.ActID, vendorIDList, params.StoreID, params.FromTime, params.ToTime, params.IsAsync, params.IsContinueWhenError) + retVal, errCode, err = orderman.FixedOrderManager.RefreshHistoryOrdersEarningPrice(params.Ctx, params.VendorOrderID, params.ActID, vendorIDList, params.StoreID, params.FromTime, params.ToTime, params.IsAsync, params.IsContinueWhenError) } - return retVal, "", err + return retVal, errCode, err }) } diff --git a/controllers/jx_report.go b/controllers/jx_report.go index f839a14cc..f604dbfc9 100644 --- a/controllers/jx_report.go +++ b/controllers/jx_report.go @@ -48,3 +48,37 @@ func (c *ReportController) StatisticsReportForAfsOrders() { return retVal, "", err }) } + +// @Title 查询京西门店商品价格统计相关信息 +// @Description 查询京西门店商品价格统计相关信息 +// @Param token header string true "认证token" +// @Param cityCodes formData string true "城市ID列表[1,2,3]" +// @Param skuIDs formData string false "skuID列表[1,2,3]" +// @Param snapDate formData string true "某天的参考价格 格式:2006-01-02,默认前一天" +// @Param offset formData int false "门店列表起始序号(以0开始,缺省为0)" +// @Param pageSize formData int false "门店列表页大小(缺省为50,-1表示全部)" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /StatisticsReportForStoreSkusPrice [post] +func (c *ReportController) StatisticsReportForStoreSkusPrice() { + c.callStatisticsReportForStoreSkusPrice(func(params *tReportStatisticsReportForStoreSkusPriceParams) (retVal interface{}, errCode string, err error) { + var cityCodeList, skuIDList []int + if err = jxutils.Strings2Objs(params.CityCodes, &cityCodeList, params.SkuIDs, &skuIDList); err == nil { + retVal, err = report.StatisticsReportForStoreSkusPrice(params.Ctx, cityCodeList, skuIDList, params.SnapDate, params.Offset, params.PageSize) + } + return retVal, "", err + }) +} + +// @Title 生成价格参考数据 +// @Description 生成价格参考数据 +// @Param token header string true "认证token" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /PriceRefer [post] +func (c *ReportController) PriceRefer() { + c.callPriceRefer(func(params *tReportPriceReferParams) (retVal interface{}, errCode string, err error) { + report.BeginSavePriceRefer(params.Ctx, nil, nil) + return retVal, "", err + }) +} diff --git a/globals/api/api.go b/globals/api/api.go index 10a651d4f..9ab7e5b4c 100644 --- a/globals/api/api.go +++ b/globals/api/api.go @@ -32,8 +32,11 @@ import ( ) var ( - JdAPI *jdapi.API - JdPageAPI *jdapi.API + JdAPI *jdapi.API + JdPageAPI *jdapi.API + + Jd2API *jdapi.API + ElmAPI *elmapi.API EbaiAPI *ebaiapi.API MtwmAPI *mtwmapi.API @@ -79,6 +82,11 @@ func Init() { conf := platformapi.NewDefAPIConfig() conf.MaxSleepSecondWhenExceedLimit = 60 * 30 // 最大重试间隙30分钟 JdPageAPI = jdapi.NewPageOnly(cookieValue, conf) + + if globals.Jd2OrgCode != "" { + Jd2API = jdapi.New(beego.AppConfig.String("jd2Token"), beego.AppConfig.String("jd2AppKey"), beego.AppConfig.String("jd2Secret")) + Jd2API.SetJdCookie(beego.AppConfig.DefaultString("jd2StorePageCookie", "")) + } } else { JdAPI = nil } diff --git a/globals/api/apimanager/apimanager.go b/globals/api/apimanager/apimanager.go index 6e62c34b6..9f6c11e87 100644 --- a/globals/api/apimanager/apimanager.go +++ b/globals/api/apimanager/apimanager.go @@ -2,6 +2,7 @@ package apimanager import ( "git.rosy.net.cn/jx-callback/business/jxutils" + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/globals" @@ -30,6 +31,9 @@ func (a *APIManager) GetAPI(vendorID int, appOrgCode string) (pfAPI interface{}) switch vendorID { case model.VendorIDJD: pfAPI = api.JdAPI + if appOrgCode != "" && appOrgCode == globals.Jd2OrgCode { + pfAPI = api.Jd2API + } case model.VendorIDMTWM: pfAPI = api.MtwmAPI case model.VendorIDEBAI: @@ -38,12 +42,15 @@ func (a *APIManager) GetAPI(vendorID int, appOrgCode string) (pfAPI interface{}) return pfAPI } +// TODO func (a *APIManager) GetAppOrgCodeList(vendorID int) (appOrgCodeList []string) { switch vendorID { case model.VendorIDJD: - appOrgCodeList = []string{"320406"} + appOrgCodeList = jxutils.BatchString2Slice(globals.JdOrgCode, globals.Jd2OrgCode) case model.VendorIDMTWM: + appOrgCodeList = []string{api.MtwmAPI.GetAppID()} case model.VendorIDEBAI: + appOrgCodeList = []string{api.EbaiAPI.GetSource()} } return appOrgCodeList } @@ -66,3 +73,11 @@ func (a *APIManager) GetVendorOrgCodeList(vendorIDs []int, appOrgCodes []string) } return vendorOrgCodeList } + +func GetVendorOrgCodeMap(ctx *jxcontext.Context) (vendorOrgCodeMap map[int][]string) { + vendorOrgCodeMap = make(map[int][]string) + for _, vendorID := range partner.GetPurchasePlatformVendorIDs() { + vendorOrgCodeMap[vendorID] = CurAPIManager.GetAppOrgCodeList(vendorID) + } + return vendorOrgCodeMap +} diff --git a/globals/beegodb/beegodb.go b/globals/beegodb/beegodb.go index 28b108a3b..6ac7d068d 100644 --- a/globals/beegodb/beegodb.go +++ b/globals/beegodb/beegodb.go @@ -32,12 +32,15 @@ func Init() { orm.RegisterModel(&model.Store{}, &model.StoreSub{}, &model.StoreMap{}, &model.StoreCourierMap{}) orm.RegisterModel(&model.SkuVendorCategory{}, &model.StoreSkuCategoryMap{}, &model.SkuName{}, &model.Sku{}, &model.SkuNamePlaceBind{}, &model.StoreSkuBind{}) orm.RegisterModel(&model.SkuCategory{}) - // orm.RegisterModel(&model.ThingMap{}) + orm.RegisterModel(&model.ThingMap{}) orm.RegisterModel(&model.AuthBind{}, &model.User{}) orm.RegisterModel(&model.PageShop{}) orm.RegisterModel(&model.VendorStoreSnapshot{}) + orm.RegisterModel(&model.PriceReferSnapshot{}) + orm.RegisterModel(&model.StorePriceScoreSnapshot{}) + orm.RegisterModel(&model.StoreSkuNamePrice{}) // orm.RegisterModel(&model.ActivityForSku{}) // orm.RegisterModel(&legacymodel.JxBadComments2{}) @@ -61,7 +64,7 @@ func Init() { orm.RegisterModel(&model.UserDeliveryAddress{}) orm.RegisterModel(&model.UserCartItem{}) - orm.RegisterModel(&model.OrderPay{}) + orm.RegisterModel(&model.OrderPay{}, &model.OrderPayRefund{}) // create table orm.RunSyncdb("default", false, true) } diff --git a/globals/globals.go b/globals/globals.go index c2a846da6..17727ac4f 100644 --- a/globals/globals.go +++ b/globals/globals.go @@ -49,6 +49,11 @@ var ( DisableWXAuth1 bool WxpayNotifyURL string + + JdOrgCode string + Jd2OrgCode string + + IsUseThingMap bool ) func init() { @@ -96,6 +101,10 @@ func Init() { DisableWXAuth1 = true WxpayNotifyURL = beego.AppConfig.DefaultString("wxpayNotifyURL", "") + JdOrgCode = beego.AppConfig.DefaultString("jdOrgCode", "") + Jd2OrgCode = beego.AppConfig.DefaultString("jd2OrgCode", "") + + IsUseThingMap = beego.AppConfig.DefaultBool("useThingMap", false) } func IsCallbackAlwaysReturnSuccess() bool { diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index 1abd060ff..2f9319078 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -304,6 +304,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"], + beego.ControllerComments{ + Method: "GetVendorOrgCodeInfo", + Router: `/GetVendorOrgCodeInfo`, + AllowHTTPMethods: []string{"get"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:CmsController"], beego.ControllerComments{ Method: "NewConfig", @@ -1044,6 +1053,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:ReportController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:ReportController"], + beego.ControllerComments{ + Method: "PriceRefer", + Router: `/PriceRefer`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:ReportController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:ReportController"], beego.ControllerComments{ Method: "StatisticsReportForAfsOrders", @@ -1062,6 +1080,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:ReportController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:ReportController"], + beego.ControllerComments{ + Method: "StatisticsReportForStoreSkusPrice", + Router: `/StatisticsReportForStoreSkusPrice`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"], beego.ControllerComments{ Method: "AddCategory", @@ -1179,15 +1206,6 @@ func init() { Filters: nil, Params: nil}) - beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"], - beego.ControllerComments{ - Method: "GetVendorSku", - Router: `/GetVendorSku`, - AllowHTTPMethods: []string{"get"}, - MethodParams: param.Make(), - Filters: nil, - Params: nil}) - beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"], beego.ControllerComments{ Method: "ReorderCategories", @@ -1287,6 +1305,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"], + beego.ControllerComments{ + Method: "CreateStorePriceScore", + Router: `/CreateStorePriceScore`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"], beego.ControllerComments{ Method: "DeleteStore", @@ -1368,6 +1395,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"], + beego.ControllerComments{ + Method: "GetStorePriceScore", + Router: `/GetStorePriceScore`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"], beego.ControllerComments{ Method: "GetStoreTotalScoreList", @@ -1404,6 +1440,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"], + beego.ControllerComments{ + Method: "GetVendorStoreInfo", + Router: `/GetVendorStoreInfo`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"], beego.ControllerComments{ Method: "GetWeeklyStoreScore", @@ -1566,6 +1611,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"], + beego.ControllerComments{ + Method: "GetTopCategorysByStoreIDs", + Router: `/GetTopCategorysByStoreIDs`, + AllowHTTPMethods: []string{"get"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"], beego.ControllerComments{ Method: "GetTopSkusByStoreIDs", @@ -1584,6 +1638,24 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"], + beego.ControllerComments{ + Method: "RefershStoreSkusMidPrice", + Router: `/RefershStoreSkusMidPrice`, + AllowHTTPMethods: []string{"put"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"], + beego.ControllerComments{ + Method: "RefreshJxPriceByExcel", + Router: `/RefreshJxPriceByExcel`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreSkuController"], beego.ControllerComments{ Method: "RefreshStoresSkuByVendor", @@ -1685,18 +1757,18 @@ func init() { beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SyncController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SyncController"], beego.ControllerComments{ - Method: "PruneMissingStoreSkus", - Router: `/PruneMissingStoreSkus`, - AllowHTTPMethods: []string{"delete"}, + Method: "FullSyncVendorStuff", + Router: `/FullSyncVendorStuff`, + AllowHTTPMethods: []string{"post"}, MethodParams: param.Make(), Filters: nil, Params: nil}) beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SyncController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SyncController"], beego.ControllerComments{ - Method: "RefreshAllSkusID", - Router: `/RefreshAllSkusID`, - AllowHTTPMethods: []string{"put"}, + Method: "PruneMissingStoreSkus", + Router: `/PruneMissingStoreSkus`, + AllowHTTPMethods: []string{"delete"}, MethodParams: param.Make(), Filters: nil, Params: nil}) @@ -1710,11 +1782,20 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SyncController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SyncController"], + beego.ControllerComments{ + Method: "SyncCategories", + Router: `/SyncCategories`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SyncController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SyncController"], beego.ControllerComments{ Method: "SyncSkuNames", Router: `/SyncSkuNames`, - AllowHTTPMethods: []string{"put"}, + AllowHTTPMethods: []string{"put","post"}, MethodParams: param.Make(), Filters: nil, Params: nil})