mergemark
This commit is contained in:
@@ -72,6 +72,7 @@ func (a *MiniAuther) DecryptData(authInfo *auth2.AuthInfo, jsCode, encryptedData
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
authInfo.AuthBindInfo.UserData = sessionKey
|
||||
return string(decryptedData), nil
|
||||
}
|
||||
|
||||
|
||||
@@ -303,7 +303,7 @@ func (c *OrderManager) SaveOrder(order *model.GoodsOrder, isAdjust bool, db *dao
|
||||
return isDuplicated, err
|
||||
}
|
||||
|
||||
func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.DaoDB, storePayPercentage int) (err error) {
|
||||
func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.DaoDB, storePayPercentage, changePriceType int) (err error) {
|
||||
globals.SugarLogger.Debugf("updateOrderSkuOtherInfo orderID:%s, VendorStoreID:%s", order.VendorOrderID, order.VendorStoreID)
|
||||
jxStoreID := jxutils.GetShowStoreIDFromOrder(order)
|
||||
var opNumStr string
|
||||
@@ -372,9 +372,17 @@ func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.
|
||||
}
|
||||
}
|
||||
}
|
||||
v.EarningPrice = jxutils.CaculateSkuEarningPrice(v.ShopPrice, v.SalePrice, storePayPercentage)
|
||||
// 直营店始终按比例结算,不考虑活动与结算表
|
||||
salePrice := v.SalePrice
|
||||
if changePriceType == model.StoreChangePriceTypeManagedStore && v.ShopPrice != 0 {
|
||||
salePrice = 0
|
||||
}
|
||||
v.EarningPrice = jxutils.CaculateSkuEarningPrice(v.ShopPrice, salePrice, storePayPercentage)
|
||||
}
|
||||
// 直营店始终按比例结算,不考虑活动与结算表
|
||||
if changePriceType != model.StoreChangePriceTypeManagedStore {
|
||||
updateSingleOrderEarningPrice(order, db)
|
||||
}
|
||||
updateSingleOrderEarningPrice(order, db)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -409,6 +417,7 @@ func (c *OrderManager) updateOrderOtherInfo(order *model.GoodsOrder, db *dao.Dao
|
||||
globals.SugarLogger.Debugf("updateOrderOtherInfo orderID:%s, VendorStoreID:%s", order.VendorOrderID, order.VendorStoreID)
|
||||
|
||||
payPercentage := 0
|
||||
changePriceType := model.StoreChangePriceTypeDirect
|
||||
storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, order.VendorStoreID, order.VendorID)
|
||||
if err != nil {
|
||||
if !dao.IsNoRowsError(err) {
|
||||
@@ -422,8 +431,9 @@ func (c *OrderManager) updateOrderOtherInfo(order *model.GoodsOrder, db *dao.Dao
|
||||
} else {
|
||||
order.JxStoreID = storeDetail.Store.ID
|
||||
payPercentage = storeDetail.PayPercentage
|
||||
changePriceType = int(storeDetail.ChangePriceType)
|
||||
}
|
||||
if err = c.updateOrderSkuOtherInfo(order, db, payPercentage); err == nil {
|
||||
if err = c.updateOrderSkuOtherInfo(order, db, payPercentage, changePriceType); err == nil {
|
||||
jxutils.RefreshOrderSkuRelated(order)
|
||||
// caculateOrderEarningPrice(order, payPercentage)
|
||||
}
|
||||
@@ -454,6 +464,11 @@ func (c *OrderManager) addOrderStatus(orderStatus *model.OrderStatus, db *dao.Da
|
||||
VendorID: orderStatus.VendorID,
|
||||
}
|
||||
if err = db.Db.ReadForUpdate(order, "VendorOrderID", "VendorID"); err == nil {
|
||||
// todo 美团在订单完成后,还可能收到订单取消(应该当成售后单处理才合适),强制忽略这种情况,比如订单:80662201436073600
|
||||
// 后来又发现有订单(81710104014426376)在完成后,直接再被取消的情况,不能生成售后单,还是再允许完成后取消。。。
|
||||
// if orderStatus.VendorID == model.VendorIDMTWM && model.IsOrderFinalStatus(order.Status) {
|
||||
// return false, order, nil
|
||||
// }
|
||||
if (model.IsOrderLockStatus(orderStatus.Status) || model.IsOrderUnlockStatus(orderStatus.Status)) ||
|
||||
(model.IsOrderMainStatus(orderStatus.Status) && orderStatus.Status >= order.Status) { // todo 要求status不能回绕
|
||||
order.VendorStatus = orderStatus.VendorStatus
|
||||
|
||||
@@ -63,6 +63,15 @@ var (
|
||||
FixedScheduler *DefScheduler
|
||||
)
|
||||
|
||||
type tTimerInfo struct {
|
||||
statusType int
|
||||
vendorID int
|
||||
status int
|
||||
|
||||
timer *time.Timer
|
||||
timerTime time.Time
|
||||
}
|
||||
|
||||
type WatchOrderInfo struct {
|
||||
order *model.GoodsOrder // order里的信息是保持更新的
|
||||
|
||||
@@ -74,10 +83,12 @@ type WatchOrderInfo struct {
|
||||
|
||||
waybills map[int]*model.Waybill // 这个waybills里的状态信息是不真实的,只使用id相关的信息
|
||||
|
||||
timerStatusType int // 0表示订单,1表示运单
|
||||
timerStatus int
|
||||
timer *time.Timer
|
||||
timerTime time.Time
|
||||
// timerStatusType int // 0表示订单,1表示运单
|
||||
// timerStatus int
|
||||
// timer *time.Timer
|
||||
// timerTime time.Time
|
||||
|
||||
timerList []*tTimerInfo
|
||||
|
||||
retryCount int // 失败后尝试的次数,调试阶段可能出现死循化,阻止这种情况发生
|
||||
}
|
||||
@@ -88,6 +99,14 @@ type StatusActionConfig struct {
|
||||
ShouldSetTimer func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) bool
|
||||
}
|
||||
|
||||
func (c *StatusActionConfig) CallTimeoutAction(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) (err error) {
|
||||
if c.TimeoutAction != nil &&
|
||||
c.CallShouldSetTimer(savedOrderInfo, bill) {
|
||||
err = c.TimeoutAction(savedOrderInfo, bill)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *StatusActionConfig) CallShouldSetTimer(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) bool {
|
||||
if c.ShouldSetTimer != nil {
|
||||
return c.ShouldSetTimer(savedOrderInfo, bill)
|
||||
@@ -145,6 +164,40 @@ func (s *WatchOrderInfo) GetWaybillVendorIDs() (vendorIDs []int) {
|
||||
return vendorIDs
|
||||
}
|
||||
|
||||
// orderType,-1:全部
|
||||
// vendorID,-1:全部
|
||||
// status,-1:全部
|
||||
func (w *WatchOrderInfo) StopTimer(statusType, vendorID, status int) {
|
||||
var newTimerList []*tTimerInfo
|
||||
for _, timerInfo := range w.timerList {
|
||||
if (statusType == -1 || statusType == timerInfo.statusType) &&
|
||||
(vendorID == -1 || vendorID == timerInfo.vendorID) &&
|
||||
(status == -1 || status <= timerInfo.status) {
|
||||
if timerInfo.timer != nil {
|
||||
timerInfo.timer.Stop()
|
||||
timerInfo.timer = nil
|
||||
}
|
||||
} else {
|
||||
newTimerList = append(newTimerList, timerInfo)
|
||||
}
|
||||
}
|
||||
w.timerList = newTimerList
|
||||
}
|
||||
|
||||
func (w *WatchOrderInfo) GetCreateWaybillTimeout() (timeoutSecond int) {
|
||||
// if w.timerStatusType == scheduler.TimerStatusTypeWaybill && w.timerStatus == model.WaybillStatusNew {
|
||||
// timeoutSecond = int(w.timerTime.Sub(time.Now()) / time.Second)
|
||||
// }
|
||||
for _, timerInfo := range w.timerList {
|
||||
if timerInfo.statusType == scheduler.TimerStatusTypeWaybill &&
|
||||
timerInfo.status == model.WaybillStatusNew {
|
||||
timeoutSecond = int(timerInfo.timerTime.Sub(time.Now()) / time.Second)
|
||||
break
|
||||
}
|
||||
}
|
||||
return timeoutSecond
|
||||
}
|
||||
|
||||
func init() {
|
||||
sch := &DefScheduler{}
|
||||
basesch.FixedBaseScheduler = &sch.BaseScheduler
|
||||
@@ -159,41 +212,39 @@ func init() {
|
||||
Timeout: 10 * time.Millisecond,
|
||||
},
|
||||
TimeoutAction: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) (err error) {
|
||||
if savedOrderInfo.order.LockStatus == model.LockStatusUnlocked && savedOrderInfo.order.Status == model.OrderStatusNew {
|
||||
order := savedOrderInfo.order
|
||||
mobile := order.ConsigneeMobile
|
||||
if order.ConsigneeMobile2 != "" {
|
||||
mobile = order.ConsigneeMobile2
|
||||
}
|
||||
_ = sch.handleAutoAcceptOrder(order.VendorOrderID, order.VendorID, mobile, jxutils.GetSaleStoreIDFromOrder(order), nil, func(isAcceptIt bool) error {
|
||||
if err = sch.AcceptOrRefuseOrder(order, isAcceptIt, ""); err != nil && err != scheduler.ErrOrderStatusAlreadySatisfyCurOperation {
|
||||
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.Status > order.Status {
|
||||
order.Status = order2.Status
|
||||
jxutils.CallMsgHandlerAsync(func() {
|
||||
sch.OnOrderStatusChanged(order, model.Order2Status(order2), false)
|
||||
}, jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID))
|
||||
err = nil
|
||||
}
|
||||
} else {
|
||||
err = err2
|
||||
}
|
||||
}
|
||||
}
|
||||
if isAcceptIt {
|
||||
if err == nil {
|
||||
sch.notifyNewOrder(order)
|
||||
msghub.OnNewOrder(order)
|
||||
}
|
||||
} else {
|
||||
partner.CurOrderManager.OnOrderMsg(order, "黑名单拒单", "")
|
||||
}
|
||||
return err
|
||||
})
|
||||
order := savedOrderInfo.order
|
||||
mobile := order.ConsigneeMobile
|
||||
if order.ConsigneeMobile2 != "" {
|
||||
mobile = order.ConsigneeMobile2
|
||||
}
|
||||
_ = sch.handleAutoAcceptOrder(order.VendorOrderID, order.VendorID, mobile, jxutils.GetSaleStoreIDFromOrder(order), nil, func(isAcceptIt bool) error {
|
||||
if err = sch.AcceptOrRefuseOrder(order, isAcceptIt, ""); err != nil && err != scheduler.ErrOrderStatusAlreadySatisfyCurOperation {
|
||||
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.Status > order.Status {
|
||||
order.Status = order2.Status
|
||||
jxutils.CallMsgHandlerAsync(func() {
|
||||
sch.OnOrderStatusChanged(order, model.Order2Status(order2), false)
|
||||
}, jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID))
|
||||
err = nil
|
||||
}
|
||||
} else {
|
||||
err = err2
|
||||
}
|
||||
}
|
||||
}
|
||||
if isAcceptIt {
|
||||
if err == nil {
|
||||
sch.notifyNewOrder(order)
|
||||
msghub.OnNewOrder(order)
|
||||
}
|
||||
} else {
|
||||
partner.CurOrderManager.OnOrderMsg(order, "黑名单拒单", "")
|
||||
}
|
||||
return err
|
||||
})
|
||||
return nil
|
||||
},
|
||||
ShouldSetTimer: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) bool {
|
||||
@@ -207,10 +258,8 @@ func init() {
|
||||
TimeoutGap: second2AutoPickupGap,
|
||||
},
|
||||
TimeoutAction: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) (err error) {
|
||||
if savedOrderInfo.autoPickupTimeoutMinute > 0 {
|
||||
if err = sch.autoPickupGood(savedOrderInfo); err != nil {
|
||||
partner.CurOrderManager.OnOrderMsg(savedOrderInfo.order, "自动拣货失败", err.Error())
|
||||
}
|
||||
if err = sch.autoPickupGood(savedOrderInfo); err != nil {
|
||||
partner.CurOrderManager.OnOrderMsg(savedOrderInfo.order, "自动拣货失败", err.Error())
|
||||
}
|
||||
return nil
|
||||
},
|
||||
@@ -225,15 +274,12 @@ func init() {
|
||||
TimeoutGap: 0,
|
||||
},
|
||||
TimeoutAction: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) (err error) {
|
||||
if model.IsOrderDeliveryByStore(savedOrderInfo.order) { // 自配送商家使用
|
||||
// 启动抢单TIMER
|
||||
sch.saveDeliveryFeeFromAndStartWatch(savedOrderInfo, savedOrderInfo.order.StatusTime)
|
||||
return sch.createWaybillOn3rdProviders(savedOrderInfo, 0, nil)
|
||||
}
|
||||
return nil
|
||||
// 启动抢单TIMER
|
||||
sch.saveDeliveryFeeFromAndStartWatch(savedOrderInfo, savedOrderInfo.order.StatusTime)
|
||||
return sch.createWaybillOn3rdProviders(savedOrderInfo, 0, nil)
|
||||
},
|
||||
ShouldSetTimer: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) bool {
|
||||
return model.IsOrderDeliveryByStore(savedOrderInfo.order)
|
||||
return model.IsOrderDeliveryByStore(savedOrderInfo.order) // 自配送商家使用
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -245,17 +291,11 @@ func init() {
|
||||
Timeout: minute2Schedule3rdCarrier * time.Minute,
|
||||
},
|
||||
TimeoutAction: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) (err error) {
|
||||
// 饿百转自送的时机不太清楚,暂时禁用超时转自送,在饿百运单取消时还是会自动创建
|
||||
if savedOrderInfo.isDeliveryCompetition &&
|
||||
model.IsOrderDeliveryByPlatform(savedOrderInfo.order) &&
|
||||
savedOrderInfo.order.VendorID == bill.WaybillVendorID &&
|
||||
savedOrderInfo.order.VendorID != model.VendorIDEBAI &&
|
||||
savedOrderInfo.order.DeliveryType != model.OrderDeliveryTypeSelfTake { // 非自配送商家使用
|
||||
return sch.createWaybillOn3rdProviders(savedOrderInfo, 0, nil)
|
||||
}
|
||||
return nil
|
||||
return sch.createWaybillOn3rdProviders(savedOrderInfo, 0, nil)
|
||||
},
|
||||
ShouldSetTimer: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) bool {
|
||||
// 饿百转自送的时机不太清楚,暂时禁用超时转自送,在饿百运单取消时还是会自动创建
|
||||
// 非自配送商家使用
|
||||
return savedOrderInfo.isDeliveryCompetition &&
|
||||
model.IsOrderDeliveryByPlatform(savedOrderInfo.order) &&
|
||||
savedOrderInfo.order.VendorID == bill.WaybillVendorID &&
|
||||
@@ -270,19 +310,11 @@ func init() {
|
||||
Timeout: 5 * time.Second,
|
||||
},
|
||||
TimeoutAction: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) (err error) {
|
||||
order := savedOrderInfo.order
|
||||
if (order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusEndBegin) &&
|
||||
savedOrderInfo.isDeliveryCompetition &&
|
||||
savedOrderInfo.order.VendorID == bill.WaybillVendorID &&
|
||||
model.IsOrderDeliveryByPlatform(savedOrderInfo.order) &&
|
||||
order.VendorID == model.VendorIDEBAI &&
|
||||
savedOrderInfo.order.DeliveryType != model.OrderDeliveryTypeSelfTake { // 非自配送商家使用
|
||||
return sch.createWaybillOn3rdProviders(savedOrderInfo, ebaiCancelWaybillMaxFee, nil)
|
||||
}
|
||||
return nil
|
||||
return sch.createWaybillOn3rdProviders(savedOrderInfo, ebaiCancelWaybillMaxFee, nil)
|
||||
},
|
||||
ShouldSetTimer: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) bool {
|
||||
order := savedOrderInfo.order
|
||||
// 非自配送商家使用
|
||||
return (order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusEndBegin) &&
|
||||
savedOrderInfo.isDeliveryCompetition &&
|
||||
savedOrderInfo.order.VendorID == bill.WaybillVendorID &&
|
||||
@@ -739,91 +771,169 @@ func (s *DefScheduler) loadSavedOrderFromMap(status *model.OrderStatus, isForceL
|
||||
return realSavedInfo
|
||||
}
|
||||
|
||||
func (s *DefScheduler) stopTimer(savedOrderInfo *WatchOrderInfo) {
|
||||
if savedOrderInfo.timer != nil {
|
||||
globals.SugarLogger.Debugf("stopTimer orderID:%s", savedOrderInfo.order.VendorOrderID)
|
||||
savedOrderInfo.timer.Stop()
|
||||
savedOrderInfo.timerStatus = model.OrderStatusUnknown
|
||||
savedOrderInfo.timerStatusType = scheduler.TimerStatusTypeUnknown
|
||||
savedOrderInfo.timer = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DefScheduler) resetTimer(savedOrderInfo *WatchOrderInfo, bill *model.Waybill, isPending bool) {
|
||||
order := savedOrderInfo.order
|
||||
status := order.Status
|
||||
statusType := scheduler.TimerStatusTypeOrder
|
||||
vendorID := order.VendorID
|
||||
statusTime := order.StatusTime
|
||||
if bill != nil {
|
||||
status = bill.Status
|
||||
statusType = scheduler.TimerStatusTypeWaybill
|
||||
vendorID = bill.WaybillVendorID
|
||||
statusTime = bill.StatusTime
|
||||
}
|
||||
globals.SugarLogger.Debugf("resetTimer, orderID:%s statusType:%d status:%d", order.VendorOrderID, statusType, status)
|
||||
if isStatusNewer(order.VendorID, savedOrderInfo.timerStatusType, savedOrderInfo.timerStatus, statusType, status) { // 新设置的TIMER不能覆盖状态在其后的TIMER,如果状态回绕,需要注意
|
||||
config := s.mergeOrderStatusConfig(savedOrderInfo, statusTime, statusType, status)
|
||||
if config == nil || config.TimerType != partner.TimerTypeByPass {
|
||||
s.stopTimer(savedOrderInfo)
|
||||
config := s.mergeOrderStatusConfig(savedOrderInfo, statusTime, statusType, status)
|
||||
|
||||
stopStatusType := statusType
|
||||
stopStatus := status
|
||||
if statusType == scheduler.TimerStatusTypeOrder {
|
||||
if status >= model.OrderStatusDelivering {
|
||||
stopStatusType = -1
|
||||
stopStatus = -1
|
||||
}
|
||||
if config != nil && config.TimeoutAction != nil && config.TimerType != partner.TimerTypeByPass {
|
||||
if config.CallShouldSetTimer(savedOrderInfo, bill) {
|
||||
timeout := config.GetRefTimeout(statusTime, order.OrderCreatedAt)
|
||||
if config.TimeoutGap != 0 {
|
||||
timeout += time.Duration(rand.Intn(int(config.TimeoutGap))) * time.Second
|
||||
}
|
||||
if isPending && timeout < pendingOrderTimerMaxSecond*time.Second { // 如果是PENDING的订单,则将其分布到2--5秒内,让后续事件有机会执行
|
||||
timeout = time.Duration(jxutils.MapValue2Scope(int64(timeout), -pendingOrderTimerMinMinSecond*1000, pendingOrderTimerMaxSecond*1000, pendingOrderTimerMinSecond*1000, pendingOrderTimerMaxSecond*1000)) * time.Millisecond
|
||||
} else if timeout < 0 {
|
||||
timeout = 0
|
||||
}
|
||||
if timeout == 0 {
|
||||
config.TimeoutAction(savedOrderInfo, bill)
|
||||
} else {
|
||||
timerName := ""
|
||||
if statusType == scheduler.TimerStatusTypeOrder {
|
||||
timerName = model.OrderStatusName[status]
|
||||
} else if statusType == scheduler.TimerStatusTypeWaybill {
|
||||
timerName = model.WaybillStatusName[status]
|
||||
}
|
||||
savedOrderInfo.timerStatusType = statusType
|
||||
savedOrderInfo.timerStatus = status
|
||||
savedOrderInfo.timerTime = time.Now().Add(timeout)
|
||||
savedOrderInfo.timer = utils.AfterFuncWithRecover(timeout, func() {
|
||||
jxutils.CallMsgHandlerAsync(func() {
|
||||
globals.SugarLogger.Debugf("fire timer:%s, orderID:%s", timerName, order.VendorOrderID)
|
||||
savedOrderInfo := s.loadSavedOrderFromMap(model.Order2Status(order), true)
|
||||
config.TimeoutAction(savedOrderInfo, bill)
|
||||
savedOrderInfo.timerStatus = 0
|
||||
savedOrderInfo.timerStatusType = scheduler.TimerStatusTypeUnknown
|
||||
}, jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID))
|
||||
})
|
||||
}
|
||||
globals.SugarLogger.Debugf("resetTimer, orderID:%s, statusType:%d, status:%d, timeout:%v", order.VendorOrderID, statusType, status, timeout)
|
||||
} else {
|
||||
globals.SugarLogger.Debugf("resetTimer, orderID:%s, statusType:%d, status:%d, should not set timer", order.VendorOrderID, statusType, status)
|
||||
}
|
||||
if config == nil || config.TimerType != partner.TimerTypeByPass {
|
||||
savedOrderInfo.StopTimer(stopStatusType, -1, stopStatus)
|
||||
}
|
||||
|
||||
if config != nil && config.TimeoutAction != nil && config.TimerType != partner.TimerTypeByPass {
|
||||
if config.CallShouldSetTimer(savedOrderInfo, bill) {
|
||||
timeout := config.GetRefTimeout(statusTime, order.OrderCreatedAt)
|
||||
if config.TimeoutGap != 0 {
|
||||
timeout += time.Duration(rand.Intn(int(config.TimeoutGap))) * time.Second
|
||||
}
|
||||
if isPending && timeout < pendingOrderTimerMaxSecond*time.Second { // 如果是PENDING的订单,则将其分布到2--5秒内,让后续事件有机会执行
|
||||
timeout = time.Duration(jxutils.MapValue2Scope(int64(timeout), -pendingOrderTimerMinMinSecond*1000, pendingOrderTimerMaxSecond*1000, pendingOrderTimerMinSecond*1000, pendingOrderTimerMaxSecond*1000)) * time.Millisecond
|
||||
} else if timeout < 0 {
|
||||
timeout = 0
|
||||
}
|
||||
if timeout == 0 {
|
||||
config.CallTimeoutAction(savedOrderInfo, bill)
|
||||
} else {
|
||||
timerName := ""
|
||||
if statusType == model.OrderTypeOrder {
|
||||
timerName = model.OrderStatusName[status]
|
||||
} else if statusType == model.OrderTypeWaybill {
|
||||
timerName = model.WaybillStatusName[status]
|
||||
}
|
||||
timerInfo := &tTimerInfo{
|
||||
statusType: statusType,
|
||||
vendorID: vendorID,
|
||||
status: status,
|
||||
timerTime: time.Now().Add(timeout),
|
||||
}
|
||||
timerInfo.timer = utils.AfterFuncWithRecover(timeout, func() {
|
||||
jxutils.CallMsgHandlerAsync(func() {
|
||||
globals.SugarLogger.Debugf("fire timer:%s, orderID:%s", timerName, order.VendorOrderID)
|
||||
ts := s.loadSavedOrderFromMap(model.Order2Status(order), true)
|
||||
config.CallTimeoutAction(ts, bill)
|
||||
timerInfo.timer = nil
|
||||
ts.StopTimer(statusType, vendorID, status)
|
||||
}, jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID))
|
||||
})
|
||||
}
|
||||
globals.SugarLogger.Debugf("resetTimer, orderID:%s, statusType:%d, status:%d, timeout:%v", order.VendorOrderID, statusType, status, timeout)
|
||||
} else {
|
||||
globals.SugarLogger.Debugf("resetTimer bypass2, orderID:%s statusType:%d status:%v, config:%s", order.VendorOrderID, statusType, status, utils.Format4Output(config, true))
|
||||
globals.SugarLogger.Debugf("resetTimer, orderID:%s, statusType:%d, status:%d, should not set timer", order.VendorOrderID, statusType, status)
|
||||
}
|
||||
} else {
|
||||
globals.SugarLogger.Debugf("resetTimer bypass1, orderID:%s statusType:%d status:%v", order.VendorOrderID, statusType, status)
|
||||
globals.SugarLogger.Debugf("resetTimer bypass2, orderID:%s statusType:%d status:%v, config:%s", order.VendorOrderID, statusType, status, utils.Format4Output(config, true))
|
||||
}
|
||||
}
|
||||
|
||||
func isStatusNewer(vendorID int, curStatusType, curStatus, statusType, status int) bool {
|
||||
// 拣货完成及之前的订单事件TIMER不能覆盖运单TIMER(一般是消息错序引起的)
|
||||
// 美团订单在接单后就会收到新运单事件,因当前只支持一个TIMER,暂时舍弃三方配送调度,而要自动拣货调度
|
||||
if vendorID != model.VendorIDMTWM {
|
||||
if curStatusType == scheduler.TimerStatusTypeWaybill && statusType == scheduler.TimerStatusTypeOrder && status <= model.OrderStatusFinishedPickup {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if curStatusType == scheduler.TimerStatusTypeWaybill {
|
||||
return curStatus != status
|
||||
}
|
||||
return curStatusType != statusType || status >= curStatus
|
||||
func (s *DefScheduler) stopTimer(savedOrderInfo *WatchOrderInfo) {
|
||||
savedOrderInfo.StopTimer(-1, -1, -1)
|
||||
}
|
||||
|
||||
// func (s *DefScheduler) stopTimer(savedOrderInfo *WatchOrderInfo) {
|
||||
// if savedOrderInfo.timer != nil {
|
||||
// globals.SugarLogger.Debugf("stopTimer orderID:%s", savedOrderInfo.order.VendorOrderID)
|
||||
// savedOrderInfo.timer.Stop()
|
||||
// savedOrderInfo.timerStatus = model.OrderStatusUnknown
|
||||
// savedOrderInfo.timerStatusType = scheduler.TimerStatusTypeUnknown
|
||||
// savedOrderInfo.timer = nil
|
||||
// }
|
||||
// }
|
||||
|
||||
// func (s *DefScheduler) resetTimer(savedOrderInfo *WatchOrderInfo, bill *model.Waybill, isPending bool) {
|
||||
// order := savedOrderInfo.order
|
||||
// status := order.Status
|
||||
// statusType := scheduler.TimerStatusTypeOrder
|
||||
// statusTime := order.StatusTime
|
||||
// if bill != nil {
|
||||
// status = bill.Status
|
||||
// statusType = scheduler.TimerStatusTypeWaybill
|
||||
// statusTime = bill.StatusTime
|
||||
// }
|
||||
// globals.SugarLogger.Debugf("resetTimer, orderID:%s statusType:%d status:%d", order.VendorOrderID, statusType, status)
|
||||
// if isStatusNewer(order.VendorID, savedOrderInfo.timerStatusType, savedOrderInfo.timerStatus, statusType, status) { // 新设置的TIMER不能覆盖状态在其后的TIMER,如果状态回绕,需要注意
|
||||
// config := s.mergeOrderStatusConfig(savedOrderInfo, statusTime, statusType, status)
|
||||
// if config == nil || config.TimerType != partner.TimerTypeByPass {
|
||||
// s.stopTimer(savedOrderInfo)
|
||||
// }
|
||||
// if config != nil && config.TimeoutAction != nil && config.TimerType != partner.TimerTypeByPass {
|
||||
// if config.CallShouldSetTimer(savedOrderInfo, bill) {
|
||||
// timeout := config.GetRefTimeout(statusTime, order.OrderCreatedAt)
|
||||
// if config.TimeoutGap != 0 {
|
||||
// timeout += time.Duration(rand.Intn(int(config.TimeoutGap))) * time.Second
|
||||
// }
|
||||
// if isPending && timeout < pendingOrderTimerMaxSecond*time.Second { // 如果是PENDING的订单,则将其分布到2--5秒内,让后续事件有机会执行
|
||||
// timeout = time.Duration(jxutils.MapValue2Scope(int64(timeout), -pendingOrderTimerMinMinSecond*1000, pendingOrderTimerMaxSecond*1000, pendingOrderTimerMinSecond*1000, pendingOrderTimerMaxSecond*1000)) * time.Millisecond
|
||||
// } else if timeout < 0 {
|
||||
// timeout = 0
|
||||
// }
|
||||
// if timeout == 0 {
|
||||
// config.CallTimeoutAction(savedOrderInfo, bill)
|
||||
// } else {
|
||||
// timerName := ""
|
||||
// if statusType == scheduler.TimerStatusTypeOrder {
|
||||
// timerName = model.OrderStatusName[status]
|
||||
// } else if statusType == scheduler.TimerStatusTypeWaybill {
|
||||
// timerName = model.WaybillStatusName[status]
|
||||
// }
|
||||
// savedOrderInfo.timerStatusType = statusType
|
||||
// savedOrderInfo.timerStatus = status
|
||||
// savedOrderInfo.timerTime = time.Now().Add(timeout)
|
||||
// savedOrderInfo.timer = utils.AfterFuncWithRecover(timeout, func() {
|
||||
// jxutils.CallMsgHandlerAsync(func() {
|
||||
// globals.SugarLogger.Debugf("fire timer:%s, orderID:%s", timerName, order.VendorOrderID)
|
||||
// savedOrderInfo := s.loadSavedOrderFromMap(model.Order2Status(order), true)
|
||||
// config.CallTimeoutAction(savedOrderInfo, bill)
|
||||
// savedOrderInfo.timerStatus = 0
|
||||
// savedOrderInfo.timerStatusType = scheduler.TimerStatusTypeUnknown
|
||||
// }, jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID))
|
||||
// })
|
||||
// }
|
||||
// globals.SugarLogger.Debugf("resetTimer, orderID:%s, statusType:%d, status:%d, timeout:%v", order.VendorOrderID, statusType, status, timeout)
|
||||
// } else {
|
||||
// globals.SugarLogger.Debugf("resetTimer, orderID:%s, statusType:%d, status:%d, should not set timer", order.VendorOrderID, statusType, status)
|
||||
// }
|
||||
// } else {
|
||||
// globals.SugarLogger.Debugf("resetTimer bypass2, orderID:%s statusType:%d status:%v, config:%s", order.VendorOrderID, statusType, status, utils.Format4Output(config, true))
|
||||
// }
|
||||
// } else {
|
||||
// globals.SugarLogger.Debugf("resetTimer bypass1, orderID:%s statusType:%d status:%v", order.VendorOrderID, statusType, status)
|
||||
// }
|
||||
// }
|
||||
|
||||
// func isStatusNewer(vendorID int, curStatusType, curStatus, statusType, status int) bool {
|
||||
// // 拣货完成及之前的订单事件TIMER不能覆盖运单TIMER(一般是消息错序引起的)
|
||||
// // 美团订单在接单后就会收到新运单事件,因当前只支持一个TIMER,暂时舍弃三方配送调度,而要自动拣货调度
|
||||
// if vendorID != model.VendorIDMTWM {
|
||||
// if curStatusType == scheduler.TimerStatusTypeWaybill && statusType == scheduler.TimerStatusTypeOrder && status <= model.OrderStatusFinishedPickup {
|
||||
// return false
|
||||
// }
|
||||
// } else {
|
||||
// return statusType == scheduler.TimerStatusTypeOrder && status >= curStatus
|
||||
// }
|
||||
// if curStatusType == scheduler.TimerStatusTypeWaybill {
|
||||
// return curStatus != status
|
||||
// }
|
||||
// return curStatusType != statusType || status >= curStatus
|
||||
// }
|
||||
|
||||
func (s *DefScheduler) mergeOrderStatusConfig(savedOrderInfo *WatchOrderInfo, statusTime time.Time, statusType, status int) (retVal *StatusActionConfig) {
|
||||
s.locker.RLock()
|
||||
defer func() {
|
||||
@@ -1015,6 +1125,10 @@ func getMaxDeliveryFee(order *model.GoodsOrder) (maxDeliveryFee int64) {
|
||||
} else {
|
||||
maxDeliveryFee = baseWaybillFee + order.DistanceFreightMoney + getWaybillTip(order)
|
||||
}
|
||||
if maxDeliveryFee < ebaiCancelWaybillMaxFee &&
|
||||
order.DeliveryType == model.OrderDeliveryTypeStoreSelf {
|
||||
maxDeliveryFee = ebaiCancelWaybillMaxFee
|
||||
}
|
||||
return maxDeliveryFee
|
||||
}
|
||||
|
||||
|
||||
@@ -226,9 +226,7 @@ func (s *DefScheduler) QueryOrderWaybillFeeInfoEx(ctx *jxcontext.Context, vendor
|
||||
|
||||
var timeoutSecond int
|
||||
if savedOrderInfo := s.loadSavedOrderByID(vendorOrderID, vendorID, false); savedOrderInfo != nil {
|
||||
if savedOrderInfo.timerStatusType == scheduler.TimerStatusTypeWaybill && savedOrderInfo.timerStatus == model.WaybillStatusNew {
|
||||
timeoutSecond = int(savedOrderInfo.timerTime.Sub(time.Now()) / time.Second)
|
||||
}
|
||||
timeoutSecond = savedOrderInfo.GetCreateWaybillTimeout()
|
||||
}
|
||||
for _, storeCourier := range storeCourierList {
|
||||
var feeInfo *partner.WaybillFeeInfo
|
||||
|
||||
@@ -150,7 +150,6 @@ func ActStoreSkuParam2Model(ctx *jxcontext.Context, db *dao.DaoDB, act *model.Ac
|
||||
jxPrice := storeSkuInfo.Price
|
||||
actSkuMap.VendorPrice = int64(getVendorPriceFromStoreSkuBind(storeSkuInfo, vendorID))
|
||||
v.OriginalPrice = int64(jxPrice)
|
||||
v.OriginalPrice = actSkuMap.VendorPrice // 暂时返回平台价
|
||||
}
|
||||
var err2 error
|
||||
if act.Type != model.ActSkuFake { // 非结算,要计算实际活动价格
|
||||
@@ -629,10 +628,6 @@ func DeleteActStoreSkuBind(ctx *jxcontext.Context, db *dao.DaoDB, actID int, act
|
||||
if len(actMap) == 0 {
|
||||
return 0, fmt.Errorf("找不到活动:%d,或已被取消", actID)
|
||||
}
|
||||
if actMap[0].Status != model.ActStatusCreated {
|
||||
// 如果不是正常状态直接跳过
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, nil, nil, nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -754,8 +754,10 @@ func UpdateStore(ctx *jxcontext.Context, storeID int, payload map[string]interfa
|
||||
if (outStore.OpenTime2 == 0 && outStore.CloseTime2 != 0) || (outStore.OpenTime2 != 0 && outStore.CloseTime2 == 0) {
|
||||
return 0, errors.New(fmt.Sprintf("门店营业时间2设置不合法!时间范围2 :[%v] 至 [%v]", outStore.OpenTime1, outStore.CloseTime1))
|
||||
}
|
||||
if outStore.OpenTime2 > outStore.OpenTime1 {
|
||||
return 0, errors.New(fmt.Sprintf("门店营业时间设置不合法!第二段营业时间应该在第一段营业时间之后!"))
|
||||
if outStore.OpenTime1 != 0 && outStore.CloseTime1 != 0 && outStore.OpenTime2 != 0 && outStore.CloseTime2 != 0 {
|
||||
if outStore.OpenTime2 < outStore.CloseTime1 {
|
||||
return 0, errors.New(fmt.Sprintf("门店营业时间设置不合法!第二段营业时间应该在第一段营业时间之后!"))
|
||||
}
|
||||
}
|
||||
if beginAt, endAt := GetTimeMixByInt(outStore.OpenTime1, outStore.CloseTime1, outStore.OpenTime2, outStore.CloseTime2); beginAt != 0 && endAt != 0 {
|
||||
return 0, errors.New(fmt.Sprintf("两段门店营业时间不可交叉!时间范围1 :[%v] 至 [%v], 时间范围2 :[%v] 至 [%v]", outStore.OpenTime1, outStore.CloseTime1, outStore.OpenTime2, outStore.CloseTime2))
|
||||
|
||||
@@ -79,6 +79,9 @@ type StoreSkuExt struct {
|
||||
|
||||
RealEarningPrice int `json:"realEarningPrice"`
|
||||
|
||||
StatusSaleBegin int16 `json:"statusSaleBegin"` //商品可售时间范围
|
||||
StatusSaleEnd int16 `json:"statusSaleEnd"`
|
||||
|
||||
Count int `json:"count"`
|
||||
Times int `json:"times"`
|
||||
}
|
||||
@@ -451,7 +454,8 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bo
|
||||
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.jd_sync_status, t4.ebai_sync_status, t4.mtwm_sync_status,
|
||||
t4.jd_price, t4.ebai_price, t4.mtwm_price, t4.jx_price
|
||||
t4.jd_price, t4.ebai_price, t4.mtwm_price, t4.jx_price,
|
||||
t4.status_sale_begin, t4.status_sale_end
|
||||
` + sql
|
||||
var tmpList []*tGetStoresSkusInfo
|
||||
beginTime := time.Now()
|
||||
|
||||
@@ -441,7 +441,8 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
|
||||
}
|
||||
return skuList
|
||||
}
|
||||
task := tasksch.NewParallelTask("syncStoreSkuNew", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||
isContinueWhenError2 := true
|
||||
task := tasksch.NewParallelTask("syncStoreSkuNew", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError2), ctx,
|
||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
step := batchItemList[0].(int)
|
||||
// globals.SugarLogger.Debugf("step:%d", step)
|
||||
@@ -462,7 +463,7 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
|
||||
updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagDeletedMask)
|
||||
}
|
||||
return nil, len(successList), err
|
||||
}, ctx, task, deleteList, 1 /*singleStoreHandler.GetStoreSkusBatchSize(partner.FuncDeleteStoreSkus)*/, isContinueWhenError)
|
||||
}, ctx, task, deleteList, 1 /*singleStoreHandler.GetStoreSkusBatchSize(partner.FuncDeleteStoreSkus)*/, isContinueWhenError2)
|
||||
}
|
||||
case 1:
|
||||
if len(createList) > 0 {
|
||||
@@ -494,7 +495,7 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
|
||||
updateStoreSku(dao.GetDB(), vendorID, successList, model.SyncFlagNewMask)
|
||||
}
|
||||
return nil, len(successList), err
|
||||
}, ctx, task, createList, 1 /*singleStoreHandler.GetStoreSkusBatchSize(partner.FuncCreateStoreSkus)*/, isContinueWhenError)
|
||||
}, ctx, task, createList, 1 /*singleStoreHandler.GetStoreSkusBatchSize(partner.FuncCreateStoreSkus)*/, isContinueWhenError2)
|
||||
}
|
||||
case 2:
|
||||
if len(updateList) > 0 {
|
||||
@@ -507,7 +508,7 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
|
||||
updateStoreSku(dao.GetDB(), vendorID, successList, model.SyncFlagModifiedMask)
|
||||
}
|
||||
return nil, len(successList), err
|
||||
}, ctx, task, updateList, singleStoreHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkus), isContinueWhenError)
|
||||
}, ctx, task, updateList, singleStoreHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkus), isContinueWhenError2)
|
||||
}
|
||||
case 3:
|
||||
for k, list := range [][]*partner.StoreSkuInfo{stockList /*, onlineList*/} {
|
||||
@@ -526,7 +527,7 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
|
||||
updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagStockMask)
|
||||
}
|
||||
return nil, len(successList), err
|
||||
}, ctx, task, list, storeSkuHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkusStock), isContinueWhenError)
|
||||
}, ctx, task, list, storeSkuHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkusStock), isContinueWhenError2)
|
||||
}
|
||||
}
|
||||
case 4, 5:
|
||||
@@ -550,7 +551,7 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
|
||||
updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagSaleMask)
|
||||
}
|
||||
return nil, len(successList), err
|
||||
}, ctx, task, statusList, storeSkuHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkusStatus), isContinueWhenError)
|
||||
}, ctx, task, statusList, storeSkuHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkusStatus), isContinueWhenError2)
|
||||
}
|
||||
case 6:
|
||||
if len(priceList) > 0 {
|
||||
@@ -565,7 +566,7 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
|
||||
updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagPriceMask)
|
||||
}
|
||||
return nil, len(successList), err
|
||||
}, ctx, task, priceList, storeSkuHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkusPrice), isContinueWhenError)
|
||||
}, ctx, task, priceList, storeSkuHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkusPrice), isContinueWhenError2)
|
||||
}
|
||||
case 7:
|
||||
if len(reorderSkuMap) > 0 {
|
||||
@@ -573,7 +574,7 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
|
||||
for vendorCatID := range reorderSkuMap {
|
||||
vendorCatIDs = append(vendorCatIDs, vendorCatID)
|
||||
}
|
||||
reorderTask := tasksch.NewParallelTask("门店商品排序", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx,
|
||||
reorderTask := tasksch.NewParallelTask("门店商品排序", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError2), ctx,
|
||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
vendorCatID := batchItemList[0].(string)
|
||||
skuList := reorderSkuMap[vendorCatID]
|
||||
|
||||
@@ -146,11 +146,14 @@ func 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)
|
||||
|
||||
cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, dao.GetDB(), []int{model.VendorIDJD}, nil, false, nil, []int{27379}, model.SyncFlagSaleMask|model.SyncFlagPriceMask, 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)
|
||||
|
||||
SaveImportantTaskID(TaskNameSyncStoreSku, SpecialTaskID)
|
||||
taskID, _ := cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, dao.GetDB(), []int{model.VendorIDEBAI, model.VendorIDMTWM}, nil, false, nil, nil, model.SyncFlagSaleMask|model.SyncFlagPriceMask, true, true)
|
||||
taskID, _ := cms.CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, dao.GetDB(), []int{model.VendorIDEBAI, model.VendorIDMTWM}, nil, false, nil, nil, syncFlag, true, true)
|
||||
SaveImportantTaskID(TaskNameSyncStoreSku, taskID)
|
||||
|
||||
InitEx()
|
||||
|
||||
@@ -8,11 +8,13 @@ import (
|
||||
"image/png"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin"
|
||||
"git.rosy.net.cn/jx-callback/business/partner/delivery"
|
||||
"github.com/360EntSecGroup-Skylar/excelize"
|
||||
|
||||
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
||||
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
||||
@@ -1302,3 +1304,58 @@ func FixMtwmCategory(ctx *jxcontext.Context, mtwmStoreIDs []int, isAsync, isCont
|
||||
}
|
||||
return hint, err
|
||||
}
|
||||
|
||||
func JdStoreInfo1125() (hint string, err error) {
|
||||
fileName := "/Users/xujianhua/Downloads/老格恢复拓店进度.xlsx"
|
||||
db := dao.GetDB()
|
||||
storeList, err := dao.GetStoresMapList(db, []int{model.VendorIDJD}, nil, model.StoreStatusAll, model.StoreIsSyncYes, "")
|
||||
if err == nil {
|
||||
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)
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
getStoreList := func(lng, lat, lng2, lat2 int) (vendorStoreIDs []string) {
|
||||
for _, v := range validStoreList {
|
||||
if v.Lng >= lng && v.Lng <= lng2 && v.Lat >= lat && v.Lat <= lat2 {
|
||||
vendorStoreIDs = append(vendorStoreIDs, v.VendorStoreID)
|
||||
}
|
||||
}
|
||||
return vendorStoreIDs
|
||||
}
|
||||
sheetName := "老格明细"
|
||||
file, err2 := excelize.OpenFile(fileName)
|
||||
if err = err2; err == nil {
|
||||
// globals.SugarLogger.Debug(err, file)
|
||||
rows, err2 := file.GetRows(sheetName)
|
||||
if err = err2; err == nil {
|
||||
str2Coords := func(str string) (lng, lat int) {
|
||||
list := strings.Split(str, ",")
|
||||
if len(list) >= 2 {
|
||||
lng, lat = jxutils.StandardCoordinate2Int(utils.Str2Float64WithDefault(list[1], 0)), jxutils.StandardCoordinate2Int(utils.Str2Float64WithDefault(list[0], 0))
|
||||
}
|
||||
return lng, lat
|
||||
}
|
||||
for i := 1; i < len(rows); i++ {
|
||||
lng, lat := str2Coords(rows[i][8])
|
||||
lng2, lat2 := str2Coords(rows[i][7])
|
||||
vendorStoreIDs := getStoreList(lng, lat, lng2, lat2)
|
||||
// fmt.Printf("%d,%v", i, vendorStoreIDs)
|
||||
countInfo := fmt.Sprintf("京西已拓%d", len(vendorStoreIDs))
|
||||
axis, _ := excelize.CoordinatesToCellName(5, i+1)
|
||||
file.SetCellStr(sheetName, axis, countInfo)
|
||||
axis2, _ := excelize.CoordinatesToCellName(6, i+1)
|
||||
file.SetCellStr(sheetName, axis2, strings.Join(vendorStoreIDs, ","))
|
||||
}
|
||||
file.SaveAs("ffff.xlsx")
|
||||
}
|
||||
}
|
||||
}
|
||||
return hint, err
|
||||
}
|
||||
|
||||
26
business/jxstore/tempop/tempop_test.go
Normal file
26
business/jxstore/tempop/tempop_test.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package tempop
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.rosy.net.cn/jx-callback/globals/api2"
|
||||
"git.rosy.net.cn/jx-callback/globals/testinit"
|
||||
|
||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai"
|
||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/elm"
|
||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd"
|
||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm"
|
||||
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/weimob/wsc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
testinit.Init()
|
||||
api2.Init()
|
||||
}
|
||||
|
||||
func TestJdStoreInfo1125(t *testing.T) {
|
||||
_, err := JdStoreInfo1125()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -6,16 +6,25 @@ import (
|
||||
"io"
|
||||
"math"
|
||||
"mime/multipart"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"git.rosy.net.cn/baseapi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"github.com/360EntSecGroup-Skylar/excelize"
|
||||
|
||||
"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
|
||||
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
||||
"git.rosy.net.cn/baseapi/platformapi/weimobapi"
|
||||
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/excel"
|
||||
"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/globals"
|
||||
@@ -26,64 +35,156 @@ import (
|
||||
type SheetParam struct {
|
||||
SkuIDCol int
|
||||
SkuPriceCol int
|
||||
SkuNameCol int
|
||||
OrgSkuIdCol int
|
||||
OrgSkuPriceCol int
|
||||
OrgSkuNameCol int
|
||||
SkuRow int
|
||||
}
|
||||
|
||||
type DataSuccessLock struct {
|
||||
dataSuccessList []DataSuccess
|
||||
locker sync.RWMutex
|
||||
}
|
||||
|
||||
type DataFailedLock struct {
|
||||
dataFailedList []DataFailed
|
||||
locker sync.RWMutex
|
||||
}
|
||||
|
||||
type DataSuccess struct {
|
||||
NameID string `json:"商品nameID"`
|
||||
Name string `json:"商品名称"`
|
||||
Unit string `json:"单位"`
|
||||
OrgPrice float64 `json:"原价"`
|
||||
NowPrice float64 `json:"现价"`
|
||||
MixPrice float64 `json:"涨跌"`
|
||||
}
|
||||
|
||||
type DataFailed struct {
|
||||
GoodsID string `json:"商品ID"`
|
||||
GoodsName string `json:"商品名称"`
|
||||
Comment string `json:"备注"`
|
||||
}
|
||||
|
||||
type Data struct {
|
||||
GoodsID string `json:"商品编码"`
|
||||
GoodsName string `json:"商品名称"`
|
||||
GoodsNum int `json:"订货数量"`
|
||||
}
|
||||
|
||||
type ExcelParam struct {
|
||||
SpuCode string
|
||||
Name string
|
||||
Price float64
|
||||
}
|
||||
|
||||
type OrderList struct {
|
||||
Name string `json:"name"`
|
||||
Phone string `json:"phone"`
|
||||
OrderNo int64 `json:"orderNo"`
|
||||
}
|
||||
|
||||
var (
|
||||
sheetMap = map[string]*SheetParam{
|
||||
"蔬菜": &SheetParam{
|
||||
SkuIDCol: 0,
|
||||
SkuPriceCol: 14,
|
||||
SkuNameCol: 1,
|
||||
OrgSkuIdCol: 5,
|
||||
OrgSkuPriceCol: 8,
|
||||
OrgSkuNameCol: 6,
|
||||
SkuRow: 2,
|
||||
}, "水果": &SheetParam{
|
||||
SkuIDCol: 0,
|
||||
SkuPriceCol: 14,
|
||||
SkuNameCol: 1,
|
||||
OrgSkuIdCol: 5,
|
||||
OrgSkuPriceCol: 8,
|
||||
OrgSkuNameCol: 6,
|
||||
SkuRow: 2,
|
||||
}, "肉禽": &SheetParam{
|
||||
SkuIDCol: 0,
|
||||
SkuPriceCol: 12,
|
||||
SkuNameCol: 1,
|
||||
OrgSkuIdCol: 4,
|
||||
OrgSkuPriceCol: 7,
|
||||
OrgSkuNameCol: 5,
|
||||
SkuRow: 1,
|
||||
}, "净配": &SheetParam{
|
||||
SkuIDCol: 0,
|
||||
SkuPriceCol: 12,
|
||||
SkuNameCol: 1,
|
||||
OrgSkuIdCol: 4,
|
||||
OrgSkuPriceCol: 7,
|
||||
OrgSkuNameCol: 5,
|
||||
SkuRow: 1,
|
||||
}, "水产": &SheetParam{
|
||||
SkuIDCol: 1,
|
||||
SkuPriceCol: 15,
|
||||
SkuNameCol: 2,
|
||||
OrgSkuIdCol: 6,
|
||||
OrgSkuPriceCol: 9,
|
||||
OrgSkuNameCol: 7,
|
||||
SkuRow: 1,
|
||||
}, "干货": &SheetParam{
|
||||
SkuIDCol: 0,
|
||||
SkuPriceCol: 13,
|
||||
SkuNameCol: 1,
|
||||
OrgSkuIdCol: 4,
|
||||
OrgSkuPriceCol: 7,
|
||||
OrgSkuNameCol: 5,
|
||||
SkuRow: 2,
|
||||
}, "MINI肉禽价格": &SheetParam{
|
||||
SkuIDCol: 1,
|
||||
SkuPriceCol: 5,
|
||||
SkuNameCol: 2,
|
||||
OrgSkuIdCol: -1,
|
||||
OrgSkuPriceCol: -1,
|
||||
OrgSkuNameCol: -1,
|
||||
SkuRow: 1,
|
||||
},
|
||||
}
|
||||
titleListSuccess = []string{
|
||||
"商品nameID",
|
||||
"商品名称",
|
||||
"单位",
|
||||
"原价",
|
||||
"现价",
|
||||
"涨跌",
|
||||
}
|
||||
titleListFailed = []string{
|
||||
"商品ID",
|
||||
"商品名称",
|
||||
"备注",
|
||||
}
|
||||
titleList = []string{
|
||||
"商品编码",
|
||||
"商品名称",
|
||||
"订货数量",
|
||||
}
|
||||
dataSuccess DataSuccessLock
|
||||
dataFailed DataFailedLock
|
||||
)
|
||||
|
||||
const (
|
||||
parallelCount = 5
|
||||
UpdateGoodsShelfStatusCount = 50 //微盟下架商品api限制一次50个
|
||||
fileExt = ".xlsx"
|
||||
)
|
||||
|
||||
func (d *DataSuccessLock) AppendData(dataSuccess DataSuccess) {
|
||||
d.locker.Lock()
|
||||
defer d.locker.Unlock()
|
||||
d.dataSuccessList = append(d.dataSuccessList, dataSuccess)
|
||||
}
|
||||
|
||||
func (d *DataFailedLock) AppendData2(dataFailed DataFailed) {
|
||||
d.locker.Lock()
|
||||
defer d.locker.Unlock()
|
||||
d.dataFailedList = append(d.dataFailedList, dataFailed)
|
||||
}
|
||||
|
||||
func LoadExcelByYongHui(ctx *jxcontext.Context, files []*multipart.FileHeader, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
if len(files) == 0 {
|
||||
return "", errors.New("没有文件上传!")
|
||||
@@ -99,11 +200,12 @@ func LoadExcelByYongHui(ctx *jxcontext.Context, files []*multipart.FileHeader, i
|
||||
|
||||
func LoadExcelBinByYongHui(ctx *jxcontext.Context, reader io.Reader, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
var (
|
||||
skuMap = make(map[string]float64)
|
||||
skuMap = make(map[string]*ExcelParam)
|
||||
errMsg string
|
||||
costPrice float64 //成本价
|
||||
goodsList []*weimobapi.GoodsInfo
|
||||
goodsIDListForPutAway []interface{}
|
||||
isCompare bool
|
||||
)
|
||||
db := dao.GetDB()
|
||||
taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||
@@ -121,7 +223,7 @@ func LoadExcelBinByYongHui(ctx *jxcontext.Context, reader io.Reader, isAsync, is
|
||||
if rowNum < sheetParam.SkuRow {
|
||||
continue
|
||||
}
|
||||
GetCellIntoMap(sheetParam.SkuIDCol, sheetParam.SkuPriceCol, sheetParam.OrgSkuIdCol, sheetParam.OrgSkuPriceCol, skuMap, row, k, rowNum)
|
||||
GetCellIntoMap(sheetParam, skuMap, row, k, rowNum)
|
||||
if len(skuMap) < 1 {
|
||||
errMsg += fmt.Sprintf("读取Excel数据失败,Excel格式排版可能发生了变化!sheetName: [%v]\n", k)
|
||||
}
|
||||
@@ -133,10 +235,14 @@ func LoadExcelBinByYongHui(ctx *jxcontext.Context, reader io.Reader, isAsync, is
|
||||
//修改分组名
|
||||
// 分类名格式为:可定XX日
|
||||
// XX为上传永辉 提供的 价格表时间 +2天
|
||||
|
||||
isCompare, err = UpdateClassifyAndGetLastClassify()
|
||||
case 1:
|
||||
//获取微盟所有商品
|
||||
goodsList, err = GetWeiMobGoodsList()
|
||||
param := &weimobapi.QueryGoodsListParam{
|
||||
PageNum: 1,
|
||||
PageSize: jdapi.MaxSkuIDsCount4QueryListBySkuIds,
|
||||
}
|
||||
goodsList, err = GetWeiMobGoodsList(param)
|
||||
if err != nil {
|
||||
baseapi.SugarLogger.Errorf("GetWeiMobGoodsList error:%v", err)
|
||||
}
|
||||
@@ -157,12 +263,15 @@ func LoadExcelBinByYongHui(ctx *jxcontext.Context, reader io.Reader, isAsync, is
|
||||
for k, _ := range skuMap {
|
||||
//表示excel上有,微盟上没有
|
||||
if goodsInfoAndDetailMap[k] == nil {
|
||||
errMsg += fmt.Sprintf("在微盟上未找到该商品!excel商品ID : [%v]\n", k)
|
||||
outPutData := DataFailed{
|
||||
GoodsID: k,
|
||||
GoodsName: skuMap[k].Name,
|
||||
Comment: "在微盟上未找到该商品",
|
||||
}
|
||||
dataFailed.AppendData2(outPutData)
|
||||
// errMsg += fmt.Sprintf("在微盟上未找到该商品xxx", xxx)
|
||||
}
|
||||
}
|
||||
// if errMsg != "" {
|
||||
// return "", errors.New(errMsg)
|
||||
// }
|
||||
case 2:
|
||||
//找出微盟上有,excel上没有的,有就更新,没有就下架
|
||||
taskFunc3 := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
@@ -171,24 +280,28 @@ func LoadExcelBinByYongHui(ctx *jxcontext.Context, reader io.Reader, isAsync, is
|
||||
spuCode := goodsDetail.OuterGoodsCode
|
||||
if spuCode != "" {
|
||||
//如果微盟商品里找得到excel中的商品
|
||||
if skuMap[spuCode] != 0 {
|
||||
if skuMap[spuCode] != nil {
|
||||
//获取京西库商品
|
||||
skuList, _ := dao.GetSkus(db, nil, []int{int(utils.Str2Int64(goodsDetail.SkuMap.SingleSku.OuterSkuCode))}, nil, nil)
|
||||
if len(skuList) == 0 {
|
||||
return "", errors.New(fmt.Sprintf("在京西库中未找到该商品!name_id : [%v]\n", goodsDetail.SkuMap.SingleSku.OuterSkuCode))
|
||||
outPutData := DataFailed{
|
||||
GoodsID: spuCode,
|
||||
GoodsName: skuMap[spuCode].Name,
|
||||
Comment: "在京西库中未找到该商品",
|
||||
}
|
||||
dataFailed.AppendData2(outPutData)
|
||||
// return "", errors.New(fmt.Sprintf("在京西库中未找到该商品!name_id : [%v]\n", goodsDetail.SkuMap.SingleSku.OuterSkuCode))
|
||||
} else {
|
||||
if skuList[0].Unit == "份" {
|
||||
if goodsDetail.SkuMap.SingleSku.B2CSku.Weight == 0 {
|
||||
costPrice = skuMap[spuCode]
|
||||
costPrice = skuMap[spuCode].Price
|
||||
} else {
|
||||
costPrice = Float64Round(0.5 / goodsDetail.SkuMap.SingleSku.B2CSku.Weight * skuMap[spuCode])
|
||||
costPrice = Float64Round(0.5 / goodsDetail.SkuMap.SingleSku.B2CSku.Weight * skuMap[spuCode].Price)
|
||||
}
|
||||
} else {
|
||||
costPrice = skuMap[spuCode]
|
||||
costPrice = skuMap[spuCode].Price
|
||||
}
|
||||
// if errMsg == "" {
|
||||
_, _, err = updateWeiMobGoods(costPrice, skuMap[spuCode], goodsDetail)
|
||||
// }
|
||||
_, _, _ = updateWeiMobGoods(costPrice, skuMap[spuCode].Price, skuList[0].Unit, isCompare, goodsDetail)
|
||||
}
|
||||
} else {
|
||||
//下架微盟商品
|
||||
@@ -197,7 +310,7 @@ func LoadExcelBinByYongHui(ctx *jxcontext.Context, reader io.Reader, isAsync, is
|
||||
}
|
||||
return retVal, err
|
||||
}
|
||||
taskParallel3 := tasksch.NewParallelTask("根据获取的微盟所有商品并更新", tasksch.NewParallelConfig().SetParallelCount(parallelCount).SetIsContinueWhenError(isContinueWhenError), ctx, taskFunc3, goodsList)
|
||||
taskParallel3 := tasksch.NewParallelTask("根据获取的微盟所有商品并更新", tasksch.NewParallelConfig().SetParallelCount(parallelCount), ctx, taskFunc3, goodsList)
|
||||
tasksch.HandleTask(taskParallel3, task, true).Run()
|
||||
goodsIDListForPutAwayInterface, err2 := taskParallel3.GetResult(0)
|
||||
if err = err2; err != nil {
|
||||
@@ -206,7 +319,6 @@ func LoadExcelBinByYongHui(ctx *jxcontext.Context, reader io.Reader, isAsync, is
|
||||
goodsIDListForPutAway = goodsIDListForPutAwayInterface
|
||||
case 3:
|
||||
// 批量下架微盟商品
|
||||
// if errMsg == "" {
|
||||
taskFunc4 := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
int64Slice := []int64{}
|
||||
for _, v := range batchItemList {
|
||||
@@ -218,14 +330,15 @@ func LoadExcelBinByYongHui(ctx *jxcontext.Context, reader io.Reader, isAsync, is
|
||||
taskParallel4 := tasksch.NewParallelTask("下架微盟商品", tasksch.NewParallelConfig().SetParallelCount(parallelCount).SetBatchSize(UpdateGoodsShelfStatusCount), ctx, taskFunc4, goodsIDListForPutAway)
|
||||
tasksch.HandleTask(taskParallel4, task, true).Run()
|
||||
_, err = taskParallel4.GetResult(0)
|
||||
// }
|
||||
}
|
||||
if errMsg != "" {
|
||||
return result, errors.New(errMsg)
|
||||
case 4:
|
||||
WriteToExcel(task, dataSuccess.dataSuccessList, dataFailed.dataFailedList)
|
||||
}
|
||||
// if errMsg != "" {
|
||||
// return result, errors.New(errMsg)
|
||||
// }
|
||||
return result, err
|
||||
}
|
||||
taskSeq := tasksch.NewSeqTask2("读取永辉Excel文件修改微盟商品价格可售状态-序列任务", ctx, isContinueWhenError, taskSeqFunc, 4)
|
||||
taskSeq := tasksch.NewSeqTask2("读取永辉Excel文件修改微盟商品价格可售状态-序列任务", ctx, isContinueWhenError, taskSeqFunc, 5)
|
||||
tasksch.HandleTask(taskSeq, nil, true).Run()
|
||||
if !isAsync {
|
||||
_, err = taskSeq.GetResult(0)
|
||||
@@ -265,13 +378,14 @@ func GetGoodsInfoAndDetailMap(goodsList []*weimobapi.GoodsInfo) (goodsMap map[st
|
||||
// return list
|
||||
// }
|
||||
|
||||
func updateWeiMobGoods(costPrice, salePrice float64, goodsDetail *weimobapi.GoodsDetailInfo) (goodsID int64, skuMap map[string]int64, err error) {
|
||||
func updateWeiMobGoods(costPrice, salePrice float64, unit string, isCompare bool, goodsDetail *weimobapi.GoodsDetailInfo) (goodsID int64, skuMap map[string]int64, err error) {
|
||||
var (
|
||||
categoryList []*weimobapi.CategoryList
|
||||
skuListInfo = goodsDetail.SkuList[0]
|
||||
skuListParam []*weimobapi.SkuList
|
||||
categoryID int
|
||||
deliveryTypeListSlice []int64
|
||||
newSkuTitle string
|
||||
)
|
||||
|
||||
//查询配送方式
|
||||
@@ -298,16 +412,51 @@ func updateWeiMobGoods(costPrice, salePrice float64, goodsDetail *weimobapi.Good
|
||||
return 0, nil, errors.New(fmt.Sprintf("未查询到此商品的分类信息!goodsID : [%v] ,", goodsDetail.GoodsID))
|
||||
}
|
||||
|
||||
//获取分组
|
||||
//商品分组(原有的分组IDs)
|
||||
selectedClassifyList := goodsDetail.SelectedClassifyList
|
||||
var selectedClassifyListID []int64
|
||||
selectedClassifyListIDMap := make(map[int64]int64)
|
||||
if len(selectedClassifyList) > 0 {
|
||||
for _, v := range selectedClassifyList {
|
||||
for _, vv := range v.ChildrenClassify {
|
||||
selectedClassifyListID = append(selectedClassifyListID, vv.ClassifyID)
|
||||
for _, v := range v.ChildrenClassify {
|
||||
selectedClassifyListIDMap[v.ClassifyID] = v.ClassifyID
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//上次上传价格和这次上传价格对比
|
||||
// 4、微盟商品。两个重要分组
|
||||
// 降价超0.2元,与前一日数据对比,需要将此类商品增加分类到这里,不改变原分类
|
||||
// 涨价超0.2元,与前一日数据对比,需要将此类商品增加分类到这里,不改变原分类
|
||||
// 其他商品,取消 这两个分类
|
||||
// 同一天第二次上传的处理,需要注意是与前一天价格的对比,不是当天的价格对比。
|
||||
|
||||
// 5. 涨价和跌价值保留2位小数
|
||||
// 需要在每个商品中增加↑0.01或↓0.02。
|
||||
// 显示在商品最前的括号里,如果没有括号,需要增加。都用小写的括号,大写括号需要删除。
|
||||
// 包装菜需要增加“精”,其他不需要加字,比如:
|
||||
// (精↓2.11)新土豆1kg/袋
|
||||
// (↓2.11)新土豆1kg
|
||||
//salePrice 这次上传的价格 goodsDetail.SkuMap.SingleSku.SalePrice 上次上传的价格 priceMix 两次上传价格差 priceMixRound 保留两位后的价格差
|
||||
if !isCompare {
|
||||
priceMix := salePrice - goodsDetail.SkuMap.SingleSku.SalePrice
|
||||
if priceMix > 0.2 {
|
||||
delete(selectedClassifyListIDMap, 1064198248)
|
||||
delete(selectedClassifyListIDMap, 1065246248)
|
||||
selectedClassifyListIDMap[1064198248] = 1064198248
|
||||
} else if priceMix < -0.2 {
|
||||
delete(selectedClassifyListIDMap, 1064198248)
|
||||
delete(selectedClassifyListIDMap, 1065246248)
|
||||
selectedClassifyListIDMap[1065246248] = 1065246248
|
||||
} else {
|
||||
delete(selectedClassifyListIDMap, 1064198248)
|
||||
delete(selectedClassifyListIDMap, 1065246248)
|
||||
}
|
||||
priceMixRound := Float64Round(priceMix)
|
||||
newSkuTitle = GetNewSkuTitle(priceMixRound, goodsDetail.Title, goodsDetail.OuterGoodsCode)
|
||||
} else {
|
||||
newSkuTitle = goodsDetail.Title
|
||||
}
|
||||
|
||||
b2CSku := &weimobapi.B2CSku{
|
||||
Weight: skuListInfo.B2CSku.Weight,
|
||||
Volume: skuListInfo.B2CSku.Volume,
|
||||
@@ -329,7 +478,7 @@ func updateWeiMobGoods(costPrice, salePrice float64, goodsDetail *weimobapi.Good
|
||||
goods := &weimobapi.Goods{
|
||||
B2CGoods: b2CGoods,
|
||||
SkuList: skuListParam,
|
||||
Title: goodsDetail.Title,
|
||||
Title: newSkuTitle,
|
||||
IsMultiSku: goodsDetail.IsMultiSku,
|
||||
IsPutAway: weimobapi.GoodsTypeNormal,
|
||||
GoodsImageURL: goodsDetail.GoodsImageURL,
|
||||
@@ -337,22 +486,38 @@ func updateWeiMobGoods(costPrice, salePrice float64, goodsDetail *weimobapi.Good
|
||||
CategoryID: categoryID,
|
||||
OuterGoodsCode: goodsDetail.OuterGoodsCode,
|
||||
PointDeductRatio: goodsDetail.PointDeductRatio,
|
||||
SelectedClassifyIDList: selectedClassifyListID,
|
||||
SelectedClassifyIDList: Map2Int64Slice(selectedClassifyListIDMap),
|
||||
}
|
||||
updateGoodsParam := &weimobapi.UpdateGoodsParam{
|
||||
Goods: goods,
|
||||
}
|
||||
if globals.EnableStoreWrite {
|
||||
goodsID, skuMap, err = api.WeimobAPI.UpdateGoods3(updateGoodsParam)
|
||||
if err != nil {
|
||||
if errExt, ok := err.(*utils.ErrorWithCode); ok {
|
||||
outPutData := DataFailed{
|
||||
GoodsID: goodsDetail.OuterGoodsCode,
|
||||
GoodsName: goodsDetail.Title,
|
||||
Comment: errExt.ErrMsg(),
|
||||
}
|
||||
dataFailed.AppendData2(outPutData)
|
||||
}
|
||||
} else {
|
||||
outPutData := DataSuccess{
|
||||
NameID: goodsDetail.SkuMap.SingleSku.OuterSkuCode,
|
||||
Name: goodsDetail.Title,
|
||||
Unit: unit,
|
||||
OrgPrice: goodsDetail.SkuMap.SingleSku.SalePrice,
|
||||
NowPrice: salePrice,
|
||||
MixPrice: Float64Round(salePrice - goodsDetail.SkuMap.SingleSku.SalePrice),
|
||||
}
|
||||
dataSuccess.AppendData(outPutData)
|
||||
}
|
||||
}
|
||||
return goodsID, skuMap, err
|
||||
}
|
||||
|
||||
func GetWeiMobGoodsList() (goodsList []*weimobapi.GoodsInfo, err error) {
|
||||
param := &weimobapi.QueryGoodsListParam{
|
||||
PageNum: 1,
|
||||
PageSize: jdapi.MaxSkuIDsCount4QueryListBySkuIds,
|
||||
}
|
||||
func GetWeiMobGoodsList(param *weimobapi.QueryGoodsListParam) (goodsList []*weimobapi.GoodsInfo, err error) {
|
||||
for {
|
||||
goodsInfoList, _, err := api.WeimobAPI.QueryGoodsList(param)
|
||||
if err != nil {
|
||||
@@ -378,52 +543,427 @@ func IsChineseChar(str string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func GetCellIntoMap(skuIDCol, skuPriceCol, orgSkuIDCol, orgSkuPriceCol int, skuMap map[string]float64, row []string, sheetName string, rowNum int) {
|
||||
func GetCellIntoMap(sheetParam *SheetParam, skuMap map[string]*ExcelParam, row []string, sheetName string, rowNum int) {
|
||||
var (
|
||||
skuID string
|
||||
orgSkuID string
|
||||
skuPrice float64
|
||||
orgSkuPrice float64
|
||||
skuID string
|
||||
orgSkuID string
|
||||
skuPrice float64
|
||||
orgSkuPrice float64
|
||||
skuName string
|
||||
orgSkuName string
|
||||
skuIDCol = sheetParam.SkuIDCol
|
||||
skuPriceCol = sheetParam.SkuPriceCol
|
||||
skuNameCol = sheetParam.SkuNameCol
|
||||
orgSkuIDCol = sheetParam.OrgSkuIdCol
|
||||
orgSkuPriceCol = sheetParam.OrgSkuPriceCol
|
||||
orgSkuNameCol = sheetParam.OrgSkuNameCol
|
||||
)
|
||||
for k, cell := range row {
|
||||
if !IsChineseChar(cell) && cell != "" {
|
||||
if k == skuIDCol && skuIDCol >= 0 {
|
||||
skuID = cell
|
||||
if cell != "" {
|
||||
if !IsChineseChar(cell) {
|
||||
if k == skuIDCol && skuIDCol >= 0 {
|
||||
skuID = cell
|
||||
}
|
||||
if k == skuPriceCol && skuPriceCol >= 0 {
|
||||
skuPrice = Float64Round(utils.Str2Float64WithDefault(cell, 0))
|
||||
}
|
||||
if k == orgSkuIDCol && orgSkuIDCol >= 0 {
|
||||
orgSkuID = "0" + cell
|
||||
}
|
||||
if k == orgSkuPriceCol && orgSkuPriceCol >= 0 {
|
||||
orgSkuPrice = Float64Round(utils.Str2Float64WithDefault(cell, 0))
|
||||
}
|
||||
}
|
||||
if k == skuPriceCol && skuPriceCol >= 0 {
|
||||
skuPrice = Float64Round(utils.Str2Float64WithDefault(cell, 0))
|
||||
if k == skuNameCol && skuNameCol >= 0 {
|
||||
skuName = cell
|
||||
}
|
||||
if k == orgSkuIDCol && orgSkuIDCol >= 0 {
|
||||
orgSkuID = "0" + cell
|
||||
}
|
||||
if k == orgSkuPriceCol && orgSkuPriceCol >= 0 {
|
||||
orgSkuPrice = Float64Round(utils.Str2Float64WithDefault(cell, 0))
|
||||
if k == orgSkuNameCol && orgSkuNameCol >= 0 {
|
||||
orgSkuName = cell
|
||||
}
|
||||
}
|
||||
}
|
||||
if skuMap[skuID] != 0 && skuMap[skuID] != skuPrice {
|
||||
if skuPrice > skuMap[skuID] {
|
||||
skuMap[skuID] = skuPrice
|
||||
if len(skuMap) > 0 {
|
||||
if skuMap[skuID] != nil {
|
||||
if skuMap[skuID].Price != 0 && skuMap[skuID].Price != skuPrice && skuPrice != 0 {
|
||||
if skuPrice > skuMap[skuID].Price {
|
||||
BuildSkuMap(skuID, skuName, skuPrice, skuMap)
|
||||
}
|
||||
} else {
|
||||
BuildSkuMap(skuID, skuName, skuPrice, skuMap)
|
||||
}
|
||||
} else if skuPrice != 0 {
|
||||
BuildSkuMap(skuID, skuName, skuPrice, skuMap)
|
||||
}
|
||||
if skuMap[orgSkuID] != nil {
|
||||
if skuMap[orgSkuID].Price != 0 && skuMap[orgSkuID].Price != orgSkuPrice && orgSkuPrice != 0 {
|
||||
if orgSkuPrice > skuMap[orgSkuID].Price {
|
||||
BuildSkuMap(orgSkuID, orgSkuName, orgSkuPrice, skuMap)
|
||||
}
|
||||
} else if orgSkuPriceCol >= 0 && orgSkuIDCol >= 0 && orgSkuNameCol >= 0 {
|
||||
BuildSkuMap(orgSkuID, orgSkuName, orgSkuPrice, skuMap)
|
||||
}
|
||||
} else if orgSkuPrice != 0 {
|
||||
BuildSkuMap(orgSkuID, orgSkuName, orgSkuPrice, skuMap)
|
||||
}
|
||||
// fmt.Sprintf("读取excel表格出错!有商品ID重复且价格不同,sheetName : [%v] ,行数 : [%v] , 商品编码 :[%v] , 价格:[%v]\n", sheetName, rowNum, skuID, skuPrice)
|
||||
} else {
|
||||
skuMap[skuID] = skuPrice
|
||||
}
|
||||
if skuMap[orgSkuID] != 0 && skuMap[orgSkuID] != orgSkuPrice {
|
||||
if orgSkuPrice > skuMap[orgSkuID] {
|
||||
skuMap[orgSkuID] = orgSkuPrice
|
||||
}
|
||||
// fmt.Sprintf("读取excel表格出错!有商品ID重复且价格不同,sheetName : [%v] ,行数 : [%v], 商品编码 :[%v] , 价格:[%v]\n", sheetName, rowNum, orgSkuID, orgSkuPrice)
|
||||
} else if orgSkuPriceCol >= 0 && orgSkuIDCol >= 0 {
|
||||
skuMap[orgSkuID] = orgSkuPrice
|
||||
BuildSkuMap(skuID, skuName, skuPrice, skuMap)
|
||||
BuildSkuMap(orgSkuID, orgSkuName, orgSkuPrice, skuMap)
|
||||
}
|
||||
delete(skuMap, "")
|
||||
}
|
||||
func BuildSkuMap(id, name string, price float64, skuMap map[string]*ExcelParam) {
|
||||
excelParam := &ExcelParam{
|
||||
SpuCode: id,
|
||||
Price: price,
|
||||
Name: name,
|
||||
}
|
||||
skuMap[id] = excelParam
|
||||
}
|
||||
|
||||
func Float64Round(f float64) (flt float64) {
|
||||
return math.Round(f*100) / 100
|
||||
}
|
||||
|
||||
func UpdateClassifyName() {
|
||||
|
||||
func Map2Int64Slice(m map[int64]int64) (result []int64) {
|
||||
for _, v := range m {
|
||||
result = append(result, v)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func UpdateClassifyAndGetLastClassify() (isCompare bool, err error) {
|
||||
var lastTitle string
|
||||
classfiyList, err := api.WeimobAPI.QueryClassifyInfoList()
|
||||
if len(classfiyList) > 0 {
|
||||
for _, v := range classfiyList {
|
||||
if v.ClassifyID == 1065244148 {
|
||||
lastTitle = v.Title
|
||||
}
|
||||
}
|
||||
}
|
||||
title := "可定"
|
||||
now := time.Now()
|
||||
afterDay := now.AddDate(0, 0, 2).Day()
|
||||
title += utils.Int2Str(afterDay) + "日"
|
||||
if lastTitle == title {
|
||||
return true, err
|
||||
} else {
|
||||
err = api.WeimobAPI.UpdateClassify(1065244148, title, "")
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
func GetNewSkuTitle(priceMixRound float64, orgTitle, outerGoodsCode string) (name string) {
|
||||
var prefix = ""
|
||||
title1 := strings.ReplaceAll(orgTitle, "(", "(")
|
||||
title := strings.ReplaceAll(title1, ")", ")")
|
||||
if outerGoodsCode[0:1] != "0" {
|
||||
prefix += "(精"
|
||||
if priceMixRound > 0 {
|
||||
prefix += "↑"
|
||||
} else if priceMixRound < 0 {
|
||||
prefix += "↓"
|
||||
} else {
|
||||
prefix += ")"
|
||||
return GetReplaceNewTitle(title, prefix)
|
||||
}
|
||||
} else {
|
||||
if priceMixRound > 0 {
|
||||
prefix += "(↑"
|
||||
} else if priceMixRound < 0 {
|
||||
prefix += "(↓"
|
||||
} else {
|
||||
return GetReplaceNewTitle(title, prefix)
|
||||
}
|
||||
}
|
||||
prefix += utils.Float64ToStr(math.Abs(priceMixRound)) + ")"
|
||||
return GetReplaceNewTitle(title, prefix)
|
||||
}
|
||||
|
||||
func GetReplaceNewTitle(title, prefix string) (newTitle string) {
|
||||
if title[0:1] == "(" {
|
||||
return strings.Replace(title, title[0:strings.Index(title, ")")+1], prefix, 1)
|
||||
} else {
|
||||
return prefix + title
|
||||
}
|
||||
}
|
||||
|
||||
func WriteToExcel(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 = UploadExeclAndPushMsg(sheetList1, "已更新商品")
|
||||
} else {
|
||||
baseapi.SugarLogger.Debug("WriteToExcel: dataSuccess is nil!")
|
||||
}
|
||||
if excelConf2 != nil {
|
||||
downloadURL2, fileName2, err = 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", globals.BackstageHost, downloadURL1, downloadURL2)
|
||||
task.SetNoticeMsg(noticeMsg)
|
||||
baseapi.SugarLogger.Debugf("WriteToExcel:upload %s ,%s success, downloadURL1:%s ,downloadURL2:%s", fileName1, fileName2, downloadURL1, downloadURL2)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func UploadExeclAndPushMsg(sheetList []*excel.Obj2ExcelSheetConfig, name string) (downloadURL, fileName string, err error) {
|
||||
excelBin := excel.Obj2Excel(sheetList)
|
||||
timeStr := utils.Int64ToStr(time.Now().Unix())
|
||||
fileName = name + timeStr + fileExt
|
||||
baseapi.SugarLogger.Debugf("WriteToExcel:save %s success", fileName)
|
||||
downloadURL, err = jxutils.UploadExportContent(excelBin, fileName)
|
||||
return downloadURL, fileName, err
|
||||
}
|
||||
|
||||
func UpdateJxPriceByWeimob(ctx *jxcontext.Context, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||
var (
|
||||
storeSkuBindInfoList []interface{}
|
||||
skuBindInfos []*cms.StoreSkuBindInfo
|
||||
)
|
||||
//获取微盟所有上架商品
|
||||
queryParameter := &weimobapi.QueryGoodsListRequestVo{
|
||||
GoodsStatus: weimobapi.GoodsTypeNormal,
|
||||
}
|
||||
param := &weimobapi.QueryGoodsListParam{
|
||||
PageNum: 1,
|
||||
PageSize: jdapi.MaxSkuIDsCount4QueryListBySkuIds,
|
||||
QueryParameter: queryParameter,
|
||||
}
|
||||
goodsList, err := GetWeiMobGoodsList(param)
|
||||
if err != nil {
|
||||
baseapi.SugarLogger.Errorf("GetWeiMobGoodsList error:%v", err)
|
||||
}
|
||||
taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||
switch step {
|
||||
case 0:
|
||||
taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||
v := batchItemList[0].(*weimobapi.GoodsInfo)
|
||||
goodsDetail, err := api.WeimobAPI.QueryGoodsDetail(v.GoodsID)
|
||||
if err != nil {
|
||||
baseapi.SugarLogger.Errorf("QueryGoodsDetail error:%v", err)
|
||||
}
|
||||
if goodsDetail.OuterGoodsCode != "" && goodsDetail.IsPutAway == weimobapi.GoodsTypeNormal {
|
||||
nameID := int(utils.Str2Int64(goodsDetail.SkuMap.SingleSku.OuterSkuCode))
|
||||
unitPrice := int(utils.Float64TwoInt64(goodsDetail.SkuMap.SingleSku.CostPrice * 100))
|
||||
storeSkuBindInfo := &cms.StoreSkuBindInfo{
|
||||
NameID: nameID,
|
||||
UnitPrice: unitPrice,
|
||||
}
|
||||
retVal = []*cms.StoreSkuBindInfo{storeSkuBindInfo}
|
||||
}
|
||||
return retVal, err
|
||||
}
|
||||
taskParallel := tasksch.NewParallelTask("获取微盟商品", tasksch.NewParallelConfig().SetParallelCount(parallelCount), ctx, taskFunc, goodsList)
|
||||
tasksch.HandleTask(taskParallel, task, true).Run()
|
||||
storeSkuBindInfoList, err = taskParallel.GetResult(0)
|
||||
case 1:
|
||||
for _, v := range storeSkuBindInfoList {
|
||||
skuBindInfos = append(skuBindInfos, v.(*cms.StoreSkuBindInfo))
|
||||
}
|
||||
cms.UpdateStoresSkus(ctx, storeIDs, skuBindInfos, isAsync, isContinueWhenError)
|
||||
}
|
||||
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 GetWeimobOrders(ctx *jxcontext.Context, fromTime, toTime string, params map[string]interface{}) (result []*OrderList, err error) {
|
||||
if fromTime != "" && toTime != "" {
|
||||
fromTimeParam := utils.Str2Time(fromTime).UnixNano() / 1e6
|
||||
toTimeParam := utils.Str2Time(toTime).UnixNano() / 1e6
|
||||
if params["keyword"] != nil {
|
||||
if jxutils.GetPossibleVendorIDFromVendorOrderID(params["keyword"].(string)) > model.VendorIDUnknown {
|
||||
resultList, err := GetSingleOrderResultList(params)
|
||||
result = append(result, resultList...)
|
||||
return result, err
|
||||
} else {
|
||||
orderList, err := GetWeimobOrdersList(fromTimeParam, toTimeParam, params["keyword"].(string))
|
||||
return orderList, err
|
||||
}
|
||||
} else {
|
||||
orderList, err := GetWeimobOrdersList(fromTimeParam, toTimeParam, "")
|
||||
return orderList, err
|
||||
}
|
||||
}
|
||||
if fromTime == "" && toTime == "" && params["keyword"] != nil {
|
||||
if jxutils.GetPossibleVendorIDFromVendorOrderID(params["keyword"].(string)) > model.VendorIDUnknown {
|
||||
resultList, err := GetSingleOrderResultList(params)
|
||||
result = append(result, resultList...)
|
||||
return result, err
|
||||
} else {
|
||||
orderList, err := GetWeimobOrdersList(0, 0, params["keyword"].(string))
|
||||
return orderList, err
|
||||
}
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
func GetWeimobOrdersList(fromTimeParam, toTimeParam int64, keyword string) (aList []*OrderList, err error) {
|
||||
var queryParameter *weimobapi.MerchantOrderListQueryParameter
|
||||
if fromTimeParam == 0 && toTimeParam == 0 {
|
||||
queryParameter = &weimobapi.MerchantOrderListQueryParameter{
|
||||
CreateStartTime: time.Now().AddDate(0, -2, 0).UnixNano() / 1e6,
|
||||
CreateEndTime: time.Now().UnixNano() / 1e6,
|
||||
}
|
||||
} else {
|
||||
queryParameter = &weimobapi.MerchantOrderListQueryParameter{
|
||||
CreateStartTime: fromTimeParam,
|
||||
CreateEndTime: toTimeParam,
|
||||
}
|
||||
}
|
||||
param := &weimobapi.QueryOrdersListParam{
|
||||
PageNum: 1,
|
||||
PageSize: weimobapi.QueryOrdersListPageSize,
|
||||
QueryParameter: queryParameter,
|
||||
}
|
||||
for {
|
||||
orderList, _, err2 := api.WeimobAPI.QueryOrdersList(param)
|
||||
err = err2
|
||||
if len(orderList) > 0 {
|
||||
if keyword != "" {
|
||||
for _, v := range orderList {
|
||||
if ContainsKeyword(v, keyword) {
|
||||
var aOrder = &OrderList{
|
||||
Name: v.ReceiverName,
|
||||
OrderNo: v.OrderNo,
|
||||
Phone: v.ReceiverMobile,
|
||||
}
|
||||
aList = append(aList, aOrder)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, v := range orderList {
|
||||
var aOrder = &OrderList{
|
||||
Name: v.ReceiverName,
|
||||
OrderNo: v.OrderNo,
|
||||
Phone: v.ReceiverMobile,
|
||||
}
|
||||
aList = append(aList, aOrder)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(orderList) < param.PageSize {
|
||||
break
|
||||
}
|
||||
param.PageNum++
|
||||
}
|
||||
return aList, err
|
||||
}
|
||||
|
||||
func GetWeimobOrderDetail(orderNo int64) (order *weimobapi.OrderDetail, err error) {
|
||||
return api.WeimobAPI.QueryOrderDetail2(orderNo, false)
|
||||
}
|
||||
|
||||
func GetSingleOrderResultList(params map[string]interface{}) (result []*OrderList, err error) {
|
||||
weimobOrderID := params["keyword"].(string)
|
||||
orderSingle, err := GetWeimobOrderDetail(utils.Str2Int64(weimobOrderID))
|
||||
orderList := &OrderList{
|
||||
Name: orderSingle.DeliveryDetail.LogisticsDeliveryDetail.ReceiverName,
|
||||
Phone: orderSingle.DeliveryDetail.LogisticsDeliveryDetail.ReceiverMobile,
|
||||
OrderNo: orderSingle.OrderNo,
|
||||
}
|
||||
result = append(result, orderList)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func ContainsKeyword(v *weimobapi.OrderInfo, keyword string) bool {
|
||||
return strings.Contains(v.ReceiverName, keyword) || strings.Contains(utils.Int64ToStr(v.OrderNo), keyword) || strings.Contains(v.ReceiverMobile, keyword)
|
||||
}
|
||||
|
||||
func GetWeimobOrdersExcel(ctx *jxcontext.Context, OrderNo string) (err error) {
|
||||
var (
|
||||
DataFineList []*Data //精品
|
||||
DataHairyList []*Data //毛菜
|
||||
)
|
||||
orderSingle, err := GetWeimobOrderDetail(utils.Str2Int64(OrderNo))
|
||||
itemList := orderSingle.ItemList
|
||||
for _, v := range itemList {
|
||||
if v.GoodsCode[0:1] == "0" {
|
||||
DataHairy := &Data{
|
||||
GoodsID: v.GoodsCode,
|
||||
GoodsName: v.GoodsTitle,
|
||||
GoodsNum: v.SkuNum,
|
||||
}
|
||||
DataHairyList = append(DataHairyList, DataHairy)
|
||||
} else {
|
||||
DataFine := &Data{
|
||||
GoodsID: v.GoodsCode,
|
||||
GoodsName: v.GoodsTitle,
|
||||
GoodsNum: v.SkuNum,
|
||||
}
|
||||
DataFineList = append(DataFineList, DataFine)
|
||||
}
|
||||
}
|
||||
WriteToExcel2(ctx, DataFineList, DataHairyList)
|
||||
return err
|
||||
}
|
||||
|
||||
func WriteToExcel2(ctx *jxcontext.Context, DataFineList, DataHairyList []*Data) (err error) {
|
||||
var (
|
||||
sheetList1 []*excel.Obj2ExcelSheetConfig
|
||||
sheetList2 []*excel.Obj2ExcelSheetConfig
|
||||
downloadURL1, downloadURL2 string
|
||||
fileName1, fileName2 string
|
||||
noticeMsg string
|
||||
)
|
||||
excelConf1 := &excel.Obj2ExcelSheetConfig{
|
||||
Title: "sheet1",
|
||||
Data: DataFineList,
|
||||
CaptionList: titleList,
|
||||
}
|
||||
sheetList1 = append(sheetList1, excelConf1)
|
||||
excelConf2 := &excel.Obj2ExcelSheetConfig{
|
||||
Title: "sheet1",
|
||||
Data: DataHairyList,
|
||||
CaptionList: titleList,
|
||||
}
|
||||
sheetList2 = append(sheetList2, excelConf2)
|
||||
noticeMsg += "[详情点我]"
|
||||
if len(DataFineList) > 0 {
|
||||
downloadURL1, fileName1, err = UploadExeclAndPushMsg(sheetList1, "京西采购_精品")
|
||||
noticeMsg += "path1=" + downloadURL1 + " "
|
||||
} else {
|
||||
baseapi.SugarLogger.Debug("WriteToExcel: DataFineList is nil!")
|
||||
}
|
||||
if len(DataHairyList) > 0 {
|
||||
downloadURL2, fileName2, err = UploadExeclAndPushMsg(sheetList2, "京西采购_毛菜")
|
||||
noticeMsg += "path2=" + downloadURL2
|
||||
} else {
|
||||
baseapi.SugarLogger.Debug("WriteToExcel: DataHairyList is nil!")
|
||||
}
|
||||
if err != nil {
|
||||
baseapi.SugarLogger.Errorf("WriteToExcel:upload %s , %s failed error:%v", fileName1, fileName2, err)
|
||||
} else {
|
||||
if authInfo, err := ctx.GetV2AuthInfo(); err == nil {
|
||||
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, authInfo.UserID, "导出微盟订单商品成功", noticeMsg)
|
||||
baseapi.SugarLogger.Debugf("WriteToExcel:upload %s ,%s success, downloadURL1:%s ,downloadURL2:%s", fileName1, fileName2, downloadURL1, downloadURL2)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -466,7 +466,7 @@ func GetVendorName(vendorID int) (vendorName string) {
|
||||
|
||||
func CaculateSkuEarningPrice(shopPrice, salePrice int64, storePayPercentage int) (earningPrice int64) {
|
||||
earningPrice = salePrice
|
||||
if shopPrice > 0 && shopPrice < earningPrice {
|
||||
if salePrice == 0 || shopPrice > 0 && shopPrice < earningPrice {
|
||||
earningPrice = shopPrice
|
||||
}
|
||||
if storePayPercentage <= 0 {
|
||||
|
||||
@@ -63,7 +63,7 @@ func GetStatisticsReportForOrders(db *DaoDB, storeIDs []int, fromDate time.Time,
|
||||
LEFT JOIN
|
||||
(
|
||||
SELECT
|
||||
a.store_id,
|
||||
IF(a.jx_store_id <> 0,a.jx_store_id,store_id) store_id,
|
||||
COUNT(*) order_counts,
|
||||
SUM(sale_price) sale_price,
|
||||
SUM(actual_pay_price) actual_pay_price,
|
||||
@@ -88,11 +88,11 @@ func GetStatisticsReportForOrders(db *DaoDB, storeIDs []int, fromDate time.Time,
|
||||
sqlParams = append(sqlParams, fromDate, toDate)
|
||||
}
|
||||
if len(storeIDs) > 0 {
|
||||
sql += ` AND a.store_id IN(` + GenQuestionMarks(len(storeIDs)) + `)`
|
||||
sql += ` AND IF(a.jx_store_id != 0, a.jx_store_id, a.store_id) IN(` + GenQuestionMarks(len(storeIDs)) + `)`
|
||||
sqlParams = append(sqlParams, storeIDs)
|
||||
}
|
||||
sql += `
|
||||
GROUP BY a.store_id
|
||||
GROUP BY 1
|
||||
)s
|
||||
ON s.store_id = c.id
|
||||
`
|
||||
@@ -136,7 +136,7 @@ func GetGetStatisticsReportForAfsOrders(db *DaoDB, storeIDs []int, fromDate time
|
||||
LEFT JOIN
|
||||
(
|
||||
SELECT
|
||||
a.store_id,
|
||||
IF(a.jx_store_id <> 0,a.jx_store_id,store_id) store_id,
|
||||
COUNT(*) order_counts,
|
||||
SUM(sale_price) sale_price,
|
||||
SUM(actual_pay_price) actual_pay_price,
|
||||
@@ -160,11 +160,11 @@ func GetGetStatisticsReportForAfsOrders(db *DaoDB, storeIDs []int, fromDate time
|
||||
sqlParams = append(sqlParams, fromDate, toDate)
|
||||
}
|
||||
if len(storeIDs) > 0 {
|
||||
sql += ` AND a.store_id IN(` + GenQuestionMarks(len(storeIDs)) + `)`
|
||||
sql += ` AND IF(a.jx_store_id != 0, a.jx_store_id, a.store_id) IN(` + GenQuestionMarks(len(storeIDs)) + `)`
|
||||
sqlParams = append(sqlParams, storeIDs)
|
||||
}
|
||||
sql += `
|
||||
GROUP BY a.store_id
|
||||
GROUP BY 1
|
||||
)s
|
||||
ON s.store_id = c.id
|
||||
`
|
||||
|
||||
@@ -236,9 +236,9 @@ var (
|
||||
StoreAuditStatusRejected: "拒绝",
|
||||
}
|
||||
StorePriceTypeName = map[int]string{
|
||||
StoreChangePriceTypeDirect: "可直接改价",
|
||||
StoreChangePriceTypeBossDisabled: "禁止改价",
|
||||
StoreChangePriceTypeManagedStore: "直营门店",
|
||||
StoreChangePriceTypeDirect: "普通门店",
|
||||
StoreChangePriceTypeBossDisabled: "普通门店禁止改价",
|
||||
StoreChangePriceTypeManagedStore: "直营门店禁止改价",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@ import (
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
)
|
||||
|
||||
const (
|
||||
actMapDuration = 2 * time.Hour
|
||||
)
|
||||
|
||||
type LogicUpdateInfo struct {
|
||||
Item interface{}
|
||||
KVs map[string]interface{}
|
||||
@@ -31,6 +35,8 @@ var (
|
||||
jdapi.PromotionStateCanceled: model.ActStatusCanceled,
|
||||
jdapi.PromotionStateEnded: model.ActStatusEnded,
|
||||
}
|
||||
|
||||
actMap jxutils.SyncMapWithTimeout
|
||||
)
|
||||
|
||||
func splitPromotionSku(skus []*jdapi.PromotionSku, maxCount int) (skusList [][]*jdapi.PromotionSku) {
|
||||
@@ -62,22 +68,25 @@ func jdSkuActStatus2Jx(jdActState int) int {
|
||||
func CreatePromotionInfos(promotionType int, name string, beginDate, endDate time.Time, outInfoId, advertising, traceId string) (infoId int64, err error) {
|
||||
if globals.EnableJdStoreWrite {
|
||||
if promotionType == model.ActSkuDirectDown {
|
||||
return getAPI("").CreatePromotionInfosSingle(name, beginDate, endDate, outInfoId, advertising, traceId)
|
||||
infoId, err = getAPI("").CreatePromotionInfosSingle(name, beginDate, endDate, outInfoId, advertising, traceId)
|
||||
} else {
|
||||
return getAPI("").CreatePromotionInfosLimitTime(name, beginDate, endDate, outInfoId, advertising, traceId)
|
||||
infoId, err = getAPI("").CreatePromotionInfosLimitTime(name, beginDate, endDate, outInfoId, advertising, traceId)
|
||||
}
|
||||
} else {
|
||||
infoId = jxutils.GenFakeID()
|
||||
}
|
||||
if err == nil {
|
||||
actMap.StoreWithTimeout(infoId, 1, actMapDuration)
|
||||
}
|
||||
return infoId, err
|
||||
}
|
||||
|
||||
func CreatePromotionRules(promotionType int, infoId int64, outInfoId string, limitDevice, limitPin, limitCount, limitDaily int, traceId string) (err error) {
|
||||
if globals.EnableJdStoreWrite {
|
||||
if promotionType == model.ActSkuDirectDown {
|
||||
return getAPI("").CreatePromotionRulesSingle(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily, traceId)
|
||||
err = getAPI("").CreatePromotionRulesSingle(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily, traceId)
|
||||
} else {
|
||||
return getAPI("").CreatePromotionRulesLimitTime(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily, traceId)
|
||||
err = getAPI("").CreatePromotionRulesLimitTime(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily, traceId)
|
||||
}
|
||||
}
|
||||
return err
|
||||
@@ -133,9 +142,9 @@ func ConfirmPromotion(promotionType int, infoId int64, outInfoId, traceId string
|
||||
func CancelPromotion(promotionType int, infoId int64, outInfoId, traceId string) (err error) {
|
||||
if globals.EnableJdStoreWrite {
|
||||
if promotionType == model.ActSkuDirectDown {
|
||||
return getAPI("").CancelPromotionSingle(infoId, outInfoId, traceId)
|
||||
err = getAPI("").CancelPromotionSingle(infoId, outInfoId, traceId)
|
||||
} else {
|
||||
return getAPI("").CancelPromotionLimitTime(infoId, outInfoId, traceId)
|
||||
err = getAPI("").CancelPromotionLimitTime(infoId, outInfoId, traceId)
|
||||
}
|
||||
}
|
||||
return err
|
||||
@@ -144,9 +153,9 @@ func CancelPromotion(promotionType int, infoId int64, outInfoId, traceId string)
|
||||
func AdjustPromotionTime(promotionType int, infoId int64, outInfoId string, endDate time.Time, traceId string) (err error) {
|
||||
if globals.EnableJdStoreWrite {
|
||||
if promotionType == model.ActSkuDirectDown {
|
||||
return getAPI("").AdjustPromotionTimeSingle(infoId, outInfoId, endDate, traceId)
|
||||
err = getAPI("").AdjustPromotionTimeSingle(infoId, outInfoId, endDate, traceId)
|
||||
} else {
|
||||
return getAPI("").AdjustPromotionTimeLimitTime(infoId, outInfoId, endDate, traceId)
|
||||
err = getAPI("").AdjustPromotionTimeLimitTime(infoId, outInfoId, endDate, traceId)
|
||||
}
|
||||
}
|
||||
return err
|
||||
@@ -155,9 +164,9 @@ func AdjustPromotionTime(promotionType int, infoId int64, outInfoId string, endD
|
||||
func AdjustPromotionSku(promotionType int, infoId int64, outInfoId string, skus []*jdapi.PromotionSku, traceId string) (skusResult []*jdapi.PromotionSku, err error) {
|
||||
if globals.EnableJdStoreWrite {
|
||||
if promotionType == model.ActSkuDirectDown {
|
||||
return getAPI("").AdjustPromotionSkuSingle(infoId, outInfoId, skus, traceId)
|
||||
skusResult, err = getAPI("").AdjustPromotionSkuSingle(infoId, outInfoId, skus, traceId)
|
||||
} else {
|
||||
return getAPI("").AdjustPromotionSkuLimitTime(infoId, outInfoId, skus, traceId)
|
||||
skusResult, err = getAPI("").AdjustPromotionSkuLimitTime(infoId, outInfoId, skus, traceId)
|
||||
}
|
||||
}
|
||||
return skusResult, err
|
||||
@@ -312,19 +321,22 @@ func OnActMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
|
||||
func (c *PurchaseHandler) onActMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
|
||||
if msg.StatusID == jdapi.PromotionStatusSingleOK || msg.StatusID == jdapi.PromotionStatusLimitTimeOK {
|
||||
promotionID := msg.BillID
|
||||
// 等几秒再执行的原因是防止通过后台自己创建时,本地还没有建好,消息就过来,导致重复记录
|
||||
// 可能的问题是在重启时丢失消息
|
||||
utils.AfterFuncWithRecover(5*time.Second, func() {
|
||||
if !partner.CurActManager.IsVendorActExist(jxcontext.AdminCtx, promotionID, model.VendorIDJD) {
|
||||
act, actStoreSkuList, err := getActFromJD(promotionID)
|
||||
if err == nil && len(actStoreSkuList) > 0 {
|
||||
_, err = partner.CurActManager.CreateActFromVendor(jxcontext.AdminCtx, act, actStoreSkuList)
|
||||
intPromotionID := utils.Str2Int64(promotionID)
|
||||
if _, ok := actMap.Load(intPromotionID); !ok {
|
||||
utils.CallFuncAsync(func() {
|
||||
if !partner.CurActManager.IsVendorActExist(jxcontext.AdminCtx, promotionID, model.VendorIDJD) {
|
||||
act, actStoreSkuList, err := getActFromJD(promotionID)
|
||||
if err == nil && len(actStoreSkuList) > 0 {
|
||||
_, err = partner.CurActManager.CreateActFromVendor(jxcontext.AdminCtx, act, actStoreSkuList)
|
||||
}
|
||||
if err != nil {
|
||||
retVal = jdapi.Err2CallbackResponse(err, promotionID)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
retVal = jdapi.Err2CallbackResponse(err, promotionID)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
actMap.Delete(intPromotionID)
|
||||
}
|
||||
}
|
||||
return retVal
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ func OnFinancialMsg(msg *mtwmapi.CallbackMsg) (err error) {
|
||||
func (p *PurchaseHandler) OrderFinancialDetail2Refund(orderFinancial *model.OrderFinancial, orderData url.Values) (afsOrder *model.AfsOrder) {
|
||||
afsOrder = &model.AfsOrder{
|
||||
VendorID: model.VendorIDMTWM,
|
||||
AfsOrderID: orderData.Get("order_id"),
|
||||
AfsOrderID: orderData.Get("refund_id"),
|
||||
VendorOrderID: orderData.Get("order_id"),
|
||||
AfsCreatedAt: utils.Timestamp2Time(utils.Str2Int64(orderData.Get("timestamp"))),
|
||||
// BoxMoney: orderFinancial.BoxMoney,
|
||||
|
||||
@@ -121,7 +121,9 @@ func openTimeMtwm2JX(vendorOpenTime string) (opTimeList []int16) {
|
||||
timePairs := strings.Split(vendorOpenTime, ",")
|
||||
for _, v := range timePairs {
|
||||
times := strings.Split(v, "-")
|
||||
opTimeList = append(opTimeList, jxutils.StrTime2JxOperationTime(times[0]+":00", 700), jxutils.StrTime2JxOperationTime(times[1]+":00", 2000))
|
||||
if len(times) >= 2 {
|
||||
opTimeList = append(opTimeList, jxutils.StrTime2JxOperationTime(times[0]+":00", 700), jxutils.StrTime2JxOperationTime(times[1]+":00", 2000))
|
||||
}
|
||||
}
|
||||
return opTimeList
|
||||
}
|
||||
|
||||
@@ -514,20 +514,6 @@ func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *mode
|
||||
return mobile, err
|
||||
}
|
||||
|
||||
// func (c *PurchaseHandler) GetStatusActionTimeout(order *model.GoodsOrder, statusType, status int) (params *partner.StatusActionParams) {
|
||||
// if statusType == scheduler.TimerStatusTypeOrder && status == model.OrderStatusAccepted {
|
||||
// params = &partner.StatusActionParams{ // PickDeadline没有设置时才有效,美团外卖要求在5分钟内拣货,不然订单会被取消
|
||||
// Timeout: pickupOrderDelay,
|
||||
// }
|
||||
// } else if statusType == scheduler.TimerStatusTypeOrder && status == model.OrderStatusFinishedPickup {
|
||||
// params = &partner.StatusActionParams{ // 立即达订单有效,自配送延时召唤配送
|
||||
// Timeout: callDeliveryDelay,
|
||||
// TimeoutGap: callDeliveryDelayGap,
|
||||
// }
|
||||
// }
|
||||
// return params
|
||||
// }
|
||||
|
||||
func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) {
|
||||
if globals.EnableMtwmStoreWrite {
|
||||
if isAgree {
|
||||
|
||||
@@ -2,6 +2,7 @@ package mtwm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
||||
@@ -119,8 +120,9 @@ func (c *PurchaseHandler) onAfsOrderMsg(msg *mtwmapi.CallbackMsg) (retVal *mtwma
|
||||
}
|
||||
afsOrder.PmSubsidyMoney += afsOrder.RefundMoney - afsOrder.SkuUserMoney
|
||||
} else {
|
||||
if orderFinancial, err2 := partner.CurOrderManager.LoadOrderFinancial(orderStatus.RefVendorOrderID, model.VendorIDMTWM); err2 == nil {
|
||||
afsOrder = c.OrderFinancialDetail2Refund(orderFinancial, msg.FormData)
|
||||
if afsOrder = c.createAfsOrder(msg.FormData); afsOrder != nil {
|
||||
// if orderFinancial, err2 := partner.CurOrderManager.LoadOrderFinancial(orderStatus.RefVendorOrderID, model.VendorIDMTWM); err2 == nil {
|
||||
// afsOrder = c.OrderFinancialDetail2Refund(orderFinancial, msg.FormData)
|
||||
afsOrder.AfsOrderID = orderStatus.VendorOrderID
|
||||
afsOrder.RefundType = model.AfsTypeFullRefund
|
||||
afsOrder.AppealType = model.AfsAppealTypeRefund
|
||||
@@ -139,6 +141,52 @@ func (c *PurchaseHandler) onAfsOrderMsg(msg *mtwmapi.CallbackMsg) (retVal *mtwma
|
||||
return mtwmapi.Err2CallbackResponse(err, "")
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) createAfsOrder(orderData url.Values) (afsOrder *model.AfsOrder) {
|
||||
afsOrder = &model.AfsOrder{
|
||||
VendorID: model.VendorIDMTWM,
|
||||
AfsOrderID: orderData.Get("refund_id"),
|
||||
VendorOrderID: orderData.Get("order_id"),
|
||||
AfsCreatedAt: utils.Timestamp2Time(utils.Str2Int64(orderData.Get("timestamp"))),
|
||||
}
|
||||
if afsOrder.AfsOrderID == "" {
|
||||
afsOrder.AfsOrderID = afsOrder.VendorOrderID
|
||||
}
|
||||
order, err := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID)
|
||||
globals.SugarLogger.Debug(utils.Format4Output(order, false))
|
||||
if err == nil {
|
||||
afsOrder.JxStoreID = order.JxStoreID
|
||||
afsOrder.VendorStoreID = order.VendorStoreID
|
||||
afsOrder.StoreID = order.StoreID
|
||||
} else {
|
||||
globals.SugarLogger.Warnf("mtwm AfsOrderDetail2Financial, afsOrderID:%s is not found from partner.CurOrderManager.LoadOrder", afsOrder.VendorOrderID)
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, sku := range order.Skus {
|
||||
orderSkuFinancial := &model.OrderSkuFinancial{
|
||||
VendorID: sku.VendorID,
|
||||
VendorOrderID: sku.VendorOrderID,
|
||||
// OrderFinancialID: sku.VendorOrderID,
|
||||
// ConfirmTime: afsOrder.AfsCreateAt,
|
||||
VendorStoreID: afsOrder.VendorStoreID,
|
||||
StoreID: afsOrder.StoreID,
|
||||
JxStoreID: afsOrder.JxStoreID,
|
||||
VendorSkuID: sku.VendorSkuID,
|
||||
SkuID: sku.SkuID,
|
||||
PromotionType: sku.PromotionType,
|
||||
Name: sku.SkuName,
|
||||
ShopPrice: sku.ShopPrice,
|
||||
SalePrice: sku.SalePrice,
|
||||
Count: sku.Count,
|
||||
// UserMoney: sku.UserMoney,
|
||||
// PmSubsidyMoney: sku.PmSubsidyMoney,
|
||||
IsAfsOrder: 1,
|
||||
}
|
||||
afsOrder.Skus = append(afsOrder.Skus, orderSkuFinancial)
|
||||
}
|
||||
return afsOrder
|
||||
}
|
||||
|
||||
func (c *PurchaseHandler) callbackAfsMsg2Status(msg *mtwmapi.CallbackMsg) (orderStatus *model.OrderStatus) {
|
||||
refundData := msg.Data.(*mtwmapi.CallbackRefundInfo)
|
||||
orderStatus = &model.OrderStatus{
|
||||
@@ -153,6 +201,8 @@ func (c *PurchaseHandler) callbackAfsMsg2Status(msg *mtwmapi.CallbackMsg) (order
|
||||
}
|
||||
if refundData.RefundID > 0 {
|
||||
orderStatus.VendorOrderID = utils.Int64ToStr(refundData.RefundID)
|
||||
} else {
|
||||
orderStatus.VendorOrderID = orderStatus.RefVendorOrderID
|
||||
}
|
||||
return orderStatus
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@ const (
|
||||
|
||||
const (
|
||||
defVendorCatID = 200001903 // 生菜
|
||||
|
||||
specialStoreID = "8171010"
|
||||
// specialStoreID = "2523687"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -197,12 +200,35 @@ func (p *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) {
|
||||
return mtwmapi.IsErrSkuNotExist(err)
|
||||
}
|
||||
|
||||
// func duplicateStoreSkuList(storeSkuList []*dao.StoreSkuSyncInfo, index int) (newStoreSkuList []*dao.StoreSkuSyncInfo) {
|
||||
// newStoreSkuList = make([]*dao.StoreSkuSyncInfo, len(storeSkuList))
|
||||
// for k, v := range storeSkuList {
|
||||
// tmp := *v
|
||||
// tmp.SkuName = fmt.Sprintf("%s.%d", tmp.SkuName, index)
|
||||
// tmp.SkuID = index*1000000 + tmp.SkuID
|
||||
// newStoreSkuList[k] = &tmp
|
||||
// }
|
||||
// return newStoreSkuList
|
||||
// }
|
||||
|
||||
func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (successList []*dao.StoreSkuSyncInfo, err error) {
|
||||
return p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, false)
|
||||
successList, err = p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, false)
|
||||
// if err == nil && vendorStoreID == specialStoreID {
|
||||
// for i := 0; i < 2; i++ {
|
||||
// p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, duplicateStoreSkuList(storeSkuList, i+1), true)
|
||||
// }
|
||||
// }
|
||||
return successList, err
|
||||
}
|
||||
|
||||
func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (successList []*dao.StoreSkuSyncInfo, err error) {
|
||||
return p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, true)
|
||||
successList, err = p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, true)
|
||||
// if err == nil && vendorStoreID == specialStoreID {
|
||||
// for i := 0; i < 2; i++ {
|
||||
// p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, duplicateStoreSkuList(storeSkuList, i+1), true)
|
||||
// }
|
||||
// }
|
||||
return successList, err
|
||||
}
|
||||
|
||||
// 对于多门店平台来说,storeSkuList中只有SkuID与VendorSkuID有意义
|
||||
@@ -235,7 +261,15 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI
|
||||
foodData["category_name"] = storeSku.VendorCatID
|
||||
}
|
||||
foodData["is_sold_out"] = skuStatusJX2Mtwm(storeSku.MergedStatus)
|
||||
foodData["picture"] = strings.Join(jxutils.BatchString2Slice(storeSku.Img, storeSku.Img2), ",")
|
||||
if true { // vendorStoreID == specialStoreID {
|
||||
img2 := storeSku.Img2
|
||||
if img2 == "" {
|
||||
img2 = storeSku.Img
|
||||
}
|
||||
foodData["picture"] = strings.Join(jxutils.BatchString2Slice(storeSku.Img, img2, storeSku.Img, storeSku.Img, storeSku.Img), ",")
|
||||
} else {
|
||||
foodData["picture"] = strings.Join(jxutils.BatchString2Slice(storeSku.Img, storeSku.Img2), ",")
|
||||
}
|
||||
if storeSku.DescImg != "" {
|
||||
foodData["picture_contents"] = storeSku.DescImg
|
||||
}
|
||||
|
||||
@@ -18,17 +18,19 @@ import (
|
||||
)
|
||||
|
||||
func GetComposedCode(c *beego.Controller, code string) (composedCode string) {
|
||||
composedCode = code
|
||||
referer := c.Ctx.Request.Referer()
|
||||
globals.SugarLogger.Debugf("GetComposedCode referer:%s", referer)
|
||||
index := strings.Index(referer, "//")
|
||||
if index > 0 {
|
||||
list := strings.Split(referer[index+2:], "/")
|
||||
if len(list) >= 2 {
|
||||
composedCode = strings.Join([]string{
|
||||
list[1],
|
||||
code,
|
||||
}, ",")
|
||||
if code != "" {
|
||||
composedCode = code
|
||||
referer := c.Ctx.Request.Referer()
|
||||
globals.SugarLogger.Debugf("GetComposedCode referer:%s", referer)
|
||||
index := strings.Index(referer, "//")
|
||||
if index > 0 {
|
||||
list := strings.Split(referer[index+2:], "/")
|
||||
if len(list) >= 2 {
|
||||
composedCode = strings.Join([]string{
|
||||
list[1],
|
||||
code,
|
||||
}, ",")
|
||||
}
|
||||
}
|
||||
}
|
||||
return composedCode
|
||||
|
||||
@@ -381,9 +381,9 @@ func (c *User2Controller) GetSelfInfo() {
|
||||
// @Title 根据小程序jsCode修改用户信息
|
||||
// @Description 根据小程序jsCode修改用户信息
|
||||
// @Param token header string true "认证token"
|
||||
// @Param jsCode query string true "小程序jsCode"
|
||||
// @Param data query string true "加密数据"
|
||||
// @Param iv query string true "iv"
|
||||
// @Param jsCode query string false "小程序jsCode"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /UpdateUserByMiniInfo [put]
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"io"
|
||||
|
||||
"git.rosy.net.cn/jx-callback/business/jxstore/yonghui"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||
"github.com/astaxie/beego"
|
||||
)
|
||||
|
||||
@@ -14,7 +15,7 @@ type YongHuiController struct {
|
||||
|
||||
// @Title 读取永辉excel文件
|
||||
// @Description 读取永辉excel文件
|
||||
// @Param token header string false "认证token"
|
||||
// @Param token header string true "认证token"
|
||||
// @Param isAsync query bool true "是否异步,缺省是同步"
|
||||
// @Param isContinueWhenError query bool true "单个同步失败是否继续,缺省false"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
@@ -42,3 +43,52 @@ func (c *YongHuiController) LoadExcelByYongHui() {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// @Title 根据微盟商品更新京西价格
|
||||
// @Description 根据微盟商品更新京西价格
|
||||
// @Param token header string true "认证token"
|
||||
// @Param storeIDs formData string true "门店ID列表"
|
||||
// @Param isAsync formData bool true "是否异步,缺省是同步"
|
||||
// @Param isContinueWhenError formData bool true "单个同步失败是否继续,缺省false"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /UpdateJxPriceByWeimob [post]
|
||||
func (c *YongHuiController) UpdateJxPriceByWeimob() {
|
||||
c.callUpdateJxPriceByWeimob(func(params *tYonghuiUpdateJxPriceByWeimobParams) (retVal interface{}, errCode string, err error) {
|
||||
var storeIDList []int
|
||||
if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDList); err == nil {
|
||||
retVal, err = yonghui.UpdateJxPriceByWeimob(params.Ctx, storeIDList, params.IsAsync, params.IsContinueWhenError)
|
||||
}
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 查询微盟订单
|
||||
// @Description 查询微盟订单
|
||||
// @Param token header string true "认证token"
|
||||
// @Param keyword query string false "查询关键字"
|
||||
// @Param fromTime formData string false "订单起始时间 (yyyy-mm-dd 00:00:00)"
|
||||
// @Param toTime formData string false "订单结束时间 (yyyy-mm-dd 00:00:00)"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /GetWeimobOrders [post]
|
||||
func (c *YongHuiController) GetWeimobOrders() {
|
||||
c.callGetWeimobOrders(func(params *tYonghuiGetWeimobOrdersParams) (retVal interface{}, errCode string, err error) {
|
||||
retVal, err = yonghui.GetWeimobOrders(params.Ctx, params.FromTime, params.ToTime, params.MapData)
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
// @Title 根据微盟订单号生成Excel
|
||||
// @Description 根据微盟订单号生成Excel
|
||||
// @Param token header string true "认证token"
|
||||
// @Param orderNo formData string true "订单号"
|
||||
// @Success 200 {object} controllers.CallResult
|
||||
// @Failure 200 {object} controllers.CallResult
|
||||
// @router /GetWeimobOrdersExcel [post]
|
||||
func (c *YongHuiController) GetWeimobOrdersExcel() {
|
||||
c.callGetWeimobOrdersExcel(func(params *tYonghuiGetWeimobOrdersExcelParams) (retVal interface{}, errCode string, err error) {
|
||||
err = yonghui.GetWeimobOrdersExcel(params.Ctx, params.OrderNo)
|
||||
return retVal, "", err
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2016,6 +2016,24 @@ func init() {
|
||||
Filters: nil,
|
||||
Params: nil})
|
||||
|
||||
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:YongHuiController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:YongHuiController"],
|
||||
beego.ControllerComments{
|
||||
Method: "GetWeimobOrders",
|
||||
Router: `/GetWeimobOrders`,
|
||||
AllowHTTPMethods: []string{"post"},
|
||||
MethodParams: param.Make(),
|
||||
Filters: nil,
|
||||
Params: nil})
|
||||
|
||||
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:YongHuiController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:YongHuiController"],
|
||||
beego.ControllerComments{
|
||||
Method: "GetWeimobOrdersExcel",
|
||||
Router: `/GetWeimobOrdersExcel`,
|
||||
AllowHTTPMethods: []string{"post"},
|
||||
MethodParams: param.Make(),
|
||||
Filters: nil,
|
||||
Params: nil})
|
||||
|
||||
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:YongHuiController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:YongHuiController"],
|
||||
beego.ControllerComments{
|
||||
Method: "LoadExcelByYongHui",
|
||||
@@ -2025,4 +2043,13 @@ func init() {
|
||||
Filters: nil,
|
||||
Params: nil})
|
||||
|
||||
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:YongHuiController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:YongHuiController"],
|
||||
beego.ControllerComments{
|
||||
Method: "UpdateJxPriceByWeimob",
|
||||
Router: `/UpdateJxPriceByWeimob`,
|
||||
AllowHTTPMethods: []string{"post"},
|
||||
MethodParams: param.Make(),
|
||||
Filters: nil,
|
||||
Params: nil})
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user