Merge branch 'master' into get-store
This commit is contained in:
@@ -102,7 +102,7 @@ func (c *OrderManager) SaveOrderFinancialInfo(order *model.OrderFinancial, opera
|
|||||||
}
|
}
|
||||||
if err = dao.CreateEntity(db, sku); err != nil {
|
if err = dao.CreateEntity(db, sku); err != nil {
|
||||||
if !dao.IsDuplicateError(err) {
|
if !dao.IsDuplicateError(err) {
|
||||||
globals.SugarLogger.Warnf("On SaveOrderSkuFinancialInfo order.VendorOrderID:%s err: order is err", order.VendorOrderID)
|
globals.SugarLogger.Warnf("On SaveOrderSkuFinancialInfo order.VendorOrderID:%s err:%v", order.VendorOrderID, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dao.Rollback(db)
|
dao.Rollback(db)
|
||||||
@@ -120,7 +120,7 @@ func (c *OrderManager) SaveOrderFinancialInfo(order *model.OrderFinancial, opera
|
|||||||
sku.JxShopMoney = order.JxShopMoney - sku.JxShopMoney
|
sku.JxShopMoney = order.JxShopMoney - sku.JxShopMoney
|
||||||
if err = dao.CreateEntity(db, sku); err != nil {
|
if err = dao.CreateEntity(db, sku); err != nil {
|
||||||
if !dao.IsDuplicateError(err) {
|
if !dao.IsDuplicateError(err) {
|
||||||
globals.SugarLogger.Warnf("On SaveOrderSkuFinancialInfo order.VendorOrderID:%s err: order is err", order.VendorOrderID)
|
globals.SugarLogger.Warnf("On SaveOrderSkuFinancialInfo order.VendorOrderID:%s err:%v", order.VendorOrderID, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dao.Rollback(db)
|
dao.Rollback(db)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package orderman
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi"
|
"git.rosy.net.cn/baseapi"
|
||||||
@@ -11,7 +10,6 @@ import (
|
|||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
"git.rosy.net.cn/jx-callback/business/msghub"
|
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
"github.com/astaxie/beego/orm"
|
"github.com/astaxie/beego/orm"
|
||||||
)
|
)
|
||||||
@@ -51,7 +49,8 @@ func (c *OrderManager) LoadPendingOrders() []*model.GoodsOrder {
|
|||||||
|
|
||||||
// msgVendorStatus的意思是事件本身的类型,类似有时收到NewOrder事件去取,订单状态不一定就是New的
|
// msgVendorStatus的意思是事件本身的类型,类似有时收到NewOrder事件去取,订单状态不一定就是New的
|
||||||
// OnOrderAdjust也类似,而OrderStatus要记录的是消息,所以添加这个
|
// OnOrderAdjust也类似,而OrderStatus要记录的是消息,所以添加这个
|
||||||
func (c *OrderManager) OnOrderNew(order *model.GoodsOrder, msgVendorStatus string) (err error) {
|
func (c *OrderManager) OnOrderNew(order *model.GoodsOrder, orderStatus *model.OrderStatus) (err error) {
|
||||||
|
globals.SugarLogger.Debugf("OnOrderNew orderID:%s", order.VendorOrderID)
|
||||||
if order.ConsigneeMobile2 == "" && !jxutils.IsMobileFake(order.ConsigneeMobile) {
|
if order.ConsigneeMobile2 == "" && !jxutils.IsMobileFake(order.ConsigneeMobile) {
|
||||||
order.ConsigneeMobile2 = order.ConsigneeMobile
|
order.ConsigneeMobile2 = order.ConsigneeMobile
|
||||||
}
|
}
|
||||||
@@ -59,6 +58,7 @@ func (c *OrderManager) OnOrderNew(order *model.GoodsOrder, msgVendorStatus strin
|
|||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
dao.Begin(db)
|
dao.Begin(db)
|
||||||
defer func() {
|
defer func() {
|
||||||
|
globals.SugarLogger.Debugf("OnOrderNew exit orderID:%s", order.VendorOrderID)
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
dao.Rollback(db)
|
dao.Rollback(db)
|
||||||
panic(r)
|
panic(r)
|
||||||
@@ -67,12 +67,7 @@ func (c *OrderManager) OnOrderNew(order *model.GoodsOrder, msgVendorStatus strin
|
|||||||
if order.Status == model.OrderStatusUnknown {
|
if order.Status == model.OrderStatusUnknown {
|
||||||
order.Status = model.OrderStatusNew
|
order.Status = model.OrderStatusNew
|
||||||
}
|
}
|
||||||
status := model.Order2Status(order)
|
isDuplicated, err := addOrderOrWaybillStatus(orderStatus, db)
|
||||||
if status.Status > model.OrderStatusNew {
|
|
||||||
status.Status = model.OrderStatusNew
|
|
||||||
}
|
|
||||||
status.VendorStatus = msgVendorStatus
|
|
||||||
isDuplicated, err := addOrderOrWaybillStatus(status, db)
|
|
||||||
if err == nil && !isDuplicated {
|
if err == nil && !isDuplicated {
|
||||||
isDuplicated, err = c.SaveOrder(order, false, db)
|
isDuplicated, err = c.SaveOrder(order, false, db)
|
||||||
}
|
}
|
||||||
@@ -88,7 +83,7 @@ func (c *OrderManager) OnOrderNew(order *model.GoodsOrder, msgVendorStatus strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// todo 调整单的处理可能还需要再细化一点,当前只是简单的删除重建
|
// todo 调整单的处理可能还需要再细化一点,当前只是简单的删除重建
|
||||||
func (c *OrderManager) OnOrderAdjust(order *model.GoodsOrder, msgVendorStatus string) (err error) {
|
func (c *OrderManager) OnOrderAdjust(order *model.GoodsOrder, orderStatus *model.OrderStatus) (err error) {
|
||||||
if order.ConsigneeMobile2 == "" && !jxutils.IsMobileFake(order.ConsigneeMobile) {
|
if order.ConsigneeMobile2 == "" && !jxutils.IsMobileFake(order.ConsigneeMobile) {
|
||||||
order.ConsigneeMobile2 = order.ConsigneeMobile
|
order.ConsigneeMobile2 = order.ConsigneeMobile
|
||||||
}
|
}
|
||||||
@@ -101,13 +96,12 @@ func (c *OrderManager) OnOrderAdjust(order *model.GoodsOrder, msgVendorStatus st
|
|||||||
panic(r)
|
panic(r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if order.Status == model.OrderStatusUnknown {
|
// 出现过调整单后,状态回到新订单状态,比如:911350836000622
|
||||||
|
// 不完全确定,加一个处理
|
||||||
|
if order.Status < model.OrderStatusAccepted {
|
||||||
order.Status = model.OrderStatusAccepted
|
order.Status = model.OrderStatusAccepted
|
||||||
}
|
}
|
||||||
status := model.Order2Status(order)
|
isDuplicated, err := addOrderOrWaybillStatus(orderStatus, db)
|
||||||
status.Status = model.OrderStatusAdjust
|
|
||||||
status.VendorStatus = msgVendorStatus
|
|
||||||
isDuplicated, err := addOrderOrWaybillStatus(status, db)
|
|
||||||
if err == nil && !isDuplicated {
|
if err == nil && !isDuplicated {
|
||||||
err = utils.CallFuncLogError(func() error {
|
err = utils.CallFuncLogError(func() error {
|
||||||
_, err = db.Db.Raw("DELETE FROM order_sku WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID).Exec()
|
_, err = db.Db.Raw("DELETE FROM order_sku WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID).Exec()
|
||||||
@@ -128,10 +122,9 @@ func (c *OrderManager) OnOrderAdjust(order *model.GoodsOrder, msgVendorStatus st
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
dao.Commit(db)
|
dao.Commit(db)
|
||||||
if !isDuplicated {
|
if !isDuplicated {
|
||||||
msghub.OnNewOrder(order)
|
|
||||||
// 因为订单调度器需要的是真实状态,所以用order的状态
|
// 因为订单调度器需要的是真实状态,所以用order的状态
|
||||||
_ = scheduler.CurrentScheduler.OnOrderNew(order, false)
|
_ = scheduler.CurrentScheduler.OnOrderNew(order, false)
|
||||||
_ = scheduler.CurrentScheduler.OnOrderStatusChanged(order, model.Order2Status(order), false)
|
_ = scheduler.CurrentScheduler.OnOrderStatusChanged(order, orderStatus, false)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dao.Rollback(db)
|
dao.Rollback(db)
|
||||||
@@ -171,7 +164,7 @@ func (c *OrderManager) OnOrderMsg(order *model.GoodsOrder, vendorStatus, remark
|
|||||||
VendorStatus: vendorStatus,
|
VendorStatus: vendorStatus,
|
||||||
Status: model.OrderStatusMsg,
|
Status: model.OrderStatusMsg,
|
||||||
StatusTime: time.Now(),
|
StatusTime: time.Now(),
|
||||||
Remark: remark,
|
Remark: utils.LimitUTF8StringLen(remark, 255),
|
||||||
}, nil)
|
}, nil)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -207,11 +200,12 @@ func (c *OrderManager) SaveOrder(order *model.GoodsOrder, isAdjust bool, db *dao
|
|||||||
order.Status = orderStatus.Status
|
order.Status = orderStatus.Status
|
||||||
order.VendorStatus = orderStatus.VendorStatus
|
order.VendorStatus = orderStatus.VendorStatus
|
||||||
order.StatusTime = orderStatus.StatusTime
|
order.StatusTime = orderStatus.StatusTime
|
||||||
|
|
||||||
|
jxutils.RefreshOrderSkuRelated(order)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
order.OrderCreatedAt = order.StatusTime
|
|
||||||
// globals.SugarLogger.Debugf("saveOrder isAdjust:%t, order:%v", isAdjust, order)
|
// globals.SugarLogger.Debugf("saveOrder isAdjust:%t, order:%v", isAdjust, order)
|
||||||
created, _, err2 := db.Db.ReadOrCreate(order, "VendorOrderID", "VendorID")
|
created, _, err2 := db.Db.ReadOrCreate(order, "VendorOrderID", "VendorID")
|
||||||
if err = err2; err == nil {
|
if err = err2; err == nil {
|
||||||
@@ -223,22 +217,8 @@ func (c *OrderManager) SaveOrder(order *model.GoodsOrder, isAdjust bool, db *dao
|
|||||||
}
|
}
|
||||||
if _, _, err = db.Db.ReadOrCreate(originalOrder, "VendorOrderID", "VendorID"); err == nil {
|
if _, _, err = db.Db.ReadOrCreate(originalOrder, "VendorOrderID", "VendorID"); err == nil {
|
||||||
if created {
|
if created {
|
||||||
sql := `INSERT INTO order_sku(vendor_order_id, vendor_id, count, vendor_sku_id, sku_id, jx_sku_id, sku_name,
|
if err = dao.CreateMultiEntities(db, order.Skus); err != nil {
|
||||||
shop_price, sale_price, weight, sku_type, promotion_type, order_created_at) VALUES`
|
baseapi.SugarLogger.Warnf("saveOrder orderID:%s, save order_sku failed with error:%v", order.VendorOrderID, err)
|
||||||
params := []interface{}{}
|
|
||||||
for _, sku := range order.Skus {
|
|
||||||
sql += "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?),"
|
|
||||||
// 有时不是通过京西平台建立的SKU,不范围要超过
|
|
||||||
skuID := 0
|
|
||||||
if sku.SkuID < math.MaxInt32 {
|
|
||||||
skuID = sku.SkuID
|
|
||||||
}
|
|
||||||
params = append(params, sku.VendorOrderID, sku.VendorID, sku.Count, sku.VendorSkuID, skuID, sku.JxSkuID, sku.SkuName,
|
|
||||||
sku.ShopPrice, sku.SalePrice, sku.Weight, sku.SkuType, sku.PromotionType, order.OrderCreatedAt)
|
|
||||||
}
|
|
||||||
sql = sql[:len(sql)-1] + ";"
|
|
||||||
if _, err = db.Db.Raw(sql, params...).Exec(); err != nil {
|
|
||||||
baseapi.SugarLogger.Warnf("saveOrder insert order:%v, order_sku error:%v", order, err)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
isDuplicated = true
|
isDuplicated = true
|
||||||
@@ -256,12 +236,35 @@ func (c *OrderManager) SaveOrder(order *model.GoodsOrder, isAdjust bool, db *dao
|
|||||||
return isDuplicated, err
|
return isDuplicated, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getPromotionSkuPriceMap(db *dao.DaoDB, storeID int, skuIDs []int) (skuPriceMap map[int64]*model.PromotionSku, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT t3.*
|
||||||
|
FROM promotion t1
|
||||||
|
JOIN promotion_store t2 ON t2.promotion_id = t1.id AND t2.store_id = ?
|
||||||
|
JOIN promotion_sku t3 ON t3.promotion_id = t1.id AND t3.sku_id IN (` + dao.GenQuestionMarks(len(skuIDs)) + `) AND t3.earning_price > 0
|
||||||
|
WHERE t1.deleted_at = ? AND (t1.status = ? OR t1.status = ?) AND (t1.begin_at <= NOW() AND t1.end_at >= NOW()) AND t1.vendor_id = ?`
|
||||||
|
var skuPriceList []*model.PromotionSku
|
||||||
|
if err = dao.GetRows(db, &skuPriceList, sql, storeID, skuIDs, utils.DefaultTimeValue, model.PromotionStatusLocalCreated, model.PromotionStatusRemoteCreated, model.VendorIDJX); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
skuPriceMap = make(map[int64]*model.PromotionSku)
|
||||||
|
for _, v := range skuPriceList {
|
||||||
|
if v.EarningPrice > 0 {
|
||||||
|
index := jxutils.Combine2Int(v.SkuID, v.Price)
|
||||||
|
if skuPriceMap[index] == nil || v.EarningPrice < skuPriceMap[index].EarningPrice {
|
||||||
|
skuPriceMap[index] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return skuPriceMap, err
|
||||||
|
}
|
||||||
|
|
||||||
func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.DaoDB) (err error) {
|
func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.DaoDB) (err error) {
|
||||||
globals.SugarLogger.Debugf("updateOrderSkuOtherInfo orderID:%s, VendorStoreID:%s", order.VendorOrderID, order.VendorStoreID)
|
globals.SugarLogger.Debugf("updateOrderSkuOtherInfo orderID:%s, VendorStoreID:%s", order.VendorOrderID, order.VendorStoreID)
|
||||||
jxStoreID := jxutils.GetShowStoreIDFromOrder(order)
|
jxStoreID := jxutils.GetShowStoreIDFromOrder(order)
|
||||||
var opNumStr string
|
var opNumStr string
|
||||||
if time.Now().Sub(order.OrderCreatedAt) < 48*time.Hour && order.VendorID != model.VendorIDJD {
|
if time.Now().Sub(order.OrderCreatedAt) < 48*time.Hour && order.VendorID != model.VendorIDJD {
|
||||||
opNumStr = ""
|
opNumStr = "2"
|
||||||
} else {
|
} else {
|
||||||
opNumStr = "2"
|
opNumStr = "2"
|
||||||
}
|
}
|
||||||
@@ -273,11 +276,16 @@ func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.
|
|||||||
orderSkus := order.Skus
|
orderSkus := order.Skus
|
||||||
|
|
||||||
vendorSkuIDs := make([]int64, 0)
|
vendorSkuIDs := make([]int64, 0)
|
||||||
|
skuIDMap := make(map[int]int)
|
||||||
for _, v := range orderSkus {
|
for _, v := range orderSkus {
|
||||||
intVendorSkuID := utils.Str2Int64WithDefault(v.VendorSkuID, 0)
|
intVendorSkuID := utils.Str2Int64WithDefault(v.VendorSkuID, 0)
|
||||||
if intVendorSkuID != 0 {
|
if intVendorSkuID != 0 {
|
||||||
vendorSkuIDs = append(vendorSkuIDs, intVendorSkuID)
|
vendorSkuIDs = append(vendorSkuIDs, intVendorSkuID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if skuID := jxutils.GetSkuIDFromOrderSku(v); skuID > 0 {
|
||||||
|
skuIDMap[skuID] = 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if len(vendorSkuIDs) > 0 {
|
if len(vendorSkuIDs) > 0 {
|
||||||
tableName := "t2"
|
tableName := "t2"
|
||||||
@@ -301,7 +309,16 @@ func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.
|
|||||||
skumapper[v.VendorSkuID] = v
|
skumapper[v.VendorSkuID] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skuPriceMap, err2 := getPromotionSkuPriceMap(db, jxStoreID, jxutils.IntMap2List(skuIDMap))
|
||||||
|
if err = err2; err != nil {
|
||||||
|
globals.SugarLogger.Errorf("updateOrderSkuOtherInfo can not get sku promotion info for orderID:%s, error:%v", order.VendorOrderID, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
for _, v := range orderSkus {
|
for _, v := range orderSkus {
|
||||||
|
v.VendorOrderID = order.VendorOrderID
|
||||||
|
v.VendorID = order.VendorID
|
||||||
|
|
||||||
intVendorSkuID := utils.Str2Int64WithDefault(v.VendorSkuID, 0)
|
intVendorSkuID := utils.Str2Int64WithDefault(v.VendorSkuID, 0)
|
||||||
if intVendorSkuID != 0 && v.VendorSkuID != "-70000" { // todo hard code
|
if intVendorSkuID != 0 && v.VendorSkuID != "-70000" { // todo hard code
|
||||||
skuBindInfo := skumapper[intVendorSkuID]
|
skuBindInfo := skumapper[intVendorSkuID]
|
||||||
@@ -317,6 +334,13 @@ func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if skuID := jxutils.GetSkuIDFromOrderSku(v); skuID > 0 && v.StoreSubName != "" {
|
||||||
|
index := jxutils.Combine2Int(jxStoreID, int(v.SalePrice))
|
||||||
|
if skuPriceMap[index] != nil {
|
||||||
|
v.EarningPrice = int64(skuPriceMap[index].EarningPrice)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -336,11 +360,7 @@ func (c *OrderManager) updateOrderOtherInfo(order *model.GoodsOrder, db *dao.Dao
|
|||||||
}
|
}
|
||||||
order.JxStoreID = storeMap.StoreID
|
order.JxStoreID = storeMap.StoreID
|
||||||
if err = c.updateOrderSkuOtherInfo(order, db); err == nil {
|
if err = c.updateOrderSkuOtherInfo(order, db); err == nil {
|
||||||
if order.Weight == 0 {
|
jxutils.RefreshOrderSkuRelated(order)
|
||||||
for _, v := range order.Skus {
|
|
||||||
order.Weight += v.Weight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -369,20 +389,21 @@ func (c *OrderManager) addOrderStatus(orderStatus *model.OrderStatus, db *dao.Da
|
|||||||
updateFields = append(updateFields, "Status", "StatusTime")
|
updateFields = append(updateFields, "Status", "StatusTime")
|
||||||
if order.LockStatus != model.OrderStatusUnknown {
|
if order.LockStatus != model.OrderStatusUnknown {
|
||||||
order.LockStatus = model.OrderStatusUnknown
|
order.LockStatus = model.OrderStatusUnknown
|
||||||
order.LockStatusTime = orderStatus.StatusTime
|
updateFields = append(updateFields, "LockStatus")
|
||||||
updateFields = append(updateFields, "LockStatus", "LockStatusTime")
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if model.IsOrderUnlockStatus(orderStatus.Status) {
|
if model.IsOrderUnlockStatus(orderStatus.Status) {
|
||||||
order.LockStatus = model.OrderStatusUnknown
|
order.LockStatus = model.OrderStatusUnknown
|
||||||
} else {
|
updateFields = append(updateFields, "LockStatus")
|
||||||
|
} else if !model.IsOrderFinalStatus(orderStatus.Status) {
|
||||||
if order.LockStatus != model.OrderStatusUnknown {
|
if order.LockStatus != model.OrderStatusUnknown {
|
||||||
globals.SugarLogger.Warnf("addOrderStatus refOrderID:%s, orderID:%s, order.LockStatus:%d, status.LockStatus:%d", orderStatus.RefVendorOrderID, orderStatus.VendorOrderID, order.LockStatus, orderStatus.Status)
|
globals.SugarLogger.Warnf("addOrderStatus refOrderID:%s, orderID:%s, order.LockStatus:%d, status.LockStatus:%d", orderStatus.RefVendorOrderID, orderStatus.VendorOrderID, order.LockStatus, orderStatus.Status)
|
||||||
}
|
}
|
||||||
|
order.Flag &= ^model.OrderFlagMaskUserApplyCancel
|
||||||
order.LockStatus = orderStatus.Status
|
order.LockStatus = orderStatus.Status
|
||||||
|
order.LockStatusTime = orderStatus.StatusTime
|
||||||
|
updateFields = append(updateFields, "LockStatus", "LockStatusTime", "Flag")
|
||||||
}
|
}
|
||||||
order.LockStatusTime = orderStatus.StatusTime
|
|
||||||
updateFields = append(updateFields, "LockStatus", "LockStatusTime")
|
|
||||||
}
|
}
|
||||||
if model.IsOrderFinalStatus(orderStatus.Status) {
|
if model.IsOrderFinalStatus(orderStatus.Status) {
|
||||||
order.OrderFinishedAt = orderStatus.StatusTime
|
order.OrderFinishedAt = orderStatus.StatusTime
|
||||||
@@ -430,6 +451,7 @@ func (c *OrderManager) loadOrder(vendorOrderID, vendorOrderID2 string, vendorID
|
|||||||
}, "LoadOrder orderID:%s", vendorOrderID)
|
}, "LoadOrder orderID:%s", vendorOrderID)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
order = nil
|
||||||
if err == orm.ErrNoRows {
|
if err == orm.ErrNoRows {
|
||||||
err = ErrCanNotFindOrder
|
err = ErrCanNotFindOrder
|
||||||
}
|
}
|
||||||
@@ -475,11 +497,12 @@ func (c *OrderManager) loadOrderFinancial(vendorOrderID, vendorOrderID2 string,
|
|||||||
if err = db.Read(order, keyFields...); err == nil {
|
if err = db.Read(order, keyFields...); err == nil {
|
||||||
vendorOrderID = order.VendorOrderID
|
vendorOrderID = order.VendorOrderID
|
||||||
err = utils.CallFuncLogError(func() error {
|
err = utils.CallFuncLogError(func() error {
|
||||||
_, err = db.QueryTable("order_sku_financial").Filter("vendor_order_id", vendorOrderID).Filter("vendor_id", vendorID).All(&order.Skus)
|
_, err = db.QueryTable("order_sku_financial").Filter("vendor_order_id", vendorOrderID).Filter("vendor_id", vendorID).Filter("is_afs_order", 0).All(&order.Skus)
|
||||||
return err
|
return err
|
||||||
}, "LoadOrder orderID:%s", vendorOrderID)
|
}, "LoadOrder orderID:%s", vendorOrderID)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
order = nil
|
||||||
if err == orm.ErrNoRows {
|
if err == orm.ErrNoRows {
|
||||||
err = ErrCanNotFindOrder
|
err = ErrCanNotFindOrder
|
||||||
}
|
}
|
||||||
@@ -488,30 +511,15 @@ func (c *OrderManager) loadOrderFinancial(vendorOrderID, vendorOrderID2 string,
|
|||||||
return order, err
|
return order, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *OrderManager) UpdateOrderStatusAndFlag(order *model.GoodsOrder) (err error) {
|
func (c *OrderManager) UpdateOrderStatusAndDeliveryFlag(order *model.GoodsOrder) (err error) {
|
||||||
db := orm.NewOrm()
|
return c.UpdateOrderFields(order, []string{"Status", "DeliveryFlag"})
|
||||||
utils.CallFuncLogError(func() error {
|
|
||||||
_, err = db.Update(order, "Status", "DeliveryFlag")
|
|
||||||
return err
|
|
||||||
}, "UpdateOrderStatusAndFlag orderID:%s failed with error:%v", order.VendorOrderID, err)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Waybill
|
func (c *OrderManager) UpdateOrderFields(order *model.GoodsOrder, fieldList []string) (err error) {
|
||||||
func (c *OrderManager) UpdateWaybillVendorID(bill *model.Waybill, revertStatus bool) (err error) {
|
|
||||||
globals.SugarLogger.Debugf("UpdateWaybillVendorID bill:%v", bill)
|
|
||||||
db := orm.NewOrm()
|
db := orm.NewOrm()
|
||||||
params := orm.Params{
|
|
||||||
"vendor_waybill_id": bill.VendorWaybillID,
|
|
||||||
"waybill_vendor_id": bill.WaybillVendorID,
|
|
||||||
}
|
|
||||||
// 如果运单被取消,则要保持在已拣货状态
|
|
||||||
if revertStatus && bill.WaybillVendorID == model.VendorIDUnknown {
|
|
||||||
params["status"] = model.OrderStatusFinishedPickup
|
|
||||||
}
|
|
||||||
utils.CallFuncLogError(func() error {
|
utils.CallFuncLogError(func() error {
|
||||||
_, err = db.QueryTable("goods_order").Filter("vendor_order_id", bill.VendorOrderID).Filter("vendor_id", bill.OrderVendorID).Update(params)
|
_, err = db.Update(order, fieldList...)
|
||||||
return err
|
return err
|
||||||
}, "UpdateWaybillVendorID update order, bill:%v", bill)
|
}, "UpdateOrderFields orderID:%s failed with error:%v", order.VendorOrderID, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
351
business/jxcallback/orderman/order_afs.go
Normal file
351
business/jxcallback/orderman/order_afs.go
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
package orderman
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
"github.com/astaxie/beego/orm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *OrderManager) LoadAfsOrder(vendorAfsOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) {
|
||||||
|
return c.loadAfsOrder(dao.GetDB(), vendorAfsOrderID, vendorID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) loadAfsOrder(db *dao.DaoDB, vendorAfsOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) {
|
||||||
|
afsOrder = &model.AfsOrder{
|
||||||
|
AfsOrderID: vendorAfsOrderID,
|
||||||
|
VendorID: vendorID,
|
||||||
|
}
|
||||||
|
if err = dao.GetEntity(db, afsOrder, "AfsOrderID", "VendorID"); err != nil {
|
||||||
|
afsOrder = nil
|
||||||
|
}
|
||||||
|
return afsOrder, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) OnAfsOrderAdjust(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus) (err error) {
|
||||||
|
return c.onAfsOrderNew(afsOrder, orderStatus, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) OnAfsOrderNew(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus) (err error) {
|
||||||
|
return c.onAfsOrderNew(afsOrder, orderStatus, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) onAfsOrderNew(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus, isAdjust bool) (err error) {
|
||||||
|
db := dao.GetDB()
|
||||||
|
// globals.SugarLogger.Debugf("onAfsOrderNew1 afsOrder:%s", utils.Format4Output(afsOrder, true))
|
||||||
|
c.setAfsOrderID(db, orderStatus)
|
||||||
|
if afsOrder.AfsOrderID == "" {
|
||||||
|
afsOrder.AfsOrderID = orderStatus.VendorOrderID
|
||||||
|
}
|
||||||
|
if afsOrder.VendorStatus == "" {
|
||||||
|
afsOrder.VendorStatus = orderStatus.VendorStatus
|
||||||
|
}
|
||||||
|
if afsOrder.Status == model.OrderStatusUnknown {
|
||||||
|
afsOrder.Status = orderStatus.Status
|
||||||
|
}
|
||||||
|
// globals.SugarLogger.Debugf("onAfsOrderNew2 afsOrder:%s", utils.Format4Output(afsOrder, true))
|
||||||
|
dao.Begin(db)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil || err != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
panic(r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
isDuplicated, err := addOrderOrWaybillStatus(orderStatus, db)
|
||||||
|
globals.SugarLogger.Debugf("onAfsOrderNew afsOrderID:%s, isDuplicated:%t", afsOrder.AfsOrderID, isDuplicated)
|
||||||
|
if err != nil || isDuplicated {
|
||||||
|
if err == nil {
|
||||||
|
dao.Commit(db)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var existAfsOrder *model.AfsOrder
|
||||||
|
if existAfsOrder, err = c.loadAfsOrder(db, afsOrder.AfsOrderID, afsOrder.VendorID); err != nil {
|
||||||
|
if !dao.IsNoRowsError(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if existAfsOrder != nil {
|
||||||
|
existAfsOrder.Status = afsOrder.Status
|
||||||
|
existAfsOrder.VendorStatus = afsOrder.VendorStatus
|
||||||
|
if _, err = dao.UpdateEntity(db, existAfsOrder, "Status", "VendorStatus"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 外退都要先全删除再建
|
||||||
|
if afsOrder.RefundType == model.AfsTypeFullRefund {
|
||||||
|
isAdjust = true
|
||||||
|
}
|
||||||
|
if err = c.SaveAfsOrder(db, afsOrder, isAdjust); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dao.Commit(db)
|
||||||
|
scheduler.CurrentScheduler.OnAfsOrderNew(afsOrder, false)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) SaveAfsOrder(db *dao.DaoDB, afsOrder *model.AfsOrder, isDeleteFirst bool) (err error) {
|
||||||
|
globals.SugarLogger.Debug(afsOrder.AfsOrderID)
|
||||||
|
if db == nil {
|
||||||
|
db = dao.GetDB()
|
||||||
|
}
|
||||||
|
if err = c.updateAfsOrderOtherInfo(db, afsOrder); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dao.Begin(db)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil || err != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
if r != nil {
|
||||||
|
panic(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if isDeleteFirst {
|
||||||
|
err = utils.CallFuncLogError(func() error {
|
||||||
|
_, err = dao.DeleteEntity(db, afsOrder, "VendorOrderID", "VendorID")
|
||||||
|
return err
|
||||||
|
}, "SaveAfsOrder delete AfsOrder, afsOrderID:%s", afsOrder.AfsOrderID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = utils.CallFuncLogError(func() error {
|
||||||
|
_, err = dao.DeleteEntity(db, &model.OrderSkuFinancial{
|
||||||
|
VendorOrderID: afsOrder.VendorOrderID,
|
||||||
|
VendorID: afsOrder.VendorID,
|
||||||
|
IsAfsOrder: 1,
|
||||||
|
}, "VendorOrderID", "VendorID", "IsAfsOrder")
|
||||||
|
return err
|
||||||
|
}, "SaveAfsOrder delete OrderSkuFinancial, afsOrderID:%s", afsOrder.AfsOrderID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 平台结算扣除汇总--平台补贴,售后产生运费,平台收包装费,同城运费、、、
|
||||||
|
deductionsByPm := afsOrder.PmSubsidyMoney + afsOrder.AfsFreightMoney + afsOrder.BoxMoney + afsOrder.TongchengFreightMoney
|
||||||
|
afsOrder.RefundMoneyByCal = afsOrder.SkuUserMoney + afsOrder.FreightUserMoney + deductionsByPm - afsOrder.PmRefundMoney
|
||||||
|
// order.TotalMoney += order.SkuJxMoney // 退款单京西补贴部分先不作计算
|
||||||
|
if err = dao.CreateEntity(db, afsOrder); err != nil {
|
||||||
|
globals.SugarLogger.Warnf("On SaveAfsOrder afsOrder.AfsOrderID:%s err:%v", afsOrder.AfsOrderID, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 京西结算扣除汇总,先不作计算,计算单条sku最终扣款金额(+该条sku承担的平台结算扣除金额)
|
||||||
|
for _, orderSku := range afsOrder.Skus[1:] {
|
||||||
|
orderSku.RefundMoneyByCal = orderSku.PmSkuSubsidyMoney +
|
||||||
|
utils.Float64TwoInt64(float64(afsOrder.RefundMoneyByCal-afsOrder.PmSkuSubsidyMoney)*float64(orderSku.UserMoney+orderSku.PmSubsidyMoney-orderSku.PmSkuSubsidyMoney)/float64(afsOrder.SkuUserMoney+afsOrder.PmSubsidyMoney-afsOrder.PmSkuSubsidyMoney))
|
||||||
|
afsOrder.Skus[0].RefundMoneyByCal += orderSku.RefundMoneyByCal
|
||||||
|
if err = dao.CreateEntity(db, orderSku); err != nil {
|
||||||
|
globals.SugarLogger.Warnf("On SaveAfsOrder afsOrder.AfsOrderID:%s err:%v, orderSku:%s", afsOrder.AfsOrderID, err, utils.Format4Output(orderSku, true))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(afsOrder.Skus) > 0 {
|
||||||
|
orderSku := afsOrder.Skus[0]
|
||||||
|
orderSku.RefundMoneyByCal = afsOrder.RefundMoneyByCal - orderSku.RefundMoneyByCal
|
||||||
|
if err = dao.CreateEntity(db, orderSku); err != nil {
|
||||||
|
globals.SugarLogger.Warnf("On SaveAfsOrder afsOrder.AfsOrderID:%s err:%v, orderSku:%s", afsOrder.AfsOrderID, err, utils.Format4Output(orderSku, true))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
globals.SugarLogger.Warnf("On SaveAfsOrder afsOrder.AfsOrderID:%s err: afsOrder have no sku", afsOrder.AfsOrderID)
|
||||||
|
}
|
||||||
|
dao.Commit(db)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) OnAfsOrderStatusChanged(orderStatus *model.OrderStatus) (err error) {
|
||||||
|
db := dao.GetDB()
|
||||||
|
c.setAfsOrderID(db, orderStatus)
|
||||||
|
dao.Begin(db)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
panic(r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
isDuplicated, afsOrder, err := c.addAfsOrderStatus(db, orderStatus)
|
||||||
|
if err != nil || isDuplicated {
|
||||||
|
if err == nil {
|
||||||
|
dao.Commit(db)
|
||||||
|
} else {
|
||||||
|
dao.Rollback(db)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dao.Commit(db)
|
||||||
|
scheduler.CurrentScheduler.OnAfsOrderStatusChanged(afsOrder, orderStatus, false)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) addAfsOrderStatus(db *dao.DaoDB, orderStatus *model.OrderStatus) (isDuplicated bool, order *model.AfsOrder, err error) {
|
||||||
|
globals.SugarLogger.Debugf("addAfsOrderStatus refOrderID:%s, orderID:%s", orderStatus.RefVendorOrderID, orderStatus.VendorOrderID)
|
||||||
|
if db == nil {
|
||||||
|
db = dao.GetDB()
|
||||||
|
}
|
||||||
|
isDuplicated, err = addOrderOrWaybillStatus(orderStatus, db)
|
||||||
|
if err == nil && !isDuplicated && (orderStatus.Status != model.OrderStatusUnknown && orderStatus.Status != model.OrderStatusMsg) {
|
||||||
|
order = &model.AfsOrder{
|
||||||
|
AfsOrderID: orderStatus.VendorOrderID,
|
||||||
|
VendorID: orderStatus.VendorID,
|
||||||
|
}
|
||||||
|
if err = db.Db.ReadForUpdate(order, "AfsOrderID", "VendorID"); err == nil {
|
||||||
|
if orderStatus.Status > model.OrderStatusUnknown { // todo 要求status不能回绕
|
||||||
|
order.VendorStatus = orderStatus.VendorStatus
|
||||||
|
order.Status = orderStatus.Status
|
||||||
|
updateFields := []string{
|
||||||
|
"VendorStatus",
|
||||||
|
"Status",
|
||||||
|
}
|
||||||
|
if model.IsAfsOrderFinalStatus(orderStatus.Status) {
|
||||||
|
order.AfsFinishedAt = orderStatus.StatusTime
|
||||||
|
updateFields = append(updateFields, "AfsFinishedAt")
|
||||||
|
}
|
||||||
|
utils.CallFuncLogError(func() error {
|
||||||
|
_, err = dao.UpdateEntity(db, order, updateFields...)
|
||||||
|
return err
|
||||||
|
}, "addAfsOrderStatus update orderID:%s, status:%v", order.VendorOrderID, orderStatus)
|
||||||
|
} else {
|
||||||
|
isDuplicated = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if dao.IsNoRowsError(err) { // todo 消息错序
|
||||||
|
err = nil
|
||||||
|
} else {
|
||||||
|
globals.SugarLogger.Warnf("addAfsOrderStatus orderID:%s read failed with error:%v", order.VendorOrderID, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isDuplicated, order, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) updateAfsOrderSkuOtherInfo(db *dao.DaoDB, order *model.AfsOrder) (err error) {
|
||||||
|
globals.SugarLogger.Debugf("updateAfsOrderSkuOtherInfo orderID:%s, VendorStoreID:%s", order.VendorOrderID, order.VendorStoreID)
|
||||||
|
jxStoreID := jxutils.GetSaleStoreIDFromAfsOrder(order)
|
||||||
|
opNumStr := "2"
|
||||||
|
if jxStoreID == 0 {
|
||||||
|
globals.SugarLogger.Infof("updateAfsOrderSkuOtherInfo [运营%s]订单在京西与平台都找不到京西门店信息orderID:%s, VendorStoreID:%s", opNumStr, order.VendorOrderID, order.VendorStoreID)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
orderSkus := order.Skus
|
||||||
|
vendorSkuIDs := make([]int64, 0)
|
||||||
|
for _, v := range orderSkus {
|
||||||
|
intVendorSkuID := utils.Str2Int64WithDefault(v.VendorSkuID, 0)
|
||||||
|
if intVendorSkuID != 0 {
|
||||||
|
vendorSkuIDs = append(vendorSkuIDs, intVendorSkuID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(vendorSkuIDs) > 0 {
|
||||||
|
tableName := "t2"
|
||||||
|
if model.MultiStoresVendorMap[order.VendorID] == 1 {
|
||||||
|
tableName = "t1"
|
||||||
|
}
|
||||||
|
fieldPrefix := dao.ConvertDBFieldPrefix(model.VendorNames[order.VendorID])
|
||||||
|
sql := `
|
||||||
|
SELECT %s.%s_id vendor_sku_id, t1.id sku_id, t2.price, t1.weight
|
||||||
|
FROM sku t1
|
||||||
|
LEFT JOIN store_sku_bind t2 ON t1.id = t2.sku_id AND t2.deleted_at = ? AND t2.store_id = ?
|
||||||
|
WHERE t1.deleted_at = ? AND %s.%s_id IN (-1, ` + dao.GenQuestionMarks(len(vendorSkuIDs)) + ")"
|
||||||
|
sql = fmt.Sprintf(sql, tableName, fieldPrefix, tableName, fieldPrefix)
|
||||||
|
var skuInfos []*tStoreSkuBindAndVendorSkuID
|
||||||
|
if err = dao.GetRows(db, &skuInfos, sql, utils.DefaultTimeValue, jxStoreID, utils.DefaultTimeValue, vendorSkuIDs); err != nil {
|
||||||
|
globals.SugarLogger.Errorf("updateAfsOrderSkuOtherInfo can not get sku info for orderID:%s, error:%v", order.VendorOrderID, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
skumapper := make(map[int64]*tStoreSkuBindAndVendorSkuID)
|
||||||
|
for _, v := range skuInfos {
|
||||||
|
skumapper[v.VendorSkuID] = v
|
||||||
|
}
|
||||||
|
for _, v := range orderSkus {
|
||||||
|
v.AfsOrderID = order.AfsOrderID
|
||||||
|
v.VendorID = order.VendorID
|
||||||
|
v.VendorOrderID = order.VendorOrderID
|
||||||
|
v.IsAfsOrder = 1
|
||||||
|
v.VendorStoreID = order.VendorStoreID
|
||||||
|
v.StoreID = order.StoreID
|
||||||
|
v.JxStoreID = jxStoreID
|
||||||
|
|
||||||
|
intVendorSkuID := utils.Str2Int64WithDefault(v.VendorSkuID, 0)
|
||||||
|
if intVendorSkuID != 0 && v.VendorSkuID != "-70000" { // todo hard code
|
||||||
|
skuBindInfo := skumapper[intVendorSkuID]
|
||||||
|
if skuBindInfo == nil {
|
||||||
|
globals.SugarLogger.Infof("updateAfsOrderSkuOtherInfo [运营%s]%s订单sku找不到门店价格(或商品映射),orderID:%s, StoreID:%d, VendorSkuID:%s, sku:%v", opNumStr, model.VendorChineseNames[order.VendorID], order.VendorOrderID, jxStoreID, v.VendorSkuID, v)
|
||||||
|
} else {
|
||||||
|
v.JxSkuID = skuBindInfo.SkuID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) updateAfsOrderOtherInfo(db *dao.DaoDB, afsOrder *model.AfsOrder) (err error) {
|
||||||
|
globals.SugarLogger.Debugf("updateAfsOrderOtherInfo orderID:%s, VendorStoreID:%s", afsOrder.VendorOrderID, afsOrder.VendorStoreID)
|
||||||
|
if afsOrder.VendorStoreID != "" {
|
||||||
|
if storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, afsOrder.VendorStoreID, 0); err == nil {
|
||||||
|
afsOrder.JxStoreID = storeDetail.Store.ID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if afsOrder.StoreID == 0 && afsOrder.JxStoreID == 0 {
|
||||||
|
if order, err2 := c.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID); err2 == nil {
|
||||||
|
afsOrder.JxStoreID = order.JxStoreID
|
||||||
|
if afsOrder.StoreID == 0 {
|
||||||
|
afsOrder.StoreID = order.StoreID
|
||||||
|
}
|
||||||
|
if afsOrder.VendorStoreID == "" {
|
||||||
|
afsOrder.VendorStoreID = order.VendorStoreID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
if err = c.updateAfsOrderSkuOtherInfo(db, afsOrder); err == nil {
|
||||||
|
jxutils.RefreshAfsOrderSkuRelated(afsOrder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) UpdateAfsOrderFields(afsOrder *model.AfsOrder, fieldList []string) (err error) {
|
||||||
|
db := orm.NewOrm()
|
||||||
|
utils.CallFuncLogError(func() error {
|
||||||
|
_, err = db.Update(afsOrder, fieldList...)
|
||||||
|
return err
|
||||||
|
}, "UpdateAfsOrderFields orderID:%s failed with error:%v", afsOrder.VendorOrderID, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) setAfsOrderID(db *dao.DaoDB, orderStatus *model.OrderStatus) {
|
||||||
|
// globals.SugarLogger.Debugf("setAfsOrderID1 orderStatus:%v", utils.Format4Output(orderStatus, true))
|
||||||
|
if dao.IsVendorThingIDEmpty(orderStatus.VendorOrderID) {
|
||||||
|
index := 1
|
||||||
|
if afsOrderList, err2 := dao.GetAfsOrders(db, orderStatus.RefVendorID, orderStatus.RefVendorOrderID, ""); err2 == nil {
|
||||||
|
if len(afsOrderList) > 0 {
|
||||||
|
list := strings.Split(afsOrderList[0].AfsOrderID, "-")
|
||||||
|
if len(list) > 1 {
|
||||||
|
index = int(utils.Str2Int64WithDefault(list[1], 0))
|
||||||
|
if afsOrderList[0].Status >= model.AfsOrderStatusFinished {
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
globals.SugarLogger.Warnf("setAfsOrderID err2:%v", err2)
|
||||||
|
}
|
||||||
|
orderStatus.VendorOrderID = composeAfsOrderID(orderStatus.RefVendorOrderID, index)
|
||||||
|
}
|
||||||
|
// globals.SugarLogger.Debugf("setAfsOrderID2 orderStatus:%v", utils.Format4Output(orderStatus, true))
|
||||||
|
}
|
||||||
|
|
||||||
|
func composeAfsOrderID(vendorOrderID string, index int) (afsOrderID string) {
|
||||||
|
return strings.Join([]string{
|
||||||
|
vendorOrderID,
|
||||||
|
utils.Int2Str(index),
|
||||||
|
}, "-")
|
||||||
|
}
|
||||||
@@ -102,12 +102,16 @@ func (c *OrderManager) OnOrderComments(orderCommentList []*model.OrderComment) (
|
|||||||
comment2.Maxmodifytime = int(orderComment.ModifyDuration)
|
comment2.Maxmodifytime = int(orderComment.ModifyDuration)
|
||||||
if orderComment.VendorID != model.VendorIDELM {
|
if orderComment.VendorID != model.VendorIDELM {
|
||||||
var order *model.GoodsOrder
|
var order *model.GoodsOrder
|
||||||
if orderComment.VendorID != model.VendorIDEBAI {
|
if true /*orderComment.VendorID != model.VendorIDEBAI*/ {
|
||||||
order, err = partner.CurOrderManager.LoadOrder(orderComment.VendorOrderID, orderComment.VendorID)
|
order, _ = partner.CurOrderManager.LoadOrder(orderComment.VendorOrderID, orderComment.VendorID)
|
||||||
}
|
}
|
||||||
if order != nil {
|
if order != nil {
|
||||||
orderComment.StoreID = jxutils.GetSaleStoreIDFromOrder(order)
|
orderComment.StoreID = jxutils.GetSaleStoreIDFromOrder(order)
|
||||||
orderComment.ConsigneeMobile = order.ConsigneeMobile
|
if order.ConsigneeMobile2 != "" {
|
||||||
|
orderComment.ConsigneeMobile = order.ConsigneeMobile2
|
||||||
|
} else {
|
||||||
|
orderComment.ConsigneeMobile = order.ConsigneeMobile
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if orderComment.StoreID > 0 {
|
if orderComment.StoreID > 0 {
|
||||||
comment2.Jxstoreid = utils.Int2Str(orderComment.StoreID)
|
comment2.Jxstoreid = utils.Int2Str(orderComment.StoreID)
|
||||||
@@ -65,8 +65,10 @@ func init() {
|
|||||||
func addOrderOrWaybillStatus(status *model.OrderStatus, db *dao.DaoDB) (isDuplicated bool, err error) {
|
func addOrderOrWaybillStatus(status *model.OrderStatus, db *dao.DaoDB) (isDuplicated bool, err error) {
|
||||||
if status.OrderType == model.OrderTypeOrder {
|
if status.OrderType == model.OrderTypeOrder {
|
||||||
globals.SugarLogger.Debugf("addOrderStatus order:%v", status)
|
globals.SugarLogger.Debugf("addOrderStatus order:%v", status)
|
||||||
} else {
|
} else if status.OrderType == model.OrderTypeWaybill {
|
||||||
globals.SugarLogger.Debugf("addOrderStatus waybill:%v", status)
|
globals.SugarLogger.Debugf("addOrderStatus waybill:%v", status)
|
||||||
|
} else {
|
||||||
|
globals.SugarLogger.Debugf("addOrderStatus afsOrder:%v", status)
|
||||||
}
|
}
|
||||||
dao.Begin(db)
|
dao.Begin(db)
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -100,6 +102,17 @@ func addOrderOrWaybillStatus(status *model.OrderStatus, db *dao.DaoDB) (isDuplic
|
|||||||
return isDuplicated, err
|
return isDuplicated, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) GetStatusDuplicatedCount(status *model.OrderStatus) (duplicatedCount int) {
|
||||||
|
if status == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
db := dao.GetDB()
|
||||||
|
if err := dao.GetEntity(db, status, "VendorOrderID", "VendorID", "OrderType", "VendorStatus", "StatusTime"); err == nil {
|
||||||
|
return status.DuplicatedCount
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
// todo 最好还是改成全事件回放算了
|
// todo 最好还是改成全事件回放算了
|
||||||
func LoadPendingOrders() {
|
func LoadPendingOrders() {
|
||||||
orders := FixedOrderManager.LoadPendingOrders()
|
orders := FixedOrderManager.LoadPendingOrders()
|
||||||
@@ -140,17 +153,17 @@ func LoadPendingOrders() {
|
|||||||
if order, ok := item.(*model.GoodsOrder); ok {
|
if order, ok := item.(*model.GoodsOrder); ok {
|
||||||
jxutils.CallMsgHandlerAsync(func() {
|
jxutils.CallMsgHandlerAsync(func() {
|
||||||
scheduler.CurrentScheduler.OnOrderNew(order, true)
|
scheduler.CurrentScheduler.OnOrderNew(order, true)
|
||||||
}, order.VendorOrderID)
|
}, jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID))
|
||||||
} else if status, ok := item.(*model.OrderStatus); ok {
|
} else if status, ok := item.(*model.OrderStatus); ok {
|
||||||
jxutils.CallMsgHandlerAsync(func() {
|
jxutils.CallMsgHandlerAsync(func() {
|
||||||
order := orderMap[jxutils.ComposeUniversalOrderID(status.VendorOrderID, status.VendorID)]
|
order := orderMap[jxutils.ComposeUniversalOrderID(status.VendorOrderID, status.VendorID)]
|
||||||
scheduler.CurrentScheduler.OnOrderStatusChanged(order, status, true)
|
scheduler.CurrentScheduler.OnOrderStatusChanged(order, status, true)
|
||||||
}, status.VendorOrderID)
|
}, jxutils.ComposeUniversalOrderID(status.RefVendorOrderID, status.RefVendorID))
|
||||||
} else {
|
} else {
|
||||||
bill := item.(*model.Waybill)
|
bill := item.(*model.Waybill)
|
||||||
jxutils.CallMsgHandlerAsync(func() {
|
jxutils.CallMsgHandlerAsync(func() {
|
||||||
scheduler.CurrentScheduler.OnWaybillStatusChanged(bill, true)
|
scheduler.CurrentScheduler.OnWaybillStatusChanged(bill, true)
|
||||||
}, bill.VendorOrderID)
|
}, jxutils.ComposeUniversalOrderID(bill.VendorOrderID, bill.OrderVendorID))
|
||||||
}
|
}
|
||||||
curTime := time.Now()
|
curTime := time.Now()
|
||||||
timeout := sleepGap - curTime.Sub(lastTime)
|
timeout := sleepGap - curTime.Sub(lastTime)
|
||||||
|
|||||||
@@ -3,8 +3,11 @@ package orderman
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/excel"
|
"git.rosy.net.cn/jx-callback/business/jxutils/excel"
|
||||||
@@ -27,33 +30,21 @@ type tWaybillExt struct {
|
|||||||
StoreID int `json:"storeID" orm:"column(store_id)"`
|
StoreID int `json:"storeID" orm:"column(store_id)"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//此函数会被GetStoreOrderCountInfo2取代
|
type StoresOrderSaleInfo struct {
|
||||||
func (c *OrderManager) GetStoreOrderCountInfo(ctx *jxcontext.Context, storeID string, lastHours int) (countInfo []*model.GoodsOrderCountInfo, err error) {
|
StoreID int `orm:"column(store_id)" json:"storeID"`
|
||||||
globals.SugarLogger.Debugf("GetStoreOrderCountInfo storeID:%s", storeID)
|
VendorID int `orm:"column(vendor_id)" json:"vendorID"`
|
||||||
if lastHours > maxLastHours {
|
Status int `json:"status"`
|
||||||
lastHours = maxLastHours
|
Count int `json:"count"`
|
||||||
} else if lastHours == 0 {
|
ShopPrice int64 `json:"shopPrice"`
|
||||||
lastHours = defLastHours
|
VendorPrice int64 `json:"vendorPrice"`
|
||||||
}
|
SalePrice int64 `json:"salePrice"`
|
||||||
|
ActualPayPrice int64 `json:"actualPayPrice"`
|
||||||
|
|
||||||
db := orm.NewOrm()
|
EarningPrice int64 `json:"earningPrice"` // 预估结算给门店老板的钱
|
||||||
_, err = db.Raw(`
|
|
||||||
SELECT t1.status, COUNT(*) count
|
|
||||||
FROM goods_order t1
|
|
||||||
WHERE t1.vendor_id <> 2 AND IF(t1.vendor_id = ?, t1.store_id, IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) ) = ?
|
|
||||||
AND t1.order_created_at >= ? AND t1.lock_status = ?
|
|
||||||
GROUP BY 1
|
|
||||||
ORDER BY 1
|
|
||||||
`, model.VendorIDWSC, storeID, time.Now().Add(-time.Duration(lastHours)*time.Hour), model.OrderStatusUnknown).QueryRows(&countInfo)
|
|
||||||
if err == nil {
|
|
||||||
return countInfo, nil
|
|
||||||
}
|
|
||||||
globals.SugarLogger.Infof("GetStoreOrderCountInfo storeID:%s failed with error:%v", storeID, err)
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *OrderManager) GetStoreOrderCountInfo2(ctx *jxcontext.Context, storeID, lastHours int) (countInfo []*model.GoodsOrderCountInfo2, err error) {
|
func (c *OrderManager) GetStoreOrderCountInfo(ctx *jxcontext.Context, storeID, lastHours int) (countInfo []*model.GoodsOrderCountInfo, err error) {
|
||||||
globals.SugarLogger.Debugf("GetStoreOrderCountInfo2 storeID:%s", storeID)
|
globals.SugarLogger.Debugf("GetStoreOrderCountInfo storeID:%d", storeID)
|
||||||
if lastHours > maxLastHours {
|
if lastHours > maxLastHours {
|
||||||
lastHours = maxLastHours
|
lastHours = maxLastHours
|
||||||
} else if lastHours == 0 {
|
} else if lastHours == 0 {
|
||||||
@@ -72,7 +63,7 @@ func (c *OrderManager) GetStoreOrderCountInfo2(ctx *jxcontext.Context, storeID,
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
return countInfo, nil
|
return countInfo, nil
|
||||||
}
|
}
|
||||||
globals.SugarLogger.Infof("GetStoreOrderCountInfo2 storeID:%s failed with error:%v", storeID, err)
|
globals.SugarLogger.Infof("GetStoreOrderCountInfo storeID:%d failed with error:%v", storeID, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +77,26 @@ func (c *OrderManager) GetOrderSkuInfo(ctx *jxcontext.Context, vendorOrderID str
|
|||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
if vendorID == model.VendorIDELM {
|
if vendorID == model.VendorIDELM {
|
||||||
err = dao.GetRows(db, &skus, fmt.Sprintf(`
|
err = dao.GetRows(db, &skus, fmt.Sprintf(`
|
||||||
SELECT t1.*, IF(t3.img IS NULL OR t3.img = '', t4.col_imageUrl, t3.img) image, %s full_sku_name
|
SELECT
|
||||||
|
t1.id,
|
||||||
|
t1.vendor_order_id,
|
||||||
|
t1.vendor_id,
|
||||||
|
t1.count,
|
||||||
|
t1.vendor_sku_id,
|
||||||
|
t1.sku_id,
|
||||||
|
t1.jx_sku_id,
|
||||||
|
t1.sku_name,
|
||||||
|
IF(t1.shop_price = 0, t1.sale_price, t1.shop_price) shop_price,
|
||||||
|
t1.sale_price,
|
||||||
|
t1.earning_price,
|
||||||
|
t1.weight,
|
||||||
|
t1.sku_type,
|
||||||
|
t1.promotion_type,
|
||||||
|
t1.order_created_at,
|
||||||
|
t1.store_sub_id,
|
||||||
|
t1.store_sub_name,
|
||||||
|
t1.vendor_price,
|
||||||
|
IF(t3.img IS NULL OR t3.img = '', t4.col_imageUrl, t3.img) image, %s full_sku_name
|
||||||
FROM order_sku t1
|
FROM order_sku t1
|
||||||
LEFT JOIN sku t2 ON IF(t1.jx_sku_id != 0, t1.jx_sku_id, t1.sku_id) = t2.id/* AND t2.deleted_at = ?*/
|
LEFT JOIN sku t2 ON IF(t1.jx_sku_id != 0, t1.jx_sku_id, t1.sku_id) = t2.id/* AND t2.deleted_at = ?*/
|
||||||
LEFT JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/
|
LEFT JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/
|
||||||
@@ -96,7 +106,26 @@ func (c *OrderManager) GetOrderSkuInfo(ctx *jxcontext.Context, vendorOrderID str
|
|||||||
`, fullSkuNameSQL), /*, utils.DefaultTimeValue, utils.DefaultTimeValue*/ vendorOrderID, vendorID)
|
`, fullSkuNameSQL), /*, utils.DefaultTimeValue, utils.DefaultTimeValue*/ vendorOrderID, vendorID)
|
||||||
} else if vendorID == model.VendorIDJD {
|
} else if vendorID == model.VendorIDJD {
|
||||||
err = dao.GetRows(db, &skus, fmt.Sprintf(`
|
err = dao.GetRows(db, &skus, fmt.Sprintf(`
|
||||||
SELECT t1.*, IF(t3.img IS NULL OR t3.img = '', t4.image, t3.img) image, %s full_sku_name
|
SELECT
|
||||||
|
t1.id,
|
||||||
|
t1.vendor_order_id,
|
||||||
|
t1.vendor_id,
|
||||||
|
t1.count,
|
||||||
|
t1.vendor_sku_id,
|
||||||
|
t1.sku_id,
|
||||||
|
t1.jx_sku_id,
|
||||||
|
t1.sku_name,
|
||||||
|
IF(t1.shop_price = 0, t1.sale_price, t1.shop_price) shop_price,
|
||||||
|
t1.sale_price,
|
||||||
|
t1.earning_price,
|
||||||
|
t1.weight,
|
||||||
|
t1.sku_type,
|
||||||
|
t1.promotion_type,
|
||||||
|
t1.order_created_at,
|
||||||
|
t1.store_sub_id,
|
||||||
|
t1.store_sub_name,
|
||||||
|
t1.vendor_price,
|
||||||
|
IF(t3.img IS NULL OR t3.img = '', t4.image, t3.img) image, %s full_sku_name
|
||||||
FROM order_sku t1
|
FROM order_sku t1
|
||||||
LEFT JOIN sku t2 ON IF(t1.jx_sku_id != 0, t1.jx_sku_id, t1.sku_id) = t2.id/* AND t2.deleted_at = ?*/
|
LEFT JOIN sku t2 ON IF(t1.jx_sku_id != 0, t1.jx_sku_id, t1.sku_id) = t2.id/* AND t2.deleted_at = ?*/
|
||||||
LEFT JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/
|
LEFT JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/
|
||||||
@@ -107,7 +136,26 @@ func (c *OrderManager) GetOrderSkuInfo(ctx *jxcontext.Context, vendorOrderID str
|
|||||||
}
|
}
|
||||||
if err != nil || len(skus) == 0 {
|
if err != nil || len(skus) == 0 {
|
||||||
err = dao.GetRows(db, &skus, fmt.Sprintf(`
|
err = dao.GetRows(db, &skus, fmt.Sprintf(`
|
||||||
SELECT t1.*, t3.img image, %s full_sku_name
|
SELECT
|
||||||
|
t1.id,
|
||||||
|
t1.vendor_order_id,
|
||||||
|
t1.vendor_id,
|
||||||
|
t1.count,
|
||||||
|
t1.vendor_sku_id,
|
||||||
|
t1.sku_id,
|
||||||
|
t1.jx_sku_id,
|
||||||
|
t1.sku_name,
|
||||||
|
IF(t1.shop_price = 0, t1.sale_price, t1.shop_price) shop_price,
|
||||||
|
t1.sale_price,
|
||||||
|
t1.earning_price,
|
||||||
|
t1.weight,
|
||||||
|
t1.sku_type,
|
||||||
|
t1.promotion_type,
|
||||||
|
t1.order_created_at,
|
||||||
|
t1.store_sub_id,
|
||||||
|
t1.store_sub_name,
|
||||||
|
t1.vendor_price,
|
||||||
|
t3.img image, %s full_sku_name
|
||||||
FROM order_sku t1
|
FROM order_sku t1
|
||||||
LEFT JOIN sku t2 ON IF(t1.jx_sku_id != 0, t1.jx_sku_id, t1.sku_id) = t2.id/* AND t2.deleted_at = ?*/
|
LEFT JOIN sku t2 ON IF(t1.jx_sku_id != 0, t1.jx_sku_id, t1.sku_id) = t2.id/* AND t2.deleted_at = ?*/
|
||||||
LEFT JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/
|
LEFT JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/
|
||||||
@@ -157,19 +205,25 @@ func (c *OrderManager) GetOrderInfo(ctx *jxcontext.Context, vendorOrderID string
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *OrderManager) GetOrderWaybillInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID int) (bills []*model.Waybill, err error) {
|
func (c *OrderManager) GetOrderWaybillInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID int, isNotEnded bool) (bills []*model.Waybill, err error) {
|
||||||
globals.SugarLogger.Debugf("GetOrderWaybillInfo orderID:%s", vendorOrderID)
|
globals.SugarLogger.Debugf("GetOrderWaybillInfo orderID:%s", vendorOrderID)
|
||||||
db := orm.NewOrm()
|
db := dao.GetDB()
|
||||||
_, err = db.Raw(`
|
sql := `
|
||||||
SELECT t1.*
|
SELECT t1.*
|
||||||
FROM waybill t1
|
FROM waybill t1
|
||||||
WHERE t1.vendor_order_id = ? AND order_vendor_id = ?
|
WHERE t1.vendor_order_id = ? AND order_vendor_id = ?
|
||||||
`, vendorOrderID, vendorID).QueryRows(&bills)
|
`
|
||||||
if err == nil {
|
sqlParams := []interface{}{
|
||||||
return bills, nil
|
vendorOrderID,
|
||||||
|
vendorID,
|
||||||
}
|
}
|
||||||
|
if isNotEnded {
|
||||||
|
sql += " AND t1.status < ?"
|
||||||
|
sqlParams = append(sqlParams, model.OrderStatusEndBegin)
|
||||||
|
}
|
||||||
|
err = dao.GetRows(db, &bills, sql, sqlParams...)
|
||||||
globals.SugarLogger.Infof("GetOrderWaybillInfo orderID:%s failed with error:%v", vendorOrderID, err)
|
globals.SugarLogger.Infof("GetOrderWaybillInfo orderID:%s failed with error:%v", vendorOrderID, err)
|
||||||
return nil, err
|
return bills, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *OrderManager) ExportMTWaybills(ctx *jxcontext.Context, fromDateStr, toDateStr string) (excelContent []byte, err error) {
|
func (c *OrderManager) ExportMTWaybills(ctx *jxcontext.Context, fromDateStr, toDateStr string) (excelContent []byte, err error) {
|
||||||
@@ -220,8 +274,8 @@ func (c *OrderManager) ExportMTWaybills(ctx *jxcontext.Context, fromDateStr, toD
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *OrderManager) GetOrders(ctx *jxcontext.Context, fromDateStr, toDateStr string, params map[string]interface{}, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
|
func (c *OrderManager) getOrders(ctx *jxcontext.Context, isIncludeSku bool, fromDateStr, toDateStr string, params map[string]interface{}, offset, pageSize int) (orders []*model.GoodsOrderExt, totalCount int, err error) {
|
||||||
globals.SugarLogger.Debugf("GetOrders from:%s to:%s", fromDateStr, toDateStr)
|
globals.SugarLogger.Debugf("getOrders from:%s to:%s", fromDateStr, toDateStr)
|
||||||
|
|
||||||
pageSize = jxutils.FormalizePageSize(pageSize)
|
pageSize = jxutils.FormalizePageSize(pageSize)
|
||||||
if offset < 0 {
|
if offset < 0 {
|
||||||
@@ -229,11 +283,21 @@ func (c *OrderManager) GetOrders(ctx *jxcontext.Context, fromDateStr, toDateStr
|
|||||||
}
|
}
|
||||||
sql := `
|
sql := `
|
||||||
SELECT SQL_CALC_FOUND_ROWS t1.*,
|
SELECT SQL_CALC_FOUND_ROWS t1.*,
|
||||||
|
CAST(IF(t1.shop_price <= t1.vendor_price, IF(t1.shop_price = 0, t1.sale_price, t1.shop_price), IF(t1.vendor_price = 0, t1.sale_price, t1.vendor_price))*IF(t5.pay_percentage IS NULL OR t5.pay_percentage <= 0, 70, t5.pay_percentage)/100 AS SIGNED) earning_price,
|
||||||
t2.status waybill_status, t2.courier_name, t2.courier_mobile,
|
t2.status waybill_status, t2.courier_name, t2.courier_mobile,
|
||||||
t2.actual_fee, t2.desired_fee, t2.waybill_created_at, t2.waybill_finished_at
|
t2.actual_fee, t2.desired_fee, t2.waybill_created_at, t2.waybill_finished_at`
|
||||||
|
if isIncludeSku {
|
||||||
|
sql += `,
|
||||||
|
t3.sku_id, t3.count sku_count2, t3.shop_price sku_shop_price, IF(t3.earning_price <> 0, t3.earning_price, t3.sale_price) sku_sale_price`
|
||||||
|
}
|
||||||
|
sql += `
|
||||||
FROM goods_order t1
|
FROM goods_order t1
|
||||||
LEFT JOIN waybill t2 ON t1.vendor_waybill_id = t2.vendor_waybill_id AND t1.waybill_vendor_id = t2.waybill_vendor_id
|
LEFT JOIN waybill t2 ON t1.vendor_waybill_id = t2.vendor_waybill_id AND t1.waybill_vendor_id = t2.waybill_vendor_id
|
||||||
`
|
LEFT JOIN store t5 ON t5.id = IF(t1.jx_store_id <> 0, t1.jx_store_id, t1.store_id)`
|
||||||
|
if isIncludeSku {
|
||||||
|
sql += `
|
||||||
|
JOIN order_sku t3 ON t3.vendor_order_id = t1.vendor_order_id AND t3.vendor_id = t1.vendor_id`
|
||||||
|
}
|
||||||
var (
|
var (
|
||||||
sqlWhere string
|
sqlWhere string
|
||||||
sqlParams []interface{}
|
sqlParams []interface{}
|
||||||
@@ -257,14 +321,14 @@ func (c *OrderManager) GetOrders(ctx *jxcontext.Context, fromDateStr, toDateStr
|
|||||||
} else {
|
} else {
|
||||||
fromDate, err2 := utils.TryStr2Time(fromDateStr)
|
fromDate, err2 := utils.TryStr2Time(fromDateStr)
|
||||||
if err = err2; err != nil {
|
if err = err2; err != nil {
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
if toDateStr == "" {
|
if toDateStr == "" {
|
||||||
toDateStr = fromDateStr
|
toDateStr = fromDateStr
|
||||||
}
|
}
|
||||||
toDate, err2 := utils.TryStr2Time(toDateStr)
|
toDate, err2 := utils.TryStr2Time(toDateStr)
|
||||||
if err = err2; err != nil {
|
if err = err2; err != nil {
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
toDate = toDate.Add(24 * time.Hour)
|
toDate = toDate.Add(24 * time.Hour)
|
||||||
|
|
||||||
@@ -279,7 +343,7 @@ func (c *OrderManager) GetOrders(ctx *jxcontext.Context, fromDateStr, toDateStr
|
|||||||
keyword := params["keyword"].(string)
|
keyword := params["keyword"].(string)
|
||||||
keywordLike := "%" + keyword + "%"
|
keywordLike := "%" + keyword + "%"
|
||||||
sqlWhere += `
|
sqlWhere += `
|
||||||
AND (t1.store_name LIKE ? OR t1.vendor_order_id LIKE ? OR t1.vendor_store_id LIKE ?
|
AND (t1.store_name LIKE ? OR t1.vendor_order_id LIKE ? OR t1.vendor_store_id LIKE ?
|
||||||
OR t1.consignee_name LIKE ? OR t1.consignee_mobile LIKE ? OR t1.consignee_mobile2 LIKE ? OR t1.consignee_address LIKE ?
|
OR t1.consignee_name LIKE ? OR t1.consignee_mobile LIKE ? OR t1.consignee_mobile2 LIKE ? OR t1.consignee_address LIKE ?
|
||||||
OR t2.vendor_waybill_id LIKE ? OR t2.courier_name LIKE ? OR t2.courier_mobile LIKE ?
|
OR t2.vendor_waybill_id LIKE ? OR t2.courier_name LIKE ? OR t2.courier_mobile LIKE ?
|
||||||
`
|
`
|
||||||
@@ -293,17 +357,17 @@ func (c *OrderManager) GetOrders(ctx *jxcontext.Context, fromDateStr, toDateStr
|
|||||||
if params["waybillVendorIDs"] != nil {
|
if params["waybillVendorIDs"] != nil {
|
||||||
var waybillVendorIDs []int
|
var waybillVendorIDs []int
|
||||||
if err = utils.UnmarshalUseNumber([]byte(params["waybillVendorIDs"].(string)), &waybillVendorIDs); err != nil {
|
if err = utils.UnmarshalUseNumber([]byte(params["waybillVendorIDs"].(string)), &waybillVendorIDs); err != nil {
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
if len(waybillVendorIDs) > 0 {
|
if len(waybillVendorIDs) > 0 {
|
||||||
sqlWhere += " AND t2.waybill_vendor_id IN (" + dao.GenQuestionMarks(len(waybillVendorIDs)) + ")"
|
sqlWhere += " AND t1.waybill_vendor_id IN (" + dao.GenQuestionMarks(len(waybillVendorIDs)) + ")"
|
||||||
sqlParams = append(sqlParams, waybillVendorIDs)
|
sqlParams = append(sqlParams, waybillVendorIDs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if params["storeIDs"] != nil {
|
if params["storeIDs"] != nil {
|
||||||
var storeIDs []int
|
var storeIDs []int
|
||||||
if err = utils.UnmarshalUseNumber([]byte(params["storeIDs"].(string)), &storeIDs); err != nil {
|
if err = utils.UnmarshalUseNumber([]byte(params["storeIDs"].(string)), &storeIDs); err != nil {
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
if len(storeIDs) > 0 {
|
if len(storeIDs) > 0 {
|
||||||
sqlWhere += " AND IF(t1.vendor_id = ?, t1.store_id, IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) ) IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")"
|
sqlWhere += " AND IF(t1.vendor_id = ?, t1.store_id, IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) ) IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")"
|
||||||
@@ -313,7 +377,7 @@ func (c *OrderManager) GetOrders(ctx *jxcontext.Context, fromDateStr, toDateStr
|
|||||||
if params["statuss"] != nil {
|
if params["statuss"] != nil {
|
||||||
var statuss []int
|
var statuss []int
|
||||||
if err = utils.UnmarshalUseNumber([]byte(params["statuss"].(string)), &statuss); err != nil {
|
if err = utils.UnmarshalUseNumber([]byte(params["statuss"].(string)), &statuss); err != nil {
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
if len(statuss) > 0 {
|
if len(statuss) > 0 {
|
||||||
sqlWhere += " AND t1.status IN (" + dao.GenQuestionMarks(len(statuss)) + ")"
|
sqlWhere += " AND t1.status IN (" + dao.GenQuestionMarks(len(statuss)) + ")"
|
||||||
@@ -323,7 +387,7 @@ func (c *OrderManager) GetOrders(ctx *jxcontext.Context, fromDateStr, toDateStr
|
|||||||
if params["lockStatuss"] != nil {
|
if params["lockStatuss"] != nil {
|
||||||
var lockStatuss []int
|
var lockStatuss []int
|
||||||
if err = utils.UnmarshalUseNumber([]byte(params["lockStatuss"].(string)), &lockStatuss); err != nil {
|
if err = utils.UnmarshalUseNumber([]byte(params["lockStatuss"].(string)), &lockStatuss); err != nil {
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
if len(lockStatuss) > 0 {
|
if len(lockStatuss) > 0 {
|
||||||
sqlWhere += " AND t1.lock_status IN (" + dao.GenQuestionMarks(len(lockStatuss)) + ")"
|
sqlWhere += " AND t1.lock_status IN (" + dao.GenQuestionMarks(len(lockStatuss)) + ")"
|
||||||
@@ -333,7 +397,7 @@ func (c *OrderManager) GetOrders(ctx *jxcontext.Context, fromDateStr, toDateStr
|
|||||||
if params["cities"] != nil {
|
if params["cities"] != nil {
|
||||||
var cities []int
|
var cities []int
|
||||||
if err = utils.UnmarshalUseNumber([]byte(params["cities"].(string)), &cities); err != nil {
|
if err = utils.UnmarshalUseNumber([]byte(params["cities"].(string)), &cities); err != nil {
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
if len(cities) > 0 {
|
if len(cities) > 0 {
|
||||||
sql += " JOIN store st ON t1.store_id = st.id"
|
sql += " JOIN store st ON t1.store_id = st.id"
|
||||||
@@ -345,39 +409,147 @@ func (c *OrderManager) GetOrders(ctx *jxcontext.Context, fromDateStr, toDateStr
|
|||||||
if params["vendorIDs"] != nil {
|
if params["vendorIDs"] != nil {
|
||||||
var vendorIDs []int
|
var vendorIDs []int
|
||||||
if err = utils.UnmarshalUseNumber([]byte(params["vendorIDs"].(string)), &vendorIDs); err != nil {
|
if err = utils.UnmarshalUseNumber([]byte(params["vendorIDs"].(string)), &vendorIDs); err != nil {
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
if len(vendorIDs) > 0 {
|
if len(vendorIDs) > 0 {
|
||||||
sqlWhere += " AND t1.vendor_id IN (" + dao.GenQuestionMarks(len(vendorIDs)) + ")"
|
sqlWhere += " AND t1.vendor_id IN (" + dao.GenQuestionMarks(len(vendorIDs)) + ")"
|
||||||
sqlParams = append(sqlParams, vendorIDs)
|
sqlParams = append(sqlParams, vendorIDs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sql += sqlWhere
|
|
||||||
sql += `
|
|
||||||
ORDER BY t1.order_created_at DESC
|
|
||||||
LIMIT ? OFFSET ?
|
|
||||||
`
|
|
||||||
sqlParams = append(sqlParams, pageSize, offset)
|
|
||||||
|
|
||||||
var orders []*model.GoodsOrderExt
|
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
dao.Begin(db)
|
sql += sqlWhere
|
||||||
defer func() {
|
if isIncludeSku {
|
||||||
if r := recover(); r != nil {
|
sql += `
|
||||||
dao.Rollback(db)
|
ORDER BY t1.id`
|
||||||
panic(r)
|
} else {
|
||||||
}
|
sql += `
|
||||||
}()
|
ORDER BY t1.order_created_at DESC
|
||||||
|
LIMIT ? OFFSET ?`
|
||||||
|
sqlParams = append(sqlParams, pageSize, offset)
|
||||||
|
|
||||||
|
dao.Begin(db)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
panic(r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
if err = dao.GetRows(db, &orders, sql, sqlParams...); err == nil {
|
if err = dao.GetRows(db, &orders, sql, sqlParams...); err == nil {
|
||||||
|
totalCount = dao.GetLastTotalRowCount(db)
|
||||||
|
}
|
||||||
|
if !isIncludeSku {
|
||||||
|
dao.Commit(db)
|
||||||
|
}
|
||||||
|
return orders, totalCount, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) GetOrders(ctx *jxcontext.Context, fromDateStr, toDateStr string, params map[string]interface{}, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
|
||||||
|
globals.SugarLogger.Debugf("GetOrders from:%s to:%s", fromDateStr, toDateStr)
|
||||||
|
orders, totalCount, err := c.getOrders(ctx, false, fromDateStr, toDateStr, params, offset, pageSize)
|
||||||
|
if err == nil {
|
||||||
pagedInfo = &model.PagedInfo{
|
pagedInfo = &model.PagedInfo{
|
||||||
TotalCount: dao.GetLastTotalRowCount(db),
|
TotalCount: totalCount,
|
||||||
Data: orders,
|
Data: orders,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dao.Commit(db)
|
|
||||||
return pagedInfo, err
|
return pagedInfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) ExportOrders(ctx *jxcontext.Context, fromDateStr, toDateStr string, mapParams map[string]interface{}) (hint string, err error) {
|
||||||
|
globals.SugarLogger.Debugf("ExportOrders from:%s to:%s", fromDateStr, toDateStr)
|
||||||
|
var (
|
||||||
|
orders, orders2 []*model.GoodsOrderExt
|
||||||
|
order *model.GoodsOrderExt
|
||||||
|
excelBin []byte
|
||||||
|
)
|
||||||
|
task := tasksch.NewSeqTask("导出订单SKU信息", ctx,
|
||||||
|
func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||||
|
switch step {
|
||||||
|
case 0:
|
||||||
|
orders, _, err = c.getOrders(ctx, true, fromDateStr, toDateStr, mapParams, 0, -1)
|
||||||
|
case 1:
|
||||||
|
for _, v := range orders {
|
||||||
|
skuStr := strings.Join([]string{
|
||||||
|
utils.Int2Str(v.SkuID),
|
||||||
|
utils.Int2Str(v.SkuCount2),
|
||||||
|
utils.Int2Str(v.SkuShopPrice),
|
||||||
|
utils.Int2Str(v.SkuSalePrice),
|
||||||
|
}, ",")
|
||||||
|
if order == nil || v.ID != order.ID {
|
||||||
|
order = v
|
||||||
|
v.CourierVendorName = model.VendorChineseNames[v.WaybillVendorID]
|
||||||
|
v.Status2 = model.OrderStatusName[v.Status]
|
||||||
|
v.SkuInfo = skuStr
|
||||||
|
orders2 = append(orders2, v)
|
||||||
|
} else {
|
||||||
|
order.SkuInfo += ";" + skuStr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
excelConf := &excel.Obj2ExcelSheetConfig{
|
||||||
|
Title: "订单导出",
|
||||||
|
Data: orders2,
|
||||||
|
CaptionList: []string{
|
||||||
|
"vendorOrderID",
|
||||||
|
"vendorID",
|
||||||
|
"vendorStoreID",
|
||||||
|
"jxStoreID",
|
||||||
|
"storeName",
|
||||||
|
"salePrice",
|
||||||
|
"shopPrice",
|
||||||
|
"weight",
|
||||||
|
"consigneeName",
|
||||||
|
"consigneeMobile",
|
||||||
|
"consigneeMobile2",
|
||||||
|
"consigneeAddress",
|
||||||
|
"skuCount",
|
||||||
|
"status",
|
||||||
|
"orderSeq",
|
||||||
|
"buyerComment",
|
||||||
|
"businessType",
|
||||||
|
"expectedDeliveredTime",
|
||||||
|
"vendorWaybillID",
|
||||||
|
"waybillVendorID",
|
||||||
|
"orderCreatedAt",
|
||||||
|
"orderFinishedAt",
|
||||||
|
"courierVendorName",
|
||||||
|
"courierName",
|
||||||
|
"courierMobile",
|
||||||
|
"courierMobile",
|
||||||
|
"desiredFee",
|
||||||
|
"waybillCreatedAt",
|
||||||
|
"waybillFinishedAt",
|
||||||
|
"status2",
|
||||||
|
"skuInfo",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
excelBin = excel.Obj2Excel([]*excel.Obj2ExcelSheetConfig{excelConf})
|
||||||
|
case 3:
|
||||||
|
keyPart := []string{
|
||||||
|
ctx.GetUserName(),
|
||||||
|
}
|
||||||
|
if fromDateStr != "" {
|
||||||
|
keyPart = append(keyPart, fromDateStr)
|
||||||
|
}
|
||||||
|
if toDateStr != "" {
|
||||||
|
keyPart = append(keyPart, toDateStr)
|
||||||
|
}
|
||||||
|
keyPart = append(keyPart, time.Now().Format("20060102T150405")+".xlsx")
|
||||||
|
key := "export/" + strings.Join(keyPart, "_")
|
||||||
|
excelURL, err2 := jxutils.UploadExportContent(excelBin, key)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
task.SetNoticeMsg(excelURL)
|
||||||
|
}
|
||||||
|
globals.SugarLogger.Debugf("导出订单SKU信息excelURL:%s, err:%v", excelURL, err)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}, 4)
|
||||||
|
tasksch.ManageTask(task).Run()
|
||||||
|
hint = task.GetID()
|
||||||
|
return hint, err
|
||||||
|
}
|
||||||
|
|
||||||
func (c *OrderManager) GetWaybills(ctx *jxcontext.Context, fromDateStr, toDateStr string, params map[string]interface{}, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
|
func (c *OrderManager) GetWaybills(ctx *jxcontext.Context, fromDateStr, toDateStr string, params map[string]interface{}, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
|
||||||
globals.SugarLogger.Debugf("GetWaybills from:%s to:%s", fromDateStr, toDateStr)
|
globals.SugarLogger.Debugf("GetWaybills from:%s to:%s", fromDateStr, toDateStr)
|
||||||
|
|
||||||
@@ -472,16 +644,14 @@ func (c *OrderManager) GetOrderStatusList(ctx *jxcontext.Context, vendorOrderID
|
|||||||
sql := `
|
sql := `
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM order_status t1
|
FROM order_status t1
|
||||||
WHERE 1 = 1
|
WHERE t1.ref_vendor_order_id = ? AND t1.ref_vendor_id = ?
|
||||||
`
|
`
|
||||||
sqlParams := []interface{}{
|
sqlParams := []interface{}{
|
||||||
vendorOrderID,
|
vendorOrderID,
|
||||||
vendorID,
|
vendorID,
|
||||||
}
|
}
|
||||||
if orderType == -1 {
|
if orderType > 0 {
|
||||||
sql += " AND t1.ref_vendor_order_id = ? AND t1.ref_vendor_id = ?"
|
sql += " AND t1.order_type = ?"
|
||||||
} else {
|
|
||||||
sql += " AND t1.vendor_order_id = ? AND t1.vendor_id = ? AND t1.order_type = ?"
|
|
||||||
sqlParams = append(sqlParams, orderType)
|
sqlParams = append(sqlParams, orderType)
|
||||||
}
|
}
|
||||||
sql += " ORDER BY t1.status_time, t1.order_type DESC"
|
sql += " ORDER BY t1.status_time, t1.order_type DESC"
|
||||||
@@ -604,3 +774,184 @@ func (c *OrderManager) GetOrdersFinancial(ctx *jxcontext.Context, fromDateStr, t
|
|||||||
|
|
||||||
return pagedInfo, err
|
return pagedInfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) GetStoresOrderSaleInfo(ctx *jxcontext.Context, storeIDList []int, fromTime time.Time, toTime time.Time, statusList []int) (saleInfoList []*StoresOrderSaleInfo, err error) {
|
||||||
|
if toTime.Sub(fromTime) > time.Hour*24*60 {
|
||||||
|
return nil, fmt.Errorf("查询时间范围不能超过60天")
|
||||||
|
}
|
||||||
|
// 用int64类型去取float型的数据库返回值,会取不到
|
||||||
|
sql := `
|
||||||
|
SELECT IF(t1.jx_store_id > 0, t1.jx_store_id, t1.store_id) store_id, t1.vendor_id, IF(t1.status < ?, 0, t1.status) status,
|
||||||
|
COUNT(*) count, SUM(t1.shop_price) shop_price, SUM(t1.vendor_price) vendor_price, SUM(t1.sale_price) sale_price, SUM(t1.actual_pay_price) actual_pay_price,
|
||||||
|
CAST(SUM(IF(t1.shop_price <= t1.vendor_price, IF(t1.shop_price = 0, t1.sale_price, t1.shop_price), IF(t1.vendor_price = 0, t1.sale_price, t1.vendor_price))*IF(t5.pay_percentage IS NULL OR t5.pay_percentage <= 0, 70, t5.pay_percentage)/100) AS SIGNED) earning_price
|
||||||
|
FROM goods_order t1
|
||||||
|
LEFT JOIN store t5 ON t5.id = IF(t1.jx_store_id <> 0, t1.jx_store_id, t1.store_id)
|
||||||
|
WHERE t1.order_created_at >= ? AND t1.order_created_at <= ?
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
model.OrderStatusEndBegin,
|
||||||
|
fromTime,
|
||||||
|
toTime,
|
||||||
|
}
|
||||||
|
if len(storeIDList) > 0 {
|
||||||
|
sql += " AND IF(t1.jx_store_id > 0, t1.jx_store_id, t1.store_id) IN (" + dao.GenQuestionMarks(len(storeIDList)) + ")"
|
||||||
|
sqlParams = append(sqlParams, storeIDList)
|
||||||
|
}
|
||||||
|
if len(statusList) > 0 {
|
||||||
|
sql += " AND t1.status IN (" + dao.GenQuestionMarks(len(statusList)) + ")"
|
||||||
|
sqlParams = append(sqlParams, statusList)
|
||||||
|
}
|
||||||
|
sql += `
|
||||||
|
GROUP BY 1,2,3
|
||||||
|
ORDER BY 1,2,3`
|
||||||
|
err = dao.GetRows(dao.GetDB(), &saleInfoList, sql, sqlParams...)
|
||||||
|
return saleInfoList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) GetAfsOrders(ctx *jxcontext.Context, keyword, afsOrderID, vendorOrderID string, vendorIDList, appealTypeList, storeIDList, statusList []int, fromTime, toTime time.Time, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
|
||||||
|
globals.SugarLogger.Debugf("GetAfsOrders")
|
||||||
|
|
||||||
|
pageSize = jxutils.FormalizePageSize(pageSize)
|
||||||
|
if offset < 0 {
|
||||||
|
offset = 0
|
||||||
|
}
|
||||||
|
sql := `
|
||||||
|
SELECT SQL_CALC_FOUND_ROWS t1.*
|
||||||
|
FROM afs_order t1
|
||||||
|
`
|
||||||
|
var (
|
||||||
|
sqlWhere string
|
||||||
|
sqlParams []interface{}
|
||||||
|
)
|
||||||
|
// 如果搜索关键字可能为订单或售后单号,则当成订单或售后单查询
|
||||||
|
if keyword != "" {
|
||||||
|
if jxutils.GetPossibleVendorIDFromAfsOrderID(keyword) > model.VendorIDUnknown && afsOrderID == "" {
|
||||||
|
afsOrderID = keyword
|
||||||
|
keyword = ""
|
||||||
|
} else if jxutils.GetPossibleVendorIDFromVendorOrderID(keyword) > model.VendorIDUnknown && vendorOrderID == "" {
|
||||||
|
vendorOrderID = keyword
|
||||||
|
keyword = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if vendorOrderID != "" || afsOrderID != "" {
|
||||||
|
if vendorOrderID != "" {
|
||||||
|
sqlWhere = " WHERE (t1.vendor_order_id = ? OR t1.vendor_order_id2 = ?)"
|
||||||
|
sqlParams = []interface{}{
|
||||||
|
vendorOrderID,
|
||||||
|
vendorOrderID,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sqlWhere = " WHERE (t1.afs_order_id = ?)"
|
||||||
|
sqlParams = []interface{}{
|
||||||
|
afsOrderID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if toTime.Sub(fromTime) > 24*time.Hour*60 {
|
||||||
|
return nil, fmt.Errorf("售后单查询时间不能超过60天")
|
||||||
|
}
|
||||||
|
sqlWhere = `
|
||||||
|
WHERE t1.afs_created_at >= ? AND t1.afs_created_at <= ?
|
||||||
|
`
|
||||||
|
sqlParams = []interface{}{
|
||||||
|
fromTime,
|
||||||
|
toTime,
|
||||||
|
}
|
||||||
|
if keyword != "" {
|
||||||
|
keywordLike := "%" + keyword + "%"
|
||||||
|
sqlWhere += `
|
||||||
|
AND (t1.vendor_order_id2 LIKE ? OR t1.vendor_order_id LIKE ? OR t1.afs_order_id LIKE ?
|
||||||
|
OR t1.vendor_store_id LIKE ? OR t1.reason_desc LIKE ?
|
||||||
|
`
|
||||||
|
sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike)
|
||||||
|
if keywordInt64 := utils.Str2Int64WithDefault(keyword, 0); keywordInt64 > 0 {
|
||||||
|
sqlWhere += " OR t1.store_id = ? OR t1.jx_store_id = ?"
|
||||||
|
sqlParams = append(sqlParams, keywordInt64, keywordInt64)
|
||||||
|
}
|
||||||
|
sqlWhere += ")"
|
||||||
|
}
|
||||||
|
if len(storeIDList) > 0 {
|
||||||
|
sqlWhere += " AND IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) IN (" + dao.GenQuestionMarks(len(storeIDList)) + ")"
|
||||||
|
sqlParams = append(sqlParams, storeIDList)
|
||||||
|
}
|
||||||
|
if len(statusList) > 0 {
|
||||||
|
sqlWhere += " AND t1.status IN (" + dao.GenQuestionMarks(len(statusList)) + ")"
|
||||||
|
sqlParams = append(sqlParams, statusList)
|
||||||
|
}
|
||||||
|
if len(appealTypeList) > 0 {
|
||||||
|
sqlWhere += " AND t1.appeal_type IN (" + dao.GenQuestionMarks(len(appealTypeList)) + ")"
|
||||||
|
sqlParams = append(sqlParams, appealTypeList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(vendorIDList) > 0 {
|
||||||
|
sqlWhere += " AND t1.vendor_id IN (" + dao.GenQuestionMarks(len(vendorIDList)) + ")"
|
||||||
|
sqlParams = append(sqlParams, vendorIDList)
|
||||||
|
}
|
||||||
|
|
||||||
|
sql += sqlWhere
|
||||||
|
sql += `
|
||||||
|
ORDER BY t1.afs_created_at DESC
|
||||||
|
LIMIT ? OFFSET ?
|
||||||
|
`
|
||||||
|
sqlParams = append(sqlParams, pageSize, offset)
|
||||||
|
|
||||||
|
var orders []*model.AfsOrder
|
||||||
|
db := dao.GetDB()
|
||||||
|
dao.Begin(db)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil || err != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
if r != nil {
|
||||||
|
panic(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if err = dao.GetRows(db, &orders, sql, sqlParams...); err == nil {
|
||||||
|
pagedInfo = &model.PagedInfo{
|
||||||
|
TotalCount: dao.GetLastTotalRowCount(db),
|
||||||
|
Data: orders,
|
||||||
|
}
|
||||||
|
dao.Commit(db)
|
||||||
|
}
|
||||||
|
return pagedInfo, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) GetAfsOrderSkuInfo(ctx *jxcontext.Context, afsOrderID string, vendorID int) (skus []*model.OrderFinancialSkuExt, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT t1.*, t3.img image
|
||||||
|
FROM order_sku_financial t1
|
||||||
|
JOIN sku t2 ON t2.id = IF(t1.jx_sku_id <> 0, t1.jx_sku_id, t1.sku_id)
|
||||||
|
JOIN sku_name t3 ON t3.id = t2.name_id
|
||||||
|
WHERE t1.afs_order_id = ? AND t1.vendor_id = ?
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
afsOrderID,
|
||||||
|
vendorID,
|
||||||
|
}
|
||||||
|
err = dao.GetRows(dao.GetDB(), &skus, sql, sqlParams...)
|
||||||
|
return skus, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OrderManager) GetStoreAfsOrderCountInfo(ctx *jxcontext.Context, storeID, lastHours int) (countInfo []*model.GoodsOrderCountInfo, err error) {
|
||||||
|
globals.SugarLogger.Debugf("GetStoreAfsOrderCountInfo storeID:%d", storeID)
|
||||||
|
if lastHours > maxLastHours {
|
||||||
|
lastHours = maxLastHours
|
||||||
|
} else if lastHours == 0 {
|
||||||
|
lastHours = defLastHours
|
||||||
|
}
|
||||||
|
|
||||||
|
db := dao.GetDB()
|
||||||
|
err = dao.GetRows(db, &countInfo, `
|
||||||
|
SELECT 0 lock_status, t1.status, COUNT(*) count
|
||||||
|
FROM afs_order t1
|
||||||
|
WHERE t1.vendor_id <> 2 AND IF(t1.vendor_id = ?, t1.store_id, IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) ) = ?
|
||||||
|
AND t1.afs_created_at >= ?
|
||||||
|
GROUP BY 1,2
|
||||||
|
ORDER BY 1,2
|
||||||
|
`, model.VendorIDWSC, storeID, time.Now().Add(-time.Duration(lastHours)*time.Hour))
|
||||||
|
if err == nil {
|
||||||
|
return countInfo, nil
|
||||||
|
}
|
||||||
|
globals.SugarLogger.Infof("GetStoreAfsOrderCountInfo storeID:%d failed with error:%v", storeID, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
waybillOrderStatusMap = map[int]int{
|
waybillOrderStatusMap = map[int]int{
|
||||||
model.WaybillStatusApplyFailedGetGoods: model.WaybillStatusApplyFailedGetGoods,
|
model.WaybillStatusApplyFailedGetGoods: model.OrderStatusApplyFailedGetGoods,
|
||||||
model.WaybillStatusAgreeFailedGetGoods: model.WaybillStatusAgreeFailedGetGoods,
|
model.WaybillStatusAgreeFailedGetGoods: model.OrderStatusAgreeFailedGetGoods,
|
||||||
model.WaybillStatusRefuseFailedGetGoods: model.WaybillStatusRefuseFailedGetGoods,
|
model.WaybillStatusRefuseFailedGetGoods: model.OrderStatusRefuseFailedGetGoods,
|
||||||
model.WaybillStatusDeliverFailed: model.WaybillStatusDeliverFailed,
|
model.WaybillStatusDeliverFailed: model.OrderStatusDeliverFailed,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -92,13 +92,48 @@ func (w *OrderManager) OnWaybillStatusChanged(bill *model.Waybill) (err error) {
|
|||||||
panic(r)
|
panic(r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
duplicatedCount := 0
|
||||||
if bill.Status == model.WaybillStatusNew {
|
if bill.Status == model.WaybillStatusNew {
|
||||||
isDuplicated, err = w.onWaybillNew(bill, db)
|
isDuplicated, err = w.onWaybillNew(bill, db)
|
||||||
|
if isDuplicated {
|
||||||
|
duplicatedCount = 1
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if bill.Status == model.WaybillStatusAccepted { // 处理美团配送丢失新运单消息的情况
|
||||||
|
existingBill, err2 := w.LoadWaybill(bill.VendorWaybillID, bill.WaybillVendorID)
|
||||||
|
if err2 != nil {
|
||||||
|
if dao.IsNoRowsError(err2) || err2 == ErrCanNotFindWaybill {
|
||||||
|
if isDuplicated, err = w.onWaybillNew(bill, db); err != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
existingBill = bill
|
||||||
|
billCopy := *bill
|
||||||
|
billCopy.Status = model.WaybillStatusNew
|
||||||
|
dao.Commit(db)
|
||||||
|
// 进运单调度器OnWaybillStatusChanged之前要确保事务是提交了的,否则会导致死锁
|
||||||
|
scheduler.CurrentScheduler.OnWaybillStatusChanged(&billCopy, false)
|
||||||
|
dao.Begin(db)
|
||||||
|
} else {
|
||||||
|
dao.Rollback(db)
|
||||||
|
return err2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 运单消息错序,之前已经结束了,直接返回
|
||||||
|
if existingBill.Status >= model.WaybillStatusEndBegin {
|
||||||
|
dao.Commit(db)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
addParams := orm.Params{}
|
addParams := orm.Params{}
|
||||||
if bill.Status >= model.WaybillStatusAccepted && bill.Status < model.WaybillStatusEndBegin {
|
if bill.Status >= model.WaybillStatusAccepted && bill.Status < model.WaybillStatusEndBegin {
|
||||||
if bill.Status == model.WaybillStatusAccepted {
|
if bill.Status == model.WaybillStatusAccepted {
|
||||||
addParams["desired_fee"] = bill.DesiredFee
|
if bill.DesiredFee > 0 {
|
||||||
|
addParams["desired_fee"] = bill.DesiredFee
|
||||||
|
}
|
||||||
|
if bill.ActualFee > 0 {
|
||||||
|
addParams["actual_fee"] = bill.ActualFee
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if bill.CourierMobile != "" {
|
if bill.CourierMobile != "" {
|
||||||
addParams["courier_name"] = bill.CourierName
|
addParams["courier_name"] = bill.CourierName
|
||||||
@@ -107,11 +142,15 @@ func (w *OrderManager) OnWaybillStatusChanged(bill *model.Waybill) (err error) {
|
|||||||
} else if bill.Status >= model.WaybillStatusEndBegin {
|
} else if bill.Status >= model.WaybillStatusEndBegin {
|
||||||
addParams["waybill_finished_at"] = bill.StatusTime
|
addParams["waybill_finished_at"] = bill.StatusTime
|
||||||
}
|
}
|
||||||
isDuplicated, err = w.addWaybillStatus(bill, db, addParams)
|
duplicatedCount, err = w.addWaybillStatus(bill, db, addParams)
|
||||||
|
if err != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
dao.Commit(db)
|
dao.Commit(db)
|
||||||
if !isDuplicated {
|
if duplicatedCount == 0 {
|
||||||
scheduler.CurrentScheduler.OnWaybillStatusChanged(bill, false)
|
scheduler.CurrentScheduler.OnWaybillStatusChanged(bill, false)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -136,21 +175,27 @@ func (w *OrderManager) OnWaybillStatusChanged(bill *model.Waybill) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OrderManager) addWaybillStatus(bill *model.Waybill, db *dao.DaoDB, addParams orm.Params) (isDuplicated bool, err error) {
|
func (w *OrderManager) addWaybillStatus(bill *model.Waybill, db *dao.DaoDB, addParams orm.Params) (duplicatedCount int, err error) {
|
||||||
waybillStatus := model.Waybill2Status(bill)
|
waybillStatus := model.Waybill2Status(bill)
|
||||||
isDuplicated, err = addOrderOrWaybillStatus(waybillStatus, db)
|
isDuplicated, err := addOrderOrWaybillStatus(waybillStatus, db)
|
||||||
if err == nil && !isDuplicated && waybillStatus.Status > model.WaybillStatusUnknown { // todo 这里应该和addOrderStatus一样的改法,状态不能回绕
|
if err == nil && !isDuplicated {
|
||||||
params := utils.MergeMaps(orm.Params{
|
if waybillStatus.Status > model.WaybillStatusUnknown { // todo 这里应该和addOrderStatus一样的改法,状态不能回绕
|
||||||
"status": bill.Status,
|
params := utils.MergeMaps(orm.Params{
|
||||||
"vendor_status": bill.VendorStatus,
|
"status": bill.Status,
|
||||||
"status_time": bill.StatusTime,
|
"vendor_status": bill.VendorStatus,
|
||||||
}, addParams)
|
"status_time": bill.StatusTime,
|
||||||
utils.CallFuncLogError(func() error {
|
}, addParams)
|
||||||
_, err = db.Db.QueryTable("waybill").Filter("vendor_waybill_id", bill.VendorWaybillID).Filter("waybill_vendor_id", bill.WaybillVendorID).Filter("status__lte", bill.Status).Update(params)
|
utils.CallFuncLogError(func() error {
|
||||||
return err
|
_, err = db.Db.QueryTable("waybill").Filter("vendor_waybill_id", bill.VendorWaybillID).Filter("waybill_vendor_id", bill.WaybillVendorID).Filter("status__lte", bill.Status).Update(params)
|
||||||
}, "addWaybillStatus update waybill status, bill:%v", bill)
|
return err
|
||||||
|
}, "addWaybillStatus update waybill status, bill:%v", bill)
|
||||||
|
} else {
|
||||||
|
duplicatedCount = -1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
duplicatedCount = 1
|
||||||
}
|
}
|
||||||
return isDuplicated, err
|
return duplicatedCount, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *OrderManager) LoadWaybill(vendorWaybillID string, waybillVendorID int) (bill *model.Waybill, err error) {
|
func (c *OrderManager) LoadWaybill(vendorWaybillID string, waybillVendorID int) (bill *model.Waybill, err error) {
|
||||||
@@ -160,6 +205,7 @@ func (c *OrderManager) LoadWaybill(vendorWaybillID string, waybillVendorID int)
|
|||||||
WaybillVendorID: waybillVendorID,
|
WaybillVendorID: waybillVendorID,
|
||||||
}
|
}
|
||||||
if err = db.Read(bill, "VendorWaybillID", "WaybillVendorID"); err != nil {
|
if err = db.Read(bill, "VendorWaybillID", "WaybillVendorID"); err != nil {
|
||||||
|
bill = nil
|
||||||
if err == orm.ErrNoRows {
|
if err == orm.ErrNoRows {
|
||||||
err = ErrCanNotFindWaybill
|
err = ErrCanNotFindWaybill
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
|
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
)
|
)
|
||||||
@@ -54,16 +55,16 @@ func (c *BaseScheduler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool
|
|||||||
|
|
||||||
func (c *BaseScheduler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) {
|
func (c *BaseScheduler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) {
|
||||||
globals.SugarLogger.Infof("Swtich2SelfDeliver orderID:%s", order.VendorOrderID)
|
globals.SugarLogger.Infof("Swtich2SelfDeliver orderID:%s", order.VendorOrderID)
|
||||||
if /*order.LockStatus == model.OrderStatusUnknown && */ order.Status == model.OrderStatusFinishedPickup {
|
if /*order.LockStatus == model.OrderStatusUnknown && */ order.Status >= model.OrderStatusFinishedPickup && order.Status <= model.OrderStatusDelivering {
|
||||||
if c.IsReallyCallPlatformAPI {
|
if order.DeliveryFlag&model.OrderDeliveryFlagMaskPurcahseDisabled == 0 && c.IsReallyCallPlatformAPI {
|
||||||
err = utils.CallFuncLogErrorWithInfo(func() error {
|
err = utils.CallFuncLogErrorWithInfo(func() error {
|
||||||
return partner.GetPurchasePlatformFromVendorID(order.VendorID).Swtich2SelfDeliver(order, userName)
|
return partner.GetPurchasePlatformFromVendorID(order.VendorID).Swtich2SelfDeliver(order, userName)
|
||||||
}, "Swtich2SelfDeliver orderID:%s", order.VendorOrderID)
|
}, "Swtich2SelfDeliver orderID:%s", order.VendorOrderID)
|
||||||
if err == nil { // 因为有些平台转自送后,不会再发送订单在配送中消息过来,所以成功后就强制设置状态为配送中
|
}
|
||||||
order.Status = model.OrderStatusDelivering
|
if err == nil { // 因为有些平台转自送后,不会再发送订单在配送中消息过来,所以成功后就强制设置状态为配送中
|
||||||
order.DeliveryFlag |= model.OrderDeliveryFlagMaskPurcahseDisabled
|
order.Status = model.OrderStatusDelivering
|
||||||
err = partner.CurOrderManager.UpdateOrderStatusAndFlag(order)
|
order.DeliveryFlag |= model.OrderDeliveryFlagMaskPurcahseDisabled
|
||||||
}
|
err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if order.LockStatus != model.OrderStatusUnknown || order.Status < model.OrderStatusFinishedPickup || order.VendorID == order.WaybillVendorID {
|
if order.LockStatus != model.OrderStatusUnknown || order.Status < model.OrderStatusFinishedPickup || order.VendorID == order.WaybillVendorID {
|
||||||
@@ -106,7 +107,7 @@ func (c *BaseScheduler) SelfDeliverDelivering(order *model.GoodsOrder, userName
|
|||||||
}, "SelfDeliverDelivering orderID:%s", order.VendorOrderID)
|
}, "SelfDeliverDelivering orderID:%s", order.VendorOrderID)
|
||||||
if err == nil { // 因为有些平台设置配送中后,不会发送订单在配送中消息过来,所以成功后就强制设置状态为配送中
|
if err == nil { // 因为有些平台设置配送中后,不会发送订单在配送中消息过来,所以成功后就强制设置状态为配送中
|
||||||
order.Status = model.OrderStatusDelivering
|
order.Status = model.OrderStatusDelivering
|
||||||
err = partner.CurOrderManager.UpdateOrderStatusAndFlag(order)
|
err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -147,16 +148,28 @@ func (c *BaseScheduler) CreateWaybill(platformVendorID int, order *model.GoodsOr
|
|||||||
globals.SugarLogger.Warnf("CreateWaybill orderID:%s, vendorID:%d is not solid!!!", order.VendorOrderID, platformVendorID)
|
globals.SugarLogger.Warnf("CreateWaybill orderID:%s, vendorID:%d is not solid!!!", order.VendorOrderID, platformVendorID)
|
||||||
return nil, scheduler.ErrOrderIsNotSolid
|
return nil, scheduler.ErrOrderIsNotSolid
|
||||||
}
|
}
|
||||||
if c.IsReallyCallPlatformAPI {
|
// if order.DeliveryFlag&model.OrderDeliveryFlagMaskScheduleDisabled != 0 {
|
||||||
handlerInfo := partner.GetDeliveryPlatformFromVendorID(platformVendorID)
|
// waybillList, err := partner.CurOrderManager.GetOrderWaybillInfo(jxcontext.AdminCtx, order.VendorOrderID, order.VendorID, true)
|
||||||
if handlerInfo != nil && handlerInfo.Use4CreateWaybill {
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// if len(waybillList) > 0 {
|
||||||
|
// return nil, fmt.Errorf("转商家自送的订单只允许有一个有效运单,当前已经有%s运单", jxutils.GetVendorName(waybillList[0].WaybillVendorID))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
handlerInfo := partner.GetDeliveryPlatformFromVendorID(platformVendorID)
|
||||||
|
if handlerInfo != nil && handlerInfo.Use4CreateWaybill {
|
||||||
|
if c.IsReallyCallPlatformAPI {
|
||||||
bill, err = handlerInfo.Handler.CreateWaybill(order, policy)
|
bill, err = handlerInfo.Handler.CreateWaybill(order, policy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
globals.SugarLogger.Infof("CreateWaybill failed orderID:%s vendorID:%d with error:%v", order.VendorOrderID, platformVendorID, err)
|
globals.SugarLogger.Infof("CreateWaybill failed orderID:%s vendorID:%d with error:%v", order.VendorOrderID, platformVendorID, err)
|
||||||
|
} else {
|
||||||
|
order.DeliveryFlag |= model.WaybillVendorID2Mask(platformVendorID)
|
||||||
|
err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
err = scheduler.ErrDeliverProviderWrong
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
err = scheduler.ErrDeliverProviderWrong
|
||||||
}
|
}
|
||||||
return bill, err
|
return bill, err
|
||||||
}
|
}
|
||||||
@@ -170,6 +183,8 @@ func (c *BaseScheduler) CancelWaybill(bill *model.Waybill, cancelReasonID int, c
|
|||||||
return handlerInfo.Handler.CancelWaybill(bill, cancelReasonID, cancelReason)
|
return handlerInfo.Handler.CancelWaybill(bill, cancelReasonID, cancelReason)
|
||||||
}, "CancelWaybill bill:%v", bill); err == nil {
|
}, "CancelWaybill bill:%v", bill); err == nil {
|
||||||
bill.Status = model.WaybillStatusCanceled
|
bill.Status = model.WaybillStatusCanceled
|
||||||
|
bill.DeliveryFlag |= model.WaybillDeliveryFlagMaskActiveCancel
|
||||||
|
_, err = dao.UpdateEntity(nil, bill, "Status", "DeliveryFlag")
|
||||||
}
|
}
|
||||||
globals.SugarLogger.Debugf("CancelWaybill bill:%v canceled by myself", bill)
|
globals.SugarLogger.Debugf("CancelWaybill bill:%v canceled by myself", bill)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,25 +13,38 @@ import (
|
|||||||
"git.rosy.net.cn/jx-callback/globals"
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *BaseScheduler) CreateWaybillOnProviders(ctx *jxcontext.Context, order *model.GoodsOrder, policyHandler partner.CreateWaybillPolicy) (bills []*model.Waybill, err error) {
|
func (c *BaseScheduler) CreateWaybillOnProviders(ctx *jxcontext.Context, order *model.GoodsOrder, courierVendorIDs []int, policyHandler partner.CreateWaybillPolicy, createOnlyOne bool) (bills []*model.Waybill, err error) {
|
||||||
userName := ctx.GetUserName()
|
userName := ctx.GetUserName()
|
||||||
globals.SugarLogger.Infof("CreateWaybillOnProviders orderID:%s userName:%s", order.VendorOrderID, userName)
|
globals.SugarLogger.Infof("CreateWaybillOnProviders orderID:%s userName:%s", order.VendorOrderID, userName)
|
||||||
storeCourierList, err := dao.GetStoreCourierList(dao.GetDB(), jxutils.GetSaleStoreIDFromOrder(order), model.StoreStatusOpened)
|
storeCourierList, err := dao.GetStoreCourierList(dao.GetDB(), jxutils.GetSaleStoreIDFromOrder(order), model.StoreStatusOpened)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
var courierVendorIDMap map[int]bool
|
||||||
|
if len(courierVendorIDs) > 0 {
|
||||||
|
courierVendorIDMap = make(map[int]bool)
|
||||||
|
for _, courierVendorID := range courierVendorIDs {
|
||||||
|
courierVendorIDMap[courierVendorID] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
var errList []string
|
var errList []string
|
||||||
for _, storeCourier := range storeCourierList {
|
for _, storeCourier := range storeCourierList {
|
||||||
courierVendorID := storeCourier.VendorID
|
if courierVendorIDMap == nil || courierVendorIDMap[storeCourier.VendorID] {
|
||||||
if order.VendorID != model.VendorIDWSC || courierVendorID != model.VendorIDDada { // 达达作为微商城的自有配送,不参与配送竞争
|
if handler := partner.GetDeliveryPlatformFromVendorID(storeCourier.VendorID); handler != nil && handler.Use4CreateWaybill {
|
||||||
bill, err2 := c.CreateWaybill(courierVendorID, order, policyHandler)
|
courierVendorID := storeCourier.VendorID
|
||||||
if err = err2; err == nil {
|
if order.VendorID != model.VendorIDWSC || courierVendorID != model.VendorIDDada { // 达达作为微商城的自有配送,不参与配送竞争
|
||||||
globals.SugarLogger.Debugf("CreateWaybillOnProviders orderID:%s userName:%s vendorID:%d bill:%v", order.VendorOrderID, userName, courierVendorID, bill)
|
bill, err2 := c.CreateWaybill(courierVendorID, order, policyHandler)
|
||||||
bills = append(bills, bill)
|
if err = err2; err == nil {
|
||||||
} else {
|
globals.SugarLogger.Debugf("CreateWaybillOnProviders orderID:%s userName:%s vendorID:%d bill:%v", order.VendorOrderID, userName, courierVendorID, bill)
|
||||||
globals.SugarLogger.Debugf("CreateWaybillOnProviders orderID:%s userName:%s vendorID:%d failed with error:%v", order.VendorOrderID, userName, courierVendorID, err)
|
bills = append(bills, bill)
|
||||||
errList = append(errList, fmt.Sprintf("平台:%s,%s", jxutils.GetVendorName(courierVendorID), err.Error()))
|
if createOnlyOne {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
globals.SugarLogger.Debugf("CreateWaybillOnProviders orderID:%s userName:%s vendorID:%d failed with error:%v", order.VendorOrderID, userName, courierVendorID, err)
|
||||||
|
errList = append(errList, fmt.Sprintf("平台:%s,%s", jxutils.GetVendorName(courierVendorID), err.Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,8 +71,8 @@ func (c *BaseScheduler) SelfDeliveredAndUpdateStatus(ctx *jxcontext.Context, ven
|
|||||||
err = c.Swtich2SelfDelivered(order, userName)
|
err = c.Swtich2SelfDelivered(order, userName)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
order.Status = model.OrderStatusFinished
|
// order.Status = model.OrderStatusFinished // todo 是否需要强制设置完成状态?
|
||||||
if err = partner.CurOrderManager.UpdateOrderStatusAndFlag(order); err == nil {
|
if err = dao.SetOrderFlag(dao.GetDB(), ctx.GetUserName(), order.VendorOrderID, order.VendorID, model.OrderFlagMaskSetDelivered); err == nil {
|
||||||
globals.SugarLogger.Infof("SelfDeliveredAndUpdateStatus orderID:%s userName:%s successfully", vendorOrderID, userName)
|
globals.SugarLogger.Infof("SelfDeliveredAndUpdateStatus orderID:%s userName:%s successfully", vendorOrderID, userName)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -81,7 +94,7 @@ func (c *BaseScheduler) PickupGoodsAndUpdateStatus(ctx *jxcontext.Context, vendo
|
|||||||
err = c.PickupGoods(order, c.GetStoreDeliveryType(order, nil) == scheduler.StoreDeliveryTypeByStore, userName)
|
err = c.PickupGoods(order, c.GetStoreDeliveryType(order, nil) == scheduler.StoreDeliveryTypeByStore, userName)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
order.Status = model.OrderStatusFinishedPickup
|
order.Status = model.OrderStatusFinishedPickup
|
||||||
if err = partner.CurOrderManager.UpdateOrderStatusAndFlag(order); err == nil {
|
if err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order); err == nil {
|
||||||
globals.SugarLogger.Infof("PickupGoodsAndUpdateStatus orderID:%s userName:%s successfully", vendorOrderID, userName)
|
globals.SugarLogger.Infof("PickupGoodsAndUpdateStatus orderID:%s userName:%s successfully", vendorOrderID, userName)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -134,7 +147,7 @@ func (c *BaseScheduler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, ord
|
|||||||
err = partner.GetPurchasePlatformFromVendorID(order.VendorID).AcceptOrRefuseFailedGetOrder(ctx, order, isAcceptIt)
|
err = partner.GetPurchasePlatformFromVendorID(order.VendorID).AcceptOrRefuseFailedGetOrder(ctx, order, isAcceptIt)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
flag := int8(model.OrderFlagAgreeFailedGetGoods)
|
flag := model.OrderFlagAgreeFailedGetGoods
|
||||||
if !isAcceptIt {
|
if !isAcceptIt {
|
||||||
flag = model.OrderFlagRefuseFailedGetGoods
|
flag = model.OrderFlagRefuseFailedGetGoods
|
||||||
}
|
}
|
||||||
@@ -168,7 +181,7 @@ func (c *BaseScheduler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model
|
|||||||
err = partner.GetPurchasePlatformFromVendorID(order.VendorID).AgreeOrRefuseCancel(ctx, order, isAcceptIt, reason)
|
err = partner.GetPurchasePlatformFromVendorID(order.VendorID).AgreeOrRefuseCancel(ctx, order, isAcceptIt, reason)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
flag := int8(model.OrderFlagAgreeUserApplyCancel)
|
flag := model.OrderFlagAgreeUserApplyCancel
|
||||||
if !isAcceptIt {
|
if !isAcceptIt {
|
||||||
flag = model.OrderFlagRefuseUserApplyCancel
|
flag = model.OrderFlagRefuseUserApplyCancel
|
||||||
}
|
}
|
||||||
@@ -176,3 +189,43 @@ func (c *BaseScheduler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *BaseScheduler) CancelWaybillByID(ctx *jxcontext.Context, vendorWaybillID string, waybillVendorID int, cancelReasonID int, cancelReason string) (err error) {
|
||||||
|
bill, err := partner.CurOrderManager.LoadWaybill(vendorWaybillID, waybillVendorID)
|
||||||
|
if err == nil {
|
||||||
|
err = c.CancelWaybill(bill, cancelReasonID, cancelReason)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *BaseScheduler) AgreeOrRefuseRefund(ctx *jxcontext.Context, afsOrderID string, vendorID, approveType int, reason string) (err error) {
|
||||||
|
afsOrder, err := partner.CurOrderManager.LoadAfsOrder(afsOrderID, vendorID)
|
||||||
|
if err == nil {
|
||||||
|
if c.IsReallyCallPlatformAPI {
|
||||||
|
err = partner.GetPurchasePlatformFromVendorID(vendorID).AgreeOrRefuseRefund(ctx, afsOrder, approveType, reason)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
flag := model.AfsOrderFlagAgreeUserRefund
|
||||||
|
if approveType == partner.AfsApproveTypeRefused {
|
||||||
|
flag = model.AfsOrderFlagRefuseUserRefund
|
||||||
|
afsOrder.RefuseReason = reason
|
||||||
|
partner.CurOrderManager.UpdateAfsOrderFields(afsOrder, []string{"RefuseReason"})
|
||||||
|
}
|
||||||
|
dao.SetAfsOrderFlag(dao.GetDB(), ctx.GetUserName(), afsOrderID, vendorID, flag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *BaseScheduler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, afsOrderID string, vendorID int) (err error) {
|
||||||
|
afsOrder, err := partner.CurOrderManager.LoadAfsOrder(afsOrderID, vendorID)
|
||||||
|
if err == nil {
|
||||||
|
if c.IsReallyCallPlatformAPI {
|
||||||
|
err = partner.GetPurchasePlatformFromVendorID(vendorID).ConfirmReceivedReturnGoods(ctx, afsOrder)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
dao.SetAfsOrderFlag(dao.GetDB(), ctx.GetUserName(), afsOrderID, vendorID, model.AfsOrderFlagMaskReturnGoods)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,9 +25,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
time2Delivered = 1 * time.Hour // 正常从下单到送达的时间。
|
time2Delivered = 1 * time.Hour // 正常从下单到送达的时间。
|
||||||
minute2Schedule3rdCarrier = 20 // 收到平台方自有配送的新运单消息后,等待创建三方配送运单的时间(分钟),如果是定时达,会再根据ExpectedDeliveredTime与dingShiDaAheadTime做调整
|
minute2Schedule3rdCarrier = 20 // 收到平台方自有配送的新运单消息后,等待创建三方配送运单的时间(分钟),如果是定时达,会再根据ExpectedDeliveredTime与dingShiDaAheadTime做调整
|
||||||
minMinute2Schedule3rdCarrier = 5 // 转三方配送最少等待时间(分钟)
|
minute2Schedule3rdCarrier4Ebai = 30 // 饿百的最少转自配送需要的时间(分钟)
|
||||||
|
minMinute2Schedule3rdCarrier = 5 // 转三方配送最少等待时间(分钟)
|
||||||
|
|
||||||
time2AutoPickupMin = 15 * time.Minute // 自动拣货等待时间,这个只有在没有PickDeadline信息才有用,否则会根据PickDeadline设置
|
time2AutoPickupMin = 15 * time.Minute // 自动拣货等待时间,这个只有在没有PickDeadline信息才有用,否则会根据PickDeadline设置
|
||||||
second2AutoPickupGap = 60 //随机60秒
|
second2AutoPickupGap = 60 //随机60秒
|
||||||
@@ -64,13 +65,22 @@ type WatchOrderInfo struct {
|
|||||||
timerStatusType int // 0表示订单,1表示运单
|
timerStatusType int // 0表示订单,1表示运单
|
||||||
timerStatus int
|
timerStatus int
|
||||||
timer *time.Timer
|
timer *time.Timer
|
||||||
|
timerTime time.Time
|
||||||
|
|
||||||
retryCount int // 失败后尝试的次数,调试阶段可能出现死循化,阻止这种情况发生
|
retryCount int // 失败后尝试的次数,调试阶段可能出现死循化,阻止这种情况发生
|
||||||
}
|
}
|
||||||
|
|
||||||
type StatusActionConfig struct {
|
type StatusActionConfig struct {
|
||||||
partner.StatusActionParams
|
partner.StatusActionParams
|
||||||
TimeoutAction func(savedOrderInfo *WatchOrderInfo) (err error) // 超时后需要执行的动作,为nil表示此状态不需要执行监控, nil在GetStatusActionConfig返回时表示不修改缺省
|
TimeoutAction func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) (err error) // 超时后需要执行的动作,为nil表示此状态不需要执行监控, nil在GetStatusActionConfig返回时表示不修改缺省
|
||||||
|
ShouldSetTimer func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *StatusActionConfig) CallShouldSetTimer(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) bool {
|
||||||
|
if c.ShouldSetTimer != nil {
|
||||||
|
return c.ShouldSetTimer(savedOrderInfo, bill)
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重要:此调度器要求同一定单的处理逻辑必须是序列化了的,不然会有并发问题
|
// 重要:此调度器要求同一定单的处理逻辑必须是序列化了的,不然会有并发问题
|
||||||
@@ -114,11 +124,6 @@ func (s *WatchOrderInfo) updateOrderStoreFeature(order *model.GoodsOrder) (err e
|
|||||||
s.autoPickupTimeoutMinute = int(storeMap.AutoPickup)
|
s.autoPickupTimeoutMinute = int(storeMap.AutoPickup)
|
||||||
s.storeDeliveryType = FixedScheduler.GetStoreDeliveryType(order, storeMap)
|
s.storeDeliveryType = FixedScheduler.GetStoreDeliveryType(order, storeMap)
|
||||||
globals.SugarLogger.Debugf("updateOrderStoreFeature orderID:%s, s.storeDeliveryType:%d", order.VendorOrderID, s.storeDeliveryType)
|
globals.SugarLogger.Debugf("updateOrderStoreFeature orderID:%s, s.storeDeliveryType:%d", order.VendorOrderID, s.storeDeliveryType)
|
||||||
// if s.storeDeliveryType == scheduler.StoreDeliveryTypeByStore && (order.DeliveryFlag&model.OrderDeliveryFlagMaskPurcahseDisabled) == 0 {
|
|
||||||
// order.DeliveryFlag |= model.OrderDeliveryFlagMaskPurcahseDisabled
|
|
||||||
// err = partner.CurOrderManager.UpdateOrderStatusAndFlag(order)
|
|
||||||
// }
|
|
||||||
// globals.SugarLogger.Debugf("updateOrderStoreFeature orderID:%s, s.storeDeliveryType:%d, order.DeliveryFlag:%d", order.VendorOrderID, s.storeDeliveryType, order.DeliveryFlag)
|
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -136,7 +141,7 @@ func init() {
|
|||||||
TimerType: partner.TimerTypeBaseStatusTime,
|
TimerType: partner.TimerTypeBaseStatusTime,
|
||||||
Timeout: 10 * time.Millisecond,
|
Timeout: 10 * time.Millisecond,
|
||||||
},
|
},
|
||||||
TimeoutAction: func(savedOrderInfo *WatchOrderInfo) (err error) {
|
TimeoutAction: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) (err error) {
|
||||||
order := savedOrderInfo.order
|
order := savedOrderInfo.order
|
||||||
mobile := order.ConsigneeMobile
|
mobile := order.ConsigneeMobile
|
||||||
if order.ConsigneeMobile2 != "" {
|
if order.ConsigneeMobile2 != "" {
|
||||||
@@ -144,10 +149,14 @@ func init() {
|
|||||||
}
|
}
|
||||||
_ = sch.handleAutoAcceptOrder(order.VendorOrderID, order.VendorID, mobile, jxutils.GetSaleStoreIDFromOrder(order), nil, func(isAcceptIt bool) error {
|
_ = 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 {
|
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 errWithCode, ok := err.(*utils.ErrorWithCode); ok && errWithCode.Level() == 1 && errWithCode.IntCode() == -1 {
|
||||||
if order2, err2 := partner.GetPurchasePlatformFromVendorID(order.VendorID).GetOrder(order.VendorOrderID); err2 == nil && order2.Status > order.Status {
|
if order2, err2 := partner.GetPurchasePlatformFromVendorID(order.VendorID).GetOrder(order.VendorOrderID); err2 == nil && order2.Status > order.Status {
|
||||||
sch.OnOrderStatusChanged(order, model.Order2Status(order2), false)
|
order.Status = order2.Status
|
||||||
|
jxutils.CallMsgHandlerAsync(func() {
|
||||||
|
sch.OnOrderStatusChanged(order, model.Order2Status(order2), false)
|
||||||
|
}, jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID))
|
||||||
err = nil
|
err = nil
|
||||||
} else {
|
} else {
|
||||||
err = err2
|
err = err2
|
||||||
@@ -165,6 +174,9 @@ func init() {
|
|||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
ShouldSetTimer: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) bool {
|
||||||
|
return savedOrderInfo.order.Status == model.OrderStatusNew
|
||||||
|
},
|
||||||
},
|
},
|
||||||
model.OrderStatusAccepted: &StatusActionConfig{ // 自动拣货
|
model.OrderStatusAccepted: &StatusActionConfig{ // 自动拣货
|
||||||
StatusActionParams: partner.StatusActionParams{
|
StatusActionParams: partner.StatusActionParams{
|
||||||
@@ -172,12 +184,17 @@ func init() {
|
|||||||
Timeout: time2AutoPickupMin,
|
Timeout: time2AutoPickupMin,
|
||||||
TimeoutGap: second2AutoPickupGap,
|
TimeoutGap: second2AutoPickupGap,
|
||||||
},
|
},
|
||||||
TimeoutAction: func(savedOrderInfo *WatchOrderInfo) (err error) {
|
TimeoutAction: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) (err error) {
|
||||||
if savedOrderInfo.autoPickupTimeoutMinute > 0 {
|
if savedOrderInfo.autoPickupTimeoutMinute > 0 {
|
||||||
return sch.autoPickupGood(savedOrderInfo)
|
if err = sch.autoPickupGood(savedOrderInfo); err != nil {
|
||||||
|
partner.CurOrderManager.OnOrderMsg(savedOrderInfo.order, "自动拣货失败", err.Error())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
ShouldSetTimer: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) bool {
|
||||||
|
return savedOrderInfo.autoPickupTimeoutMinute > 0
|
||||||
|
},
|
||||||
},
|
},
|
||||||
model.OrderStatusFinishedPickup: &StatusActionConfig{
|
model.OrderStatusFinishedPickup: &StatusActionConfig{
|
||||||
StatusActionParams: partner.StatusActionParams{
|
StatusActionParams: partner.StatusActionParams{
|
||||||
@@ -185,27 +202,62 @@ func init() {
|
|||||||
Timeout: 1 * time.Second,
|
Timeout: 1 * time.Second,
|
||||||
TimeoutGap: 0,
|
TimeoutGap: 0,
|
||||||
},
|
},
|
||||||
TimeoutAction: func(savedOrderInfo *WatchOrderInfo) (err error) {
|
TimeoutAction: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) (err error) {
|
||||||
if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore { // 自配送商家使用
|
if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore { // 自配送商家使用
|
||||||
return sch.createWaybillOn3rdProviders(savedOrderInfo, nil)
|
return sch.createWaybillOn3rdProviders(savedOrderInfo, nil)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
ShouldSetTimer: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) bool {
|
||||||
|
return savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
map[int]*StatusActionConfig{
|
map[int]*StatusActionConfig{
|
||||||
|
// todo 平台物流二次创建运单的话,这个TIMER有问题
|
||||||
model.WaybillStatusNew: &StatusActionConfig{
|
model.WaybillStatusNew: &StatusActionConfig{
|
||||||
StatusActionParams: partner.StatusActionParams{
|
StatusActionParams: partner.StatusActionParams{
|
||||||
TimerType: partner.TimerTypeBaseStatusTime,
|
TimerType: partner.TimerTypeBaseStatusTime,
|
||||||
Timeout: minute2Schedule3rdCarrier * time.Minute,
|
Timeout: minute2Schedule3rdCarrier * time.Minute,
|
||||||
},
|
},
|
||||||
TimeoutAction: func(savedOrderInfo *WatchOrderInfo) (err error) {
|
TimeoutAction: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) (err error) {
|
||||||
if savedOrderInfo.storeDeliveryType != scheduler.StoreDeliveryTypeByStore { // 非自配送商家使用
|
// 饿百转自送的时机不太清楚,暂时禁用超时转自送,在饿百运单取消时还是会自动创建
|
||||||
|
if savedOrderInfo.storeDeliveryType != scheduler.StoreDeliveryTypeByStore && savedOrderInfo.order.VendorID != model.VendorIDEBAI { // 非自配送商家使用
|
||||||
return sch.createWaybillOn3rdProviders(savedOrderInfo, nil)
|
return sch.createWaybillOn3rdProviders(savedOrderInfo, nil)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
ShouldSetTimer: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) bool {
|
||||||
|
return savedOrderInfo.storeDeliveryType != scheduler.StoreDeliveryTypeByStore &&
|
||||||
|
savedOrderInfo.order.VendorID == bill.WaybillVendorID &&
|
||||||
|
savedOrderInfo.order.VendorID != model.VendorIDEBAI
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
//*
|
||||||
|
model.WaybillStatusCanceled: &StatusActionConfig{
|
||||||
|
StatusActionParams: partner.StatusActionParams{
|
||||||
|
TimerType: partner.TimerTypeBaseNow,
|
||||||
|
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.order.VendorID == bill.WaybillVendorID &&
|
||||||
|
savedOrderInfo.storeDeliveryType != scheduler.StoreDeliveryTypeByStore &&
|
||||||
|
order.VendorID == model.VendorIDEBAI { // 非自配送商家使用
|
||||||
|
return sch.createWaybillOn3rdProviders(savedOrderInfo, nil)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
ShouldSetTimer: func(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) bool {
|
||||||
|
order := savedOrderInfo.order
|
||||||
|
return (order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusEndBegin) &&
|
||||||
|
savedOrderInfo.order.VendorID == bill.WaybillVendorID &&
|
||||||
|
savedOrderInfo.storeDeliveryType != scheduler.StoreDeliveryTypeByStore &&
|
||||||
|
order.VendorID == model.VendorIDEBAI
|
||||||
|
},
|
||||||
|
},
|
||||||
|
//*/
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,10 +295,11 @@ func (s *DefScheduler) OnOrderStatusChanged(order *model.GoodsOrder, status *mod
|
|||||||
globals.SugarLogger.Debugf("OnOrderStatusChanged orderID:%s %s, status:%v", status.VendorOrderID, model.OrderStatusName[status.Status], status)
|
globals.SugarLogger.Debugf("OnOrderStatusChanged orderID:%s %s, status:%v", status.VendorOrderID, model.OrderStatusName[status.Status], status)
|
||||||
if order == nil {
|
if order == nil {
|
||||||
globals.SugarLogger.Warnf("OnOrderStatusChanged order is nil, status:%s", utils.Format4Output(status, true))
|
globals.SugarLogger.Warnf("OnOrderStatusChanged order is nil, status:%s", utils.Format4Output(status, true))
|
||||||
|
} else if order.Status > model.OrderStatusUnknown && status.Status > model.OrderStatusUnknown && order.Status != status.Status {
|
||||||
|
globals.SugarLogger.Warnf("OnOrderStatusChanged strange order:%s, status:%s", utils.Format4Output(order, true), utils.Format4Output(status, true))
|
||||||
}
|
}
|
||||||
savedOrderInfo := s.loadSavedOrderFromMap(status, false)
|
savedOrderInfo := s.loadSavedOrderFromMap(status, false)
|
||||||
savedOrderInfo.SetOrder(order)
|
savedOrderInfo.SetOrder(order)
|
||||||
// s.updateOrderByStatus(savedOrderInfo.order, status)
|
|
||||||
|
|
||||||
// if status.Status == model.OrderStatusNew {
|
// if status.Status == model.OrderStatusNew {
|
||||||
// if !isPending {
|
// if !isPending {
|
||||||
@@ -259,7 +312,7 @@ func (s *DefScheduler) OnOrderStatusChanged(order *model.GoodsOrder, status *mod
|
|||||||
(order.LockStatus == model.OrderStatusUnknown && (status.Status > model.OrderStatusUnknown || status.Status == model.OrderStatusRefuseFailedGetGoods)) { // 只处理状态转换,一般消息不处理
|
(order.LockStatus == model.OrderStatusUnknown && (status.Status > model.OrderStatusUnknown || status.Status == model.OrderStatusRefuseFailedGetGoods)) { // 只处理状态转换,一般消息不处理
|
||||||
if status.Status == model.OrderStatusRefuseFailedGetGoods && order.Status != model.OrderStatusFinishedPickup && !model.IsOrderFinalStatus(order.Status) {
|
if status.Status == model.OrderStatusRefuseFailedGetGoods && order.Status != model.OrderStatusFinishedPickup && !model.IsOrderFinalStatus(order.Status) {
|
||||||
order.Status = model.OrderStatusFinishedPickup
|
order.Status = model.OrderStatusFinishedPickup
|
||||||
partner.CurOrderManager.UpdateOrderStatusAndFlag(order)
|
partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
|
||||||
}
|
}
|
||||||
s.resetTimer(savedOrderInfo, nil, isPending)
|
s.resetTimer(savedOrderInfo, nil, isPending)
|
||||||
if status.Status >= model.OrderStatusDelivering {
|
if status.Status >= model.OrderStatusDelivering {
|
||||||
@@ -271,12 +324,12 @@ func (s *DefScheduler) OnOrderStatusChanged(order *model.GoodsOrder, status *mod
|
|||||||
if !(status.Status == model.OrderStatusCanceled) { // 订单取消时,取消所有运单
|
if !(status.Status == model.OrderStatusCanceled) { // 订单取消时,取消所有运单
|
||||||
curWaybill = savedOrderInfo.waybills[savedOrderInfo.order.WaybillVendorID]
|
curWaybill = savedOrderInfo.waybills[savedOrderInfo.order.WaybillVendorID]
|
||||||
if status.Status == model.OrderStatusFinished {
|
if status.Status == model.OrderStatusFinished {
|
||||||
if curWaybill != nil && curWaybill.WaybillVendorID != curWaybill.OrderVendorID {
|
if curWaybill != nil && !model.IsWaybillPlatformOwn(curWaybill) {
|
||||||
globals.SugarLogger.Infof("OnOrderStatusChanged [运营2]订单orderID:%s可能被手动点击送达,会对程序状态产生不利影响,请通知门店不要这样操作!", status.VendorOrderID)
|
globals.SugarLogger.Infof("OnOrderStatusChanged [运营2]订单orderID:%s可能被手动点击送达,会对程序状态产生不利影响,请通知门店不要这样操作!", status.VendorOrderID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.cancelOtherWaybills(savedOrderInfo, curWaybill, partner.CancelWaybillReasonOther, partner.CancelWaybillReasonStrOrderAlreadyFinished)
|
s.cancelOtherWaybillsCheckOrderDeliveryFlag(savedOrderInfo, curWaybill, partner.CancelWaybillReasonOther, partner.CancelWaybillReasonStrOrderAlreadyFinished)
|
||||||
if status.Status >= model.OrderStatusEndBegin {
|
if status.Status >= model.OrderStatusEndBegin {
|
||||||
s.orderMap.Delete(jxutils.GetUniversalOrderIDFromOrderStatus(status))
|
s.orderMap.Delete(jxutils.GetUniversalOrderIDFromOrderStatus(status))
|
||||||
}
|
}
|
||||||
@@ -285,12 +338,13 @@ func (s *DefScheduler) OnOrderStatusChanged(order *model.GoodsOrder, status *mod
|
|||||||
if order.LockStatus != model.OrderStatusUnknown {
|
if order.LockStatus != model.OrderStatusUnknown {
|
||||||
s.stopTimer(savedOrderInfo)
|
s.stopTimer(savedOrderInfo)
|
||||||
}
|
}
|
||||||
if model.IsOrderLockStatus(status.Status) ||
|
if !isPending {
|
||||||
model.IsOrderUnlockStatus(status.Status) ||
|
if status.Status == model.OrderStatusFinishedPickup {
|
||||||
status.Status == model.OrderStatusApplyFailedGetGoods ||
|
msghub.OnFinishedPickup(savedOrderInfo.order)
|
||||||
status.Status == model.OrderStatusAgreeFailedGetGoods ||
|
} else if status.Status == model.OrderStatusApplyCancel || //model.IsOrderLockStatus(status.Status) ||
|
||||||
status.Status == model.OrderStatusDeliverFailed {
|
status.Status == model.OrderStatusApplyFailedGetGoods || //model.IsOrderUnlockStatus(status.Status) ||
|
||||||
if isPending {
|
status.Status == model.OrderStatusAgreeFailedGetGoods ||
|
||||||
|
status.Status == model.OrderStatusDeliverFailed {
|
||||||
if status.Status == model.OrderStatusApplyCancel {
|
if status.Status == model.OrderStatusApplyCancel {
|
||||||
utils.CallFuncAsync(func() {
|
utils.CallFuncAsync(func() {
|
||||||
weixinmsg.NotifyUserApplyCancel(savedOrderInfo.order, status.Remark)
|
weixinmsg.NotifyUserApplyCancel(savedOrderInfo.order, status.Remark)
|
||||||
@@ -323,10 +377,10 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill, isPending boo
|
|||||||
if !isPending {
|
if !isPending {
|
||||||
if order.Status > model.OrderStatusEndBegin {
|
if order.Status > model.OrderStatusEndBegin {
|
||||||
s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
||||||
} else if s.IsOrderHasWaybill(order) {
|
} else if model.IsOrderHaveWaybill(order) {
|
||||||
globals.SugarLogger.Debugf("OnWaybillStatusChanged multiple waybill created, bill:%v", bill)
|
globals.SugarLogger.Debugf("OnWaybillStatusChanged multiple waybill created, bill:%v", bill)
|
||||||
if s.IsOrderPlatformWaybill(bill) { // 是购物平台运单
|
if model.IsWaybillPlatformOwn(bill) { // 是购物平台运单
|
||||||
if order.VendorID != order.WaybillVendorID { // 既有运单不是购物平台运单
|
if !model.IsOrderHaveOwnWaybill(order) { // 既有运单不是购物平台运单
|
||||||
globals.SugarLogger.Infof("OnWaybillStatusChanged bill:%v purchase platform bill came later than others, strange!!!", bill)
|
globals.SugarLogger.Infof("OnWaybillStatusChanged bill:%v purchase platform bill came later than others, strange!!!", bill)
|
||||||
oldBill := savedOrderInfo.waybills[order.WaybillVendorID]
|
oldBill := savedOrderInfo.waybills[order.WaybillVendorID]
|
||||||
if oldBill != nil {
|
if oldBill != nil {
|
||||||
@@ -335,124 +389,146 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill, isPending boo
|
|||||||
globals.SugarLogger.Warnf("OnWaybillStatusChanged bill:%v, oldBill is null, strange!!!", bill)
|
globals.SugarLogger.Warnf("OnWaybillStatusChanged bill:%v, oldBill is null, strange!!!", bill)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bill.WaybillVendorID = model.VendorIDUnknown
|
s.updateOrderByBill(order, nil, false)
|
||||||
s.updateOrderByBill(order, bill, false)
|
|
||||||
} else {
|
} else {
|
||||||
s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
flag2Clear := model.WaybillVendorID2Mask(bill.WaybillVendorID)
|
||||||
|
if order.DeliveryFlag&flag2Clear != 0 {
|
||||||
|
order.DeliveryFlag &= ^flag2Clear
|
||||||
|
err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 只有购物平台的新运单消息才会启动抢单TIMER
|
// 只有购物平台的新运单消息才会启动抢单TIMER
|
||||||
if s.IsOrderPlatformWaybill(bill) {
|
if model.IsWaybillPlatformOwn(bill) {
|
||||||
s.resetTimer(savedOrderInfo, bill, isPending)
|
s.resetTimer(savedOrderInfo, bill, isPending)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
isBillExist := s.updateBillsInfo(savedOrderInfo, bill)
|
isBillExist := s.updateBillsInfo(savedOrderInfo, bill)
|
||||||
if !isBillExist {
|
if !isBillExist {
|
||||||
|
// s.addWaybill2Map(savedOrderInfo, bill) // updateBillsInfo中会添加
|
||||||
globals.SugarLogger.Debugf("OnWaybillStatusChanged bill not exist! orderID:%s, bill:%v", bill.VendorOrderID, bill)
|
globals.SugarLogger.Debugf("OnWaybillStatusChanged bill not exist! orderID:%s, bill:%v", bill.VendorOrderID, bill)
|
||||||
}
|
}
|
||||||
switch bill.Status {
|
switch bill.Status {
|
||||||
case model.WaybillStatusAccepted:
|
case model.WaybillStatusAccepted, model.WaybillStatusCourierArrived, model.WaybillStatusDelivering:
|
||||||
s.resetTimer(savedOrderInfo, bill, isPending)
|
s.resetTimer(savedOrderInfo, bill, isPending)
|
||||||
if (isBillExist || bill.WaybillVendorID != model.VendorIDDada) && !isPending { // todo 达达运单有错序的情况,临时看看
|
if (isBillExist || bill.WaybillVendorID != model.VendorIDDada) && !isPending { // todo 达达运单有错序的情况,临时看看
|
||||||
isBillAlreadyCandidate := s.isBillCandidate(order, bill)
|
isBillAlreadyCandidate := s.isBillCandidate(order, bill)
|
||||||
// todo 购买平台的运单,优先级最高,但这样写也可能带来问题,即在这个时间,因为之前3方已经接单,已经发出了转自送请求(而且可能成功了),所以加个状态判断
|
// todo 购买平台的运单,优先级最高,但这样写也可能带来问题,即在这个时间,因为之前3方已经接单,已经发出了转自送请求(而且可能成功了),所以加个状态判断
|
||||||
if order.WaybillVendorID == model.VendorIDUnknown ||
|
if !model.IsOrderHaveWaybill(order) ||
|
||||||
(s.IsOrderPlatformWaybill(bill) && order.VendorID != order.WaybillVendorID && (order.DeliveryFlag&model.OrderDeliveryFlagMaskPurcahseDisabled) == 0) {
|
(model.IsWaybillPlatformOwn(bill) && !model.IsOrderHaveOwnWaybill(order) && (order.DeliveryFlag&model.OrderDeliveryFlagMaskPurcahseDisabled) == 0) {
|
||||||
if s.IsOrderHasWaybill(order) {
|
if model.IsOrderHaveWaybill(order) {
|
||||||
// 进到这里的原因是,在这个时间点,购物平台物流已经抢单(但抢单消息还没有被收到)(比如:818810379000941)
|
// 进到这里的原因是,在这个时间点,购物平台物流已经抢单(但抢单消息还没有被收到)(比如:818810379000941)
|
||||||
globals.SugarLogger.Infof("OnWaybillStatusChanged orderID:%s purchase platform waybill arrvied later, may case problem", order.VendorOrderID)
|
globals.SugarLogger.Infof("OnWaybillStatusChanged orderID:%s purchase platform waybill arrvied later, may cause problem", order.VendorOrderID)
|
||||||
}
|
}
|
||||||
s.updateOrderByBill(order, bill, false)
|
s.updateOrderByBill(order, bill, false)
|
||||||
s.cancelOtherWaybills(savedOrderInfo, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
s.cancelOtherWaybillsCheckOrderDeliveryFlag(savedOrderInfo, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
||||||
if !s.IsOrderPlatformWaybill(bill) {
|
|
||||||
if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore {
|
if model.IsWaybillPlatformOwn(bill) {
|
||||||
s.SelfDeliverDelivering(savedOrderInfo.order, bill.CourierMobile)
|
if bill.Status == model.WaybillStatusDelivering {
|
||||||
|
// 强制将订单状态置为配送中?
|
||||||
|
order.Status = model.OrderStatusDelivering
|
||||||
|
partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore ||
|
||||||
|
model.IsSpecialOrderPlatformWaybill(bill) {
|
||||||
|
if err := s.SelfDeliverDelivering(savedOrderInfo.order, bill.CourierMobile); err != nil {
|
||||||
|
partner.CurOrderManager.OnOrderMsg(order, "自送出设置失败", err.Error())
|
||||||
|
}
|
||||||
|
utils.CallFuncAsync(func() {
|
||||||
|
weixinmsg.NotifyWaybillStatus(bill, order, isBillAlreadyCandidate)
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
s.swtich2SelfDeliverWithRetry(savedOrderInfo, bill, 2, 10*time.Second)
|
s.swtich2SelfDeliverWithRetry(savedOrderInfo, bill, 2, 10*time.Second)
|
||||||
}
|
}
|
||||||
} else if s.IsSpecialOrderPlatformWaybill(bill) {
|
|
||||||
s.SelfDeliverDelivering(savedOrderInfo.order, bill.CourierMobile)
|
|
||||||
}
|
}
|
||||||
} else if !s.isBillCandidate(order, bill) && bill.WaybillVendorID != order.VendorID {
|
} else if !s.isBillCandidate(order, bill) && bill.WaybillVendorID != order.VendorID {
|
||||||
// 发生这种情况的原因就是两个接单事件几乎同时到达(来不及取消),也算正常
|
// 发生这种情况的原因就是两个接单事件几乎同时到达(来不及取消),也算正常
|
||||||
s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
||||||
globals.SugarLogger.Infof("OnWaybillStatusChanged Accepted orderID:%s got multiple bill:%v", order.VendorOrderID, bill)
|
globals.SugarLogger.Infof("OnWaybillStatusChanged Accepted orderID:%s got multiple bill:%v", order.VendorOrderID, bill)
|
||||||
}
|
}
|
||||||
if s.isBillCandidate(order, bill) && order.WaybillVendorID != order.VendorID {
|
if isBillAlreadyCandidate && !s.isWaybillCourierSame(savedOrderInfo, bill) && !model.IsWaybillPlatformOwn(bill) {
|
||||||
if !isBillAlreadyCandidate || !s.isWaybillCourierSame(savedOrderInfo, bill) {
|
utils.CallFuncAsync(func() {
|
||||||
utils.CallFuncAsync(func() {
|
weixinmsg.NotifyWaybillStatus(bill, order, isBillAlreadyCandidate)
|
||||||
weixinmsg.NotifyWaybillStatus(bill, order, isBillAlreadyCandidate)
|
})
|
||||||
})
|
}
|
||||||
}
|
flag2Clear := model.WaybillVendorID2Mask(bill.WaybillVendorID)
|
||||||
|
if order.DeliveryFlag&flag2Clear != 0 {
|
||||||
|
order.DeliveryFlag &= ^flag2Clear
|
||||||
|
err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case model.WaybillStatusAcceptCanceled:
|
case model.WaybillStatusAcceptCanceled:
|
||||||
if s.isBillCandidate(order, bill) {
|
if s.isBillCandidate(order, bill) {
|
||||||
s.resetTimer(savedOrderInfo, bill, isPending)
|
s.resetTimer(savedOrderInfo, bill, isPending)
|
||||||
if !isPending {
|
if !isPending {
|
||||||
bill.WaybillVendorID = model.VendorIDUnknown
|
s.updateOrderByBill(order, nil, true)
|
||||||
s.updateOrderByBill(order, bill, false)
|
|
||||||
|
|
||||||
// 取消抢单应该不需要发3方运单
|
|
||||||
// s.createWaybillOn3rdProviders(savedOrderInfo, bill)
|
|
||||||
}
|
}
|
||||||
} else if s.IsOrderHasWaybill(order) {
|
} else if model.IsOrderHaveWaybill(order) {
|
||||||
s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
||||||
if !isPending {
|
if !isPending {
|
||||||
globals.SugarLogger.Warnf("OnWaybillStatusChanged AcceptCanceled orderID:%s got multiple bill:%v, order details:%v", order.VendorOrderID, bill, order)
|
globals.SugarLogger.Warnf("OnWaybillStatusChanged AcceptCanceled orderID:%s got multiple bill:%v, order details:%v", order.VendorOrderID, bill, order)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case model.WaybillStatusCourierArrived: // do nothing
|
// case model.WaybillStatusCourierArrived: // do nothing
|
||||||
s.resetTimer(savedOrderInfo, bill, isPending)
|
// s.resetTimer(savedOrderInfo, bill, isPending)
|
||||||
if s.isBillCandidate(order, bill) {
|
// if s.isBillCandidate(order, bill) {
|
||||||
} else {
|
// } else {
|
||||||
// s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
// // s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
||||||
globals.SugarLogger.Infof("OnWaybillStatusChanged CourierArrived order(%d, %s) bill(%d, %s), bill:%v shouldn't get here", order.WaybillVendorID, order.VendorWaybillID, bill.WaybillVendorID, bill.VendorWaybillID, bill)
|
// globals.SugarLogger.Infof("OnWaybillStatusChanged CourierArrived order(%d, %s) bill(%d, %s), bill:%v shouldn't get here", order.WaybillVendorID, order.VendorWaybillID, bill.WaybillVendorID, bill.VendorWaybillID, bill)
|
||||||
}
|
// }
|
||||||
case model.WaybillStatusCanceled, model.WaybillStatusFailed:
|
case model.WaybillStatusCanceled, model.WaybillStatusFailed:
|
||||||
s.removeWaybillFromMap(savedOrderInfo, bill.WaybillVendorID)
|
s.removeWaybillFromMap(savedOrderInfo, bill.WaybillVendorID)
|
||||||
if s.isBillCandidate(order, bill) || order.WaybillVendorID == model.VendorIDUnknown {
|
if s.isBillCandidate(order, bill) || order.WaybillVendorID == model.VendorIDUnknown {
|
||||||
s.resetTimer(savedOrderInfo, nil, isPending)
|
s.resetTimer(savedOrderInfo, nil, isPending)
|
||||||
if !isPending {
|
if !isPending {
|
||||||
if s.IsOrderHasWaybill(order) {
|
if model.IsOrderHaveWaybill(order) {
|
||||||
bill.WaybillVendorID = model.VendorIDUnknown
|
s.updateOrderByBill(order, nil, true)
|
||||||
s.updateOrderByBill(order, bill, false)
|
|
||||||
}
|
}
|
||||||
// 3方的运单取消才会重新发起创建3方订单,购物平台的运单取消后,它本身还会再创建新运单(NewWaybill事件有相应TIMER)),至少京东是这样的,暂时按京东的行为来
|
// 3方的运单取消才会重新发起创建3方订单,购物平台的运单取消后,它本身还会再创建新运单(NewWaybill事件有相应TIMER)),至少京东是这样的,暂时按京东的行为来
|
||||||
// 现在发现饿百取消订单后不会再创建运单了,所以饿百运单取消也允许直接创建三方运单
|
// 现在发现饿百取消订单后不会再创建运单了,所以饿百运单取消也允许直接创建三方运单
|
||||||
// 之前的条件是order.Status < model.OrderStatusDelivering,但像订单902322817000122确实有在配送中取消状态,改成非订单结束状态都可以
|
// 之前的条件是order.Status < model.OrderStatusDelivering,但像订单902322817000122确实有在配送中取消状态,改成非订单结束状态都可以
|
||||||
// OrderStatusFinishedPickup状态的订单依赖于TIMER重新建运单
|
// OrderStatusFinishedPickup状态的订单依赖于TIMER重新建运单
|
||||||
if order.Status >= model.OrderStatusDelivering && order.Status < model.OrderStatusEndBegin && (bill.WaybillVendorID != order.VendorID || order.VendorID == model.VendorIDEBAI) {
|
if bill.DeliveryFlag&model.WaybillDeliveryFlagMaskActiveCancel == 0 {
|
||||||
s.createWaybillOn3rdProviders(savedOrderInfo, nil)
|
if (order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusEndBegin) && (bill.WaybillVendorID != order.VendorID /* || bill.WaybillVendorID == model.VendorIDEBAI*/) {
|
||||||
|
s.createWaybillOn3rdProviders(savedOrderInfo, nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case model.WaybillStatusDelivering:
|
// case model.WaybillStatusDelivering:
|
||||||
s.resetTimer(savedOrderInfo, bill, isPending)
|
// s.resetTimer(savedOrderInfo, bill, isPending)
|
||||||
if s.isBillCandidate(order, bill) {
|
// if s.isBillCandidate(order, bill) {
|
||||||
// do nothing
|
// // do nothing
|
||||||
} else {
|
// } else {
|
||||||
// s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
// // s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime)
|
||||||
globals.SugarLogger.Infof("OnWaybillStatusChanged Delivering order(%d, %s) bill(%d, %s), bill:%v shouldn't get here", order.WaybillVendorID, order.VendorWaybillID, bill.WaybillVendorID, bill.VendorWaybillID, bill)
|
// globals.SugarLogger.Infof("OnWaybillStatusChanged Delivering order(%d, %s) bill(%d, %s), bill:%v shouldn't get here", order.WaybillVendorID, order.VendorWaybillID, bill.WaybillVendorID, bill.VendorWaybillID, bill)
|
||||||
}
|
// }
|
||||||
case model.WaybillStatusDelivered:
|
case model.WaybillStatusDelivered:
|
||||||
s.resetTimer(savedOrderInfo, bill, isPending)
|
s.resetTimer(savedOrderInfo, bill, isPending)
|
||||||
s.removeWaybillFromMap(savedOrderInfo, bill.WaybillVendorID)
|
s.removeWaybillFromMap(savedOrderInfo, bill.WaybillVendorID)
|
||||||
if !s.IsOrderPlatformWaybill(bill) && !isPending {
|
if !isPending {
|
||||||
if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore {
|
var err2 error
|
||||||
s.SelfDeliverDelivered(order, "")
|
if !model.IsWaybillPlatformOwn(bill) {
|
||||||
} else {
|
if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore {
|
||||||
s.Swtich2SelfDelivered(order, "")
|
err2 = s.SelfDeliverDelivered(order, "")
|
||||||
|
} else {
|
||||||
|
err2 = s.Swtich2SelfDelivered(order, "")
|
||||||
|
}
|
||||||
|
} else if model.IsSpecialOrderPlatformWaybill(bill) {
|
||||||
|
err2 = s.SelfDeliverDelivered(savedOrderInfo.order, "")
|
||||||
|
}
|
||||||
|
if err2 != nil {
|
||||||
|
partner.CurOrderManager.OnOrderMsg(order, "送达设置失败", err2.Error())
|
||||||
}
|
}
|
||||||
} else if s.IsSpecialOrderPlatformWaybill(bill) {
|
|
||||||
s.SelfDeliverDelivered(savedOrderInfo.order, "")
|
|
||||||
}
|
}
|
||||||
if !s.isBillCandidate(order, bill) {
|
if !s.isBillCandidate(order, bill) {
|
||||||
// 一般只会消息乱序才会到这里,即新订单消息在运单接单消息后到达
|
// 一般只会消息乱序才会到这里,即新订单消息在运单接单消息后到达
|
||||||
// 典型的一个:1223633660228537567
|
// 典型的一个:1223633660228537567
|
||||||
globals.SugarLogger.Infof("OnWaybillStatusChanged Delivered order(%d, %s) bill(%d, %s), bill:%v shouldn't get here", order.WaybillVendorID, order.VendorWaybillID, bill.WaybillVendorID, bill.VendorWaybillID, bill)
|
globals.SugarLogger.Infof("OnWaybillStatusChanged Delivered order(%d, %s) bill(%d, %s), bill:%v shouldn't get here", order.WaybillVendorID, order.VendorWaybillID, bill.WaybillVendorID, bill.VendorWaybillID, bill)
|
||||||
if order.WaybillVendorID == model.VendorIDUnknown {
|
if !model.IsOrderHaveWaybill(order) {
|
||||||
s.updateOrderByBill(order, bill, false)
|
s.updateOrderByBill(order, bill, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -461,14 +537,16 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill, isPending boo
|
|||||||
weixinmsg.NotifyWaybillStatus(bill, order, false)
|
weixinmsg.NotifyWaybillStatus(bill, order, false)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
case model.WaybillStatusNeverSend: // 平台不配送,直接创建三方运单
|
// case model.WaybillStatusNeverSend: // 平台不配送,直接创建三方运单
|
||||||
|
// s.resetTimer(savedOrderInfo, bill, isPending)
|
||||||
|
// s.removeWaybillFromMap(savedOrderInfo, bill.WaybillVendorID)
|
||||||
|
// if order.WaybillVendorID == model.VendorIDUnknown {
|
||||||
|
// s.createWaybillOn3rdProviders(savedOrderInfo, nil)
|
||||||
|
// }
|
||||||
|
default:
|
||||||
s.resetTimer(savedOrderInfo, bill, isPending)
|
s.resetTimer(savedOrderInfo, bill, isPending)
|
||||||
s.removeWaybillFromMap(savedOrderInfo, bill.WaybillVendorID)
|
|
||||||
if order.WaybillVendorID == model.VendorIDUnknown {
|
|
||||||
s.createWaybillOn3rdProviders(savedOrderInfo, nil)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
s.updateBillsInfo(savedOrderInfo, bill) // 更新可能的运单状态变化
|
// s.updateBillsInfo(savedOrderInfo, bill) // 更新可能的运单状态变化
|
||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
@@ -481,7 +559,7 @@ func (s *DefScheduler) isWaybillCourierSame(savedOrderInfo *WatchOrderInfo, bill
|
|||||||
|
|
||||||
func (s *DefScheduler) addWaybill2Map(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) {
|
func (s *DefScheduler) addWaybill2Map(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) {
|
||||||
if _, ok := savedOrderInfo.waybills[bill.WaybillVendorID]; ok {
|
if _, ok := savedOrderInfo.waybills[bill.WaybillVendorID]; ok {
|
||||||
if !s.IsOrderPlatformWaybill(bill) { // 购买平台重复发相同号的新运单是正常的,京东就是
|
if !model.IsWaybillPlatformOwn(bill) { // 购买平台重复发相同号的新运单是正常的,京东就是
|
||||||
globals.SugarLogger.Warnf("addWaybill2Map bill:%v already exists", bill)
|
globals.SugarLogger.Warnf("addWaybill2Map bill:%v already exists", bill)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -503,17 +581,17 @@ func (s *DefScheduler) createWaybillOn3rdProviders(savedOrderInfo *WatchOrderInf
|
|||||||
if err = s.canOrderCreateWaybillNormally(order); err == nil {
|
if err = s.canOrderCreateWaybillNormally(order); err == nil {
|
||||||
if (order.DeliveryFlag & model.OrderDeliveryFlagMaskScheduleDisabled) == 0 {
|
if (order.DeliveryFlag & model.OrderDeliveryFlagMaskScheduleDisabled) == 0 {
|
||||||
if savedOrderInfo.retryCount <= maxWaybillRetryCount {
|
if savedOrderInfo.retryCount <= maxWaybillRetryCount {
|
||||||
_, err = s.CreateWaybillOnProviders4SavedOrder(jxcontext.AdminCtx, savedOrderInfo, false)
|
savedOrderInfo.retryCount++
|
||||||
|
_, err = s.CreateWaybillOnProviders4SavedOrder(jxcontext.AdminCtx, savedOrderInfo, nil, false, 0, 0)
|
||||||
} else {
|
} else {
|
||||||
err = fmt.Errorf("订单:%s已经自动创建过了%d次运单,请人工处理", order.VendorOrderID, savedOrderInfo.retryCount)
|
err = fmt.Errorf("订单:%s已经自动创建过了%d次运单,请人工处理", order.VendorOrderID, savedOrderInfo.retryCount)
|
||||||
globals.SugarLogger.Infof("createWaybillOn3rdProviders [运营]同一订单orderID:%s尝试了%d次创建运单失败, 停止调度,如果还需要发单,请人工处理", order.VendorOrderID, savedOrderInfo.retryCount)
|
globals.SugarLogger.Infof("createWaybillOn3rdProviders [运营2]同一订单orderID:%s尝试了%d次创建运单失败, 停止调度,如果还需要发单,请人工处理", order.VendorOrderID, savedOrderInfo.retryCount)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
globals.SugarLogger.Debugf("createWaybillOn3rdProviders, orderID:%s, store:%d dont't support 3rd delivery platform", order.VendorOrderID, jxutils.GetSaleStoreIDFromOrder(order))
|
globals.SugarLogger.Debugf("createWaybillOn3rdProviders, orderID:%s, store:%d dont't support 3rd delivery platform", order.VendorOrderID, jxutils.GetSaleStoreIDFromOrder(order))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
partner.CurOrderManager.OnOrderMsg(order, "自动创建三方运单", utils.LimitUTF8StringLen(err.Error(), 255))
|
partner.CurOrderManager.OnOrderMsg(order, "自动创建三方运单失败", err.Error())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err = nil
|
err = nil
|
||||||
@@ -521,73 +599,79 @@ func (s *DefScheduler) createWaybillOn3rdProviders(savedOrderInfo *WatchOrderInf
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DefScheduler) cancelOtherWaybills(savedOrderInfo *WatchOrderInfo, bill2Keep *model.Waybill, cancelReasonID int, cancelReason string) (err error) {
|
func (s *DefScheduler) cancelOtherWaybillsCheckOrderDeliveryFlag(savedOrderInfo *WatchOrderInfo, bill2Keep *model.Waybill, cancelReasonID int, cancelReason string) (err error) {
|
||||||
globals.SugarLogger.Debugf("cancelOtherWaybills, orderID:%s, bill:%v", savedOrderInfo.order.VendorOrderID, bill2Keep)
|
globals.SugarLogger.Debugf("cancelOtherWaybillsCheckOrderDeliveryFlag, orderID:%s, bill:%v", savedOrderInfo.order.VendorOrderID, bill2Keep)
|
||||||
if (savedOrderInfo.order.DeliveryFlag & model.OrderDeliveryFlagMaskScheduleDisabled) == 0 {
|
if (savedOrderInfo.order.DeliveryFlag & model.OrderDeliveryFlagMaskScheduleDisabled) == 0 {
|
||||||
err = s.cancelOtherWaybills2(savedOrderInfo, bill2Keep, cancelReasonID, cancelReason)
|
err = s.cancelOtherWaybills(savedOrderInfo, bill2Keep, cancelReasonID, cancelReason)
|
||||||
} else {
|
} else {
|
||||||
globals.SugarLogger.Debugf("cancelOtherWaybills, orderID:%s, bill:%v stop schedule", savedOrderInfo.order.VendorOrderID, bill2Keep)
|
globals.SugarLogger.Debugf("cancelOtherWaybillsCheckOrderDeliveryFlag, orderID:%s, bill:%v stop schedule", savedOrderInfo.order.VendorOrderID, bill2Keep)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DefScheduler) cancelOtherWaybills2(savedOrderInfo *WatchOrderInfo, bill2Keep *model.Waybill, cancelReasonID int, cancelReason string) (err error) {
|
func (s *DefScheduler) cancelOtherWaybills(savedOrderInfo *WatchOrderInfo, bill2Keep *model.Waybill, cancelReasonID int, cancelReason string) (err error) {
|
||||||
globals.SugarLogger.Debugf("cancelOtherWaybills2, orderID:%s, bill:%v", savedOrderInfo.order.VendorOrderID, bill2Keep)
|
globals.SugarLogger.Debugf("cancelOtherWaybills, orderID:%s, bill:%v", savedOrderInfo.order.VendorOrderID, bill2Keep)
|
||||||
toBeDeleted := []*model.Waybill{}
|
|
||||||
for _, v := range savedOrderInfo.waybills {
|
for _, v := range savedOrderInfo.waybills {
|
||||||
if !s.IsOrderPlatformWaybill(v) && (bill2Keep == nil || !(v.WaybillVendorID == bill2Keep.WaybillVendorID && v.VendorWaybillID == bill2Keep.VendorWaybillID)) {
|
if v.Status < model.WaybillStatusEndBegin &&
|
||||||
err2 := s.ProxyCancelWaybill(savedOrderInfo.order, v, cancelReasonID, cancelReason)
|
!model.IsWaybillPlatformOwn(v) &&
|
||||||
|
(bill2Keep == nil || !(v.WaybillVendorID == bill2Keep.WaybillVendorID && v.VendorWaybillID == bill2Keep.VendorWaybillID)) {
|
||||||
|
err2 := s.CancelWaybill(v, cancelReasonID, cancelReason)
|
||||||
if err2 == nil {
|
if err2 == nil {
|
||||||
toBeDeleted = append(toBeDeleted, v)
|
// 在这里就从map里删除,而不是等收到运单结束事件才删除,可避免不必要的重复取消(第二次取消还会失败)
|
||||||
}
|
s.removeWaybillFromMap(savedOrderInfo, v.WaybillVendorID)
|
||||||
// 至少返回一个错误
|
} else {
|
||||||
if err == nil && err2 != nil {
|
// 至少返回一个错误
|
||||||
err = err2
|
if err == nil {
|
||||||
|
err = err2
|
||||||
|
}
|
||||||
|
partner.CurOrderManager.OnOrderMsg(savedOrderInfo.order, "取消三方运单失败", err2.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(toBeDeleted) > 0 {
|
|
||||||
// todo 这里为什么要删除运单,应该只需要在运单完成,取消或失败时才删除
|
|
||||||
// for _, v := range toBeDeleted {
|
|
||||||
// s.removeWaybillFromMap(savedOrderInfo, v.WaybillVendorID)
|
|
||||||
// }
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Debugf("cancelOtherWaybills, orderID:%s, bill:%v cancel 0 bills", savedOrderInfo.order.VendorOrderID, bill2Keep)
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DefScheduler) swtich2SelfDeliverWithRetry(savedOrderInfo *WatchOrderInfo, bill *model.Waybill, retryCount int, duration time.Duration) {
|
func (s *DefScheduler) swtich2SelfDeliverWithRetry(savedOrderInfo *WatchOrderInfo, bill *model.Waybill, retryCount int, duration time.Duration) {
|
||||||
order := savedOrderInfo.order
|
order := savedOrderInfo.order
|
||||||
globals.SugarLogger.Debugf("swtich2SelfDeliverWithRetry orderID:%s", order.VendorOrderID)
|
globals.SugarLogger.Debugf("swtich2SelfDeliverWithRetry orderID:%s", order.VendorOrderID)
|
||||||
if (order.DeliveryFlag & model.OrderDeliveryFlagMaskPurcahseDisabled) == 0 {
|
if order.WaybillVendorID != order.VendorID {
|
||||||
if order.WaybillVendorID != order.VendorID {
|
if err := s.Swtich2SelfDeliver(order, ""); err != nil && err != scheduler.ErrOrderStatusAlreadySatisfyCurOperation {
|
||||||
if err := s.Swtich2SelfDeliver(order, ""); err != nil && err != scheduler.ErrOrderStatusAlreadySatisfyCurOperation {
|
globals.SugarLogger.Infof("swtich2SelfDeliverWithRetry failed, bill:%v, err:%v", bill, err)
|
||||||
globals.SugarLogger.Infof("swtich2SelfDeliverWithRetry failed, bill:%v, err:%v", bill, err)
|
if retryCount > 0 {
|
||||||
if retryCount > 0 {
|
utils.AfterFuncWithRecover(duration, func() {
|
||||||
utils.AfterFuncWithRecover(duration, func() {
|
jxutils.CallMsgHandlerAsync(func() {
|
||||||
jxutils.CallMsgHandlerAsync(func() {
|
s.swtich2SelfDeliverWithRetry(savedOrderInfo, bill, retryCount-1, duration)
|
||||||
s.swtich2SelfDeliverWithRetry(savedOrderInfo, bill, retryCount-1, duration)
|
}, jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID))
|
||||||
}, order.VendorOrderID)
|
})
|
||||||
})
|
} else {
|
||||||
} else {
|
errStr := fmt.Sprintf("订单:%s转自配送失败, 错误信息:%v", order.VendorOrderID, err)
|
||||||
globals.SugarLogger.Infof("swtich2SelfDeliverWithRetry finally failed, orderID:%s bill:%v, err:%v", order.VendorOrderID, bill, err)
|
globals.SugarLogger.Info(errStr)
|
||||||
if s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonSwitch2SelfFailed, partner.CancelWaybillReasonStrSwitch2SelfFailed) == nil {
|
if s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonSwitch2SelfFailed, partner.CancelWaybillReasonStrSwitch2SelfFailed) == nil {
|
||||||
// 转自送失败的取消,要将订单中的运单状态更新
|
// 转自送失败的取消,要将订单中的运单状态更新
|
||||||
if s.isBillCandidate(order, bill) {
|
if s.isBillCandidate(order, bill) {
|
||||||
bill.WaybillVendorID = model.VendorIDUnknown
|
s.updateOrderByBill(order, nil, false)
|
||||||
s.updateOrderByBill(order, bill, false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled
|
||||||
s.removeWaybillFromMap(savedOrderInfo, order.VendorID)
|
partner.CurOrderManager.UpdateOrderFields(order, []string{"DeliveryFlag"})
|
||||||
|
|
||||||
|
partner.CurOrderManager.OnOrderMsg(order, "转商家自配送失败", errStr)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 进到这里的原因是,在这个时间点,购物平台物流已经抢单(但抢单消息还没有被收到),所以转自送会失败 (比如:818810379000941),更好的做法应该是判断Swtich2SelfDeliver的返回值,这种情况下就不得试了
|
utils.CallFuncAsync(func() {
|
||||||
globals.SugarLogger.Infof("swtich2SelfDeliverWithRetry orderID:%s status is wrong(maybe purchase platform accepted waybill)", order.VendorOrderID)
|
weixinmsg.NotifyWaybillStatus(bill, order, false)
|
||||||
// globals.SugarLogger.Warnf("swtich2SelfDeliverWithRetry orderID:%s status is wrong, order details:%v", order.VendorOrderID, order)
|
})
|
||||||
|
s.removeWaybillFromMap(savedOrderInfo, order.VendorID)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
s.cancelOtherWaybills(savedOrderInfo, nil, partner.CancelWaybillReasonOther, partner.CancelWaybillReasonStrNotAcceptIntime)
|
||||||
|
order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled
|
||||||
|
partner.CurOrderManager.UpdateOrderFields(order, []string{"DeliveryFlag"})
|
||||||
|
|
||||||
|
// 进到这里的原因是,在这个时间点,购物平台物流已经抢单(但抢单消息还没有被收到),所以转自送会失败 (比如:818810379000941),更好的做法应该是判断Swtich2SelfDeliver的返回值,这种情况下就不得试了
|
||||||
|
globals.SugarLogger.Infof("swtich2SelfDeliverWithRetry orderID:%s status is wrong(maybe purchase platform accepted waybill)", order.VendorOrderID)
|
||||||
|
partner.CurOrderManager.OnOrderMsg(order, "转商家自配送失败", "平台物流已接单")
|
||||||
|
// globals.SugarLogger.Warnf("swtich2SelfDeliverWithRetry orderID:%s status is wrong, order details:%v", order.VendorOrderID, order)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,7 +708,7 @@ func (s *DefScheduler) stopTimer(savedOrderInfo *WatchOrderInfo) {
|
|||||||
if savedOrderInfo.timer != nil {
|
if savedOrderInfo.timer != nil {
|
||||||
globals.SugarLogger.Debugf("stopTimer orderID:%s", savedOrderInfo.order.VendorOrderID)
|
globals.SugarLogger.Debugf("stopTimer orderID:%s", savedOrderInfo.order.VendorOrderID)
|
||||||
savedOrderInfo.timer.Stop()
|
savedOrderInfo.timer.Stop()
|
||||||
savedOrderInfo.timerStatus = 0
|
savedOrderInfo.timerStatus = model.OrderStatusUnknown
|
||||||
savedOrderInfo.timerStatusType = scheduler.TimerStatusTypeUnknown
|
savedOrderInfo.timerStatusType = scheduler.TimerStatusTypeUnknown
|
||||||
savedOrderInfo.timer = nil
|
savedOrderInfo.timer = nil
|
||||||
}
|
}
|
||||||
@@ -641,47 +725,61 @@ func (s *DefScheduler) resetTimer(savedOrderInfo *WatchOrderInfo, bill *model.Wa
|
|||||||
statusTime = bill.StatusTime
|
statusTime = bill.StatusTime
|
||||||
}
|
}
|
||||||
globals.SugarLogger.Debugf("resetTimer, orderID:%s statusType:%d status:%v", order.VendorOrderID, statusType, status)
|
globals.SugarLogger.Debugf("resetTimer, orderID:%s statusType:%d status:%v", order.VendorOrderID, statusType, status)
|
||||||
if statusType != savedOrderInfo.timerStatusType || status >= savedOrderInfo.timerStatus { // 新设置的TIMER不能覆盖状态在其后的TIMER,如果状态回绕,需要注意
|
if isStatusNewer(savedOrderInfo.timerStatusType, savedOrderInfo.timerStatus, statusType, status) { // 新设置的TIMER不能覆盖状态在其后的TIMER,如果状态回绕,需要注意
|
||||||
config := s.mergeOrderStatusConfig(savedOrderInfo, statusTime, statusType, status)
|
config := s.mergeOrderStatusConfig(savedOrderInfo, statusTime, statusType, status)
|
||||||
if config == nil || config.TimerType != partner.TimerTypeByPass {
|
if config == nil || config.TimerType != partner.TimerTypeByPass {
|
||||||
s.stopTimer(savedOrderInfo)
|
s.stopTimer(savedOrderInfo)
|
||||||
}
|
}
|
||||||
if config != nil && config.TimeoutAction != nil && config.TimerType != partner.TimerTypeByPass {
|
if config != nil && config.TimeoutAction != nil && config.TimerType != partner.TimerTypeByPass {
|
||||||
timeout := config.GetRefTimeout(statusTime)
|
if config.CallShouldSetTimer(savedOrderInfo, bill) {
|
||||||
if config.TimeoutGap != 0 {
|
timeout := config.GetRefTimeout(statusTime, order.OrderCreatedAt)
|
||||||
timeout += time.Duration(rand.Intn(int(config.TimeoutGap))) * time.Second
|
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)
|
|
||||||
} else {
|
|
||||||
timerName := ""
|
|
||||||
if statusType == scheduler.TimerStatusTypeOrder {
|
|
||||||
timerName = model.OrderStatusName[status]
|
|
||||||
} else if statusType == scheduler.TimerStatusTypeWaybill {
|
|
||||||
timerName = model.WaybillStatusName[status]
|
|
||||||
}
|
}
|
||||||
savedOrderInfo.timerStatusType = statusType
|
if isPending && timeout < pendingOrderTimerMaxSecond*time.Second { // 如果是PENDING的订单,则将其分布到2--5秒内,让后续事件有机会执行
|
||||||
savedOrderInfo.timerStatus = status
|
timeout = time.Duration(jxutils.MapValue2Scope(int64(timeout), -pendingOrderTimerMinMinSecond*1000, pendingOrderTimerMaxSecond*1000, pendingOrderTimerMinSecond*1000, pendingOrderTimerMaxSecond*1000)) * time.Millisecond
|
||||||
savedOrderInfo.timer = utils.AfterFuncWithRecover(timeout, func() {
|
} else if timeout < 0 {
|
||||||
jxutils.CallMsgHandlerAsync(func() {
|
timeout = 0
|
||||||
globals.SugarLogger.Debugf("fire timer:%s, orderID:%s", timerName, order.VendorOrderID)
|
}
|
||||||
savedOrderInfo := s.loadSavedOrderFromMap(model.Order2Status(order), true)
|
if timeout == 0 {
|
||||||
config.TimeoutAction(savedOrderInfo)
|
config.TimeoutAction(savedOrderInfo, bill)
|
||||||
savedOrderInfo.timerStatus = 0
|
} else {
|
||||||
savedOrderInfo.timerStatusType = scheduler.TimerStatusTypeUnknown
|
timerName := ""
|
||||||
}, order.VendorOrderID)
|
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, status:%d, timeout:%v", order.VendorOrderID, status, timeout)
|
||||||
}
|
}
|
||||||
globals.SugarLogger.Debugf("resetTimer, orderID:%s, status:%d, timeout:%v", order.VendorOrderID, status, timeout)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isStatusNewer(curStatusType, curStatus, statusType, status int) bool {
|
||||||
|
// 拣货完成及之前的订单事件TIMER不能覆盖运单TIMER(一般是消息错序引起的)
|
||||||
|
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) mergeOrderStatusConfig(savedOrderInfo *WatchOrderInfo, statusTime time.Time, statusType, status int) (retVal *StatusActionConfig) {
|
func (s *DefScheduler) mergeOrderStatusConfig(savedOrderInfo *WatchOrderInfo, statusTime time.Time, statusType, status int) (retVal *StatusActionConfig) {
|
||||||
s.locker.RLock()
|
s.locker.RLock()
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -709,7 +807,7 @@ func (s *DefScheduler) mergeOrderStatusConfig(savedOrderInfo *WatchOrderInfo, st
|
|||||||
TimeoutGap: -1,
|
TimeoutGap: -1,
|
||||||
}
|
}
|
||||||
timeout := statusTime.Sub(time.Now()) + minMinute2Schedule3rdCarrier*time.Minute
|
timeout := statusTime.Sub(time.Now()) + minMinute2Schedule3rdCarrier*time.Minute
|
||||||
if vendorActionParams.GetRefTimeout(statusTime) < timeout { // 如果非立即达订单,根据ExpectedDeliveredTime算出来的timeout太早
|
if vendorActionParams.GetRefTimeout(statusTime, order.OrderCreatedAt) < timeout { // 如果非立即达订单,根据ExpectedDeliveredTime算出来的timeout太早
|
||||||
vendorActionParams.Timeout = timeout
|
vendorActionParams.Timeout = timeout
|
||||||
vendorActionParams.TimeoutGap = 0
|
vendorActionParams.TimeoutGap = 0
|
||||||
}
|
}
|
||||||
@@ -742,10 +840,18 @@ func (s *DefScheduler) mergeOrderStatusConfig(savedOrderInfo *WatchOrderInfo, st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // 有最后拣货时间,反推
|
} else { // 有最后拣货时间,反推
|
||||||
|
timeout := order.PickDeadline.Sub(time.Now()) - (time2AutoPickupAhead + second2AutoPickupGap*time.Second)
|
||||||
|
realSecond2AutoPickupGap := second2AutoPickupGap
|
||||||
|
if realSecond2AutoPickupGap > int(timeout/time.Second) {
|
||||||
|
realSecond2AutoPickupGap = int(timeout / time.Second)
|
||||||
|
if realSecond2AutoPickupGap < 0 {
|
||||||
|
realSecond2AutoPickupGap = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
vendorActionParams = &partner.StatusActionParams{
|
vendorActionParams = &partner.StatusActionParams{
|
||||||
TimerType: partner.TimerTypeBaseNow,
|
TimerType: partner.TimerTypeBaseNow,
|
||||||
Timeout: order.PickDeadline.Sub(time.Now()) - time2AutoPickupAhead - second2AutoPickupGap*time.Second,
|
Timeout: timeout,
|
||||||
TimeoutGap: second2AutoPickupGap,
|
TimeoutGap: realSecond2AutoPickupGap,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -795,40 +901,39 @@ func (s *DefScheduler) handleAutoAcceptOrder(orderID string, vendorID int, userM
|
|||||||
return handleType
|
return handleType
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (s *DefScheduler) updateOrderByStatus(order *model.GoodsOrder, status *model.OrderStatus) (retVal *model.GoodsOrder) {
|
|
||||||
// order.Status = status.Status
|
|
||||||
// order.VendorStatus = status.VendorStatus
|
|
||||||
// order.StatusTime = status.StatusTime
|
|
||||||
// order.LockStatus = status.LockStatus
|
|
||||||
// return order
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (s *DefScheduler) updateOrderByBill(order *model.GoodsOrder, bill *model.Waybill, revertStatus bool) {
|
func (s *DefScheduler) updateOrderByBill(order *model.GoodsOrder, bill *model.Waybill, revertStatus bool) {
|
||||||
if order.Status > model.OrderStatusEndBegin {
|
if order.Status > model.OrderStatusEndBegin {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if bill.WaybillVendorID == model.VendorIDUnknown {
|
updateFields := []string{
|
||||||
bill.VendorWaybillID = ""
|
"WaybillVendorID",
|
||||||
|
"VendorWaybillID",
|
||||||
|
}
|
||||||
|
if bill == nil {
|
||||||
|
order.WaybillVendorID = model.VendorIDUnknown
|
||||||
|
order.VendorWaybillID = ""
|
||||||
|
} else {
|
||||||
|
order.WaybillVendorID = bill.WaybillVendorID
|
||||||
|
order.VendorWaybillID = bill.VendorWaybillID
|
||||||
}
|
}
|
||||||
partner.CurOrderManager.UpdateWaybillVendorID(bill, revertStatus)
|
|
||||||
order.WaybillVendorID = bill.WaybillVendorID
|
|
||||||
order.VendorWaybillID = bill.VendorWaybillID
|
|
||||||
if revertStatus {
|
if revertStatus {
|
||||||
order.Status = model.OrderStatusFinishedPickup
|
order.Status = model.OrderStatusFinishedPickup
|
||||||
partner.CurOrderManager.UpdateOrderStatusAndFlag(order)
|
updateFields = append(updateFields, "Status")
|
||||||
}
|
}
|
||||||
|
partner.CurOrderManager.UpdateOrderFields(order, updateFields)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DefScheduler) updateBillsInfo(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) (isBillExist bool) {
|
func (s *DefScheduler) updateBillsInfo(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) (isBillExist bool) {
|
||||||
if savedOrderInfo != nil {
|
if savedOrderInfo != nil {
|
||||||
if savedBill := savedOrderInfo.waybills[bill.WaybillVendorID]; savedBill != nil {
|
if savedBill := savedOrderInfo.waybills[bill.WaybillVendorID]; savedBill != nil {
|
||||||
isBillExist = true
|
isBillExist = true
|
||||||
if savedBill.Status > bill.Status {
|
// if savedBill.Status > bill.Status {
|
||||||
bill.Status = savedBill.Status
|
// bill.Status = savedBill.Status
|
||||||
} else if bill.Status > savedBill.Status {
|
// } else if bill.Status > savedBill.Status {
|
||||||
savedBill.Status = bill.Status
|
// savedBill.Status = bill.Status
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
savedOrderInfo.waybills[bill.WaybillVendorID] = bill
|
||||||
}
|
}
|
||||||
return isBillExist
|
return isBillExist
|
||||||
}
|
}
|
||||||
@@ -848,7 +953,10 @@ func (s *DefScheduler) isBillCandidate(order *model.GoodsOrder, bill *model.Wayb
|
|||||||
func (s *DefScheduler) ProxyCancelWaybill(order *model.GoodsOrder, bill *model.Waybill, cancelReasonID int, cancelReason string) (err error) {
|
func (s *DefScheduler) ProxyCancelWaybill(order *model.GoodsOrder, bill *model.Waybill, cancelReasonID int, cancelReason string) (err error) {
|
||||||
globals.SugarLogger.Debugf("ProxyCancelWaybill orderID:%s", order.VendorOrderID)
|
globals.SugarLogger.Debugf("ProxyCancelWaybill orderID:%s", order.VendorOrderID)
|
||||||
if (order.DeliveryFlag & model.OrderDeliveryFlagMaskScheduleDisabled) == 0 {
|
if (order.DeliveryFlag & model.OrderDeliveryFlagMaskScheduleDisabled) == 0 {
|
||||||
return s.CancelWaybill(bill, cancelReasonID, cancelReason)
|
if err = s.CancelWaybill(bill, cancelReasonID, cancelReason); err != nil {
|
||||||
|
partner.CurOrderManager.OnOrderMsg(order, "取消三方运单失败", err.Error())
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
globals.SugarLogger.Debugf("ProxyCancelWaybill orderID:%s stop schedule, bypass CancelWaybill", order.VendorOrderID)
|
globals.SugarLogger.Debugf("ProxyCancelWaybill orderID:%s stop schedule, bypass CancelWaybill", order.VendorOrderID)
|
||||||
return nil
|
return nil
|
||||||
@@ -868,18 +976,3 @@ func OnDefSchConfChanged(key, value string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断是否是购买平台自有物流
|
|
||||||
// 对于京东,饿百来说,就是其自有的物流,对于微商城来说,是达达
|
|
||||||
func (s *DefScheduler) IsOrderPlatformWaybill(bill *model.Waybill) bool {
|
|
||||||
return bill.OrderVendorID == bill.WaybillVendorID || s.IsSpecialOrderPlatformWaybill(bill)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 是否是特殊物流
|
|
||||||
func (s *DefScheduler) IsSpecialOrderPlatformWaybill(bill *model.Waybill) bool {
|
|
||||||
return (bill.OrderVendorID == model.VendorIDWSC && bill.WaybillVendorID == model.VendorIDDada)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *DefScheduler) IsOrderHasWaybill(order *model.GoodsOrder) bool {
|
|
||||||
return order.WaybillVendorID != model.VendorIDUnknown
|
|
||||||
}
|
|
||||||
|
|||||||
27
business/jxcallback/scheduler/defsch/defsch_afs.go
Normal file
27
business/jxcallback/scheduler/defsch/defsch_afs.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package defsch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/weixinmsg"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/msghub"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *DefScheduler) OnAfsOrderNew(order *model.AfsOrder, isPending bool) (err error) {
|
||||||
|
if order.Status == model.AfsOrderStatusWait4Approve {
|
||||||
|
if !isPending {
|
||||||
|
msghub.OnNewWait4ApproveAfsOrder(order)
|
||||||
|
weixinmsg.NotifyAfsOrderStatus(order)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DefScheduler) OnAfsOrderStatusChanged(order *model.AfsOrder, status *model.OrderStatus, isPending bool) (err error) {
|
||||||
|
if status.Status == model.AfsOrderStatusWait4ReceiveGoods {
|
||||||
|
if !isPending {
|
||||||
|
msghub.OnKeyAfsOrderStatusChanged(order)
|
||||||
|
weixinmsg.NotifyAfsOrderStatus(order)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -15,23 +15,25 @@ import (
|
|||||||
"git.rosy.net.cn/jx-callback/globals"
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (s *DefScheduler) loadSavedOrderByID(vendorOrderID string, vendorID int, isForceLoad bool) *WatchOrderInfo {
|
||||||
|
return s.loadSavedOrderFromMap(&model.OrderStatus{
|
||||||
|
RefVendorOrderID: vendorOrderID,
|
||||||
|
RefVendorID: vendorID,
|
||||||
|
}, isForceLoad)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *DefScheduler) SelfDeliveringAndUpdateStatus(ctx *jxcontext.Context, vendorOrderID string, vendorID int, userName string) (err error) {
|
func (s *DefScheduler) SelfDeliveringAndUpdateStatus(ctx *jxcontext.Context, vendorOrderID string, vendorID int, userName string) (err error) {
|
||||||
jxutils.CallMsgHandler(func() {
|
jxutils.CallMsgHandler(func() {
|
||||||
err = func() (err error) {
|
err = func() (err error) {
|
||||||
globals.SugarLogger.Infof("SelfDeliveringAndUpdateStatus orderID:%s userName:%s", vendorOrderID, userName)
|
globals.SugarLogger.Infof("SelfDeliveringAndUpdateStatus orderID:%s userName:%s", vendorOrderID, userName)
|
||||||
status := &model.OrderStatus{
|
savedOrderInfo := s.loadSavedOrderByID(vendorOrderID, vendorID, true)
|
||||||
RefVendorOrderID: vendorOrderID,
|
|
||||||
RefVendorID: vendorID,
|
|
||||||
}
|
|
||||||
savedOrderInfo := s.loadSavedOrderFromMap(status, true)
|
|
||||||
if savedOrderInfo != nil {
|
if savedOrderInfo != nil {
|
||||||
order := savedOrderInfo.order
|
order := savedOrderInfo.order
|
||||||
err = s.cancelOtherWaybills(savedOrderInfo, nil, partner.CancelWaybillReasonOther, partner.CancelWaybillReasonStrActive)
|
if err = s.isPossibleSwitch2SelfDelivery(order); err == nil {
|
||||||
if err == nil {
|
err = s.cancelOtherWaybillsCheckOrderDeliveryFlag(savedOrderInfo, nil, partner.CancelWaybillReasonOther, partner.CancelWaybillReasonStrActive)
|
||||||
// todo
|
if err == nil {
|
||||||
if true { //order.DeliveryFlag&model.OrderDeliveryFlagMaskPurcahseDisabled == 0 {
|
|
||||||
if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore {
|
if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore {
|
||||||
if order.Status <= model.OrderStatusFinishedPickup {
|
if order.Status < model.OrderStatusDelivering {
|
||||||
storeDetail, err2 := dao.GetStoreDetail(dao.GetDB(), order.StoreID, order.VendorID)
|
storeDetail, err2 := dao.GetStoreDetail(dao.GetDB(), order.StoreID, order.VendorID)
|
||||||
phone := userName
|
phone := userName
|
||||||
if err = err2; err == nil {
|
if err = err2; err == nil {
|
||||||
@@ -40,7 +42,7 @@ func (s *DefScheduler) SelfDeliveringAndUpdateStatus(ctx *jxcontext.Context, ven
|
|||||||
err = s.SelfDeliverDelivering(order, phone)
|
err = s.SelfDeliverDelivering(order, phone)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if order.Status <= model.OrderStatusFinishedPickup {
|
if order.Status < model.OrderStatusDelivering {
|
||||||
err = s.Swtich2SelfDeliver(order, userName)
|
err = s.Swtich2SelfDeliver(order, userName)
|
||||||
} else if order.VendorID == order.WaybillVendorID { // 状态为配送中,且是购物平台运单,不能转自送了
|
} else if order.VendorID == order.WaybillVendorID { // 状态为配送中,且是购物平台运单,不能转自送了
|
||||||
err = scheduler.ErrOrderStatusIsNotSuitable4CurOperation
|
err = scheduler.ErrOrderStatusIsNotSuitable4CurOperation
|
||||||
@@ -51,7 +53,7 @@ func (s *DefScheduler) SelfDeliveringAndUpdateStatus(ctx *jxcontext.Context, ven
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
order.Status = model.OrderStatusDelivering
|
order.Status = model.OrderStatusDelivering
|
||||||
order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled | model.OrderDeliveryFlagMaskPurcahseDisabled
|
order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled | model.OrderDeliveryFlagMaskPurcahseDisabled
|
||||||
if err = partner.CurOrderManager.UpdateOrderStatusAndFlag(order); err == nil {
|
if err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order); err == nil {
|
||||||
s.stopTimer(savedOrderInfo)
|
s.stopTimer(savedOrderInfo)
|
||||||
globals.SugarLogger.Infof("SelfDeliveringAndUpdateStatus orderID:%s userName:%s successfully", vendorOrderID, userName)
|
globals.SugarLogger.Infof("SelfDeliveringAndUpdateStatus orderID:%s userName:%s successfully", vendorOrderID, userName)
|
||||||
return err
|
return err
|
||||||
@@ -70,25 +72,47 @@ func (s *DefScheduler) SelfDeliveringAndUpdateStatus(ctx *jxcontext.Context, ven
|
|||||||
func (s *DefScheduler) canOrderCreateWaybillNormally(order *model.GoodsOrder) (err error) {
|
func (s *DefScheduler) canOrderCreateWaybillNormally(order *model.GoodsOrder) (err error) {
|
||||||
if !(order.LockStatus != model.OrderStatusLocked && order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusEndBegin) {
|
if !(order.LockStatus != model.OrderStatusLocked && order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusEndBegin) {
|
||||||
err = fmt.Errorf("当前订单%s没有处于拣货完成且没有结束没有锁定的订单才能进行召唤配送操作", order.VendorOrderID)
|
err = fmt.Errorf("当前订单%s没有处于拣货完成且没有结束没有锁定的订单才能进行召唤配送操作", order.VendorOrderID)
|
||||||
} else if s.IsOrderHasWaybill(order) {
|
} else if model.IsOrderHaveWaybill(order) {
|
||||||
err = fmt.Errorf("当前订单%s已经有了有效的承运人%s了", order.VendorOrderID, jxutils.GetVendorName(order.WaybillVendorID))
|
err = fmt.Errorf("当前订单%s已经有了有效的承运人%s了", order.VendorOrderID, jxutils.GetVendorName(order.WaybillVendorID))
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DefScheduler) CreateWaybillOnProviders4SavedOrder(ctx *jxcontext.Context, savedOrderInfo *WatchOrderInfo, forceCreate bool) (bills []*model.Waybill, err error) {
|
func (s *DefScheduler) isPossibleSwitch2SelfDelivery(order *model.GoodsOrder) (err error) {
|
||||||
|
if scheduler.StoreDeliveryTypeByStore != s.GetStoreDeliveryType(order, nil) {
|
||||||
|
if order.Status < model.OrderStatusFinishedPickup {
|
||||||
|
err = fmt.Errorf("拣货完成后才能转自配送")
|
||||||
|
} else if order.Status >= model.OrderStatusFinishedPickup && order.Status < model.OrderStatusDelivering {
|
||||||
|
if time.Now().Sub(order.StatusTime) < minMinute2Schedule3rdCarrier*time.Minute {
|
||||||
|
err = fmt.Errorf("非自配送门店转3方配送至少要求拣货完成后%d分钟才能操作", minMinute2Schedule3rdCarrier)
|
||||||
|
}
|
||||||
|
} else if order.Status >= model.OrderStatusDelivering && order.Status < model.OrderStatusEndBegin {
|
||||||
|
if model.IsOrderHaveOwnWaybill(order) {
|
||||||
|
err = fmt.Errorf("%s物流已在配送中,不能转自配送", jxutils.GetVendorName(order.VendorID))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("订单%s已经结束,请刷新状态", order.VendorOrderID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DefScheduler) CreateWaybillOnProviders4SavedOrder(ctx *jxcontext.Context, savedOrderInfo *WatchOrderInfo, courierVendorIDs []int, forceCreate bool, maxAddFee, maxDiffFee2Mtps int64) (bills []*model.Waybill, err error) {
|
||||||
order := savedOrderInfo.order
|
order := savedOrderInfo.order
|
||||||
err = s.canOrderCreateWaybillNormally(order)
|
if !forceCreate {
|
||||||
if forceCreate || err == nil {
|
err = s.canOrderCreateWaybillNormally(order)
|
||||||
err = nil
|
}
|
||||||
|
if err == nil {
|
||||||
feeHandler := delivery.DefCreateWaybillPolicy
|
feeHandler := delivery.DefCreateWaybillPolicy
|
||||||
if forceCreate {
|
if forceCreate {
|
||||||
feeHandler = delivery.NullCreateWaybillPolicy
|
feeHandler = delivery.NullCreateWaybillPolicy
|
||||||
|
} else if maxAddFee != 0 {
|
||||||
|
feeHandler = delivery.CreateWaybillPolicy(maxDiffFee2Mtps, maxAddFee)
|
||||||
}
|
}
|
||||||
if bills, err = s.CreateWaybillOnProviders(ctx, order, feeHandler); err == nil {
|
if bills, err = s.CreateWaybillOnProviders(ctx, order, courierVendorIDs, feeHandler, forceCreate); err == nil {
|
||||||
if forceCreate {
|
if forceCreate {
|
||||||
order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled
|
order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled
|
||||||
err = partner.CurOrderManager.UpdateOrderStatusAndFlag(order)
|
err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if forceCreate {
|
if forceCreate {
|
||||||
@@ -105,7 +129,7 @@ func (s *DefScheduler) CreateWaybillOnProviders4SavedOrder(ctx *jxcontext.Contex
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DefScheduler) CreateWaybillOnProvidersEx(ctx *jxcontext.Context, vendorOrderID string, vendorID int, forceCreate bool) (bills []*model.Waybill, err error) {
|
func (s *DefScheduler) CreateWaybillOnProvidersEx(ctx *jxcontext.Context, vendorOrderID string, vendorID int, courierVendorIDs []int, forceCreate bool, maxAddFee, maxDiffFee2Mtps int64) (bills []*model.Waybill, err error) {
|
||||||
jxutils.CallMsgHandler(func() {
|
jxutils.CallMsgHandler(func() {
|
||||||
bills, err = func() (bills []*model.Waybill, err error) {
|
bills, err = func() (bills []*model.Waybill, err error) {
|
||||||
userName := ctx.GetUserName()
|
userName := ctx.GetUserName()
|
||||||
@@ -113,19 +137,15 @@ func (s *DefScheduler) CreateWaybillOnProvidersEx(ctx *jxcontext.Context, vendor
|
|||||||
if vendorID == model.VendorIDELM {
|
if vendorID == model.VendorIDELM {
|
||||||
return nil, fmt.Errorf("不要直接使用饿了么订单号,请使用相应的饿百订单号")
|
return nil, fmt.Errorf("不要直接使用饿了么订单号,请使用相应的饿百订单号")
|
||||||
}
|
}
|
||||||
status := &model.OrderStatus{
|
savedOrderInfo := s.loadSavedOrderByID(vendorOrderID, vendorID, true)
|
||||||
RefVendorOrderID: vendorOrderID,
|
|
||||||
RefVendorID: vendorID,
|
|
||||||
}
|
|
||||||
savedOrderInfo := s.loadSavedOrderFromMap(status, true)
|
|
||||||
if savedOrderInfo != nil {
|
if savedOrderInfo != nil {
|
||||||
order := savedOrderInfo.order
|
order := savedOrderInfo.order
|
||||||
if scheduler.StoreDeliveryTypeByStore != s.GetStoreDeliveryType(order, nil) &&
|
if !forceCreate {
|
||||||
order.Status == model.OrderStatusFinishedPickup &&
|
err = s.isPossibleSwitch2SelfDelivery(order)
|
||||||
time.Now().Sub(order.StatusTime) < minMinute2Schedule3rdCarrier*time.Minute {
|
}
|
||||||
return nil, fmt.Errorf("非自配送门店转3方配送至少要求拣货完成后%d分钟才能操作", minMinute2Schedule3rdCarrier)
|
if err == nil {
|
||||||
|
bills, err = s.CreateWaybillOnProviders4SavedOrder(ctx, savedOrderInfo, courierVendorIDs, forceCreate, maxAddFee, maxDiffFee2Mtps)
|
||||||
}
|
}
|
||||||
bills, err = s.CreateWaybillOnProviders4SavedOrder(ctx, savedOrderInfo, forceCreate)
|
|
||||||
} else {
|
} else {
|
||||||
err = scheduler.ErrCanNotFindOrder
|
err = scheduler.ErrCanNotFindOrder
|
||||||
}
|
}
|
||||||
@@ -141,13 +161,9 @@ func (s *DefScheduler) CancelAll3rdWaybills(ctx *jxcontext.Context, vendorOrderI
|
|||||||
jxutils.CallMsgHandler(func() {
|
jxutils.CallMsgHandler(func() {
|
||||||
err = func() (err error) {
|
err = func() (err error) {
|
||||||
globals.SugarLogger.Infof("CancelAll3rdWaybills orderID:%s userName:%s", vendorOrderID, ctx.GetUserName())
|
globals.SugarLogger.Infof("CancelAll3rdWaybills orderID:%s userName:%s", vendorOrderID, ctx.GetUserName())
|
||||||
status := &model.OrderStatus{
|
savedOrderInfo := s.loadSavedOrderByID(vendorOrderID, vendorID, true)
|
||||||
RefVendorOrderID: vendorOrderID,
|
|
||||||
RefVendorID: vendorID,
|
|
||||||
}
|
|
||||||
savedOrderInfo := s.loadSavedOrderFromMap(status, true)
|
|
||||||
if savedOrderInfo != nil {
|
if savedOrderInfo != nil {
|
||||||
err = s.cancelOtherWaybills2(savedOrderInfo, nil, partner.CancelWaybillReasonOther, partner.CancelWaybillReasonStrActive)
|
err = s.cancelOtherWaybills(savedOrderInfo, nil, partner.CancelWaybillReasonOther, partner.CancelWaybillReasonStrActive)
|
||||||
} else {
|
} else {
|
||||||
err = scheduler.ErrCanNotFindOrder
|
err = scheduler.ErrCanNotFindOrder
|
||||||
}
|
}
|
||||||
@@ -155,7 +171,7 @@ func (s *DefScheduler) CancelAll3rdWaybills(ctx *jxcontext.Context, vendorOrderI
|
|||||||
if err == nil && isStopSchedule {
|
if err == nil && isStopSchedule {
|
||||||
order := savedOrderInfo.order
|
order := savedOrderInfo.order
|
||||||
order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled
|
order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled
|
||||||
if err = partner.CurOrderManager.UpdateOrderStatusAndFlag(order); err == nil {
|
if err = partner.CurOrderManager.UpdateOrderStatusAndDeliveryFlag(order); err == nil {
|
||||||
s.stopTimer(savedOrderInfo)
|
s.stopTimer(savedOrderInfo)
|
||||||
globals.SugarLogger.Infof("CancelAll3rdWaybills orderID:%s userName:%s successfully", vendorOrderID, ctx.GetUserName())
|
globals.SugarLogger.Infof("CancelAll3rdWaybills orderID:%s userName:%s successfully", vendorOrderID, ctx.GetUserName())
|
||||||
}
|
}
|
||||||
@@ -165,3 +181,80 @@ func (s *DefScheduler) CancelAll3rdWaybills(ctx *jxcontext.Context, vendorOrderI
|
|||||||
}, jxutils.ComposeUniversalOrderID(vendorOrderID, vendorID))
|
}, jxutils.ComposeUniversalOrderID(vendorOrderID, vendorID))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *DefScheduler) QueryOrderWaybillFeeInfoEx(ctx *jxcontext.Context, vendorOrderID string, vendorID int) (deliveryFeeMap map[int]*partner.WaybillFeeInfo, err error) {
|
||||||
|
jxutils.CallMsgHandler(func() {
|
||||||
|
deliveryFeeMap, err = func() (deliveryFeeMap map[int]*partner.WaybillFeeInfo, err error) {
|
||||||
|
userName := ctx.GetUserName()
|
||||||
|
globals.SugarLogger.Infof("GetWaybillsInfoEx orderID:%s userName:%s", vendorOrderID, userName)
|
||||||
|
|
||||||
|
db := dao.GetDB()
|
||||||
|
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
storeCourierList, err := dao.GetStoreCourierList(db, jxutils.GetSaleStoreIDFromOrder(order), model.StoreStatusAll)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
waybillList, err := partner.CurOrderManager.GetOrderWaybillInfo(ctx, vendorOrderID, vendorID, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
waybillMap := make(map[int]*model.Waybill)
|
||||||
|
for _, bill := range waybillList {
|
||||||
|
waybillMap[bill.WaybillVendorID] = bill
|
||||||
|
}
|
||||||
|
deliveryFeeMap = make(map[int]*partner.WaybillFeeInfo)
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, storeCourier := range storeCourierList {
|
||||||
|
var feeInfo *partner.WaybillFeeInfo
|
||||||
|
if waybillMap[storeCourier.VendorID] != nil {
|
||||||
|
feeInfo = &partner.WaybillFeeInfo{
|
||||||
|
Waybill: waybillMap[storeCourier.VendorID],
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if storeCourier.Status != model.StoreStatusOpened {
|
||||||
|
feeInfo = &partner.WaybillFeeInfo{
|
||||||
|
ErrCode: partner.WaybillFeeErrCodeCourierNotOpen,
|
||||||
|
ErrStr: fmt.Sprintf("%d配送门店没有启用", storeCourier.VendorID),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if handler := partner.GetDeliveryPlatformFromVendorID(storeCourier.VendorID); handler != nil {
|
||||||
|
if handler.Use4CreateWaybill {
|
||||||
|
if feeInfo, err = handler.Handler.GetWaybillFee(order); err != nil {
|
||||||
|
feeInfo = &partner.WaybillFeeInfo{
|
||||||
|
ErrCode: partner.WaybillFeeErrCodeCourierOthers,
|
||||||
|
ErrStr: err.Error(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
feeInfo.TimeoutSecond = timeoutSecond
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
feeInfo = &partner.WaybillFeeInfo{
|
||||||
|
ErrCode: partner.WaybillFeeErrCodeCourierForbidden,
|
||||||
|
ErrStr: fmt.Sprintf("内部错误,%d不能用于创建运单", storeCourier.VendorID),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
feeInfo = &partner.WaybillFeeInfo{
|
||||||
|
ErrCode: partner.WaybillFeeErrCodeCourierNotSupported,
|
||||||
|
ErrStr: fmt.Sprintf("内部错误,%d不被支持", storeCourier.VendorID),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deliveryFeeMap[storeCourier.VendorID] = feeInfo
|
||||||
|
}
|
||||||
|
err = nil
|
||||||
|
return deliveryFeeMap, err
|
||||||
|
}()
|
||||||
|
}, jxutils.ComposeUniversalOrderID(vendorOrderID, vendorID))
|
||||||
|
return deliveryFeeMap, err
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,4 +40,8 @@ type IScheduler interface {
|
|||||||
|
|
||||||
// 以下是运单
|
// 以下是运单
|
||||||
OnWaybillStatusChanged(bill *model.Waybill, isPending bool) (err error)
|
OnWaybillStatusChanged(bill *model.Waybill, isPending bool) (err error)
|
||||||
|
|
||||||
|
// 以下是售后单
|
||||||
|
OnAfsOrderNew(order *model.AfsOrder, isPending bool) (err error)
|
||||||
|
OnAfsOrderStatusChanged(order *model.AfsOrder, status *model.OrderStatus, isPending bool) (err error)
|
||||||
}
|
}
|
||||||
|
|||||||
355
business/jxstore/act/act.go
Normal file
355
business/jxstore/act/act.go
Normal file
@@ -0,0 +1,355 @@
|
|||||||
|
package act
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ActionTypeNA = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
type ActOrderRuleParam struct {
|
||||||
|
SalePrice int64 `orm:"" json:"salePrice"` // 满的价格
|
||||||
|
DeductPrice int64 `orm:"" json:"deductPrice"` // 减的价格
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActStoreSkuParam struct {
|
||||||
|
Action int // -1删除,1修改,2新增
|
||||||
|
|
||||||
|
StoreID int `orm:"column(store_id)" json:"storeID"`
|
||||||
|
SkuID int `orm:"column(sku_id)" json:"skuID"`
|
||||||
|
|
||||||
|
PricePercentage int `orm:"" json:"pricePercentage"` // 单品级活动用,SKU级的价格比例,非0覆盖Act中的PricePercentage
|
||||||
|
ActPrice int64 `orm:"" json:"actPrice"` // 单品级活动用,SKU级指定的价格,非0覆盖CustomPricePercentage与Act中的PricePercentage
|
||||||
|
|
||||||
|
Stock int `orm:"" json:"stock"` // 订单级活动用
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActDetail struct {
|
||||||
|
model.Act2
|
||||||
|
}
|
||||||
|
|
||||||
|
func ActStoreSkuParam2Map(actStoreSku []*ActStoreSkuParam) (actStoreSkuMap map[int][]*ActStoreSkuParam) {
|
||||||
|
if len(actStoreSku) > 0 {
|
||||||
|
for _, v := range actStoreSku {
|
||||||
|
actStoreSkuMap[v.StoreID] = append(actStoreSkuMap[v.StoreID], v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actStoreSkuMap
|
||||||
|
}
|
||||||
|
|
||||||
|
func genStoreSkuMapKey(storeID, skuID int) int64 {
|
||||||
|
return int64(storeID) + int64(skuID)*1000000
|
||||||
|
}
|
||||||
|
|
||||||
|
func ActStoreSkuParam2Model(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, actStoreSku []*ActStoreSkuParam) (actMapList []*model.ActMap, actStoreMapList []*model.ActStoreMap, actStoreSkuList []*model.ActStoreSku, actStoreSkuMapList []*model.ActStoreSkuMap, err error) {
|
||||||
|
if len(actStoreSku) > 0 {
|
||||||
|
storeIDMap := make(map[int]int)
|
||||||
|
skuIDMap := make(map[int]int)
|
||||||
|
storeSkuParamMap := make(map[int][]*ActStoreSkuParam)
|
||||||
|
for _, v := range actStoreSku {
|
||||||
|
storeIDMap[v.StoreID] = 1
|
||||||
|
skuIDMap[v.SkuID] = 1
|
||||||
|
storeSkuParamMap[v.StoreID] = append(storeSkuParamMap[v.StoreID], v)
|
||||||
|
}
|
||||||
|
db := dao.GetDB()
|
||||||
|
|
||||||
|
storeSkuList, err2 := dao.GetStoresSkusInfo(db, jxutils.IntMap2List(storeIDMap), jxutils.IntMap2List(skuIDMap))
|
||||||
|
if err = err2; err != nil {
|
||||||
|
return nil, nil, nil, nil, err
|
||||||
|
}
|
||||||
|
storeSkuMap := make(map[int64]*model.StoreSkuBind)
|
||||||
|
for _, v := range storeSkuList {
|
||||||
|
storeSkuMap[genStoreSkuMapKey(v.StoreID, v.SkuID)] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
wholeValidVendorMap := make(map[int]int)
|
||||||
|
for storeID, oneStoreSkuParam := range storeSkuParamMap {
|
||||||
|
validVendorMap := make(map[int]int)
|
||||||
|
validSkuMap := make(map[int]int)
|
||||||
|
for _, vendorID := range vendorIDs {
|
||||||
|
storeDetail, err2 := dao.GetStoreDetail(db, storeID, vendorID)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
for _, v := range oneStoreSkuParam {
|
||||||
|
if storeSkuInfo := storeSkuMap[genStoreSkuMapKey(v.StoreID, v.SkuID)]; storeSkuInfo != nil {
|
||||||
|
validVendorMap[vendorID] = 1
|
||||||
|
validSkuMap[v.SkuID] = 1
|
||||||
|
actSkuMap := &model.ActStoreSkuMap{
|
||||||
|
ActID: act.ID,
|
||||||
|
StoreID: storeID,
|
||||||
|
SkuID: v.SkuID,
|
||||||
|
VendorID: vendorID,
|
||||||
|
|
||||||
|
SyncStatus: model.SyncFlagNewMask,
|
||||||
|
}
|
||||||
|
if v.ActPrice != 0 {
|
||||||
|
actSkuMap.ActualActPrice = v.ActPrice
|
||||||
|
} else {
|
||||||
|
percentage := act.PricePercentage
|
||||||
|
if v.PricePercentage != 0 {
|
||||||
|
percentage = v.PricePercentage
|
||||||
|
}
|
||||||
|
percentage = percentage * int(storeDetail.PricePercentage) / 100
|
||||||
|
actSkuMap.ActualActPrice = int64(jxutils.CaculateSkuVendorPrice(storeSkuInfo.Price, percentage, 0))
|
||||||
|
}
|
||||||
|
dao.WrapAddIDCULDEntity(actSkuMap, ctx.GetUserName())
|
||||||
|
actStoreSkuMapList = append(actStoreSkuMapList, actSkuMap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if !dao.IsNoRowsError(err) {
|
||||||
|
return nil, nil, nil, nil, err
|
||||||
|
} else {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range oneStoreSkuParam {
|
||||||
|
if validSkuMap[v.SkuID] == 1 {
|
||||||
|
if storeSkuInfo := storeSkuMap[genStoreSkuMapKey(v.StoreID, v.SkuID)]; storeSkuInfo != nil {
|
||||||
|
storeSku := &model.ActStoreSku{
|
||||||
|
ActID: act.ID,
|
||||||
|
StoreID: v.StoreID,
|
||||||
|
SkuID: v.SkuID,
|
||||||
|
OriginalPrice: int64(storeSkuInfo.Price),
|
||||||
|
PricePercentage: v.PricePercentage,
|
||||||
|
ActPrice: v.ActPrice,
|
||||||
|
Stock: v.Stock,
|
||||||
|
}
|
||||||
|
dao.WrapAddIDCULDEntity(storeSku, ctx.GetUserName())
|
||||||
|
actStoreSkuList = append(actStoreSkuList, storeSku)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for vendorID := range validVendorMap {
|
||||||
|
wholeValidVendorMap[vendorID] = 1
|
||||||
|
actStoreMap := &model.ActStoreMap{
|
||||||
|
ActID: act.ID,
|
||||||
|
StoreID: storeID,
|
||||||
|
VendorID: vendorID,
|
||||||
|
|
||||||
|
SyncStatus: model.SyncFlagNewMask,
|
||||||
|
}
|
||||||
|
dao.WrapAddIDCULDEntity(actStoreMap, ctx.GetUserName())
|
||||||
|
actStoreMapList = append(actStoreMapList, actStoreMap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for vendorID := range wholeValidVendorMap {
|
||||||
|
actMap := &model.ActMap{
|
||||||
|
ActID: act.ID,
|
||||||
|
VendorID: vendorID,
|
||||||
|
|
||||||
|
SyncStatus: model.SyncFlagNewMask,
|
||||||
|
}
|
||||||
|
dao.WrapAddIDCULDEntity(actMap, ctx.GetUserName())
|
||||||
|
actMapList = append(actMapList, actMap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actMapList, actStoreMapList, actStoreSkuList, actStoreSkuMapList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateAct(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam) (actID int, err error) {
|
||||||
|
vendorIDMap := make(map[int]bool)
|
||||||
|
for _, v := range vendorIDs {
|
||||||
|
vendorIDMap[v] = true
|
||||||
|
}
|
||||||
|
db := dao.GetDB()
|
||||||
|
dao.WrapAddIDCULDEntity(act, ctx.GetUserName())
|
||||||
|
dao.Begin(db)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
panic(r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
err = dao.CreateEntity(db, act)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
actMapList, actStoreMapList, actStoreSkuList, actStoreSkuMapList, err := ActStoreSkuParam2Model(ctx, act, vendorIDs, actStoreSku)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
isEmptyAct := true
|
||||||
|
for _, list := range []interface{}{
|
||||||
|
actMapList, actStoreMapList, actStoreSkuList, actStoreSkuMapList,
|
||||||
|
} {
|
||||||
|
if len(utils.Interface2Slice(list)) > 0 {
|
||||||
|
err = dao.CreateMultiEntities(db, list)
|
||||||
|
if err != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
isEmptyAct = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if isEmptyAct {
|
||||||
|
dao.Rollback(db)
|
||||||
|
return 0, fmt.Errorf("没有门店及SKU满足需求,空操作")
|
||||||
|
}
|
||||||
|
dao.Commit(db)
|
||||||
|
actID = act.ID
|
||||||
|
err = SyncAct(ctx, actID, nil, nil, nil)
|
||||||
|
return actID, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func QueryActs(ctx *jxcontext.Context, actID int, keyword string, statusList []int, actTypeList []int, storeID, skuID int, beginAt, endAt time.Time) (actList []*model.Act, err error) {
|
||||||
|
return actList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetActDetail(ctx *jxcontext.Context, actID int) (actDetail *ActDetail, err error) {
|
||||||
|
return actDetail, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// func GetAcVendorInfo(ctx *jxcontext.Context, actID int) (err error) {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func GetAcStoresVendorInfo(ctx *jxcontext.Context, actID int, storeIDs []int) (err error) {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func GetAcStoresSkusVendorInfo(ctx *jxcontext.Context, actID int, storeIDs, skuIDs []int) (err error) {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
|
||||||
|
func parseActStoreSkuParam(actStoreSku []*ActStoreSkuParam) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateAct(ctx *jxcontext.Context, act *model.Act, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam) (err error) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func CancelAct(ctx *jxcontext.Context, actID int) (err error) {
|
||||||
|
db := dao.GetDB()
|
||||||
|
act := &model.Act{}
|
||||||
|
act.ID = actID
|
||||||
|
if err = dao.GetEntity(db, act); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dao.Begin(db)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
panic(r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
dao.UpdateEntityLogically(db, act, map[string]interface{}{
|
||||||
|
model.FieldStatus: model.ActStatusCanceled,
|
||||||
|
}, ctx.GetUserName(), nil)
|
||||||
|
_, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, &model.ActMap{}, nil, ctx.GetUserName(), map[string]interface{}{
|
||||||
|
model.FieldActID: actID,
|
||||||
|
}, model.FieldSyncStatus, model.SyncFlagModifiedMask)
|
||||||
|
if err == nil {
|
||||||
|
dao.Commit(db)
|
||||||
|
globals.SugarLogger.Debugf("CancelAct track:%s", ctx.GetTrackInfo())
|
||||||
|
err = SyncAct(ctx, actID, nil, nil, nil)
|
||||||
|
} else {
|
||||||
|
dao.Rollback(db)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SyncAct(ctx *jxcontext.Context, actID int, vendorIDs, storeIDs, skuIDs []int) (err error) {
|
||||||
|
var actOrderRules []*model.ActOrderRule
|
||||||
|
db := dao.GetDB()
|
||||||
|
actMap, err := dao.GetActVendorInfo(db, actID, vendorIDs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
actStoreMap, err := dao.GetActStoreVendorInfo(db, actID, vendorIDs, storeIDs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, vendorIDs, storeIDs, skuIDs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var realVendorIDs []int
|
||||||
|
for vendorID := range actMap {
|
||||||
|
realVendorIDs = append(realVendorIDs, vendorID)
|
||||||
|
}
|
||||||
|
|
||||||
|
task := tasksch.NewParallelTask("SyncAct", nil, ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
vendorID := batchItemList[0].(int)
|
||||||
|
handler := partner.GetPurchasePlatformFromVendorID(vendorID)
|
||||||
|
if handler == nil {
|
||||||
|
err = fmt.Errorf("不被支持的vendorID:%d", vendorID)
|
||||||
|
} else {
|
||||||
|
act := actMap[vendorID]
|
||||||
|
actStore := actStoreMap[vendorID]
|
||||||
|
actStoreSku := actStoreSkuMap[vendorID]
|
||||||
|
// globals.SugarLogger.Debugf("%s", utils.Format4Output(act, false))
|
||||||
|
// globals.SugarLogger.Debugf("%s", utils.Format4Output(actStore, false))
|
||||||
|
// globals.SugarLogger.Debugf("%s", utils.Format4Output(actStoreSku, false))
|
||||||
|
if act != nil && actStore != nil && actStoreSku != nil {
|
||||||
|
if model.IsSyncStatusNeedCreate(act.SyncStatus) {
|
||||||
|
err = handler.CreateAct(ctx, task, act, actOrderRules, actStore, actStoreSku)
|
||||||
|
} else if model.IsSyncStatusNeedUpdate(act.SyncStatus) {
|
||||||
|
if act.Status == model.ActStatusCanceled {
|
||||||
|
err = handler.CancelAct(ctx, task, act, actStore, actStoreSku)
|
||||||
|
} else {
|
||||||
|
// actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update := splitActStore(actStore)
|
||||||
|
// err = handler.UpdateAct(ctx, task, act, actOrderRules, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update, actStoreSku)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
actMap := &model.ActMap{}
|
||||||
|
actMap.ID = act.MapID
|
||||||
|
dao.UpdateEntityLogically(db, actMap, map[string]interface{}{
|
||||||
|
model.FieldSyncStatus: 0,
|
||||||
|
model.FieldVendorActID: act.VendorActID,
|
||||||
|
}, ctx.GetUserName(), nil)
|
||||||
|
for _, v := range actStore {
|
||||||
|
storeMap := model.ActStoreMap{}
|
||||||
|
storeMap.ID = v.MapID
|
||||||
|
dao.UpdateEntityLogically(db, storeMap, map[string]interface{}{
|
||||||
|
model.FieldSyncStatus: 0,
|
||||||
|
model.FieldVendorActID: v.VendorActID,
|
||||||
|
}, ctx.GetUserName(), nil)
|
||||||
|
}
|
||||||
|
for _, v := range actStoreSku {
|
||||||
|
storeSkuMap := model.ActStoreSkuMap{}
|
||||||
|
storeSkuMap.ID = v.MapID
|
||||||
|
dao.UpdateEntityLogically(db, storeSkuMap, map[string]interface{}{
|
||||||
|
model.FieldSyncStatus: 0,
|
||||||
|
model.FieldVendorActID: v.VendorActID,
|
||||||
|
}, ctx.GetUserName(), nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}, realVendorIDs)
|
||||||
|
tasksch.ManageTask(task).Run()
|
||||||
|
_, err = task.GetResult(0)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func splitActStore(actStore []*model.ActStore2) (actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2) {
|
||||||
|
for _, v := range actStore {
|
||||||
|
if model.IsSyncStatusNeedDelete(v.SyncStatus) {
|
||||||
|
if !dao.IsVendorThingIDEmpty(v.VendorActID) {
|
||||||
|
actStoreMap2Remove = append(actStoreMap2Remove, v)
|
||||||
|
}
|
||||||
|
} else if model.IsSyncStatusNeedCreate(v.SyncStatus) {
|
||||||
|
actStoreMap2Add = append(actStoreMap2Add, v)
|
||||||
|
} else if model.IsSyncStatusNeedUpdate(v.SyncStatus) {
|
||||||
|
actStoreMap2Update = append(actStoreMap2Update, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update
|
||||||
|
}
|
||||||
68
business/jxstore/act/act_test.go
Normal file
68
business/jxstore/act/act_test.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
package act
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals/testinit"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
|
||||||
|
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai"
|
||||||
|
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd"
|
||||||
|
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
testinit.Init()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInitDb(t *testing.T) {
|
||||||
|
dao.ExecuteSQL(dao.GetDB(), `
|
||||||
|
DROP TABLE IF EXISTS act,act_map, act_order_rule, act_store_map, act_store_sku, act_store_sku_map;
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateAct(t *testing.T) {
|
||||||
|
actID, err := CreateAct(jxcontext.AdminCtx, &model.Act{
|
||||||
|
Name: "测试活动2",
|
||||||
|
PricePercentage: 80,
|
||||||
|
}, []int{0, 1, 3}, nil, []*ActStoreSkuParam{
|
||||||
|
&ActStoreSkuParam{
|
||||||
|
StoreID: 100119,
|
||||||
|
SkuID: 30828,
|
||||||
|
},
|
||||||
|
&ActStoreSkuParam{
|
||||||
|
StoreID: 100119,
|
||||||
|
SkuID: 30827,
|
||||||
|
},
|
||||||
|
&ActStoreSkuParam{
|
||||||
|
StoreID: 100118,
|
||||||
|
SkuID: 30592,
|
||||||
|
},
|
||||||
|
&ActStoreSkuParam{
|
||||||
|
StoreID: 100118,
|
||||||
|
SkuID: 30565,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
globals.SugarLogger.Debug(actID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCancelAct(t *testing.T) {
|
||||||
|
err := CancelAct(jxcontext.AdminCtx, 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSyncAct(t *testing.T) {
|
||||||
|
err := SyncAct(jxcontext.AdminCtx, 1, nil, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,7 +20,12 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
serviceInfo map[string]interface{}
|
serviceInfo map[string]interface{}
|
||||||
|
allowUpdatePlaceFieldsMap = map[string]bool{
|
||||||
|
"name": true,
|
||||||
|
"enabled": true,
|
||||||
|
"mtpsPrice": true,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitServiceInfo(version string, buildTime time.Time, gitCommit string) {
|
func InitServiceInfo(version string, buildTime time.Time, gitCommit string) {
|
||||||
@@ -55,6 +60,8 @@ func InitServiceInfo(version string, buildTime time.Time, gitCommit string) {
|
|||||||
"shopChineseNames": model.ShopChineseNames,
|
"shopChineseNames": model.ShopChineseNames,
|
||||||
"printerVendorInfo": model.PrinterVendorInfo,
|
"printerVendorInfo": model.PrinterVendorInfo,
|
||||||
"purchaseVendorInfo": model.PurchaseVendorInfo,
|
"purchaseVendorInfo": model.PurchaseVendorInfo,
|
||||||
|
"afsReasonTypeName": model.AfsReasonTypeName,
|
||||||
|
"afsAppealTypeName": model.AfsAppealTypeName,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
Init()
|
Init()
|
||||||
@@ -124,12 +131,18 @@ func UpdatePlaces(ctx *jxcontext.Context, places []map[string]interface{}, userN
|
|||||||
if len(places) == 0 {
|
if len(places) == 0 {
|
||||||
return 0, ErrMissingInput
|
return 0, ErrMissingInput
|
||||||
}
|
}
|
||||||
|
updateFields := []string{}
|
||||||
|
for k := range places[0] {
|
||||||
|
if allowUpdatePlaceFieldsMap[k] {
|
||||||
|
updateFields = append(updateFields, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
for _, place := range places {
|
for _, place := range places {
|
||||||
if place["code"] == nil {
|
if place["code"] == nil {
|
||||||
return 0, ErrMissingInput
|
return 0, ErrMissingInput
|
||||||
}
|
}
|
||||||
placeid := &model.Place{}
|
placeid := &model.Place{}
|
||||||
valid := dao.NormalMakeMapByFieldList(place, []string{"jdCode", "enabled", "mtpsPrice"}, userName)
|
valid := dao.NormalMakeMapByFieldList(place, updateFields, userName)
|
||||||
if num, err = dao.UpdateEntityLogically(nil, placeid, valid, userName, utils.Params2Map("Code", place["code"])); err != nil {
|
if num, err = dao.UpdateEntityLogically(nil, placeid, valid, userName, utils.Params2Map("Code", place["code"])); err != nil {
|
||||||
return num, err
|
return num, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,12 @@ import (
|
|||||||
"git.rosy.net.cn/jx-callback/globals"
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type MessageStatusExt struct {
|
||||||
|
model.MessageStatus
|
||||||
|
|
||||||
|
Title string `json:"title"`
|
||||||
|
}
|
||||||
|
|
||||||
func SendStoreMessage(ctx *jxcontext.Context, title, content string, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
func SendStoreMessage(ctx *jxcontext.Context, title, content string, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
dao.Begin(db)
|
dao.Begin(db)
|
||||||
@@ -128,8 +134,11 @@ func GetStoreMessages(ctx *jxcontext.Context, msgIDs, storeIDs, types []int, fro
|
|||||||
|
|
||||||
func GetStoreMessageStatuses(ctx *jxcontext.Context, msgIDs, storeIDs []int, fromReadCount, toReadCount int, fromTime, toTime time.Time, keyword string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
|
func GetStoreMessageStatuses(ctx *jxcontext.Context, msgIDs, storeIDs []int, fromReadCount, toReadCount int, fromTime, toTime time.Time, keyword string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
|
||||||
sql := `
|
sql := `
|
||||||
SELECT SQL_CALC_FOUND_ROWS t1.*
|
SELECT SQL_CALC_FOUND_ROWS
|
||||||
|
t1.*,
|
||||||
|
t2.title
|
||||||
FROM message_status t1
|
FROM message_status t1
|
||||||
|
JOIN message t2 ON t2.id = t1.message_id
|
||||||
WHERE 1 = 1
|
WHERE 1 = 1
|
||||||
`
|
`
|
||||||
sqlParams := []interface{}{}
|
sqlParams := []interface{}{}
|
||||||
@@ -167,7 +176,7 @@ func GetStoreMessageStatuses(ctx *jxcontext.Context, msgIDs, storeIDs []int, fro
|
|||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
dao.Begin(db)
|
dao.Begin(db)
|
||||||
defer dao.Commit(db)
|
defer dao.Commit(db)
|
||||||
var msgStatusList []*model.MessageStatus
|
var msgStatusList []*MessageStatusExt
|
||||||
// globals.SugarLogger.Debug(sql)
|
// globals.SugarLogger.Debug(sql)
|
||||||
// globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false))
|
// globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false))
|
||||||
if err = dao.GetRows(db, &msgStatusList, sql, sqlParams...); err == nil {
|
if err = dao.GetRows(db, &msgStatusList, sql, sqlParams...); err == nil {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi/ebaiapi"
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
@@ -14,6 +15,7 @@ import (
|
|||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SkuNamesInfo struct {
|
type SkuNamesInfo struct {
|
||||||
@@ -25,6 +27,19 @@ var (
|
|||||||
ErrInputCatsDoesntMatch = errors.New("输入的类别列表不合法,需要输入一个父ID下的所有子类别")
|
ErrInputCatsDoesntMatch = errors.New("输入的类别列表不合法,需要输入一个父ID下的所有子类别")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ebaiUploadRTFShopID string // 饿百找一个店用于调用SkuUploadRTF
|
||||||
|
)
|
||||||
|
|
||||||
|
func getAndSetEbaiUploadRTFShopID() (shopID string) {
|
||||||
|
if ebaiUploadRTFShopID == "" {
|
||||||
|
if storeDetail, err := dao.GetStoreDetail(dao.GetDB(), 0, model.VendorIDEBAI); err == nil {
|
||||||
|
ebaiUploadRTFShopID = utils.Int2Str(storeDetail.Store.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ebaiUploadRTFShopID
|
||||||
|
}
|
||||||
|
|
||||||
// parentID 为-1表示所有
|
// parentID 为-1表示所有
|
||||||
func GetVendorCategories(ctx *jxcontext.Context, vendorID int, parentID string) (vendorCats []*model.SkuVendorCategory, err error) {
|
func GetVendorCategories(ctx *jxcontext.Context, vendorID int, parentID string) (vendorCats []*model.SkuVendorCategory, err error) {
|
||||||
cond := map[string]interface{}{
|
cond := map[string]interface{}{
|
||||||
@@ -72,7 +87,7 @@ func AddCategory(ctx *jxcontext.Context, cat *model.SkuCategory, userName string
|
|||||||
|
|
||||||
dao.WrapAddIDCULDEntity(cat, userName)
|
dao.WrapAddIDCULDEntity(cat, userName)
|
||||||
cat.JdSyncStatus = model.SyncFlagNewMask
|
cat.JdSyncStatus = model.SyncFlagNewMask
|
||||||
cat.JdID = 0 //jxutils.GenFakeID()
|
cat.JdID = 0
|
||||||
cat.Name = strings.Trim(cat.Name, " ")
|
cat.Name = strings.Trim(cat.Name, " ")
|
||||||
if cat.Seq <= 0 {
|
if cat.Seq <= 0 {
|
||||||
var maxSeq struct {
|
var maxSeq struct {
|
||||||
@@ -93,19 +108,83 @@ func AddCategory(ctx *jxcontext.Context, cat *model.SkuCategory, userName string
|
|||||||
func UpdateCategory(ctx *jxcontext.Context, categoryID int, payload map[string]interface{}, userName string) (num int64, err error) {
|
func UpdateCategory(ctx *jxcontext.Context, categoryID int, payload map[string]interface{}, userName string) (num int64, err error) {
|
||||||
cat := &model.SkuCategory{}
|
cat := &model.SkuCategory{}
|
||||||
cat.ID = categoryID
|
cat.ID = categoryID
|
||||||
valid := dao.NormalMakeMapByStructObject(payload, cat, userName)
|
db := dao.GetDB()
|
||||||
|
if err = dao.GetEntity(db, cat); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
valid := dao.StrictMakeMapByStructObject(payload, cat, userName)
|
||||||
if len(valid) > 0 {
|
if len(valid) > 0 {
|
||||||
|
syncStatus := 0
|
||||||
if valid["name"] != nil {
|
if valid["name"] != nil {
|
||||||
valid["name"] = strings.Trim(valid["name"].(string), " ")
|
valid["name"] = strings.Trim(valid["name"].(string), " ")
|
||||||
|
syncStatus = model.SyncFlagModifiedMask
|
||||||
}
|
}
|
||||||
db := dao.GetDB()
|
if num, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, cat, valid, userName, nil, model.FieldJdSyncStatus, syncStatus); err == nil {
|
||||||
if num, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, cat, valid, userName, nil, model.FieldJdSyncStatus, model.SyncFlagModifiedMask); err == nil {
|
SetStoreCategorySyncStatus2(db, nil, []int{categoryID}, model.SyncFlagModifiedMask)
|
||||||
|
if valid["jdCategoryID"] != nil || valid["ebaiCategoryID"] != nil || valid["mtwmCategoryID"] != nil ||
|
||||||
|
valid["jdPricePercentage"] != nil || valid["ebaiPricePercentage"] != nil || valid["mtwmPricePercentage"] != nil {
|
||||||
|
if skuList, err2 := dao.GetSkuByCats(db, []int{categoryID}); err2 == nil && len(skuList) > 0 {
|
||||||
|
var skuIDs []int
|
||||||
|
for _, sku := range skuList {
|
||||||
|
skuIDs = append(skuIDs, sku.ID)
|
||||||
|
}
|
||||||
|
if valid["jdCategoryID"] != nil {
|
||||||
|
dao.SetSkuSyncStatus(db, model.VendorIDJD, skuIDs, model.SyncFlagModifiedMask)
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo 如下逻辑,在不同平台同时改pricePercentage与平台分类映射时,会不必要的打上多余的标记
|
||||||
|
var vendorIDs []int
|
||||||
|
syncStatus := model.SyncFlagModifiedMask
|
||||||
|
if valid["jdPricePercentage"] != nil {
|
||||||
|
vendorIDs = append(vendorIDs, model.VendorIDJD)
|
||||||
|
syncStatus |= model.SyncFlagPriceMask
|
||||||
|
}
|
||||||
|
|
||||||
|
if valid["ebaiPricePercentage"] != nil {
|
||||||
|
vendorIDs = append(vendorIDs, model.VendorIDEBAI)
|
||||||
|
syncStatus |= model.SyncFlagPriceMask
|
||||||
|
} else if valid["ebaiCategoryID"] != nil {
|
||||||
|
vendorIDs = append(vendorIDs, model.VendorIDEBAI)
|
||||||
|
}
|
||||||
|
|
||||||
|
if valid["mtwmPricePercentage"] != nil {
|
||||||
|
vendorIDs = append(vendorIDs, model.VendorIDMTWM)
|
||||||
|
syncStatus |= model.SyncFlagPriceMask
|
||||||
|
} else if valid["mtwmCategoryID"] != nil {
|
||||||
|
vendorIDs = append(vendorIDs, model.VendorIDMTWM)
|
||||||
|
}
|
||||||
|
if len(vendorIDs) > 0 {
|
||||||
|
SetStoreSkuSyncStatus2(db, nil, vendorIDs, skuIDs, syncStatus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_, err = CurVendorSync.SyncCategory(ctx, db, categoryID, false, userName)
|
_, err = CurVendorSync.SyncCategory(ctx, db, categoryID, false, userName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return num, err
|
return num, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetStoreCategorySyncStatus2(db *dao.DaoDB, storeIDs []int, catIDs []int, syncStatus int) (num int64, err error) {
|
||||||
|
dao.Begin(db)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil || err != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
if r != nil {
|
||||||
|
panic(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
for _, vendorID := range CurVendorSync.SingleStoreVendorIDs {
|
||||||
|
num2, err2 := dao.SetStoreCategorySyncStatus(db, vendorID, storeIDs, catIDs, syncStatus)
|
||||||
|
if err = err2; err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
num += num2
|
||||||
|
}
|
||||||
|
dao.Commit(db)
|
||||||
|
return num, nil
|
||||||
|
}
|
||||||
|
|
||||||
func ReorderCategories(ctx *jxcontext.Context, parentID int, categoryIDs []int, userName string) (err error) {
|
func ReorderCategories(ctx *jxcontext.Context, parentID int, categoryIDs []int, userName string) (err error) {
|
||||||
var cats []*model.SkuCategory
|
var cats []*model.SkuCategory
|
||||||
parentCat := &model.SkuCategory{}
|
parentCat := &model.SkuCategory{}
|
||||||
@@ -211,8 +290,8 @@ func GetSkuNames(ctx *jxcontext.Context, keyword string, isBySku bool, params ma
|
|||||||
sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike)
|
sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike)
|
||||||
|
|
||||||
if keywordInt64, err2 := strconv.ParseInt(keyword, 10, 64); err2 == nil {
|
if keywordInt64, err2 := strconv.ParseInt(keyword, 10, 64); err2 == nil {
|
||||||
sql += " OR t2.jd_id = ? OR t1.id = ? OR t1.category_id = ?"
|
sql += " OR t1.id = ? OR t2.id = ? OR t2.jd_id = ? OR t1.category_id = ?"
|
||||||
sqlParams = append(sqlParams, keywordInt64, keywordInt64, keywordInt64)
|
sqlParams = append(sqlParams, keywordInt64, keywordInt64, keywordInt64, keywordInt64)
|
||||||
}
|
}
|
||||||
sql += ")"
|
sql += ")"
|
||||||
}
|
}
|
||||||
@@ -340,6 +419,7 @@ func GetSkuNames(ctx *jxcontext.Context, keyword string, isBySku bool, params ma
|
|||||||
t1.name,
|
t1.name,
|
||||||
t1.brand_id,
|
t1.brand_id,
|
||||||
t1.category_id,
|
t1.category_id,
|
||||||
|
t1.jd_category_id,
|
||||||
t1.is_global,
|
t1.is_global,
|
||||||
t1.unit,
|
t1.unit,
|
||||||
t1.price,
|
t1.price,
|
||||||
@@ -348,6 +428,7 @@ func GetSkuNames(ctx *jxcontext.Context, keyword string, isBySku bool, params ma
|
|||||||
t1.status,
|
t1.status,
|
||||||
t1.is_spu,
|
t1.is_spu,
|
||||||
t1.img_hash_code,
|
t1.img_hash_code,
|
||||||
|
t1.desc_img,
|
||||||
t1.upc`
|
t1.upc`
|
||||||
if isBySku {
|
if isBySku {
|
||||||
sql += `,
|
sql += `,
|
||||||
@@ -365,6 +446,7 @@ func GetSkuNames(ctx *jxcontext.Context, keyword string, isBySku bool, params ma
|
|||||||
t1.name,
|
t1.name,
|
||||||
t1.brand_id,
|
t1.brand_id,
|
||||||
t1.category_id,
|
t1.category_id,
|
||||||
|
t1.jd_category_id,
|
||||||
t1.is_global,
|
t1.is_global,
|
||||||
t1.unit,
|
t1.unit,
|
||||||
t1.price,
|
t1.price,
|
||||||
@@ -373,6 +455,7 @@ func GetSkuNames(ctx *jxcontext.Context, keyword string, isBySku bool, params ma
|
|||||||
t1.status,
|
t1.status,
|
||||||
t1.is_spu,
|
t1.is_spu,
|
||||||
t1.img_hash_code,
|
t1.img_hash_code,
|
||||||
|
t1.desc_img,
|
||||||
t1.upc,
|
t1.upc,
|
||||||
t1.jd_id,
|
t1.jd_id,
|
||||||
t1.jd_sync_status,
|
t1.jd_sync_status,
|
||||||
@@ -463,30 +546,39 @@ func AddSkuName(ctx *jxcontext.Context, skuNameExt *model.SkuNameExt, userName s
|
|||||||
skuNameExt.SpecQuality = skuNameExt.Skus[0].SpecQuality
|
skuNameExt.SpecQuality = skuNameExt.Skus[0].SpecQuality
|
||||||
skuNameExt.SpecUnit = skuNameExt.Skus[0].SpecUnit
|
skuNameExt.SpecUnit = skuNameExt.Skus[0].SpecUnit
|
||||||
}
|
}
|
||||||
imgContent, imgMD5, err := jxutils.DownloadFileByURL(skuNameExt.Img)
|
|
||||||
if err != nil {
|
|
||||||
dao.Rollback(db)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if skuNameExt.ImgHashCode == "" {
|
|
||||||
skuNameExt.ImgHashCode = imgMD5
|
|
||||||
} else if skuNameExt.ImgHashCode != imgMD5 {
|
|
||||||
dao.Rollback(db)
|
|
||||||
return nil, errors.New("图片HASH值不同")
|
|
||||||
}
|
|
||||||
imgHintMap, err := UploadImg2Platforms(ctx, nil, skuNameExt.Img, imgContent, "")
|
|
||||||
if err != nil {
|
|
||||||
dao.Rollback(db)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
skuNameExt.ImgWeimob = imgHintMap[model.VendorIDWSC]
|
|
||||||
skuNameExt.ImgEbai = imgHintMap[model.VendorIDEBAI]
|
|
||||||
|
|
||||||
|
if globals.EnableStoreWrite {
|
||||||
|
imgContent, imgMD5, err := jxutils.DownloadFileByURL(skuNameExt.Img)
|
||||||
|
if err != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if skuNameExt.ImgHashCode == "" {
|
||||||
|
skuNameExt.ImgHashCode = imgMD5
|
||||||
|
} else if skuNameExt.ImgHashCode != imgMD5 {
|
||||||
|
dao.Rollback(db)
|
||||||
|
return nil, errors.New("图片HASH值不同")
|
||||||
|
}
|
||||||
|
imgHintMap, err := UploadImg2Platforms(ctx, nil, skuNameExt.Img, imgContent, "")
|
||||||
|
if err != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
skuNameExt.ImgWeimob = imgHintMap[model.VendorIDWSC]
|
||||||
|
skuNameExt.ImgEbai = imgHintMap[model.VendorIDEBAI]
|
||||||
|
|
||||||
|
if skuNameExt.DescImg != "" && getAndSetEbaiUploadRTFShopID() != "" {
|
||||||
|
skuNameExt.DescImgEbai, err = api.EbaiAPI.SkuUploadRTF(getAndSetEbaiUploadRTFShopID(), ebaiapi.BuildRFTFromImgs(skuNameExt.DescImg))
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
if err = dao.CreateEntity(db, &skuNameExt.SkuName); err != nil {
|
if err = dao.CreateEntity(db, &skuNameExt.SkuName); err != nil {
|
||||||
dao.Rollback(db)
|
dao.Rollback(db)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// beginJDID := jxutils.GenFakeID()
|
|
||||||
for _, sku := range skuNameExt.Skus {
|
for _, sku := range skuNameExt.Skus {
|
||||||
dao.WrapAddIDCULDEntity(sku, userName)
|
dao.WrapAddIDCULDEntity(sku, userName)
|
||||||
sku.NameID = skuNameExt.ID
|
sku.NameID = skuNameExt.ID
|
||||||
@@ -496,7 +588,6 @@ func AddSkuName(ctx *jxcontext.Context, skuNameExt *model.SkuNameExt, userName s
|
|||||||
dao.Rollback(db)
|
dao.Rollback(db)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// beginJDID++
|
|
||||||
}
|
}
|
||||||
for _, placeCode := range skuNameExt.Places {
|
for _, placeCode := range skuNameExt.Places {
|
||||||
placeBind := &model.SkuNamePlaceBind{}
|
placeBind := &model.SkuNamePlaceBind{}
|
||||||
@@ -528,9 +619,12 @@ func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interf
|
|||||||
if err = dao.GetEntity(db, skuName); err != nil {
|
if err = dao.GetEntity(db, skuName); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
if _, ok := payload["isSpu"]; ok {
|
delete(payload, "isSpu")
|
||||||
delete(payload, "isSpu")
|
delete(payload, "ImgHashCode")
|
||||||
}
|
delete(payload, "ImgWeimob")
|
||||||
|
delete(payload, "ImgEbai")
|
||||||
|
delete(payload, "descImgEbai")
|
||||||
|
|
||||||
valid := dao.StrictMakeMapByStructObject(payload, skuName, userName)
|
valid := dao.StrictMakeMapByStructObject(payload, skuName, userName)
|
||||||
valid = utils.RemoveGeneralMapKeys(valid, model.FieldSpecQuality, model.FieldSpecUnit)
|
valid = utils.RemoveGeneralMapKeys(valid, model.FieldSpecQuality, model.FieldSpecUnit)
|
||||||
_, hasPlaces := payload["places"]
|
_, hasPlaces := payload["places"]
|
||||||
@@ -550,19 +644,35 @@ func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interf
|
|||||||
}
|
}
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
if valid["img"] != nil {
|
if globals.EnableStoreWrite {
|
||||||
imgContent, imgMD5, err2 := jxutils.DownloadFileByURL(valid["img"].(string))
|
if valid["img"] != nil {
|
||||||
if err = err2; err != nil {
|
imgContent, imgMD5, err2 := jxutils.DownloadFileByURL(valid["img"].(string))
|
||||||
return 0, err
|
if err = err2; err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
valid["ImgHashCode"] = imgMD5
|
||||||
|
imgHintMap, err := UploadImg2Platforms(ctx, nil, valid["img"].(string), imgContent, "")
|
||||||
|
if err != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
valid["ImgWeimob"] = imgHintMap[model.VendorIDWSC]
|
||||||
|
valid["ImgEbai"] = imgHintMap[model.VendorIDEBAI]
|
||||||
}
|
}
|
||||||
valid["ImgHashCode"] = imgMD5
|
if valid["descImg"] != nil {
|
||||||
imgHintMap, err := UploadImg2Platforms(ctx, nil, valid["img"].(string), imgContent, "")
|
descImg := valid["descImg"].(string)
|
||||||
if err != nil {
|
if descImg != "" {
|
||||||
dao.Rollback(db)
|
if getAndSetEbaiUploadRTFShopID() != "" {
|
||||||
return 0, err
|
valid["descImgEbai"], err = api.EbaiAPI.SkuUploadRTF(getAndSetEbaiUploadRTFShopID(), ebaiapi.BuildRFTFromImgs(descImg))
|
||||||
|
if err != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
valid["descImgEbai"] = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
valid["ImgWeimob"] = imgHintMap[model.VendorIDWSC]
|
|
||||||
valid["ImgEbai"] = imgHintMap[model.VendorIDEBAI]
|
|
||||||
}
|
}
|
||||||
if num, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, skuName, valid, userName, nil, model.FieldJdSyncStatus, model.SyncFlagModifiedMask); err == nil && num == 1 {
|
if num, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, skuName, valid, userName, nil, model.FieldJdSyncStatus, model.SyncFlagModifiedMask); err == nil && num == 1 {
|
||||||
if utils.Interface2Int64WithDefault(payload["isGlobal"], 0) == 0 && payload["places"] != nil {
|
if utils.Interface2Int64WithDefault(payload["isGlobal"], 0) == 0 && payload["places"] != nil {
|
||||||
@@ -588,8 +698,14 @@ func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interf
|
|||||||
model.FieldNameID: nameID,
|
model.FieldNameID: nameID,
|
||||||
}, model.FieldJdSyncStatus, model.SyncFlagModifiedMask)
|
}, model.FieldJdSyncStatus, model.SyncFlagModifiedMask)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
dao.Commit(db)
|
skuIDs, err2 := dao.GetSkuIDByNames(db, []int{nameID})
|
||||||
_, err = CurVendorSync.SyncSku(ctx, db, nameID, -1, false, false, userName)
|
if err = err2; err == nil && len(skuIDs) > 0 {
|
||||||
|
_, err = SetStoreSkuSyncStatus2(db, nil, CurVendorSync.SingleStoreVendorIDs, skuIDs, model.SyncFlagModifiedMask)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
dao.Commit(db)
|
||||||
|
_, err = CurVendorSync.SyncSku(ctx, db, nameID, -1, false, false, userName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -597,6 +713,27 @@ func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interf
|
|||||||
return num, err
|
return num, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetStoreSkuSyncStatus2(db *dao.DaoDB, storeIDs []int, vendorIDs, skuIDs []int, syncStatus int) (num int64, err error) {
|
||||||
|
dao.Begin(db)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil || err != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
if r != nil {
|
||||||
|
panic(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
for _, vendorID := range vendorIDs {
|
||||||
|
num2, err2 := dao.SetStoreSkuSyncStatus(db, vendorID, storeIDs, skuIDs, syncStatus)
|
||||||
|
if err = err2; err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
num += num2
|
||||||
|
}
|
||||||
|
dao.Commit(db)
|
||||||
|
return num, nil
|
||||||
|
}
|
||||||
|
|
||||||
func DeleteSkuName(ctx *jxcontext.Context, nameID int, userName string) (num int64, err error) {
|
func DeleteSkuName(ctx *jxcontext.Context, nameID int, userName string) (num int64, err error) {
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
dao.Begin(db)
|
dao.Begin(db)
|
||||||
@@ -647,7 +784,7 @@ func AddSku(ctx *jxcontext.Context, nameID int, sku *model.Sku, userName string)
|
|||||||
dao.WrapAddIDCULDEntity(sku, userName)
|
dao.WrapAddIDCULDEntity(sku, userName)
|
||||||
sku.JdSyncStatus = model.SyncFlagNewMask
|
sku.JdSyncStatus = model.SyncFlagNewMask
|
||||||
sku.NameID = nameID
|
sku.NameID = nameID
|
||||||
sku.JdID = 0 //jxutils.GenFakeID()
|
sku.JdID = 0
|
||||||
if err = dao.CreateEntity(db, sku); err == nil {
|
if err = dao.CreateEntity(db, sku); err == nil {
|
||||||
result, err2 := GetSkuNames(ctx, "", false, utils.Params2Map("skuID", sku.ID), 0, 0)
|
result, err2 := GetSkuNames(ctx, "", false, utils.Params2Map("skuID", sku.ID), 0, 0)
|
||||||
if err = err2; err == nil {
|
if err = err2; err == nil {
|
||||||
@@ -691,8 +828,10 @@ func UpdateSku(ctx *jxcontext.Context, skuID int, payload map[string]interface{}
|
|||||||
`, utils.DefaultTimeValue, skuID, model.SpecialUnit); err != nil {
|
`, utils.DefaultTimeValue, skuID, model.SpecialUnit); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
dao.Commit(db)
|
if _, err = SetStoreSkuSyncStatus2(db, nil, CurVendorSync.SingleStoreVendorIDs, []int{skuID}, model.SyncFlagModifiedMask); err == nil {
|
||||||
_, err = CurVendorSync.SyncSku(ctx, db, -1, sku.ID, false, false, userName)
|
dao.Commit(db)
|
||||||
|
_, err = CurVendorSync.SyncSku(ctx, db, -1, sku.ID, false, false, userName)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
err = ErrEntityNotExist
|
err = ErrEntityNotExist
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,10 @@ import (
|
|||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/dadaapi"
|
"git.rosy.net.cn/baseapi/platformapi/dadaapi"
|
||||||
"git.rosy.net.cn/baseapi/platformapi/feieapi"
|
"git.rosy.net.cn/baseapi/platformapi/feieapi"
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
|
"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/jxcontext"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/netprinter"
|
"git.rosy.net.cn/jx-callback/business/jxutils/netprinter"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||||
@@ -19,6 +21,7 @@ import (
|
|||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
"git.rosy.net.cn/jx-callback/business/model/legacymodel"
|
"git.rosy.net.cn/jx-callback/business/model/legacymodel"
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner/purchase/ebai"
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
)
|
)
|
||||||
@@ -59,6 +62,37 @@ var (
|
|||||||
ErrCanNotFindVendor = errors.New("vendorID参数不合法")
|
ErrCanNotFindVendor = errors.New("vendorID参数不合法")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
dadaDistrictMap = map[string]string{
|
||||||
|
"苏州工业园区": "工业园区",
|
||||||
|
"郫都区": "郫县",
|
||||||
|
"管城回族区": "管城区",
|
||||||
|
"昆山市": "1",
|
||||||
|
"常熟市": "1",
|
||||||
|
"太仓市": "1",
|
||||||
|
"虞山街道": "虞山镇",
|
||||||
|
"常福街道": "虞山镇",
|
||||||
|
}
|
||||||
|
|
||||||
|
storeKeyPropertyMap = map[string]int{
|
||||||
|
"name": 1,
|
||||||
|
"cityCode": 1,
|
||||||
|
"districtCode": 1,
|
||||||
|
"address": 1,
|
||||||
|
"tel1": 1,
|
||||||
|
"tel2": 1,
|
||||||
|
"openTime1": 1,
|
||||||
|
"closeTime1": 1,
|
||||||
|
"openTime2": 1,
|
||||||
|
"closeTime2": 1,
|
||||||
|
"lng": 1,
|
||||||
|
"lat": 1,
|
||||||
|
"deliveryRangeType": 1,
|
||||||
|
"deliveryRange": 1,
|
||||||
|
"status": 1,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// todo 门店绑定信息可以考虑以数组形式返回,而不是现在这样
|
// todo 门店绑定信息可以考虑以数组形式返回,而不是现在这样
|
||||||
func GetStores(ctx *jxcontext.Context, keyword string, params map[string]interface{}, offset, pageSize int) (retVal *StoresInfo, err error) {
|
func GetStores(ctx *jxcontext.Context, keyword string, params map[string]interface{}, offset, pageSize int) (retVal *StoresInfo, err error) {
|
||||||
sql := `
|
sql := `
|
||||||
@@ -92,17 +126,46 @@ func GetStores(ctx *jxcontext.Context, keyword string, params map[string]interfa
|
|||||||
t1.printer_sn,
|
t1.printer_sn,
|
||||||
t1.printer_key,
|
t1.printer_key,
|
||||||
t1.printer_vendor_id,
|
t1.printer_vendor_id,
|
||||||
|
|
||||||
|
t1.licence_type,
|
||||||
|
t1.licence_corp_name,
|
||||||
|
t1.licence_owner_name,
|
||||||
|
t1.licence_address,
|
||||||
|
t1.licence_valid,
|
||||||
|
t1.licence_expire,
|
||||||
|
t1.id_name,
|
||||||
|
t1.id_code,
|
||||||
|
t1.id_valid,
|
||||||
|
t1.id_expire,
|
||||||
|
t1.licence2_image,
|
||||||
|
t1.licence2_code,
|
||||||
|
t1.licence2_valid,
|
||||||
|
t1.licence2_expire,
|
||||||
|
t1.market_man_name,
|
||||||
|
t1.market_man_phone,
|
||||||
|
t1.jx_brand_fee_factor,
|
||||||
|
t1.market_add_fee_factor,
|
||||||
|
t1.payee_name,
|
||||||
|
t1.payee_account_no,
|
||||||
|
t1.payee_bank_branch_name,
|
||||||
|
t1.payee_bank_name,
|
||||||
|
|
||||||
|
t1.pay_percentage,
|
||||||
|
t1.operator_name,
|
||||||
|
t1.operator_phone,
|
||||||
|
|
||||||
city.name city_name,
|
city.name city_name,
|
||||||
district.name district_name,
|
district.name district_name,
|
||||||
CONCAT("[", GROUP_CONCAT(DISTINCT CONCAT('{"vendorStoreID":"', m1.vendor_store_id, '", "vendorID":', m1.vendor_id,
|
CONCAT('[', GROUP_CONCAT(DISTINCT CONCAT('{"vendorStoreID":"', m1.vendor_store_id, '", "vendorID":', m1.vendor_id,
|
||||||
', "status":', m1.status, ', "pricePercentage":', m1.price_percentage, ', "vendorStoreName":"',
|
', "status":', m1.status, ', "pricePercentage":', m1.price_percentage, ', "vendorStoreName":"',
|
||||||
CASE m1.vendor_id
|
CASE m1.vendor_id
|
||||||
WHEN 0 THEN IF(jd.name IS NULL, '', jd.name)
|
WHEN 0 THEN IF(jd.name IS NULL, '', jd.name)
|
||||||
WHEN 3 THEN IF(eb.col_name IS NULL, '', eb.col_name)
|
WHEN 3 THEN IF(eb.col_name IS NULL, '', eb.col_name)
|
||||||
ELSE ''
|
ELSE ''
|
||||||
END,
|
END,
|
||||||
'"}')), ']') store_map_str,
|
'", "isSync":', m1.is_sync, '}')), ']') store_map_str,
|
||||||
CONCAT("[", GROUP_CONCAT(DISTINCT CONCAT('{"vendorStoreID":"', m2.vendor_store_id, '", "vendorID":', m2.vendor_id, ', "status":', m2.status, "}")), "]") courier_map_str
|
CONCAT('[', GROUP_CONCAT(DISTINCT CONCAT('{"vendorStoreID":"', m2.vendor_store_id, '", "vendorID":', m2.vendor_id,
|
||||||
|
', "status":', m2.status, '}')), ']') courier_map_str
|
||||||
FROM store t1
|
FROM store t1
|
||||||
LEFT JOIN place city ON t1.city_code = city.code AND city.level = 2
|
LEFT JOIN place city ON t1.city_code = city.code AND city.level = 2
|
||||||
LEFT JOIN place district ON t1.district_code = district.code AND district.level = 3
|
LEFT JOIN place district ON t1.district_code = district.code AND district.level = 3
|
||||||
@@ -228,7 +291,7 @@ func GetStores(ctx *jxcontext.Context, keyword string, params map[string]interfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
sql += sqlWhere + `
|
sql += sqlWhere + `
|
||||||
GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
|
GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53
|
||||||
ORDER BY t1.id DESC
|
ORDER BY t1.id DESC
|
||||||
LIMIT ? OFFSET ?`
|
LIMIT ? OFFSET ?`
|
||||||
pageSize = jxutils.FormalizePageSize(pageSize)
|
pageSize = jxutils.FormalizePageSize(pageSize)
|
||||||
@@ -249,8 +312,9 @@ func GetStores(ctx *jxcontext.Context, keyword string, params map[string]interfa
|
|||||||
// globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false))
|
// globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false))
|
||||||
// globals.SugarLogger.Debug(sql)
|
// globals.SugarLogger.Debug(sql)
|
||||||
var storeList []*StoreExt
|
var storeList []*StoreExt
|
||||||
|
mapLimit := false
|
||||||
if err = dao.GetRows(db, &storeList, sql, sqlParams...); err == nil {
|
if err = dao.GetRows(db, &storeList, sql, sqlParams...); err == nil {
|
||||||
mapLimit := false
|
// globals.SugarLogger.Debugf("GetStores, len(storeList):%d", len(storeList))
|
||||||
var (
|
var (
|
||||||
mapLatitude, mapLongitude float64
|
mapLatitude, mapLongitude float64
|
||||||
mapRadius int
|
mapRadius int
|
||||||
@@ -289,8 +353,9 @@ func GetStores(ctx *jxcontext.Context, keyword string, params map[string]interfa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dao.Commit(db)
|
dao.Commit(db)
|
||||||
|
if mapLimit {
|
||||||
retVal.MapCenterLng, retVal.MapCenterLat = getMapCenter(retVal.Stores)
|
retVal.MapCenterLng, retVal.MapCenterLat = getMapCenter(retVal.Stores)
|
||||||
|
}
|
||||||
return retVal, err
|
return retVal, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,6 +430,15 @@ func GetVendorStore(ctx *jxcontext.Context, vendorStoreID string, vendorID int)
|
|||||||
return nil, ErrCanNotFindVendor
|
return nil, ErrCanNotFindVendor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isUpdateStoreNeedSync(valid map[string]interface{}) bool {
|
||||||
|
for k := range valid {
|
||||||
|
if storeKeyPropertyMap[k] == 1 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func UpdateStore(ctx *jxcontext.Context, storeID int, payload map[string]interface{}, userName string) (num int64, err error) {
|
func UpdateStore(ctx *jxcontext.Context, storeID int, payload map[string]interface{}, userName string) (num int64, err error) {
|
||||||
globals.SugarLogger.Debugf("UpdateStore storeID:%d, payload:%s", storeID, utils.Format4Output(payload, false))
|
globals.SugarLogger.Debugf("UpdateStore storeID:%d, payload:%s", storeID, utils.Format4Output(payload, false))
|
||||||
|
|
||||||
@@ -458,14 +532,18 @@ func UpdateStore(ctx *jxcontext.Context, storeID int, payload map[string]interfa
|
|||||||
dao.Rollback(db)
|
dao.Rollback(db)
|
||||||
}()
|
}()
|
||||||
if num, err = dao.UpdateEntityLogically(db, store, valid, userName, nil); err == nil && num == 1 {
|
if num, err = dao.UpdateEntityLogically(db, store, valid, userName, nil); err == nil && num == 1 {
|
||||||
dummy := &model.StoreMap{}
|
if isUpdateStoreNeedSync(valid) {
|
||||||
_, err2 := dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, dummy, nil, userName, map[string]interface{}{
|
dummy := &model.StoreMap{}
|
||||||
model.FieldStoreID: store.ID,
|
_, err2 := dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, dummy, nil, userName, map[string]interface{}{
|
||||||
}, model.FieldSyncStatus, syncStatus)
|
model.FieldStoreID: store.ID,
|
||||||
if err = err2; err == nil {
|
}, model.FieldSyncStatus, syncStatus)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
dao.Commit(db)
|
||||||
|
globals.SugarLogger.Debugf("UpdateStore track:%s, before call SyncStore", ctx.GetTrackInfo())
|
||||||
|
_, err = CurVendorSync.SyncStore(ctx, db, -1, store.ID, false, userName)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
dao.Commit(db)
|
dao.Commit(db)
|
||||||
globals.SugarLogger.Debugf("UpdateStore track:%s, before call SyncStore", ctx.GetTrackInfo())
|
|
||||||
_, err = CurVendorSync.SyncStore(ctx, db, -1, store.ID, false, userName)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -474,6 +552,42 @@ func UpdateStore(ctx *jxcontext.Context, storeID int, payload map[string]interfa
|
|||||||
return num, err
|
return num, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetStoreStatus(ctx *jxcontext.Context, storeID, status int) (err error) {
|
||||||
|
payload := map[string]interface{}{
|
||||||
|
"status": status,
|
||||||
|
}
|
||||||
|
_, err = UpdateStore(ctx, storeID, payload, ctx.GetUserName())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnableHaveRestStores(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
|
storeInfo, err := GetStores(ctx, "", map[string]interface{}{
|
||||||
|
"statuss": string(utils.MustMarshal([]int{model.StoreStatusHaveRest})),
|
||||||
|
}, 0, model.UnlimitedPageSize)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if len(storeInfo.Stores) == 0 {
|
||||||
|
return "0", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
task := tasksch.NewParallelTask("EnableHaveRestStores", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
store := batchItemList[0].(*StoreExt)
|
||||||
|
err = SetStoreStatus(ctx, store.ID, model.StoreStatusOpened)
|
||||||
|
return nil, err
|
||||||
|
}, storeInfo.Stores)
|
||||||
|
tasksch.ManageTask(task).Run()
|
||||||
|
if !isAsync {
|
||||||
|
if _, err = task.GetResult(0); err == nil {
|
||||||
|
hint = utils.Int2Str(len(storeInfo.Stores))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hint = task.GetID()
|
||||||
|
}
|
||||||
|
return hint, err
|
||||||
|
}
|
||||||
|
|
||||||
func CreateStore(ctx *jxcontext.Context, storeExt *StoreExt, userName string) (id int, err error) {
|
func CreateStore(ctx *jxcontext.Context, storeExt *StoreExt, userName string) (id int, err error) {
|
||||||
globals.SugarLogger.Debugf("CreateStore storeExt:%s", utils.Format4Output(storeExt, false))
|
globals.SugarLogger.Debugf("CreateStore storeExt:%s", utils.Format4Output(storeExt, false))
|
||||||
store := &storeExt.Store
|
store := &storeExt.Store
|
||||||
@@ -547,6 +661,9 @@ func AddStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendorID
|
|||||||
if storeID == 0 {
|
if storeID == 0 {
|
||||||
return nil, fmt.Errorf("storeID不能为0")
|
return nil, fmt.Errorf("storeID不能为0")
|
||||||
}
|
}
|
||||||
|
if vendorID != model.VendorIDJD && (storeMap.AutoPickup == 0) {
|
||||||
|
return nil, fmt.Errorf("非京东平台要求必须自动拣货")
|
||||||
|
}
|
||||||
userName := ctx.GetUserName()
|
userName := ctx.GetUserName()
|
||||||
if handler := CurVendorSync.GetStoreHandler(vendorID); handler != nil {
|
if handler := CurVendorSync.GetStoreHandler(vendorID); handler != nil {
|
||||||
store, err2 := handler.ReadStore(storeMap.VendorStoreID)
|
store, err2 := handler.ReadStore(storeMap.VendorStoreID)
|
||||||
@@ -605,6 +722,11 @@ func DeleteStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendor
|
|||||||
}
|
}
|
||||||
|
|
||||||
func UpdateStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendorID int, payload map[string]interface{}, userName string) (num int64, err error) {
|
func UpdateStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendorID int, payload map[string]interface{}, userName string) (num int64, err error) {
|
||||||
|
if vendorID != model.VendorIDJD {
|
||||||
|
if autoPickup, ok := payload["autoPickup"]; ok && autoPickup == 0 {
|
||||||
|
return 0, fmt.Errorf("非京东平台要求必须自动拣货")
|
||||||
|
}
|
||||||
|
}
|
||||||
storeHandler := CurVendorSync.GetStoreHandler(vendorID)
|
storeHandler := CurVendorSync.GetStoreHandler(vendorID)
|
||||||
if storeHandler == nil {
|
if storeHandler == nil {
|
||||||
return 0, ErrCanNotFindVendor
|
return 0, ErrCanNotFindVendor
|
||||||
@@ -651,7 +773,7 @@ func UpdateStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendor
|
|||||||
storeSkuBind := &model.StoreSkuBind{}
|
storeSkuBind := &model.StoreSkuBind{}
|
||||||
if num, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, storeSkuBind, nil, userName, map[string]interface{}{
|
if num, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, storeSkuBind, nil, userName, map[string]interface{}{
|
||||||
model.FieldStoreID: storeID,
|
model.FieldStoreID: storeID,
|
||||||
}, dao.GetSyncStatusStructField(model.VendorNames[vendorID]), model.SyncFlagModifiedMask); err != nil {
|
}, dao.GetSyncStatusStructField(model.VendorNames[vendorID]), model.SyncFlagPriceMask); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -797,9 +919,22 @@ func AddStoreCourierMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendorID
|
|||||||
dao.WrapAddIDCULDEntity(storeCourierMap, userName)
|
dao.WrapAddIDCULDEntity(storeCourierMap, userName)
|
||||||
storeCourierMap.StoreID = storeID
|
storeCourierMap.StoreID = storeID
|
||||||
storeCourierMap.VendorID = vendorID
|
storeCourierMap.VendorID = vendorID
|
||||||
|
|
||||||
if db == nil {
|
if db == nil {
|
||||||
db = dao.GetDB()
|
db = dao.GetDB()
|
||||||
}
|
}
|
||||||
|
if vendorID == model.VendorIDDada {
|
||||||
|
storeList, err2 := dao.GetMissingDadaStores(db, storeID, false)
|
||||||
|
if err = err2; err == nil && len(storeList) > 0 {
|
||||||
|
storeList[0].DadaStoreID = storeCourierMap.VendorStoreID
|
||||||
|
err = updateOrCreateDadaStore(storeList[0])
|
||||||
|
} else {
|
||||||
|
globals.SugarLogger.Debugf("AddStoreCourierMap GetMissingDadaStores error:%v, len(storeList):%d", err, len(storeList))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
dao.Begin(db)
|
dao.Begin(db)
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
@@ -809,15 +944,6 @@ func AddStoreCourierMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendorID
|
|||||||
}()
|
}()
|
||||||
if err = dao.CreateEntity(db, storeCourierMap); err == nil {
|
if err = dao.CreateEntity(db, storeCourierMap); err == nil {
|
||||||
dao.Commit(db)
|
dao.Commit(db)
|
||||||
if vendorID == model.VendorIDDada {
|
|
||||||
storeList, err := dao.GetMissingDadaStores(db, storeID, false)
|
|
||||||
if err == nil && len(storeList) > 0 {
|
|
||||||
storeList[0].DadaStoreID = storeCourierMap.VendorStoreID
|
|
||||||
err = updateOrCreateDadaStore(storeList[0])
|
|
||||||
} else {
|
|
||||||
globals.SugarLogger.Debugf("AddStoreCourierMap GetMissingDadaStores error:%v, len(storeList):%d", err, len(storeList))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outStoreCourierMap = storeCourierMap
|
outStoreCourierMap = storeCourierMap
|
||||||
if err == nil {
|
if err == nil {
|
||||||
_, err = CurVendorSync.SyncStore(ctx, db, storeCourierMap.VendorID, storeID, false, userName)
|
_, err = CurVendorSync.SyncStore(ctx, db, storeCourierMap.VendorID, storeID, false, userName)
|
||||||
@@ -871,46 +997,74 @@ func RefreshMissingDadaStores(ctx *jxcontext.Context, storeID int, isAsync, isCo
|
|||||||
task := tasksch.NewParallelTask("RefreshMissingDadaStores", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
task := tasksch.NewParallelTask("RefreshMissingDadaStores", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
storeDetail := batchItemList[0].(*dao.StoreDetail2)
|
storeDetail := batchItemList[0].(*dao.StoreDetail2)
|
||||||
|
var resultList []interface{}
|
||||||
if storeDetail.DadaStoreID == "" {
|
if storeDetail.DadaStoreID == "" {
|
||||||
|
if storeDetail.DistrictName == "" || storeDetail.CityName == "" {
|
||||||
|
return nil, fmt.Errorf("门店:%s的城市码或区码有错误", storeDetail.Name)
|
||||||
|
}
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
_, err = AddStoreCourierMap(ctx, db, storeDetail.ID, model.VendorIDDada, &model.StoreCourierMap{
|
if _, err = AddStoreCourierMap(ctx, db, storeDetail.ID, model.VendorIDDada, &model.StoreCourierMap{
|
||||||
VendorStoreID: utils.Int2Str(storeDetail.ID),
|
VendorStoreID: utils.Int2Str(storeDetail.ID),
|
||||||
Status: model.StoreStatusOpened,
|
Status: model.StoreStatusOpened,
|
||||||
})
|
}); err == nil {
|
||||||
|
resultList = append(resultList, 1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil, err
|
return resultList, err
|
||||||
}, storeList)
|
}, storeList)
|
||||||
tasksch.HandleTask(task, nil, true).Run()
|
tasksch.HandleTask(task, nil, true).Run()
|
||||||
hint = task.ID
|
|
||||||
if !isAsync {
|
if !isAsync {
|
||||||
_, err = task.GetResult(0)
|
resultList, err2 := task.GetResult(0)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
hint = utils.Int2Str(len(resultList))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hint = task.ID
|
||||||
}
|
}
|
||||||
return hint, err
|
return hint, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateOrCreateDadaStore(storeDetail *dao.StoreDetail2) (err error) {
|
func updateOrCreateDadaStore(storeDetail *dao.StoreDetail2) (err error) {
|
||||||
_, err = api.DadaAPI.ShopDetail(storeDetail.DadaStoreID)
|
if storeDetail.DistrictName == "" {
|
||||||
if err != nil {
|
return fmt.Errorf("门店的区码有问题,请检查")
|
||||||
if codeErr, ok := err.(*utils.ErrorWithCode); ok && codeErr.IntCode() == dadaapi.ResponseCodeShopNotExist {
|
}
|
||||||
_, err = api.DadaAPI.ShopAdd(storeDetail.DadaStoreID, composeDadaStoreName(storeDetail), dadaapi.BusinessTypeConvStore, storeDetail.CityName,
|
if storeDetail.CityName == "" {
|
||||||
storeDetail.DistrictName, storeDetail.Address, jxutils.IntCoordinate2Standard(storeDetail.Lng), jxutils.IntCoordinate2Standard(storeDetail.Lat),
|
return fmt.Errorf("门店的城市码有问题,请检查")
|
||||||
storeDetail.Tel1, storeDetail.Tel1, nil)
|
}
|
||||||
|
if dadaDistrictMap[storeDetail.DistrictName] != "" {
|
||||||
|
if dadaDistrictMap[storeDetail.DistrictName] == "1" { // 区镇信息
|
||||||
|
storeDetail.CityName = storeDetail.DistrictName
|
||||||
|
storeDetail.DistrictName, _ = api.AutonaviAPI.GetCoordinateTownInfo(jxutils.IntCoordinate2Standard(storeDetail.Lng), jxutils.IntCoordinate2Standard(storeDetail.Lat))
|
||||||
}
|
}
|
||||||
} else {
|
if dadaDistrictMap[storeDetail.DistrictName] != "" {
|
||||||
params := map[string]interface{}{
|
storeDetail.DistrictName = dadaDistrictMap[storeDetail.DistrictName]
|
||||||
"station_name": composeDadaStoreName(storeDetail),
|
}
|
||||||
"business": dadaapi.BusinessTypeConvStore,
|
}
|
||||||
"city_name": storeDetail.CityName,
|
if globals.EnableStoreWrite {
|
||||||
"area_name": storeDetail.DistrictName,
|
_, err = api.DadaAPI.ShopDetail(storeDetail.DadaStoreID)
|
||||||
"station_address": storeDetail.Address,
|
if err != nil {
|
||||||
"lng": jxutils.IntCoordinate2Standard(storeDetail.Lng),
|
if codeErr, ok := err.(*utils.ErrorWithCode); ok && codeErr.IntCode() == dadaapi.ResponseCodeShopNotExist {
|
||||||
"lat": jxutils.IntCoordinate2Standard(storeDetail.Lat),
|
_, err = api.DadaAPI.ShopAdd(storeDetail.DadaStoreID, composeDadaStoreName(storeDetail), dadaapi.BusinessTypeConvStore, storeDetail.CityName,
|
||||||
"contact_name": storeDetail.Tel1,
|
storeDetail.DistrictName, storeDetail.Address, jxutils.IntCoordinate2Standard(storeDetail.Lng), jxutils.IntCoordinate2Standard(storeDetail.Lat),
|
||||||
"phone": storeDetail.Tel1,
|
storeDetail.Tel1, storeDetail.Tel1, nil)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
params := map[string]interface{}{
|
||||||
|
"station_name": composeDadaStoreName(storeDetail),
|
||||||
|
"business": dadaapi.BusinessTypeConvStore,
|
||||||
|
"city_name": storeDetail.CityName,
|
||||||
|
"area_name": storeDetail.DistrictName,
|
||||||
|
"station_address": storeDetail.Address,
|
||||||
|
"lng": jxutils.IntCoordinate2Standard(storeDetail.Lng),
|
||||||
|
"lat": jxutils.IntCoordinate2Standard(storeDetail.Lat),
|
||||||
|
"contact_name": storeDetail.Tel1,
|
||||||
|
"phone": storeDetail.Tel1,
|
||||||
|
}
|
||||||
|
err = api.DadaAPI.ShopUpdate(storeDetail.DadaStoreID, params)
|
||||||
}
|
}
|
||||||
err = api.DadaAPI.ShopUpdate(storeDetail.DadaStoreID, params)
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
err = fmt.Errorf("门店ID:%d,门店名:%s,错误描述:%s", storeDetail.Store.ID, storeDetail.Name, err.Error())
|
||||||
globals.SugarLogger.Debugf("updateOrCreateDadaStore storeID:%d failed with error:%v", storeDetail.ID, err)
|
globals.SugarLogger.Debugf("updateOrCreateDadaStore storeID:%d failed with error:%v", storeDetail.ID, err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@@ -919,3 +1073,91 @@ func updateOrCreateDadaStore(storeDetail *dao.StoreDetail2) (err error) {
|
|||||||
func composeDadaStoreName(storeDetail *dao.StoreDetail2) (storeName string) {
|
func composeDadaStoreName(storeDetail *dao.StoreDetail2) (storeName string) {
|
||||||
return storeDetail.Name + "-" + storeDetail.DadaStoreID
|
return storeDetail.Name + "-" + storeDetail.DadaStoreID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExportShopsHealthInfo(ctx *jxcontext.Context, vendorIDs, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
|
db := dao.GetDB()
|
||||||
|
vendorID := model.VendorIDEBAI
|
||||||
|
storeMapList, err := dao.GetStoresMapList(db, []int{vendorID}, storeIDs, model.StoreStatusAll)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
storeMap2 := make(map[string]*model.StoreMap)
|
||||||
|
for _, v := range storeMapList {
|
||||||
|
storeMap2[v.VendorStoreID] = v
|
||||||
|
}
|
||||||
|
if len(storeMapList) > 0 {
|
||||||
|
var healthInfoList []interface{}
|
||||||
|
var excelBin []byte
|
||||||
|
var excelURL string
|
||||||
|
task := tasksch.NewSeqTask(fmt.Sprintf("ExportShopHealthInfo[%s]", model.VendorChineseNames[vendorID]), ctx,
|
||||||
|
func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||||
|
switch step {
|
||||||
|
case 0:
|
||||||
|
subTask := tasksch.NewParallelTask(fmt.Sprintf("ExportShopHealthInfo2[%s]", model.VendorChineseNames[vendorID]), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
storeMap := batchItemList[0].(*model.StoreMap)
|
||||||
|
healthInfo, err := ebai.CurPurchaseHandler.GetShopHealthInfo(storeMap.VendorStoreID)
|
||||||
|
if err == nil {
|
||||||
|
retVal = []map[string]interface{}{healthInfo}
|
||||||
|
}
|
||||||
|
return retVal, err
|
||||||
|
}, storeMapList)
|
||||||
|
tasksch.AddChild(task, subTask).Run()
|
||||||
|
healthInfoList, err = subTask.GetResult(0)
|
||||||
|
if isContinueWhenError && err != nil && len(healthInfoList) > 0 {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
var healthInfoList2 []map[string]interface{}
|
||||||
|
for _, v := range healthInfoList {
|
||||||
|
mapInfo := v.(map[string]interface{})
|
||||||
|
mapInfo["real_shop_id"] = storeMap2[utils.Interface2String(mapInfo["merchant_id"])].StoreID
|
||||||
|
healthInfoList2 = append(healthInfoList2, mapInfo)
|
||||||
|
}
|
||||||
|
excelConf := &excel.Obj2ExcelSheetConfig{
|
||||||
|
Title: "饿百门店情况导出",
|
||||||
|
Data: healthInfoList2,
|
||||||
|
CaptionList: []string{
|
||||||
|
"real_shop_id",
|
||||||
|
"merchant_id",
|
||||||
|
"merchant_name",
|
||||||
|
"hours",
|
||||||
|
"sku_num",
|
||||||
|
"target_jiedan",
|
||||||
|
"is_healthy",
|
||||||
|
"bad_order_rate",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
excelBin = excel.Obj2Excel([]*excel.Obj2ExcelSheetConfig{excelConf})
|
||||||
|
case 2:
|
||||||
|
keyPart := []string{
|
||||||
|
ctx.GetUserName(),
|
||||||
|
"饿百门店情况",
|
||||||
|
}
|
||||||
|
keyPart = append(keyPart, time.Now().Format("20060102T150405")+".xlsx")
|
||||||
|
key := "export/" + strings.Join(keyPart, "_")
|
||||||
|
excelURL, err = jxutils.UploadExportContent(excelBin, key)
|
||||||
|
if err == nil {
|
||||||
|
task.SetNoticeMsg(excelURL)
|
||||||
|
}
|
||||||
|
globals.SugarLogger.Debugf("导出饿百门店情况excelURL:%s, err:%v", excelURL, err)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}, 3)
|
||||||
|
tasksch.HandleTask(task, nil, true).Run()
|
||||||
|
if !isAsync {
|
||||||
|
_, err = task.GetResult(0)
|
||||||
|
if err == nil {
|
||||||
|
hint = excelURL
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hint = task.GetID()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hint, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCorporationInfo(ctx *jxcontext.Context, licenceCode string) (corporationInfo *jdapi.CorporationInfo, err error) {
|
||||||
|
corporationInfo, err = api.JdAPI.GetCorporationInfo("", licenceCode)
|
||||||
|
return corporationInfo, err
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,8 +6,14 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner/purchase/jd"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxcallback/auth/weixin"
|
"git.rosy.net.cn/jx-callback/business/jxcallback/auth/weixin"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
@@ -20,6 +26,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
MaxSkuUnitPrice = 100000
|
||||||
|
|
||||||
CopyStoreSkuModeFresh = "fresh"
|
CopyStoreSkuModeFresh = "fresh"
|
||||||
CopyStoreSkuModeUpdate = "update"
|
CopyStoreSkuModeUpdate = "update"
|
||||||
// CopyStoreSkuModeAdd = "add"
|
// CopyStoreSkuModeAdd = "add"
|
||||||
@@ -48,24 +56,26 @@ type StoreSkuNamesInfo struct {
|
|||||||
// UpdateStoreSku用,API调用时
|
// UpdateStoreSku用,API调用时
|
||||||
type StoreSkuBindSkuInfo struct {
|
type StoreSkuBindSkuInfo struct {
|
||||||
SkuID int `json:"skuID"`
|
SkuID int `json:"skuID"`
|
||||||
IsSale int `json:"isSale"` // -1:不可售,0:忽略,1:可售
|
IsSale int `json:"isSale,omitempty"` // -1:不可售,0:忽略,1:可售
|
||||||
|
|
||||||
ElmID int64 `json:"elmID"`
|
ElmID int64 `json:"elmID,omitempty"`
|
||||||
EbaiID int64 `json:"ebaiID"`
|
EbaiID int64 `json:"ebaiID,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateStoreSku用,API调用时
|
// UpdateStoreSku用,API调用时
|
||||||
type StoreSkuBindInfo struct {
|
type StoreSkuBindInfo struct {
|
||||||
|
StoreID int `json:"storeID"`
|
||||||
NameID int `json:"nameID"`
|
NameID int `json:"nameID"`
|
||||||
UnitPrice int `json:"unitPrice"` // 对于是份的SKU就是单价(每斤价格),其它则为总价
|
UnitPrice int `json:"unitPrice"` // 对于是份的SKU就是单价(每斤价格),其它则为总价
|
||||||
IsFocus int `json:"isFocus"` // -1:不关注,0:忽略,1:关注
|
IsFocus int `json:"isFocus"` // -1:不关注,0:忽略,1:关注
|
||||||
IsSale int `json:"isSale"` // -1:不可售,0:忽略,1:可售
|
IsSale int `json:"isSale"` // -1:不可售,0:忽略,1:可售
|
||||||
SubStoreID int `json:"subStoreID"`
|
SubStoreID int `json:"subStoreID,omitempty"`
|
||||||
Skus []*StoreSkuBindSkuInfo `json:"skus"`
|
Skus []*StoreSkuBindSkuInfo `json:"skus,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type tStoreSkuBindAndSpec struct {
|
type tStoreSkuBindAndSpec struct {
|
||||||
model.StoreSkuBind
|
model.StoreSkuBind
|
||||||
|
Name string
|
||||||
SpecQuality float32
|
SpecQuality float32
|
||||||
SpecUnit string
|
SpecUnit string
|
||||||
SkuNamePrice int
|
SkuNamePrice int
|
||||||
@@ -88,6 +98,11 @@ type StoreOpRequestInfo struct {
|
|||||||
UnitPrice int `json:"unitPrice"`
|
UnitPrice int `json:"unitPrice"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
maxStoreNameBind = 3000 // 最大门店SkuName bind个数
|
||||||
|
maxStoreNameBind2 = 10000 // 最大门店乘SkuName个数
|
||||||
|
)
|
||||||
|
|
||||||
func GetStoreSkus(ctx *jxcontext.Context, storeID int, isFocus bool, keyword string, isBySku bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *StoreSkuNamesInfo, err error) {
|
func GetStoreSkus(ctx *jxcontext.Context, storeID int, isFocus bool, keyword string, isBySku bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *StoreSkuNamesInfo, err error) {
|
||||||
return GetStoresSkus(ctx, []int{storeID}, isFocus, keyword, isBySku, params, offset, pageSize)
|
return GetStoresSkus(ctx, []int{storeID}, isFocus, keyword, isBySku, params, offset, pageSize)
|
||||||
}
|
}
|
||||||
@@ -102,7 +117,7 @@ func GetStoresSkus(ctx *jxcontext.Context, storeIDs []int, isFocus bool, keyword
|
|||||||
JOIN store t3 ON t3.id IN (` + dao.GenQuestionMarks(len(storeIDs)) + `)
|
JOIN store t3 ON t3.id IN (` + dao.GenQuestionMarks(len(storeIDs)) + `)
|
||||||
LEFT JOIN store_sku_bind t4 ON t4.sku_id = t2.id AND t4.deleted_at = ? AND t4.store_id = t3.id
|
LEFT JOIN store_sku_bind t4 ON t4.sku_id = t2.id AND t4.deleted_at = ? AND t4.store_id = t3.id
|
||||||
LEFT JOIN sku_name_place_bind t5 ON t1.id = t5.name_id AND t3.city_code = t5.place_code
|
LEFT JOIN sku_name_place_bind t5 ON t1.id = t5.name_id AND t3.city_code = t5.place_code
|
||||||
WHERE t1.deleted_at = ? AND (t1.is_global = 1 OR t5.id IS NOT NULL OR t4.status = ?)/* AND t1.status = ?*/
|
WHERE t1.deleted_at = ? AND (t1.is_global = 1 OR t5.id IS NOT NULL OR 1 = ?)/* AND t1.status = ?*/
|
||||||
`
|
`
|
||||||
sqlParams := []interface{}{
|
sqlParams := []interface{}{
|
||||||
utils.DefaultTimeValue,
|
utils.DefaultTimeValue,
|
||||||
@@ -110,7 +125,7 @@ func GetStoresSkus(ctx *jxcontext.Context, storeIDs []int, isFocus bool, keyword
|
|||||||
storeIDs,
|
storeIDs,
|
||||||
utils.DefaultTimeValue,
|
utils.DefaultTimeValue,
|
||||||
utils.DefaultTimeValue,
|
utils.DefaultTimeValue,
|
||||||
model.SkuStatusNormal,
|
utils.Bool2Int(isFocus),
|
||||||
// model.SkuStatusNormal,
|
// model.SkuStatusNormal,
|
||||||
}
|
}
|
||||||
if isFocus {
|
if isFocus {
|
||||||
@@ -122,12 +137,12 @@ func GetStoresSkus(ctx *jxcontext.Context, storeIDs []int, isFocus bool, keyword
|
|||||||
}
|
}
|
||||||
if keyword != "" {
|
if keyword != "" {
|
||||||
keywordLike := "%" + keyword + "%"
|
keywordLike := "%" + keyword + "%"
|
||||||
sql += " AND (t1.name LIKE ? OR t1.prefix LIKE ? OR t2.comment LIKE ?"
|
sql += " AND (t1.name LIKE ? OR t1.prefix LIKE ? OR t1.upc LIKE ? OR t2.comment LIKE ?"
|
||||||
sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike)
|
sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike)
|
||||||
|
|
||||||
if keywordInt64, err2 := strconv.ParseInt(keyword, 10, 64); err2 == nil {
|
if keywordInt64, err2 := strconv.ParseInt(keyword, 10, 64); err2 == nil {
|
||||||
sql += " OR t2.jd_id = ? OR t4.id = ?"
|
sql += " OR t1.id = ? OR t2.id = ? OR t2.jd_id = ? OR t4.ebai_id = ? OR t4.mtwm_id = ?"
|
||||||
sqlParams = append(sqlParams, keywordInt64, keywordInt64)
|
sqlParams = append(sqlParams, keywordInt64, keywordInt64, keywordInt64, keywordInt64, keywordInt64)
|
||||||
}
|
}
|
||||||
sql += ")"
|
sql += ")"
|
||||||
}
|
}
|
||||||
@@ -197,14 +212,36 @@ func GetStoresSkus(ctx *jxcontext.Context, storeIDs []int, isFocus bool, keyword
|
|||||||
sqlParams = append(sqlParams, skuIDs)
|
sqlParams = append(sqlParams, skuIDs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isFocus && params["fromStatus"] != nil {
|
if isFocus {
|
||||||
fromStatus := params["fromStatus"].(int)
|
if params["fromStatus"] != nil {
|
||||||
toStatus := fromStatus
|
fromStatus := params["fromStatus"].(int)
|
||||||
if params["toStatus"] != nil {
|
toStatus := fromStatus
|
||||||
toStatus = params["toStatus"].(int)
|
if params["toStatus"] != nil {
|
||||||
|
toStatus = params["toStatus"].(int)
|
||||||
|
}
|
||||||
|
sql += " AND t4.status >= ? AND t4.status <= ?"
|
||||||
|
sqlParams = append(sqlParams, fromStatus, toStatus)
|
||||||
|
}
|
||||||
|
if params["jdSyncStatus"] != nil || params["ebaiSyncStatus"] != nil || params["mtwmSyncStatus"] != nil {
|
||||||
|
realVendorMap, err2 := getValidStoreVendorMap(db, storeIDs)
|
||||||
|
if err = err2; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sql += " AND ( 1 = 0"
|
||||||
|
if params["jdSyncStatus"] != nil && realVendorMap[model.VendorIDJD] == 1 {
|
||||||
|
sql += " OR (t4.jd_sync_status & ? <> 0 AND t4.jd_sync_status & ? = 0 AND t2.jd_id <> 0 AND t1.status = ? AND t2.status = ?)"
|
||||||
|
sqlParams = append(sqlParams, params["jdSyncStatus"], model.SyncFlagDeletedMask|model.SyncFlagNewMask, model.SkuStatusNormal, model.SkuStatusNormal)
|
||||||
|
}
|
||||||
|
if params["ebaiSyncStatus"] != nil && realVendorMap[model.VendorIDEBAI] == 1 {
|
||||||
|
sql += " OR (t4.ebai_sync_status & ? <> 0 AND t4.ebai_sync_status & ? = 0)"
|
||||||
|
sqlParams = append(sqlParams, params["ebaiSyncStatus"], model.SyncFlagDeletedMask|model.SyncFlagNewMask)
|
||||||
|
}
|
||||||
|
if params["mtwmSyncStatus"] != nil && realVendorMap[model.VendorIDMTWM] == 1 {
|
||||||
|
sql += " OR (t4.mtwm_sync_status & ? <> 0 AND t4.mtwm_sync_status & ? = 0)"
|
||||||
|
sqlParams = append(sqlParams, params["mtwmSyncStatus"], model.SyncFlagDeletedMask|model.SyncFlagNewMask)
|
||||||
|
}
|
||||||
|
sql += ")"
|
||||||
}
|
}
|
||||||
sql += " AND t4.status >= ? AND t4.status <= ?"
|
|
||||||
sqlParams = append(sqlParams, fromStatus, toStatus)
|
|
||||||
}
|
}
|
||||||
sql += `
|
sql += `
|
||||||
GROUP BY
|
GROUP BY
|
||||||
@@ -392,6 +429,80 @@ func GetStoresSkus(ctx *jxcontext.Context, storeIDs []int, isFocus bool, keyword
|
|||||||
return skuNamesInfo, err
|
return skuNamesInfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getValidStoreVendorMap(db *dao.DaoDB, storeIDs []int) (realVendorMap map[int]int, err error) {
|
||||||
|
storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, model.StoreStatusAll)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
realVendorMap = make(map[int]int)
|
||||||
|
for _, v := range storeMapList {
|
||||||
|
if v.IsSync != 0 {
|
||||||
|
realVendorMap[v.VendorID] = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return realVendorMap, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetStoreAbnormalSkuCount(ctx *jxcontext.Context, storeID, syncStatus int, isBySku bool, params map[string]interface{}) (count int, err error) {
|
||||||
|
db := dao.GetDB()
|
||||||
|
realVendorMap, err2 := getValidStoreVendorMap(db, []int{storeID})
|
||||||
|
if err = err2; err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sql := `
|
||||||
|
SELECT COUNT(*) ct`
|
||||||
|
if !isBySku {
|
||||||
|
sql += `
|
||||||
|
FROM (
|
||||||
|
SELECT DISTINCT t3.id`
|
||||||
|
}
|
||||||
|
sql += `
|
||||||
|
FROM store_sku_bind t1
|
||||||
|
JOIN sku t2 ON t2.id = t1.sku_id AND t2.deleted_at = ?
|
||||||
|
JOIN sku_name t3 ON t3.id = t2.name_id AND t3.deleted_at = ?
|
||||||
|
WHERE t1.deleted_at = ? AND t1.store_id = ? AND
|
||||||
|
((t2.status = ? AND t3.status = ?) OR t1.status = ?) AND
|
||||||
|
(1 = 0`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
storeID,
|
||||||
|
model.SkuStatusNormal,
|
||||||
|
model.SkuStatusNormal,
|
||||||
|
model.SkuStatusNormal,
|
||||||
|
}
|
||||||
|
for _, vendorID := range []int{model.VendorIDJD, model.VendorIDEBAI, model.VendorIDMTWM} {
|
||||||
|
if realVendorMap[vendorID] != 0 {
|
||||||
|
prefix := dao.ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
||||||
|
sql += fmt.Sprintf(" OR (t1.%s_sync_status & ? <> 0 AND t1.%s_sync_status & ? = 0", prefix, prefix)
|
||||||
|
sqlParams = append(sqlParams, syncStatus, model.SyncFlagDeletedMask|model.SyncFlagNewMask)
|
||||||
|
if model.MultiStoresVendorMap[vendorID] == 1 {
|
||||||
|
sql += fmt.Sprintf(" AND t2.%s_id <> 0 AND t2.status = ? AND t3.status = ?", prefix)
|
||||||
|
sqlParams = append(sqlParams, model.SkuStatusNormal, model.SkuStatusNormal)
|
||||||
|
}
|
||||||
|
sql += ")"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sql += ")"
|
||||||
|
if params["fromStatus"] != nil {
|
||||||
|
fromStatus := params["fromStatus"].(int)
|
||||||
|
toStatus := fromStatus
|
||||||
|
if params["toStatus"] != nil {
|
||||||
|
toStatus = params["toStatus"].(int)
|
||||||
|
}
|
||||||
|
sql += " AND t1.status >= ? AND t1.status <= ?"
|
||||||
|
sqlParams = append(sqlParams, fromStatus, toStatus)
|
||||||
|
}
|
||||||
|
if !isBySku {
|
||||||
|
sql += `
|
||||||
|
) t1`
|
||||||
|
}
|
||||||
|
err = dao.GetRow(db, &count, sql, sqlParams...)
|
||||||
|
return count, err
|
||||||
|
}
|
||||||
|
|
||||||
func GetStoresSkusSaleInfo(ctx *jxcontext.Context, storeIDs []int, skuIDs []int, fromTime, toTime time.Time, fromCount, toCount int) (saleInfoList []*SkuSaleInfo, err error) {
|
func GetStoresSkusSaleInfo(ctx *jxcontext.Context, storeIDs []int, skuIDs []int, fromTime, toTime time.Time, fromCount, toCount int) (saleInfoList []*SkuSaleInfo, err error) {
|
||||||
globals.SugarLogger.Debugf("GetStoresSkusSaleInfo storeIDs:%v, fromTime:%v, toTime:%v, fromCount:%d, toCount:%d", storeIDs, fromTime, toTime, fromCount, toCount)
|
globals.SugarLogger.Debugf("GetStoresSkusSaleInfo storeIDs:%v, fromTime:%v, toTime:%v, fromCount:%d, toCount:%d", storeIDs, fromTime, toTime, fromCount, toCount)
|
||||||
|
|
||||||
@@ -436,24 +547,65 @@ func UpdateStoreSku(ctx *jxcontext.Context, storeID int, skuBindInfo *StoreSkuBi
|
|||||||
}
|
}
|
||||||
|
|
||||||
func UpdateStoreSkus(ctx *jxcontext.Context, storeID int, skuBindInfos []*StoreSkuBindInfo, isAsync, isContinueWhenError bool) (hint string, err error) {
|
func UpdateStoreSkus(ctx *jxcontext.Context, storeID int, skuBindInfos []*StoreSkuBindInfo, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
// skuIDs, err := updateStoresSkusWithoutSync(ctx, []int{storeID}, skuBindInfos)
|
|
||||||
// num = int64(len(skuIDs))
|
|
||||||
// if err == nil && num > 0 {
|
|
||||||
// db := dao.GetDB()
|
|
||||||
// _, err = CurVendorSync.SyncStoresSkus(ctx, db, nil, []int{storeID}, skuIDs, false, false)
|
|
||||||
// return int64(len(skuIDs)), err
|
|
||||||
// }
|
|
||||||
// return 0, err
|
|
||||||
return UpdateStoresSkus(ctx, []int{storeID}, skuBindInfos, isAsync, isContinueWhenError)
|
return UpdateStoresSkus(ctx, []int{storeID}, skuBindInfos, isAsync, isContinueWhenError)
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateStoresSkus(ctx *jxcontext.Context, storeIDs []int, skuBindInfos []*StoreSkuBindInfo, isAsync, isContinueWhenError bool) (hint string, err error) {
|
func UpdateStoresSkus(ctx *jxcontext.Context, storeIDs []int, skuBindInfos []*StoreSkuBindInfo, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
var num int64
|
var num int64
|
||||||
skuIDs, err := updateStoresSkusWithoutSync(ctx, storeIDs, skuBindInfos)
|
db := dao.GetDB()
|
||||||
|
skuIDs, err := updateStoresSkusWithoutSync(ctx, db, storeIDs, skuBindInfos)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
num = int64(len(skuIDs))
|
num = int64(len(skuIDs))
|
||||||
if num > 0 {
|
if num > 0 {
|
||||||
db := dao.GetDB()
|
hint, err = CurVendorSync.SyncStoresSkus(ctx, db, nil, storeIDs, skuIDs, false, isAsync, isContinueWhenError)
|
||||||
hint, err = CurVendorSync.SyncStoresSkus(ctx, db, nil, storeIDs, skuIDs, isAsync, isContinueWhenError)
|
}
|
||||||
|
if num == 0 || !isAsync || hint == "" {
|
||||||
|
hint = utils.Int64ToStr(num)
|
||||||
|
}
|
||||||
|
return hint, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateStoresSkusByBind(ctx *jxcontext.Context, skuBindInfos []*StoreSkuBindInfo, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
|
if len(skuBindInfos) > maxStoreNameBind {
|
||||||
|
return "", fmt.Errorf("门店商品信息大于%d", maxStoreNameBind)
|
||||||
|
}
|
||||||
|
skuBindInfosMap := make(map[int][]*StoreSkuBindInfo)
|
||||||
|
storeIDMap := make(map[int]int)
|
||||||
|
for _, v := range skuBindInfos {
|
||||||
|
if v.StoreID > 9 {
|
||||||
|
skuBindInfosMap[v.StoreID] = append(skuBindInfosMap[v.StoreID], v)
|
||||||
|
storeIDMap[v.StoreID] = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeIDs := jxutils.IntMap2List(storeIDMap)
|
||||||
|
sort.Ints(storeIDs)
|
||||||
|
var num int64
|
||||||
|
skuIDMap := make(map[int]int)
|
||||||
|
db := dao.GetDB()
|
||||||
|
dao.Begin(db)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
panic(r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
for _, storeID := range storeIDs {
|
||||||
|
skuIDs, err2 := updateStoresSkusWithoutSync(ctx, db, []int{storeID}, skuBindInfosMap[storeID])
|
||||||
|
if err = err2; err != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
for _, v := range skuIDs {
|
||||||
|
skuIDMap[v] = 1
|
||||||
|
}
|
||||||
|
num += int64(len(skuIDs))
|
||||||
|
}
|
||||||
|
dao.Commit(db)
|
||||||
|
if num > 0 {
|
||||||
|
skuIDs := jxutils.IntMap2List(skuIDMap)
|
||||||
|
hint, err = CurVendorSync.SyncStoresSkus(ctx, db, nil, storeIDs, skuIDs, false, isAsync, isContinueWhenError)
|
||||||
}
|
}
|
||||||
if num == 0 || !isAsync || hint == "" {
|
if num == 0 || !isAsync || hint == "" {
|
||||||
hint = utils.Int64ToStr(num)
|
hint = utils.Int64ToStr(num)
|
||||||
@@ -504,13 +656,41 @@ func checkStoresSkusSaleCity(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs []i
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateStoresSkusWithoutSync(ctx *jxcontext.Context, storeIDs []int, skuBindInfos []*StoreSkuBindInfo) (needSyncSkus []int, err error) {
|
func uniqueStoreIDs(storeIDs []int) []int {
|
||||||
|
storeIDMap := make(map[int]int)
|
||||||
|
for _, v := range storeIDs {
|
||||||
|
storeIDMap[v] = 1
|
||||||
|
}
|
||||||
|
return jxutils.IntMap2List(storeIDMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
func uniqueStoreNameBind(skuBindInfos []*StoreSkuBindInfo) (outSkuBindInfos []*StoreSkuBindInfo) {
|
||||||
|
nameIDMap := make(map[int]int)
|
||||||
|
for _, v := range skuBindInfos {
|
||||||
|
if nameIDMap[v.NameID] != 1 {
|
||||||
|
outSkuBindInfos = append(outSkuBindInfos, v)
|
||||||
|
nameIDMap[v.NameID] = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return outSkuBindInfos
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs []int, skuBindInfos []*StoreSkuBindInfo) (needSyncSkus []int, err error) {
|
||||||
|
if len(storeIDs)*len(skuBindInfos) > maxStoreNameBind2 {
|
||||||
|
return nil, fmt.Errorf("门店商品信息大于%d", maxStoreNameBind2)
|
||||||
|
}
|
||||||
|
|
||||||
|
storeIDs = uniqueStoreIDs(storeIDs)
|
||||||
|
skuBindInfos = uniqueStoreNameBind(skuBindInfos)
|
||||||
|
|
||||||
sort.Ints(storeIDs)
|
sort.Ints(storeIDs)
|
||||||
globals.SugarLogger.Debugf("updateStoresSkusWithoutSync, storeIDs:%v, skuBindInfos:%s", storeIDs, utils.Format4Output(skuBindInfos, false))
|
globals.SugarLogger.Debugf("updateStoresSkusWithoutSync, storeIDs:%v, skuBindInfos:%s", storeIDs, utils.Format4Output(skuBindInfos, false))
|
||||||
db := dao.GetDB()
|
if db == nil {
|
||||||
if err = checkStoresSkusSaleCity(ctx, db, storeIDs, skuBindInfos); err != nil {
|
db = dao.GetDB()
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
// if err = checkStoresSkusSaleCity(ctx, db, storeIDs, skuBindInfos); err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
if storeIDs, skuBindInfos, err = filterStorePriceChange(ctx, storeIDs, skuBindInfos); err != nil {
|
if storeIDs, skuBindInfos, err = filterStorePriceChange(ctx, storeIDs, skuBindInfos); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -527,27 +707,45 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, storeIDs []int, skuBind
|
|||||||
}()
|
}()
|
||||||
for _, storeID := range storeIDs {
|
for _, storeID := range storeIDs {
|
||||||
for _, skuBindInfo := range skuBindInfos {
|
for _, skuBindInfo := range skuBindInfos {
|
||||||
|
// 关注且没有给价时,需要尝试从store_sku_bind中得到已有的单价
|
||||||
|
needGetExistingUnitPrice := skuBindInfo.UnitPrice == 0 && skuBindInfo.IsFocus == 1
|
||||||
inSkuBinds := skuBindInfo.Skus
|
inSkuBinds := skuBindInfo.Skus
|
||||||
var allBinds []*tStoreSkuBindAndSpec
|
var allBinds []*tStoreSkuBindAndSpec
|
||||||
sql := `
|
sql := `
|
||||||
SELECT
|
SELECT
|
||||||
t2.*,
|
t2.*,
|
||||||
t1.id real_sku_id, t1.spec_quality, t1.spec_unit,
|
t1.id real_sku_id, t1.spec_quality, t1.spec_unit,`
|
||||||
t3.price sku_name_price, t3.unit sku_name_unit
|
if needGetExistingUnitPrice {
|
||||||
|
sql += " IF(t5.unit_price > 0, t5.unit_price, t3.price) sku_name_price,"
|
||||||
|
}
|
||||||
|
sql += `
|
||||||
|
t3.unit sku_name_unit, t3.name
|
||||||
FROM sku t1
|
FROM sku t1
|
||||||
JOIN store ts ON ts.id = ? AND ts.deleted_at = ?
|
JOIN store ts ON ts.id = ? AND ts.deleted_at = ?
|
||||||
LEFT JOIN store_sku_bind t2 ON t2.sku_id = t1.id AND t2.store_id = ts.id AND t2.deleted_at = ?
|
LEFT JOIN store_sku_bind t2 ON t2.sku_id = t1.id AND t2.store_id = ts.id AND t2.deleted_at = ?
|
||||||
JOIN sku_name t3 ON t1.name_id = t3.id AND t3.deleted_at = ?
|
JOIN sku_name t3 ON t1.name_id = t3.id AND t3.deleted_at = ?`
|
||||||
WHERE t1.name_id = ? AND t1.deleted_at = ?
|
|
||||||
FOR UPDATE`
|
|
||||||
sqlParams := []interface{}{
|
sqlParams := []interface{}{
|
||||||
storeID,
|
storeID,
|
||||||
utils.DefaultTimeValue,
|
utils.DefaultTimeValue,
|
||||||
utils.DefaultTimeValue,
|
utils.DefaultTimeValue,
|
||||||
utils.DefaultTimeValue,
|
utils.DefaultTimeValue,
|
||||||
skuBindInfo.NameID,
|
|
||||||
utils.DefaultTimeValue,
|
|
||||||
}
|
}
|
||||||
|
if needGetExistingUnitPrice {
|
||||||
|
sql += `
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT t7.store_id, t8.name_id, CAST(AVG(t7.unit_price) AS SIGNED) unit_price
|
||||||
|
FROM store_sku_bind t7
|
||||||
|
JOIN sku t8 ON t8.id = t7.sku_id AND t8.name_id = ?
|
||||||
|
WHERE t7.deleted_at = ? AND t7.store_id = ?
|
||||||
|
GROUP BY 1,2
|
||||||
|
) t5 ON t5.store_id = ts.id AND t5.name_id = t1.name_id`
|
||||||
|
sqlParams = append(sqlParams, skuBindInfo.NameID, utils.DefaultTimeValue, storeID)
|
||||||
|
}
|
||||||
|
sql += `
|
||||||
|
WHERE t1.name_id = ? AND t1.deleted_at = ?
|
||||||
|
FOR UPDATE`
|
||||||
|
sqlParams = append(sqlParams, skuBindInfo.NameID, utils.DefaultTimeValue)
|
||||||
|
// globals.SugarLogger.Debug(sql)
|
||||||
if err = dao.GetRows(db, &allBinds, sql, sqlParams...); err == nil {
|
if err = dao.GetRows(db, &allBinds, sql, sqlParams...); err == nil {
|
||||||
if len(allBinds) > 0 {
|
if len(allBinds) > 0 {
|
||||||
// globals.SugarLogger.Debug(utils.Format4Output(allBinds, false))
|
// globals.SugarLogger.Debug(utils.Format4Output(allBinds, false))
|
||||||
@@ -557,6 +755,10 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, storeIDs []int, skuBind
|
|||||||
}
|
}
|
||||||
unitPrice := 0
|
unitPrice := 0
|
||||||
if skuBindInfo.UnitPrice != 0 {
|
if skuBindInfo.UnitPrice != 0 {
|
||||||
|
if skuBindInfo.UnitPrice > MaxSkuUnitPrice {
|
||||||
|
dao.Rollback(db)
|
||||||
|
return nil, fmt.Errorf("商品:%s价格:%s太夸张", allBinds[0].Name, jxutils.IntPrice2StandardCurrencyString(int64(skuBindInfo.UnitPrice)))
|
||||||
|
}
|
||||||
unitPrice = skuBindInfo.UnitPrice
|
unitPrice = skuBindInfo.UnitPrice
|
||||||
} else {
|
} else {
|
||||||
unitPrice = allBinds[0].UnitPrice
|
unitPrice = allBinds[0].UnitPrice
|
||||||
@@ -650,7 +852,7 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, storeIDs []int, skuBind
|
|||||||
updateFieldMap[model.FieldUpdatedAt] = 1
|
updateFieldMap[model.FieldUpdatedAt] = 1
|
||||||
updateFieldMap[model.FieldLastOperator] = 1
|
updateFieldMap[model.FieldLastOperator] = 1
|
||||||
|
|
||||||
setStoreSkuBindStatus(skuBind, model.SyncFlagModifiedMask)
|
// setStoreSkuBindStatus(skuBind, model.SyncFlagModifiedMask)
|
||||||
dao.WrapUpdateULEntity(skuBind, userName)
|
dao.WrapUpdateULEntity(skuBind, userName)
|
||||||
if num, err = dao.UpdateEntity(db, skuBind /*, utils.Map2KeySlice(updateFieldMap)...*/); err != nil {
|
if num, err = dao.UpdateEntity(db, skuBind /*, utils.Map2KeySlice(updateFieldMap)...*/); err != nil {
|
||||||
dao.Rollback(db)
|
dao.Rollback(db)
|
||||||
@@ -712,11 +914,11 @@ func updateStoreSkusSaleWithoutSync(ctx *jxcontext.Context, storeID int, skuBind
|
|||||||
}
|
}
|
||||||
if num, err = dao.UpdateEntityLogically(db, skuBind, map[string]interface{}{
|
if num, err = dao.UpdateEntityLogically(db, skuBind, map[string]interface{}{
|
||||||
model.FieldStatus: skuBind.Status,
|
model.FieldStatus: skuBind.Status,
|
||||||
model.FieldJdSyncStatus: skuBind.JdSyncStatus | model.SyncFlagSaleMask | model.SyncFlagModifiedMask,
|
model.FieldJdSyncStatus: skuBind.JdSyncStatus | model.SyncFlagSaleMask,
|
||||||
model.FieldEbaiSyncStatus: skuBind.EbaiSyncStatus | model.SyncFlagSaleMask | model.SyncFlagModifiedMask,
|
model.FieldEbaiSyncStatus: skuBind.EbaiSyncStatus | model.SyncFlagSaleMask,
|
||||||
model.FieldMtwmSyncStatus: skuBind.MtwmSyncStatus | model.SyncFlagSaleMask | model.SyncFlagModifiedMask,
|
model.FieldMtwmSyncStatus: skuBind.MtwmSyncStatus | model.SyncFlagSaleMask,
|
||||||
model.FieldElmSyncStatus: skuBind.ElmSyncStatus | model.SyncFlagSaleMask | model.SyncFlagModifiedMask,
|
model.FieldElmSyncStatus: skuBind.ElmSyncStatus | model.SyncFlagSaleMask,
|
||||||
model.FieldWscSyncStatus: skuBind.WscSyncStatus | model.SyncFlagSaleMask | model.SyncFlagModifiedMask,
|
model.FieldWscSyncStatus: skuBind.WscSyncStatus | model.SyncFlagSaleMask,
|
||||||
}, userName, map[string]interface{}{
|
}, userName, map[string]interface{}{
|
||||||
model.FieldStoreID: storeID,
|
model.FieldStoreID: storeID,
|
||||||
model.FieldSkuID: v.SkuID,
|
model.FieldSkuID: v.SkuID,
|
||||||
@@ -734,7 +936,21 @@ func updateStoreSkusSaleWithoutSync(ctx *jxcontext.Context, storeID int, skuBind
|
|||||||
return needSyncSkus, err
|
return needSyncSkus, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func uniqueStoreSkuBind(skuBindSkuInfos []*StoreSkuBindSkuInfo) (outSkuBindSkuInfos []*StoreSkuBindSkuInfo) {
|
||||||
|
skuIDMap := make(map[int]int)
|
||||||
|
for _, v := range skuBindSkuInfos {
|
||||||
|
if skuIDMap[v.SkuID] != 1 {
|
||||||
|
outSkuBindSkuInfos = append(outSkuBindSkuInfos, v)
|
||||||
|
skuIDMap[v.SkuID] = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return outSkuBindSkuInfos
|
||||||
|
}
|
||||||
|
|
||||||
func UpdateStoresSkusSale(ctx *jxcontext.Context, storeIDs []int, skuBindSkuInfos []*StoreSkuBindSkuInfo, userName string, isAsync, isContinueWhenError bool) (hint string, err error) {
|
func UpdateStoresSkusSale(ctx *jxcontext.Context, storeIDs []int, skuBindSkuInfos []*StoreSkuBindSkuInfo, userName string, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
|
storeIDs = uniqueStoreIDs(storeIDs)
|
||||||
|
skuBindSkuInfos = uniqueStoreSkuBind(skuBindSkuInfos)
|
||||||
|
|
||||||
var num int64
|
var num int64
|
||||||
for _, storeID := range storeIDs {
|
for _, storeID := range storeIDs {
|
||||||
skuIDs, err2 := updateStoreSkusSaleWithoutSync(ctx, storeID, skuBindSkuInfos, userName)
|
skuIDs, err2 := updateStoreSkusSaleWithoutSync(ctx, storeID, skuBindSkuInfos, userName)
|
||||||
@@ -749,7 +965,7 @@ func UpdateStoresSkusSale(ctx *jxcontext.Context, storeIDs []int, skuBindSkuInfo
|
|||||||
skuIDs = append(skuIDs, v.SkuID)
|
skuIDs = append(skuIDs, v.SkuID)
|
||||||
}
|
}
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
hint, err = CurVendorSync.SyncStoresSkus(ctx, db, nil, storeIDs, skuIDs, isAsync, isContinueWhenError)
|
hint, err = CurVendorSync.SyncStoresSkus(ctx, db, nil, storeIDs, skuIDs, false, isAsync, isContinueWhenError)
|
||||||
}
|
}
|
||||||
if num == 0 || !isAsync || hint == "" {
|
if num == 0 || !isAsync || hint == "" {
|
||||||
hint = utils.Int64ToStr(num)
|
hint = utils.Int64ToStr(num)
|
||||||
@@ -823,11 +1039,11 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode
|
|||||||
now,
|
now,
|
||||||
pricePercentage,
|
pricePercentage,
|
||||||
pricePercentage,
|
pricePercentage,
|
||||||
model.SyncFlagModifiedMask | model.SyncFlagPriceMask,
|
model.SyncFlagPriceMask,
|
||||||
model.SyncFlagModifiedMask | model.SyncFlagPriceMask,
|
model.SyncFlagPriceMask,
|
||||||
model.SyncFlagModifiedMask | model.SyncFlagPriceMask,
|
model.SyncFlagPriceMask,
|
||||||
model.SyncFlagModifiedMask | model.SyncFlagPriceMask,
|
model.SyncFlagPriceMask,
|
||||||
model.SyncFlagModifiedMask | model.SyncFlagPriceMask,
|
model.SyncFlagPriceMask,
|
||||||
toStoreID,
|
toStoreID,
|
||||||
utils.DefaultTimeValue,
|
utils.DefaultTimeValue,
|
||||||
}
|
}
|
||||||
@@ -927,11 +1143,11 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode
|
|||||||
pricePercentage,
|
pricePercentage,
|
||||||
pricePercentage,
|
pricePercentage,
|
||||||
pricePercentage,
|
pricePercentage,
|
||||||
model.SyncFlagModifiedMask | model.SyncFlagPriceMask | model.SyncFlagSaleMask,
|
model.SyncFlagStoreSkuOnlyMask,
|
||||||
model.SyncFlagModifiedMask | model.SyncFlagPriceMask | model.SyncFlagSaleMask,
|
model.SyncFlagStoreSkuOnlyMask,
|
||||||
model.SyncFlagModifiedMask | model.SyncFlagPriceMask | model.SyncFlagSaleMask,
|
model.SyncFlagStoreSkuOnlyMask,
|
||||||
model.SyncFlagModifiedMask | model.SyncFlagPriceMask | model.SyncFlagSaleMask,
|
model.SyncFlagStoreSkuOnlyMask,
|
||||||
model.SyncFlagModifiedMask | model.SyncFlagPriceMask | model.SyncFlagSaleMask,
|
model.SyncFlagStoreSkuOnlyMask,
|
||||||
toStoreID,
|
toStoreID,
|
||||||
utils.DefaultTimeValue,
|
utils.DefaultTimeValue,
|
||||||
}
|
}
|
||||||
@@ -1349,3 +1565,186 @@ func checkStoreExisting(db *dao.DaoDB, storeID int) (err error) {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RefreshStoresSkuByVendor(ctx *jxcontext.Context, storeIDs []int, vendorID int, isAsync bool) (hint string, err error) {
|
||||||
|
if vendorID != model.VendorIDJD {
|
||||||
|
return "", fmt.Errorf("此功能当前只支持京东到家平台")
|
||||||
|
}
|
||||||
|
db := dao.GetDB()
|
||||||
|
storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, model.StoreStatusAll)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if len(storeMapList) != len(storeIDs) {
|
||||||
|
return "", fmt.Errorf("门店绑定信息不匹配,请确定门店绑定且只绑定了京东平台")
|
||||||
|
}
|
||||||
|
storeMap := make(map[int]*model.StoreMap)
|
||||||
|
for _, v := range storeMapList {
|
||||||
|
if v.VendorID != vendorID {
|
||||||
|
return "", fmt.Errorf("门店%d绑定的不(只)是京东", v.StoreID)
|
||||||
|
}
|
||||||
|
storeMap[v.StoreID] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
handler := partner.GetPurchasePlatformFromVendorID(vendorID)
|
||||||
|
var storeSkuList []*model.StoreSkuBind
|
||||||
|
rootTask := tasksch.NewSeqTask(fmt.Sprintf("根据厂家门店商品信息相应刷新本地数据:%v", storeIDs), ctx,
|
||||||
|
func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||||
|
switch step {
|
||||||
|
case 0:
|
||||||
|
storeSkuList, err = handler.GetStoresSku(ctx, task, storeIDs)
|
||||||
|
case 1:
|
||||||
|
if len(storeSkuList) > 0 {
|
||||||
|
var skuList []*model.SkuAndName
|
||||||
|
skuList, err = dao.GetSkus(db, nil, nil, nil, nil)
|
||||||
|
if err == nil {
|
||||||
|
skuNameMap := make(map[int]*model.SkuName)
|
||||||
|
skuMap := make(map[int]*model.SkuAndName)
|
||||||
|
for _, sku := range skuList {
|
||||||
|
if skuNameMap[sku.NameID] == nil {
|
||||||
|
skuNameMap[sku.NameID] = &model.SkuName{
|
||||||
|
Unit: sku.Unit,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
skuMap[sku.ID] = sku
|
||||||
|
}
|
||||||
|
for _, v := range storeSkuList {
|
||||||
|
sku := skuMap[v.SkuID]
|
||||||
|
skuName := skuNameMap[sku.NameID]
|
||||||
|
if skuName.IsGlobal == 0 && (jxutils.IsSkuSpecial(sku.SpecQuality, sku.SpecUnit) || skuName.Unit != model.SpecialUnit) {
|
||||||
|
skuName.Price = v.Price
|
||||||
|
skuName.IsGlobal = 1 // 标准价
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, v := range storeSkuList {
|
||||||
|
sku := skuMap[v.SkuID]
|
||||||
|
skuName := skuNameMap[sku.NameID]
|
||||||
|
if skuName.IsGlobal == 0 {
|
||||||
|
if skuName.Price == 0 {
|
||||||
|
skuName.Price = jxutils.CaculateUnitPrice(v.Price, sku.SpecQuality, sku.SpecUnit, skuName.Unit)
|
||||||
|
} else {
|
||||||
|
skuName.Price = (skuName.Price + jxutils.CaculateUnitPrice(v.Price, sku.SpecQuality, sku.SpecUnit, skuName.Unit)) / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, v := range storeSkuList {
|
||||||
|
pricePercentage := int(storeMap[v.StoreID].PricePercentage)
|
||||||
|
skuName := skuNameMap[skuMap[v.SkuID].NameID]
|
||||||
|
v.Price = jxutils.CaculateSkuPriceFromVendor(v.Price, pricePercentage, 0)
|
||||||
|
v.UnitPrice = jxutils.CaculateSkuPriceFromVendor(skuName.Price, pricePercentage, 0)
|
||||||
|
dao.WrapAddIDCULDEntity(v, ctx.GetUserName())
|
||||||
|
setStoreSkuBindStatus(v, model.SyncFlagNewMask)
|
||||||
|
v.JdSyncStatus = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
if len(storeSkuList) > 0 {
|
||||||
|
dao.Begin(db)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil || err != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
if r != nil {
|
||||||
|
panic(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if _, err = dao.ExecuteSQL(db, `
|
||||||
|
DELETE t1
|
||||||
|
FROM store_sku_bind t1
|
||||||
|
WHERE t1.store_id IN (
|
||||||
|
`+dao.GenQuestionMarks(len(storeIDs))+")", storeIDs); err == nil {
|
||||||
|
if err = dao.CreateMultiEntities(db, storeSkuList); err == nil {
|
||||||
|
hint = utils.Int2Str(len(storeSkuList))
|
||||||
|
dao.Commit(db)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}, 3)
|
||||||
|
tasksch.ManageTask(rootTask).Run()
|
||||||
|
if isAsync {
|
||||||
|
hint = rootTask.GetID()
|
||||||
|
} else {
|
||||||
|
_, err = rootTask.GetResult(0)
|
||||||
|
}
|
||||||
|
return hint, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetVendorStoreSkusInfo(ctx *jxcontext.Context, storeID int, vendorIDs, skuIDs []int, isContinueWhenError bool) (skuVendorMap map[int][]*partner.BareStoreSkuInfo, err error) {
|
||||||
|
globals.SugarLogger.Debugf("GetVendorStoreSkusInfo, storeID:%d, vendorIDs:%v, skuID:%v", storeID, vendorIDs, skuIDs)
|
||||||
|
db := dao.GetDB()
|
||||||
|
var locker sync.RWMutex
|
||||||
|
skuVendorMap = make(map[int][]*partner.BareStoreSkuInfo)
|
||||||
|
_, err = CurVendorSync.LoopStoresMap(ctx, db, fmt.Sprintf("GetVendorStoreSkusInfo storeID:%d", storeID), false, false, vendorIDs, []int{storeID},
|
||||||
|
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||||
|
loopMapInfo := batchItemList[0].(*LoopStoreMapInfo)
|
||||||
|
if handler := CurVendorSync.GetStoreHandler(loopMapInfo.VendorID); handler != nil {
|
||||||
|
storeSkuList, err2 := dao.GetStoreSkus2(db, loopMapInfo.VendorID, storeID, skuIDs, false)
|
||||||
|
if err = err2; err == nil && len(storeSkuList) > 0 {
|
||||||
|
bareStoreSkuInfoList := make([]*partner.BareStoreSkuInfo, len(skuIDs))
|
||||||
|
for k, v := range storeSkuList {
|
||||||
|
bareStoreSkuInfoList[k] = &partner.BareStoreSkuInfo{
|
||||||
|
SkuID: v.SkuID,
|
||||||
|
VendorSkuID: v.VendorSkuID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outBareStoreSkuInfoList, err2 := handler.GetStoreSkusInfo(ctx, t, loopMapInfo.StoreMapList[0].StoreID, loopMapInfo.StoreMapList[0].VendorStoreID, bareStoreSkuInfoList)
|
||||||
|
if err = err2; err == nil && outBareStoreSkuInfoList != nil {
|
||||||
|
locker.Lock()
|
||||||
|
defer locker.Unlock()
|
||||||
|
skuVendorMap[loopMapInfo.VendorID] = outBareStoreSkuInfoList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}, true)
|
||||||
|
if err != nil {
|
||||||
|
skuVendorMap = nil
|
||||||
|
}
|
||||||
|
return skuVendorMap, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SyncJdStoreProducts(ctx *jxcontext.Context, storeIDs, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
|
db := dao.GetDB()
|
||||||
|
isManageIt := len(storeIDs) != 1 || len(skuIDs) == 0 || len(skuIDs) > 8
|
||||||
|
hint, err = CurVendorSync.LoopStoresMap(ctx, db, fmt.Sprintf("京东商家商品状态同步:%v", storeIDs), isAsync, isManageIt, []int{model.VendorIDJD}, storeIDs,
|
||||||
|
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
loopMapInfo := batchItemList[0].(*LoopStoreMapInfo)
|
||||||
|
if handler := partner.GetPurchasePlatformFromVendorID(loopMapInfo.VendorID); handler != nil {
|
||||||
|
jdHandler := handler.(*jd.PurchaseHandler)
|
||||||
|
hint, err2 := jdHandler.SyncStoreProducts(ctx, t, loopMapInfo.StoreMapList[0].StoreID, skuIDs, false, isContinueWhenError)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
retVal = []interface{}{hint}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retVal, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID)
|
||||||
|
}, isContinueWhenError)
|
||||||
|
return hint, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMissingStoreSkuFromOrder(ctx *jxcontext.Context, fromTime time.Time) (missingList []*StoreSkuBindInfo, err error) {
|
||||||
|
storeSkuList, err := dao.GetMissingStoreSkuFromOrder(dao.GetDB(), nil, fromTime)
|
||||||
|
if err == nil {
|
||||||
|
storeSkuNameMap := make(map[int64]*StoreSkuBindInfo)
|
||||||
|
for _, v := range storeSkuList {
|
||||||
|
skuName := storeSkuNameMap[jxutils.Combine2Int(v.StoreID, v.NameID)]
|
||||||
|
if skuName == nil {
|
||||||
|
skuName = &StoreSkuBindInfo{
|
||||||
|
StoreID: v.StoreID,
|
||||||
|
NameID: v.NameID,
|
||||||
|
IsFocus: 1,
|
||||||
|
IsSale: 1,
|
||||||
|
// 这里没有考虑平台价格比例
|
||||||
|
UnitPrice: jxutils.CaculateUnitPrice(v.RefPrice, v.SpecQuality, v.SpecUnit, v.Unit),
|
||||||
|
}
|
||||||
|
missingList = append(missingList, skuName)
|
||||||
|
}
|
||||||
|
skuName.Skus = append(skuName.Skus, &StoreSkuBindSkuInfo{
|
||||||
|
SkuID: v.SkuID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return missingList, err
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *StoreManager) OnStoreStatusChanged(vendorStoreID string, vendorID int, storeStatus int) (err error) {
|
func (s *StoreManager) OnStoreStatusChanged(vendorStoreID string, vendorID int, storeStatus int) (err error) {
|
||||||
|
return err
|
||||||
globals.SugarLogger.Debugf("OnStoreStatusChanged venvendorStoreID:%s, storeStatus:%d", vendorStoreID, storeStatus)
|
globals.SugarLogger.Debugf("OnStoreStatusChanged venvendorStoreID:%s, storeStatus:%d", vendorStoreID, storeStatus)
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, vendorStoreID, vendorID)
|
storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, vendorStoreID, vendorID)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
@@ -81,14 +82,14 @@ func Init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *MultiStoreHandlerWrapper) DeleteCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) {
|
func (p *MultiStoreHandlerWrapper) DeleteCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) {
|
||||||
if jxutils.IsFakeID(cat.JdID) {
|
if jxutils.IsEmptyID(cat.JdID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return p.IMultipleStoresHandler.DeleteCategory(db, cat, userName)
|
return p.IMultipleStoresHandler.DeleteCategory(db, cat, userName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *MultiStoreHandlerWrapper) UpdateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) {
|
func (p *MultiStoreHandlerWrapper) UpdateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) {
|
||||||
if jxutils.IsFakeID(cat.JdID) {
|
if jxutils.IsEmptyID(cat.JdID) {
|
||||||
globals.SugarLogger.Warnf("UpdateCategory fakeid cat:%s should not get here", utils.Format4Output(cat, true))
|
globals.SugarLogger.Warnf("UpdateCategory fakeid cat:%s should not get here", utils.Format4Output(cat, true))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -97,14 +98,14 @@ func (p *MultiStoreHandlerWrapper) UpdateCategory(db *dao.DaoDB, cat *model.SkuC
|
|||||||
|
|
||||||
func (p *MultiStoreHandlerWrapper) DeleteSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
func (p *MultiStoreHandlerWrapper) DeleteSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||||
globals.SugarLogger.Debugf("wrapper DeleteSku, sku:%s", utils.Format4Output(sku, false))
|
globals.SugarLogger.Debugf("wrapper DeleteSku, sku:%s", utils.Format4Output(sku, false))
|
||||||
if jxutils.IsFakeID(sku.JdID) {
|
if jxutils.IsEmptyID(sku.JdID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return p.IMultipleStoresHandler.DeleteSku(db, sku, userName)
|
return p.IMultipleStoresHandler.DeleteSku(db, sku, userName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *MultiStoreHandlerWrapper) UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
func (p *MultiStoreHandlerWrapper) UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) {
|
||||||
if jxutils.IsFakeID(sku.JdID) {
|
if jxutils.IsEmptyID(sku.JdID) {
|
||||||
globals.SugarLogger.Warnf("UpdateSku fakeid sku:%s should not get here", utils.Format4Output(sku, true))
|
globals.SugarLogger.Warnf("UpdateSku fakeid sku:%s should not get here", utils.Format4Output(sku, true))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -213,32 +214,36 @@ func (v *VendorSync) SyncStore(ctx *jxcontext.Context, db *dao.DaoDB, vendorID,
|
|||||||
vendorID,
|
vendorID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hint, err = v.LoopStoresMap(ctx, db, fmt.Sprintf("同步门店信息:%d", storeID), isAsync, false, vendorIDs, []int{storeID}, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
hint, err = v.LoopStoresMap(ctx, db, fmt.Sprintf("同步门店信息:%d", storeID), isAsync, false, vendorIDs, []int{storeID}, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (resultList interface{}, err error) {
|
||||||
loopMapInfo := batchItemList[0].(*LoopStoreMapInfo)
|
loopMapInfo := batchItemList[0].(*LoopStoreMapInfo)
|
||||||
handler := v.GetStoreHandler(loopMapInfo.VendorID)
|
handler := v.GetStoreHandler(loopMapInfo.VendorID)
|
||||||
if len(loopMapInfo.StoreMapList) > 1 {
|
if len(loopMapInfo.StoreMapList) > 1 {
|
||||||
loopStoreTask := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), nil, ctx,
|
loopStoreTask := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), nil, ctx,
|
||||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
var resultList []interface{}
|
||||||
storeMap := batchItemList[0].(*model.StoreMap)
|
storeMap := batchItemList[0].(*model.StoreMap)
|
||||||
if err = handler.UpdateStore(db, storeMap.StoreID, userName); err == nil {
|
if err = handler.UpdateStore(db, storeMap.StoreID, userName); err == nil {
|
||||||
storeMap.SyncStatus = 0
|
storeMap.SyncStatus = 0
|
||||||
_, err = dao.UpdateEntity(db, storeMap, model.FieldSyncStatus)
|
_, err = dao.UpdateEntity(db, storeMap, model.FieldSyncStatus)
|
||||||
|
resultList = append(resultList, 1)
|
||||||
}
|
}
|
||||||
return nil, err
|
return resultList, err
|
||||||
}, loopMapInfo.StoreMapList)
|
}, loopMapInfo.StoreMapList)
|
||||||
t.AddChild(loopStoreTask).Run()
|
t.AddChild(loopStoreTask).Run()
|
||||||
_, err = loopStoreTask.GetResult(0)
|
resultList, err = loopStoreTask.GetResult(0)
|
||||||
return nil, err
|
} else {
|
||||||
|
storeMap := loopMapInfo.StoreMapList[0]
|
||||||
|
if err = handler.UpdateStore(db, storeMap.StoreID, userName); err == nil {
|
||||||
|
storeMap.SyncStatus = 0
|
||||||
|
_, err = dao.UpdateEntity(db, storeMap, model.FieldSyncStatus)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
resultList = []interface{}{1}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
storeMap := loopMapInfo.StoreMapList[0]
|
return resultList, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID)
|
||||||
if err = handler.UpdateStore(db, storeMap.StoreID, userName); err == nil {
|
}, true)
|
||||||
storeMap.SyncStatus = 0
|
return hint, makeSyncError(err)
|
||||||
_, err = dao.UpdateEntity(db, storeMap, model.FieldSyncStatus)
|
|
||||||
}
|
|
||||||
err = jxutils.AddVendorInfo2Err(err, loopMapInfo.VendorID)
|
|
||||||
return nil, err
|
|
||||||
})
|
|
||||||
return hint, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *VendorSync) SyncSku(ctx *jxcontext.Context, db *dao.DaoDB, nameID, skuID int, isAsync, isContinueWhenError bool, userName string) (hint string, err error) {
|
func (v *VendorSync) SyncSku(ctx *jxcontext.Context, db *dao.DaoDB, nameID, skuID int, isAsync, isContinueWhenError bool, userName string) (hint string, err error) {
|
||||||
@@ -259,6 +264,7 @@ func (v *VendorSync) SyncSkus(ctx *jxcontext.Context, db *dao.DaoDB, nameIDs []i
|
|||||||
globals.SugarLogger.Debugf("SyncSku trackInfo:%s, nameIDs:%v, skuIDs:%v, userName:%s", ctx.GetTrackInfo(), nameIDs, skuIDs, userName)
|
globals.SugarLogger.Debugf("SyncSku trackInfo:%s, nameIDs:%v, skuIDs:%v, userName:%s", ctx.GetTrackInfo(), nameIDs, skuIDs, userName)
|
||||||
return v.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("同步商品信息, nameIDs:%v, skuIDs:%v", nameIDs, skuIDs), isAsync, userName,
|
return v.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("同步商品信息, nameIDs:%v, skuIDs:%v", nameIDs, skuIDs), isAsync, userName,
|
||||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||||
|
var resultList []interface{}
|
||||||
vendorID := batchItemList[0].(int)
|
vendorID := batchItemList[0].(int)
|
||||||
multiStoresHandler := v.GetMultiStoreHandler(vendorID)
|
multiStoresHandler := v.GetMultiStoreHandler(vendorID)
|
||||||
syncStatusFieldName := dao.GetSyncStatusStructField(model.VendorNames[multiStoresHandler.GetVendorID()])
|
syncStatusFieldName := dao.GetSyncStatusStructField(model.VendorNames[multiStoresHandler.GetVendorID()])
|
||||||
@@ -297,6 +303,7 @@ func (v *VendorSync) SyncSkus(ctx *jxcontext.Context, db *dao.DaoDB, nameIDs []i
|
|||||||
// todo 同一skuName下的sku顺序处理的原因是京东SPU特殊类型必须要序列化同步才能正常处理, db可能会有多线程问题
|
// todo 同一skuName下的sku顺序处理的原因是京东SPU特殊类型必须要序列化同步才能正常处理, db可能会有多线程问题
|
||||||
task := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[vendorID]), tasksch.NewParallelConfig().SetParallelCount(10).SetIsContinueWhenError(isContinueWhenError), ctx,
|
task := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[vendorID]), tasksch.NewParallelConfig().SetParallelCount(10).SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||||
|
var resultList []interface{}
|
||||||
skuName := batchItemList[0].(*model.SkuName)
|
skuName := batchItemList[0].(*model.SkuName)
|
||||||
var skuList []*model.Sku
|
var skuList []*model.Sku
|
||||||
if err = dao.GetRows(db, &skuList, fmt.Sprintf(`
|
if err = dao.GetRows(db, &skuList, fmt.Sprintf(`
|
||||||
@@ -333,6 +340,8 @@ func (v *VendorSync) SyncSkus(ctx *jxcontext.Context, db *dao.DaoDB, nameIDs []i
|
|||||||
refutil.SetObjFieldByName(sku, syncStatusFieldName, int8(0))
|
refutil.SetObjFieldByName(sku, syncStatusFieldName, int8(0))
|
||||||
if _, err = dao.UpdateEntity(db, sku, updateFields...); err != nil {
|
if _, err = dao.UpdateEntity(db, sku, updateFields...); err != nil {
|
||||||
break
|
break
|
||||||
|
} else {
|
||||||
|
resultList = append(resultList, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -342,22 +351,28 @@ func (v *VendorSync) SyncSkus(ctx *jxcontext.Context, db *dao.DaoDB, nameIDs []i
|
|||||||
refutil.SetObjFieldByName(skuName, syncStatusFieldName, int8(0))
|
refutil.SetObjFieldByName(skuName, syncStatusFieldName, int8(0))
|
||||||
_, err = dao.UpdateEntity(db, skuName, syncStatusFieldName)
|
_, err = dao.UpdateEntity(db, skuName, syncStatusFieldName)
|
||||||
}
|
}
|
||||||
return nil, err
|
return resultList, err
|
||||||
}, skuNameList)
|
}, skuNameList)
|
||||||
t.AddChild(task).Run()
|
t.AddChild(task).Run()
|
||||||
_, err = task.GetResult(0)
|
result, err2 := task.GetResult(0)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
resultList = append(resultList, result...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil, err
|
return resultList, err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *VendorSync) SyncStoresCategory(ctx *jxcontext.Context, db *dao.DaoDB, vendorIDs []int, storeIDs []int, isAsync bool) (hint string, err error) {
|
func (v *VendorSync) SyncStoresCategory(ctx *jxcontext.Context, db *dao.DaoDB, vendorIDs []int, storeIDs []int, isForce, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
globals.SugarLogger.Debug("SyncStoresCategory")
|
globals.SugarLogger.Debug("SyncStoresCategory")
|
||||||
isManageIt := len(storeIDs) != 1
|
isManageIt := len(storeIDs) != 1
|
||||||
return v.LoopStoresMap(ctx, db, fmt.Sprintf("同步门店分类信息:%v", storeIDs), isAsync, isManageIt, vendorIDs, storeIDs,
|
hint, err = v.LoopStoresMap(ctx, db, fmt.Sprintf("同步门店分类信息:%v", storeIDs), isAsync, isManageIt, vendorIDs, storeIDs,
|
||||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||||
loopMapInfo := batchItemList[0].(*LoopStoreMapInfo)
|
loopMapInfo := batchItemList[0].(*LoopStoreMapInfo)
|
||||||
if handler := v.GetSingleStoreHandler(loopMapInfo.VendorID); handler != nil {
|
if handler := v.GetSingleStoreHandler(loopMapInfo.VendorID); handler != nil {
|
||||||
|
if isForce {
|
||||||
|
dao.SetStoreCategorySyncStatus(db, loopMapInfo.VendorID, storeIDs, nil, model.SyncFlagModifiedMask)
|
||||||
|
}
|
||||||
if len(loopMapInfo.StoreMapList) > 1 {
|
if len(loopMapInfo.StoreMapList) > 1 {
|
||||||
loopStoreTask := tasksch.NewSeqTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), ctx,
|
loopStoreTask := tasksch.NewSeqTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), ctx,
|
||||||
func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||||
@@ -367,73 +382,120 @@ func (v *VendorSync) SyncStoresCategory(ctx *jxcontext.Context, db *dao.DaoDB, v
|
|||||||
}, len(loopMapInfo.StoreMapList))
|
}, len(loopMapInfo.StoreMapList))
|
||||||
t.AddChild(loopStoreTask).Run()
|
t.AddChild(loopStoreTask).Run()
|
||||||
_, err = loopStoreTask.GetResult(0)
|
_, err = loopStoreTask.GetResult(0)
|
||||||
return nil, err
|
} else {
|
||||||
|
_, err = handler.SyncStoreCategory(ctx, t, loopMapInfo.StoreMapList[0].StoreID, false)
|
||||||
}
|
}
|
||||||
_, err = handler.SyncStoreCategory(ctx, t, loopMapInfo.StoreMapList[0].StoreID, false)
|
|
||||||
err = jxutils.AddVendorInfo2Err(err, loopMapInfo.VendorID)
|
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID)
|
||||||
})
|
}, isContinueWhenError)
|
||||||
|
return hint, makeSyncError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
func (v *VendorSync) SyncStoresSkus(ctx *jxcontext.Context, db *dao.DaoDB, vendorIDs []int, storeIDs []int, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
func (v *VendorSync) SyncStoresSkus(ctx *jxcontext.Context, db *dao.DaoDB, vendorIDs []int, storeIDs []int, skuIDs []int, isForce, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
globals.SugarLogger.Debug("SyncStoresSkus")
|
globals.SugarLogger.Debug("SyncStoresSkus")
|
||||||
isManageIt := len(storeIDs) != 1 || len(skuIDs) == 0 || len(skuIDs) > 8
|
isManageIt := len(storeIDs) != 1 || len(skuIDs) == 0 || len(skuIDs) > 8
|
||||||
return v.LoopStoresMap(ctx, db, fmt.Sprintf("同步门店商品信息:%v", storeIDs), isAsync, isManageIt, vendorIDs, storeIDs,
|
task, hint, err := v.LoopStoresMap2(ctx, db, fmt.Sprintf("同步门店商品信息:%v", storeIDs), isAsync, isManageIt, vendorIDs, storeIDs,
|
||||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||||
loopMapInfo := batchItemList[0].(*LoopStoreMapInfo)
|
loopMapInfo := batchItemList[0].(*LoopStoreMapInfo)
|
||||||
if handler := v.GetStoreHandler(loopMapInfo.VendorID); handler != nil {
|
if handler := v.GetStoreHandler(loopMapInfo.VendorID); handler != nil {
|
||||||
|
if isForce {
|
||||||
|
dao.SetStoreSkuSyncStatus(db, loopMapInfo.VendorID, storeIDs, skuIDs, model.SyncFlagModifiedMask)
|
||||||
|
}
|
||||||
if len(loopMapInfo.StoreMapList) > 1 {
|
if len(loopMapInfo.StoreMapList) > 1 {
|
||||||
loopStoreTask := tasksch.NewSeqTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), ctx,
|
var loopStoreTask tasksch.ITask
|
||||||
func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
if model.MultiStoresVendorMap[loopMapInfo.VendorID] == 1 {
|
||||||
storeID := loopMapInfo.StoreMapList[step].StoreID
|
loopStoreTask = tasksch.NewSeqTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), ctx,
|
||||||
if _, err = handler.SyncStoreSkus(ctx, task, storeID, skuIDs, false, isContinueWhenError); err != nil {
|
func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||||
globals.SugarLogger.Debugf("SyncStoresSkus failed1 store:%d failed with error:%v", storeID, err)
|
storeID := loopMapInfo.StoreMapList[step].StoreID
|
||||||
if isContinueWhenError {
|
if _, err = handler.SyncStoreSkus(ctx, task, storeID, skuIDs, false, isContinueWhenError); err != nil {
|
||||||
err = nil
|
globals.SugarLogger.Debugf("SyncStoresSkus failed1 store:%d failed with error:%v", storeID, err)
|
||||||
|
if isContinueWhenError {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return nil, err
|
||||||
return nil, err
|
}, len(loopMapInfo.StoreMapList))
|
||||||
}, len(loopMapInfo.StoreMapList))
|
} else {
|
||||||
|
loopStoreTask = tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
storeMap := batchItemList[0].(*model.StoreMap)
|
||||||
|
if _, err = handler.SyncStoreSkus(ctx, task, storeMap.StoreID, skuIDs, false, isContinueWhenError); err != nil {
|
||||||
|
globals.SugarLogger.Debugf("SyncStoresSkus failed2 store:%d failed with error:%v", storeMap.StoreID, err)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}, loopMapInfo.StoreMapList)
|
||||||
|
}
|
||||||
t.AddChild(loopStoreTask).Run()
|
t.AddChild(loopStoreTask).Run()
|
||||||
_, err = loopStoreTask.GetResult(0)
|
_, err = loopStoreTask.GetResult(0)
|
||||||
return nil, err
|
} else {
|
||||||
|
_, err = handler.SyncStoreSkus(ctx, t, loopMapInfo.StoreMapList[0].StoreID, skuIDs, false, isContinueWhenError)
|
||||||
}
|
}
|
||||||
_, err = handler.SyncStoreSkus(ctx, t, loopMapInfo.StoreMapList[0].StoreID, skuIDs, false, isContinueWhenError)
|
|
||||||
err = jxutils.AddVendorInfo2Err(err, loopMapInfo.VendorID)
|
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID)
|
||||||
})
|
}, isContinueWhenError)
|
||||||
|
if task != nil {
|
||||||
|
if vendorErr := partner.IsErrChangePriceFailed(task.GetOriginalErr()); vendorErr != nil {
|
||||||
|
platformList := make([]string, len(task.GetDetailErrList()))
|
||||||
|
for k, v := range task.GetDetailErrList() {
|
||||||
|
if vendorErr := partner.IsErrVendorError(v); vendorErr != nil {
|
||||||
|
platformList[k] = model.VendorChineseNames[vendorErr.VendorID()]
|
||||||
|
} else {
|
||||||
|
platformList[k] = "未知"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = fmt.Errorf("同步价格失败\n失败平台:%s", strings.Join(platformList, ","))
|
||||||
|
} else {
|
||||||
|
err = makeSyncError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hint, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *VendorSync) FullSyncStoresSkus(ctx *jxcontext.Context, db *dao.DaoDB, vendorIDs []int, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
func (v *VendorSync) FullSyncStoresSkus(ctx *jxcontext.Context, db *dao.DaoDB, vendorIDs []int, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
globals.SugarLogger.Debug("FullSyncStoresSkus")
|
globals.SugarLogger.Debug("FullSyncStoresSkus")
|
||||||
return v.LoopStoresMap(ctx, db, fmt.Sprintf("初始化门店商品信息:%v", storeIDs), isAsync, true, vendorIDs, storeIDs,
|
hint, err = v.LoopStoresMap(ctx, db, fmt.Sprintf("初始化门店商品信息:%v", storeIDs), isAsync, true, vendorIDs, storeIDs,
|
||||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||||
loopMapInfo := batchItemList[0].(*LoopStoreMapInfo)
|
loopMapInfo := batchItemList[0].(*LoopStoreMapInfo)
|
||||||
if handler := v.GetStoreHandler(loopMapInfo.VendorID); handler != nil {
|
if handler := v.GetStoreHandler(loopMapInfo.VendorID); handler != nil {
|
||||||
if len(loopMapInfo.StoreMapList) > 1 {
|
if len(loopMapInfo.StoreMapList) > 1 {
|
||||||
loopStoreTask := tasksch.NewSeqTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), ctx,
|
var loopStoreTask tasksch.ITask
|
||||||
func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
if model.MultiStoresVendorMap[loopMapInfo.VendorID] == 1 {
|
||||||
storeID := loopMapInfo.StoreMapList[step].StoreID
|
loopStoreTask = tasksch.NewSeqTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), ctx,
|
||||||
_, err = handler.FullSyncStoreSkus(ctx, task, storeID, false, isContinueWhenError)
|
func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||||
return nil, err
|
storeID := loopMapInfo.StoreMapList[step].StoreID
|
||||||
}, len(loopMapInfo.StoreMapList))
|
if _, err = handler.FullSyncStoreSkus(ctx, task, storeID, false, isContinueWhenError); err != nil {
|
||||||
|
globals.SugarLogger.Debugf("FullSyncStoresSkus failed1 store:%d failed with error:%v", storeID, err)
|
||||||
|
if isContinueWhenError {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}, len(loopMapInfo.StoreMapList))
|
||||||
|
} else {
|
||||||
|
loopStoreTask = tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
storeMap := batchItemList[0].(*model.StoreMap)
|
||||||
|
if _, err = handler.FullSyncStoreSkus(ctx, task, storeMap.StoreID, false, isContinueWhenError); err != nil {
|
||||||
|
globals.SugarLogger.Debugf("FullSyncStoresSkus failed2 store:%d failed with error:%v", storeMap.StoreID, err)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}, loopMapInfo.StoreMapList)
|
||||||
|
}
|
||||||
t.AddChild(loopStoreTask).Run()
|
t.AddChild(loopStoreTask).Run()
|
||||||
_, err = loopStoreTask.GetResult(0)
|
_, err = loopStoreTask.GetResult(0)
|
||||||
return nil, err
|
} else {
|
||||||
|
_, err = handler.FullSyncStoreSkus(ctx, t, loopMapInfo.StoreMapList[0].StoreID, false, isContinueWhenError)
|
||||||
}
|
}
|
||||||
_, err = handler.FullSyncStoreSkus(ctx, t, loopMapInfo.StoreMapList[0].StoreID, false, isContinueWhenError)
|
|
||||||
err = jxutils.AddVendorInfo2Err(err, loopMapInfo.VendorID)
|
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID)
|
||||||
})
|
}, isContinueWhenError)
|
||||||
|
return hint, makeSyncError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *VendorSync) DeleteRemoteStoreSkus(ctx *jxcontext.Context, db *dao.DaoDB, vendorIDs []int, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
func (v *VendorSync) DeleteRemoteStoreSkus(ctx *jxcontext.Context, db *dao.DaoDB, vendorIDs []int, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
globals.SugarLogger.Debug("DeleteRemoteStoreSkus")
|
globals.SugarLogger.Debug("DeleteRemoteStoreSkus")
|
||||||
return v.LoopStoresMap(ctx, db, fmt.Sprintf("删除远程门店商品信息:%v", storeIDs), isAsync, true, vendorIDs, storeIDs,
|
hint, err = v.LoopStoresMap(ctx, db, fmt.Sprintf("删除远程门店商品信息:%v", storeIDs), isAsync, true, vendorIDs, storeIDs,
|
||||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
||||||
loopMapInfo := batchItemList[0].(*LoopStoreMapInfo)
|
loopMapInfo := batchItemList[0].(*LoopStoreMapInfo)
|
||||||
if handler := v.GetStoreHandler(loopMapInfo.VendorID); handler != nil {
|
if handler := v.GetStoreHandler(loopMapInfo.VendorID); handler != nil {
|
||||||
@@ -446,16 +508,16 @@ func (v *VendorSync) DeleteRemoteStoreSkus(ctx *jxcontext.Context, db *dao.DaoDB
|
|||||||
}, len(loopMapInfo.StoreMapList))
|
}, len(loopMapInfo.StoreMapList))
|
||||||
t.AddChild(loopStoreTask).Run()
|
t.AddChild(loopStoreTask).Run()
|
||||||
_, err = loopStoreTask.GetResult(0)
|
_, err = loopStoreTask.GetResult(0)
|
||||||
return nil, err
|
} else {
|
||||||
|
_, err = handler.DeleteRemoteStoreSkus(ctx, t, loopMapInfo.StoreMapList[0].StoreID, false, isContinueWhenError)
|
||||||
}
|
}
|
||||||
_, err = handler.DeleteRemoteStoreSkus(ctx, t, loopMapInfo.StoreMapList[0].StoreID, false, isContinueWhenError)
|
|
||||||
err = jxutils.AddVendorInfo2Err(err, loopMapInfo.VendorID)
|
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID)
|
||||||
})
|
}, isContinueWhenError)
|
||||||
|
return hint, makeSyncError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *VendorSync) LoopStoresMap(ctx *jxcontext.Context, db *dao.DaoDB, taskName string, isAsync, isManageIt bool, vendorIDs []int, storeIDs []int, handler tasksch.WorkFunc) (hint string, err error) {
|
func (v *VendorSync) LoopStoresMap2(ctx *jxcontext.Context, db *dao.DaoDB, taskName string, isAsync, isManageIt bool, vendorIDs []int, storeIDs []int, handler tasksch.WorkFunc, isContinueWhenError bool) (task tasksch.ITask, hint string, err error) {
|
||||||
sql := `
|
sql := `
|
||||||
SELECT t1.*
|
SELECT t1.*
|
||||||
FROM store_map t1
|
FROM store_map t1
|
||||||
@@ -475,11 +537,11 @@ func (v *VendorSync) LoopStoresMap(ctx *jxcontext.Context, db *dao.DaoDB, taskNa
|
|||||||
sql += " ORDER BY t1.store_id, t1.vendor_id"
|
sql += " ORDER BY t1.store_id, t1.vendor_id"
|
||||||
var storeMapList []*model.StoreMap
|
var storeMapList []*model.StoreMap
|
||||||
if err = dao.GetRows(db, &storeMapList, sql, sqlParams...); err != nil {
|
if err = dao.GetRows(db, &storeMapList, sql, sqlParams...); err != nil {
|
||||||
return "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(storeMapList) == 0 {
|
if len(storeMapList) == 0 {
|
||||||
return "", nil
|
return nil, "", nil
|
||||||
}
|
}
|
||||||
vendorStoreMap := make(map[int][]*model.StoreMap)
|
vendorStoreMap := make(map[int][]*model.StoreMap)
|
||||||
for _, v := range storeMapList {
|
for _, v := range storeMapList {
|
||||||
@@ -497,21 +559,40 @@ func (v *VendorSync) LoopStoresMap(ctx *jxcontext.Context, db *dao.DaoDB, taskNa
|
|||||||
if len(loopInfoList) == 1 {
|
if len(loopInfoList) == 1 {
|
||||||
taskName = fmt.Sprintf("%s,处理平台%s", taskName, model.VendorChineseNames[loopInfoList[0].VendorID])
|
taskName = fmt.Sprintf("%s,处理平台%s", taskName, model.VendorChineseNames[loopInfoList[0].VendorID])
|
||||||
}
|
}
|
||||||
task := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, handler, loopInfoList)
|
task = tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, handler, loopInfoList)
|
||||||
tasksch.HandleTask(task, nil, isManageIt).Run()
|
tasksch.HandleTask(task, nil, isManageIt).Run()
|
||||||
if !isAsync {
|
if !isAsync {
|
||||||
_, err = task.GetResult(0)
|
resultList, err2 := task.GetResult(0)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
if len(resultList) == 0 {
|
||||||
|
hint = "1" // todo 暂时这样
|
||||||
|
} else {
|
||||||
|
hint = jxutils.TaskResult2Hint(resultList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hint = task.GetID()
|
||||||
}
|
}
|
||||||
return task.ID, makeSyncError(err)
|
return task, hint, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *VendorSync) LoopStoresMap(ctx *jxcontext.Context, db *dao.DaoDB, taskName string, isAsync, isManageIt bool, vendorIDs []int, storeIDs []int, handler tasksch.WorkFunc, isContinueWhenError bool) (hint string, err error) {
|
||||||
|
_, hint, err = v.LoopStoresMap2(ctx, db, taskName, isAsync, isManageIt, vendorIDs, storeIDs, handler, isContinueWhenError)
|
||||||
|
return hint, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *VendorSync) LoopMultiStoresVendors(ctx *jxcontext.Context, db *dao.DaoDB, taskName string, isAsync bool, userName string, handler tasksch.WorkFunc) (hint string, err error) {
|
func (v *VendorSync) LoopMultiStoresVendors(ctx *jxcontext.Context, db *dao.DaoDB, taskName string, isAsync bool, userName string, handler tasksch.WorkFunc) (hint string, err error) {
|
||||||
task := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, handler, v.MultiStoreVendorIDs)
|
task := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, handler, v.MultiStoreVendorIDs)
|
||||||
tasksch.HandleTask(task, nil, true).Run()
|
tasksch.HandleTask(task, nil, true).Run()
|
||||||
if !isAsync {
|
if !isAsync {
|
||||||
_, err = task.GetResult(0)
|
result, err2 := task.GetResult(0)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
hint = utils.Int2Str(len(result))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hint = task.ID
|
||||||
}
|
}
|
||||||
return task.ID, makeSyncError(err)
|
return hint, makeSyncError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *VendorSync) RefreshAllSkusID(ctx *jxcontext.Context, isAsync bool, vendorIDs []int, storeIDs []int) (hint string, err error) {
|
func (v *VendorSync) RefreshAllSkusID(ctx *jxcontext.Context, isAsync bool, vendorIDs []int, storeIDs []int) (hint string, err error) {
|
||||||
@@ -552,8 +633,10 @@ func (v *VendorSync) RefreshAllStoresID(ctx *jxcontext.Context, isAsync bool, ve
|
|||||||
|
|
||||||
func makeSyncError(err error) (newErr error) {
|
func makeSyncError(err error) (newErr error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &SyncError{
|
if _, ok := err.(*SyncError); !ok {
|
||||||
Original: err,
|
return &SyncError{
|
||||||
|
Original: err,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ func SendFilesToStores(ctx *jxcontext.Context, files []*multipart.FileHeader, ti
|
|||||||
globals.SugarLogger.Debugf("SendFilesToStores upload file:%s", fileHeader.Filename)
|
globals.SugarLogger.Debugf("SendFilesToStores upload file:%s", fileHeader.Filename)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ret := storage.PutRet{}
|
ret := storage.PutRet{}
|
||||||
key := "storeBill_" + utils.Int2Str(storeID) + "_" + strings.ToLower(utils.GetUUID()) + path.Ext(fileHeader.Filename)
|
key := "storeBill/" + utils.Int2Str(storeID) + "_" + strings.ToLower(utils.GetUUID()) + path.Ext(fileHeader.Filename)
|
||||||
formUploader := storage.NewFormUploader(cfg)
|
formUploader := storage.NewFormUploader(cfg)
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
if err = formUploader.Put(context.Background(), &ret, upToken, key, file, fileHeader.Size, &storage.PutExtra{}); err == nil {
|
if err = formUploader.Put(context.Background(), &ret, upToken, key, file, fileHeader.Size, &storage.PutExtra{}); err == nil {
|
||||||
@@ -73,7 +73,7 @@ func SendFilesToStores(ctx *jxcontext.Context, files []*multipart.FileHeader, ti
|
|||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
billRec := &legacymodel.StoreBill{
|
billRec := &legacymodel.StoreBill{
|
||||||
Date: time.Now(),
|
Date: time.Now(),
|
||||||
Url: jxutils.ComposeQiniuResURL(strings.Replace(ret.Key, "http://", "https://", -1)),
|
Url: strings.Replace(jxutils.ComposeQiniuResURL(ret.Key), "http://", "https://", -1),
|
||||||
StoreId: storeID,
|
StoreId: storeID,
|
||||||
BillName: fileHeader.Filename,
|
BillName: fileHeader.Filename,
|
||||||
ShopName: shopName,
|
ShopName: shopName,
|
||||||
|
|||||||
@@ -57,86 +57,135 @@ func insertPlace(ctx *jxcontext.Context, db *dao.DaoDB, parent *autonavi.Distric
|
|||||||
}
|
}
|
||||||
|
|
||||||
func InitPlace(ctx *jxcontext.Context) (err error) {
|
func InitPlace(ctx *jxcontext.Context) (err error) {
|
||||||
|
placeList, err2 := api.AutonaviAPI.GetDistricts(autonavi.DistrictLevelDistrict, "")
|
||||||
|
if err = err2; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
placeList = placeList[0].Districts
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
if err = TruncateTable(db, "place"); err == nil {
|
dao.Begin(db)
|
||||||
placeList, err2 := api.AutonaviAPI.GetDistricts(autonavi.DistrictLevelDistrict, "")
|
defer func() {
|
||||||
if err = err2; err != nil {
|
if r := recover(); r != nil || err != nil {
|
||||||
return err
|
|
||||||
}
|
|
||||||
placeList = placeList[0].Districts
|
|
||||||
dao.Begin(db)
|
|
||||||
defer func() {
|
|
||||||
dao.Rollback(db)
|
dao.Rollback(db)
|
||||||
}()
|
if r != nil {
|
||||||
if err = insertPlace(ctx, db, nil, placeList); err != nil {
|
panic(r)
|
||||||
return err
|
|
||||||
}
|
|
||||||
updateSqls := []string{
|
|
||||||
`
|
|
||||||
UPDATE place t1
|
|
||||||
JOIN jde_city t2 ON t1.code = t2.col_tencentAddressCode
|
|
||||||
SET t1.jd_code = t2.col_areaCode;
|
|
||||||
`,
|
|
||||||
`
|
|
||||||
UPDATE place t1
|
|
||||||
JOIN place t2 ON t1.parent_code = t2.code AND t2.jd_code != 0
|
|
||||||
JOIN jde_district t3 ON t1.name = t3.col_areaName AND t2.jd_code = t3.col_cityCode
|
|
||||||
SET t1.jd_code = t3.col_areaCode
|
|
||||||
WHERE t1.level = 3;
|
|
||||||
`,
|
|
||||||
`
|
|
||||||
UPDATE
|
|
||||||
place t1
|
|
||||||
JOIN ebde_places t2 ON t1.name = t2.col_city_name
|
|
||||||
SET t1.ebai_code = t2.col_city_id
|
|
||||||
WHERE t1.level = 1 OR t1.level = 2;
|
|
||||||
`,
|
|
||||||
`
|
|
||||||
UPDATE
|
|
||||||
place t1
|
|
||||||
JOIN place t1p ON t1.parent_code = t1p.code
|
|
||||||
JOIN ebde_places t2 ON t1.name = t2.col_city_name
|
|
||||||
JOIN ebde_places t2p ON t2.col_parent_id = t2p.col_city_id AND t1p.ebai_code = t2p.col_city_id
|
|
||||||
SET t1.ebai_code = t2.col_city_id
|
|
||||||
WHERE t1.level = 3;
|
|
||||||
`,
|
|
||||||
`
|
|
||||||
UPDATE
|
|
||||||
place t1
|
|
||||||
JOIN mtpsdeliveryprice t2 ON t1.code = t2.citycode
|
|
||||||
SET t1.mtps_price = t2.price;
|
|
||||||
`,
|
|
||||||
`
|
|
||||||
UPDATE
|
|
||||||
place t1
|
|
||||||
JOIN mtpsdeliveryprice t2 ON t1.name LIKE CONCAT(t2.cityname, '%')
|
|
||||||
SET t1.mtps_price = t2.price
|
|
||||||
WHERE t1.level = 2 AND t1.mtps_price = 0;
|
|
||||||
`,
|
|
||||||
`
|
|
||||||
UPDATE place t1
|
|
||||||
LEFT JOIN (
|
|
||||||
SELECT DISTINCT city_code
|
|
||||||
FROM store
|
|
||||||
UNION DISTINCT
|
|
||||||
SELECT DISTINCT place_code city_code
|
|
||||||
FROM sku_name_place_bind
|
|
||||||
) t2 ON t1.code = t2.city_code
|
|
||||||
SET t1.enabled = 0
|
|
||||||
WHERE t1.level = 2 AND t2.city_code IS NULL;
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
for _, v := range updateSqls {
|
|
||||||
if _, err = dao.ExecuteSQL(db, v); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dao.Commit(db)
|
}()
|
||||||
|
if _, err = dao.ExecuteSQL(db, `
|
||||||
|
DELETE t1
|
||||||
|
FROM place t1
|
||||||
|
WHERE code < 9000000;
|
||||||
|
`); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
if err = insertPlace(ctx, db, nil, placeList); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
updateSqls := []string{
|
||||||
|
`
|
||||||
|
UPDATE place t1
|
||||||
|
JOIN jde_city t2 ON t1.code = t2.col_tencentAddressCode
|
||||||
|
SET t1.jd_code = t2.col_areaCode;
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
UPDATE place t1
|
||||||
|
JOIN place t2 ON t1.parent_code = t2.code AND t2.jd_code != 0
|
||||||
|
JOIN jde_district t3 ON t1.name = t3.col_areaName AND t2.jd_code = t3.col_cityCode
|
||||||
|
SET t1.jd_code = t3.col_areaCode
|
||||||
|
WHERE t1.level = 3;
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
UPDATE
|
||||||
|
place t1
|
||||||
|
JOIN ebde_places t2 ON t1.name = t2.col_city_name
|
||||||
|
SET t1.ebai_code = t2.col_city_id
|
||||||
|
WHERE t1.level = 1 OR t1.level = 2;
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
UPDATE
|
||||||
|
place t1
|
||||||
|
JOIN place t1p ON t1.parent_code = t1p.code
|
||||||
|
JOIN ebde_places t2 ON t1.name = t2.col_city_name
|
||||||
|
JOIN ebde_places t2p ON t2.col_parent_id = t2p.col_city_id AND t1p.ebai_code = t2p.col_city_id
|
||||||
|
SET t1.ebai_code = t2.col_city_id
|
||||||
|
WHERE t1.level = 3;
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
UPDATE
|
||||||
|
place t1
|
||||||
|
JOIN mtpsdeliveryprice t2 ON t1.code = t2.citycode
|
||||||
|
SET t1.mtps_price = t2.price;
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
UPDATE
|
||||||
|
place t1
|
||||||
|
JOIN mtpsdeliveryprice t2 ON t1.name LIKE CONCAT(t2.cityname, '%')
|
||||||
|
SET t1.mtps_price = t2.price
|
||||||
|
WHERE t1.level = 2 AND t1.mtps_price = 0;
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
UPDATE place t1
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT DISTINCT city_code
|
||||||
|
FROM store
|
||||||
|
UNION DISTINCT
|
||||||
|
SELECT DISTINCT place_code city_code
|
||||||
|
FROM sku_name_place_bind
|
||||||
|
) t2 ON t1.code = t2.city_code
|
||||||
|
SET t1.enabled = 0
|
||||||
|
WHERE t1.level = 2 AND t2.city_code IS NULL;
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
for _, v := range updateSqls {
|
||||||
|
if _, err = dao.ExecuteSQL(db, v); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dao.Commit(db)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitSkuName(ctx *jxcontext.Context, isForce, isAsync, isContinueWhenError bool) (hint string, err error) {
|
func RefreshSkuNameImg(ctx *jxcontext.Context, parentTask tasksch.ITask, isForce, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
|
db := dao.GetDB()
|
||||||
|
var skuNameList []*model.SkuName
|
||||||
|
if err = dao.GetRows(db, &skuNameList, `
|
||||||
|
SELECT t1.id, t1.img, MAX(t2.jd_id) jd_id
|
||||||
|
FROM sku_name t1
|
||||||
|
JOIN sku t2 ON t2.name_id = t1.id AND t2.deleted_at = ?
|
||||||
|
WHERE t1.deleted_at = ?
|
||||||
|
GROUP BY 1,2
|
||||||
|
ORDER BY t1.id
|
||||||
|
`, utils.DefaultTimeValue, utils.DefaultTimeValue); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
task := tasksch.NewParallelTask("RefreshSkuNameImg", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
skuName := batchItemList[0].(*model.SkuName)
|
||||||
|
if !jxutils.IsEmptyID(skuName.JdID) {
|
||||||
|
if skuName.Img == "" || isForce {
|
||||||
|
var imgList []*jdapi.SkuPageImg
|
||||||
|
if imgList, err = api.JdAPI.GetSkuPageImageInfo(skuName.JdID); err == nil {
|
||||||
|
if len(imgList) > 0 {
|
||||||
|
skuName.Img = imgList[0].Big
|
||||||
|
_, err = dao.UpdateEntity(db, skuName, "Img")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}, skuNameList)
|
||||||
|
tasksch.HandleTask(task, parentTask, true).Run()
|
||||||
|
if !isAsync {
|
||||||
|
_, err = task.GetResult(0)
|
||||||
|
} else {
|
||||||
|
hint = task.ID
|
||||||
|
}
|
||||||
|
return hint, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func RefreshImgMd5(ctx *jxcontext.Context, parentTask tasksch.ITask, isForce, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
var skuNameList []*model.SkuName
|
var skuNameList []*model.SkuName
|
||||||
if err = dao.GetRows(db, &skuNameList, `
|
if err = dao.GetRows(db, &skuNameList, `
|
||||||
@@ -169,7 +218,7 @@ func InitSkuName(ctx *jxcontext.Context, isForce, isAsync, isContinueWhenError b
|
|||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}, skuNameList)
|
}, skuNameList)
|
||||||
tasksch.ManageTask(task).Run()
|
tasksch.HandleTask(task, parentTask, true).Run()
|
||||||
if !isAsync {
|
if !isAsync {
|
||||||
_, err = task.GetResult(0)
|
_, err = task.GetResult(0)
|
||||||
} else {
|
} else {
|
||||||
@@ -178,6 +227,26 @@ func InitSkuName(ctx *jxcontext.Context, isForce, isAsync, isContinueWhenError b
|
|||||||
return hint, err
|
return hint, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func InitSkuName(ctx *jxcontext.Context, isForce, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
|
rootTask := tasksch.NewSeqTask("InitSkuName", ctx,
|
||||||
|
func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||||
|
switch step {
|
||||||
|
case 0:
|
||||||
|
_, err = RefreshSkuNameImg(ctx, task, isForce, false, isContinueWhenError)
|
||||||
|
case 1:
|
||||||
|
_, err = RefreshImgMd5(ctx, task, isForce, false, isContinueWhenError)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}, 2)
|
||||||
|
tasksch.ManageTask(rootTask).Run()
|
||||||
|
if !isAsync {
|
||||||
|
_, err = rootTask.GetResult(0)
|
||||||
|
} else {
|
||||||
|
hint = rootTask.ID
|
||||||
|
}
|
||||||
|
return hint, err
|
||||||
|
}
|
||||||
|
|
||||||
func InitVendorCategory(ctx *jxcontext.Context, vendorID int) (num int64, err error) {
|
func InitVendorCategory(ctx *jxcontext.Context, vendorID int) (num int64, err error) {
|
||||||
if handler := partner.GetPurchasePlatformFromVendorID(vendorID); handler != nil {
|
if handler := partner.GetPurchasePlatformFromVendorID(vendorID); handler != nil {
|
||||||
cats, err2 := handler.GetVendorCategories(ctx)
|
cats, err2 := handler.GetVendorCategories(ctx)
|
||||||
@@ -437,7 +506,7 @@ func BuildSkuFromEbaiStore(ctx *jxcontext.Context, baiduShopID int64, isAsync, i
|
|||||||
}
|
}
|
||||||
price := sku.LinkID
|
price := sku.LinkID
|
||||||
sku.LinkID = 0
|
sku.LinkID = 0
|
||||||
skuName := jxutils.ComposeSkuName(skuNameExt.Prefix, skuNameExt.Name, sku.Comment, skuNameExt.Unit, sku.SpecQuality, sku.SpecUnit, jdapi.MaxSkuNameLen)
|
skuName := jxutils.ComposeSkuName(skuNameExt.Prefix, skuNameExt.Name, sku.Comment, skuNameExt.Unit, sku.SpecQuality, sku.SpecUnit, jdapi.MaxSkuNameCharCount)
|
||||||
fixedStatus := 1
|
fixedStatus := 1
|
||||||
if sku.Status != model.SkuStatusNormal {
|
if sku.Status != model.SkuStatusNormal {
|
||||||
fixedStatus = 2
|
fixedStatus = 2
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
"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/jxutils/tasksch"
|
||||||
@@ -47,11 +48,10 @@ func RefreshRealMobile(ctx *jxcontext.Context, vendorID int, fromTime, toTime ti
|
|||||||
sql := `
|
sql := `
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM goods_order
|
FROM goods_order
|
||||||
WHERE vendor_id = ? AND consignee_mobile2 = '' AND order_created_at <= ?
|
WHERE vendor_id = ? AND consignee_mobile2 = ''
|
||||||
`
|
`
|
||||||
sqlParams := []interface{}{
|
sqlParams := []interface{}{
|
||||||
vendorID,
|
vendorID,
|
||||||
time.Now().Add(-4 * time.Hour), // 最近的刷新意义不大
|
|
||||||
}
|
}
|
||||||
if !utils.IsTimeZero(fromTime) {
|
if !utils.IsTimeZero(fromTime) {
|
||||||
sql += " AND order_created_at >= ?"
|
sql += " AND order_created_at >= ?"
|
||||||
@@ -97,29 +97,6 @@ func StartGetCityStoreInfo() {
|
|||||||
}
|
}
|
||||||
cityCenters = append(cityCenters, guiyang)
|
cityCenters = append(cityCenters, guiyang)
|
||||||
GetCityStoreInfo(cityCenters)
|
GetCityStoreInfo(cityCenters)
|
||||||
// countries, err := api.AutonaviAPI.GetDistricts(2, "")
|
|
||||||
// if err == nil {
|
|
||||||
// cityCenters := make([]*CityCenter, 0)
|
|
||||||
// country := countries[0]
|
|
||||||
// districts := country.Districts
|
|
||||||
// for _, province := range districts { // 省
|
|
||||||
// for _, city := range province.Districts { // 市
|
|
||||||
// // globals.SugarLogger.Debug(utils.Format4Output(city.Name, false))
|
|
||||||
// cityCenter := &CityCenter{
|
|
||||||
// Lng: city.Lng,
|
|
||||||
// Lat: city.Lat,
|
|
||||||
// CityName: city.Name,
|
|
||||||
// }
|
|
||||||
// // globals.SugarLogger.Debug(utils.Format4Output(cityCenter, false))
|
|
||||||
// cityCenters = append(cityCenters, cityCenter)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // globals.SugarLogger.Debug(utils.Format4Output(cityCenters, false))
|
|
||||||
// GetCityStoreInfo(cityCenters)
|
|
||||||
// }
|
|
||||||
// utils.AfterFuncWithRecover(12*time.Hour, func() {
|
|
||||||
// StartGetCityStoreInfo()
|
|
||||||
// })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetCityStoreInfo(cityCenters []*CityCenter) {
|
func GetCityStoreInfo(cityCenters []*CityCenter) {
|
||||||
@@ -233,63 +210,6 @@ func SaveEbaiStoreInfo(storeId, cityName string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// func GetCityStoreInfo(cityCenters []*CityCenter, i int) {
|
|
||||||
// cityCenter := cityCenters[i]
|
|
||||||
// cityPoints := GetCityPoints(cityCenter.lng, cityCenter.lat)
|
|
||||||
// GetJdCityPointsStores(jxcontext.AdminCtx, cityPoints, true, true)
|
|
||||||
// utils.AfterFuncWithRecover(10*time.Minute, func() {
|
|
||||||
// GetEbaiCityPointsStores(jxcontext.AdminCtx, cityPoints, true, true)
|
|
||||||
// utils.AfterFuncWithRecover(10*time.Minute, func() {
|
|
||||||
// i++
|
|
||||||
// if i < len(cityCenters) {
|
|
||||||
// GetCityStoreInfo(cityCenters, i)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func GetJdCityPointsStores(ctx *jxcontext.Context, cityPoints [][]string, isAsync, isContinueWhenError bool) (hint string, err error) {
|
|
||||||
// if len(cityPoints) > 0 {
|
|
||||||
// task := tasksch.NewParallelTask("misc GetJdCityPointsStores", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
|
||||||
// func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
// // globals.SugarLogger.Debug(batchItemList)
|
|
||||||
// point := batchItemList[0].([]string)
|
|
||||||
// err2 := jd.OnSaveStoreListInfo(point[0], point[1])
|
|
||||||
// if err = err2; err != nil {
|
|
||||||
// globals.SugarLogger.Infof("GetJdCityPointsStores point:%s,%s failed with error:%v", point[0], point[1], err)
|
|
||||||
// }
|
|
||||||
// return nil, err
|
|
||||||
// }, cityPoints)
|
|
||||||
// // globals.SugarLogger.Debug(utils.Format4Output(task, false))
|
|
||||||
// tasksch.HandleTask(task, nil, true).Run()
|
|
||||||
// hint = task.ID
|
|
||||||
// if !isAsync {
|
|
||||||
// _, err = task.GetResult(0)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return hint, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func GetEbaiCityPointsStores(ctx *jxcontext.Context, cityPoints [][]string, isAsync, isContinueWhenError bool) (hint string, err error) {
|
|
||||||
// if len(cityPoints) > 0 {
|
|
||||||
// task := tasksch.NewParallelTask("misc GetEbaiCityPointsStores", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
|
||||||
// func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
|
||||||
// point := batchItemList[0].([]interface{})
|
|
||||||
// err2 := ebai.OnSaveStoreListInfo(point[0].(string), point[1].(string))
|
|
||||||
// if err = err2; err != nil {
|
|
||||||
// globals.SugarLogger.Infof("GetEbaiCityPointsStores point:%s,%s failed with error:%v", point[0].(string), point[1].(string), err)
|
|
||||||
// }
|
|
||||||
// return nil, err
|
|
||||||
// }, cityPoints)
|
|
||||||
// tasksch.HandleTask(task, nil, true).Run()
|
|
||||||
// hint = task.ID
|
|
||||||
// if !isAsync {
|
|
||||||
// _, err = task.GetResult(0)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return hint, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
func GetCityPoints(lng float64, lat float64, cityName string) (cityPoints [][]string) {
|
func GetCityPoints(lng float64, lat float64, cityName string) (cityPoints [][]string) {
|
||||||
oneDu := 111319.55
|
oneDu := 111319.55
|
||||||
for a := 0; a <= 80; a++ {
|
for a := 0; a <= 80; a++ {
|
||||||
@@ -309,3 +229,25 @@ func GetCityPoints(lng float64, lat float64, cityName string) (cityPoints [][]st
|
|||||||
}
|
}
|
||||||
return cityPoints
|
return cityPoints
|
||||||
}
|
}
|
||||||
|
func StartDailyWork() {
|
||||||
|
if globals.ReallyCallPlatformAPI {
|
||||||
|
now := time.Now()
|
||||||
|
runTime := time.Date(now.Year(), now.Month(), now.Day(), 21, 0, 0, 0, time.Local) // 凌晨00:25点开始执行
|
||||||
|
waitDuration := runTime.Sub(now)
|
||||||
|
if waitDuration < 5*time.Second {
|
||||||
|
waitDuration += 24 * time.Hour
|
||||||
|
}
|
||||||
|
globals.SugarLogger.Debugf("dailyWork waitDuration:%d minutes", waitDuration/time.Minute)
|
||||||
|
utils.AfterFuncWithRecover(waitDuration, func() {
|
||||||
|
doDailyWork()
|
||||||
|
StartDailyWork()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func doDailyWork() {
|
||||||
|
globals.SugarLogger.Debug("doDailyWork")
|
||||||
|
cms.EnableHaveRestStores(jxcontext.AdminCtx, true, true)
|
||||||
|
// cms.CurVendorSync.FullSyncStoresSkus(jxcontext.AdminCtx, dao.GetDB(), []int{model.VendorIDJD}, nil, true, true)
|
||||||
|
cms.CurVendorSync.SyncStoresSkus(jxcontext.AdminCtx, dao.GetDB(), []int{model.VendorIDJD, model.VendorIDEBAI, model.VendorIDMTWM}, nil, nil, false, true, true)
|
||||||
|
}
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ type SkuPrice struct {
|
|||||||
Price int `json:"price"` // 分,这个不是单价,是这个sku的活动价
|
Price int `json:"price"` // 分,这个不是单价,是这个sku的活动价
|
||||||
LimitSkuCount int `json:"limitSkuCount"`
|
LimitSkuCount int `json:"limitSkuCount"`
|
||||||
IsLock int8 `json:"isLock"`
|
IsLock int8 `json:"isLock"`
|
||||||
|
|
||||||
|
EarningPrice int `json:"earningPrice"` // 活动商品设置,结算给门店老板的钱
|
||||||
}
|
}
|
||||||
|
|
||||||
type tPromotionItemInfo struct {
|
type tPromotionItemInfo struct {
|
||||||
@@ -131,7 +133,7 @@ var (
|
|||||||
type JdPromotionHandler interface {
|
type JdPromotionHandler interface {
|
||||||
CreatePromotionInfos(name string, beginDate, endDate time.Time, outInfoId, advertising string) (infoId int64, err error)
|
CreatePromotionInfos(name string, beginDate, endDate time.Time, outInfoId, advertising string) (infoId int64, err error)
|
||||||
CreatePromotionRules(infoId int64, outInfoId string, limitDevice, limitPin, limitCount, limitDaily int) (err error)
|
CreatePromotionRules(infoId int64, outInfoId string, limitDevice, limitPin, limitCount, limitDaily int) (err error)
|
||||||
CreatePromotionSku(infoId int64, outInfoId string, skus []map[string]interface{}) (skusResult []map[string]interface{}, err error)
|
CreatePromotionSku(infoId int64, outInfoId string, skus []*jdapi.PromotionSku) (skusResult []*jdapi.PromotionSku, err error)
|
||||||
ConfirmPromotion(infoId int64, outInfoId string) (err error)
|
ConfirmPromotion(infoId int64, outInfoId string) (err error)
|
||||||
CancelPromotion(infoId int64, outInfoId string) (err error)
|
CancelPromotion(infoId int64, outInfoId string) (err error)
|
||||||
}
|
}
|
||||||
@@ -140,38 +142,38 @@ type JdDirectDownHandler struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *JdDirectDownHandler) CreatePromotionInfos(name string, beginDate, endDate time.Time, outInfoId, advertising string) (infoId int64, err error) {
|
func (p *JdDirectDownHandler) CreatePromotionInfos(name string, beginDate, endDate time.Time, outInfoId, advertising string) (infoId int64, err error) {
|
||||||
return api.JdAPI.CreatePromotionInfosSingle(name, beginDate, endDate, outInfoId, advertising)
|
return api.JdAPI.CreatePromotionInfosSingle(name, beginDate, endDate, outInfoId, advertising, "")
|
||||||
}
|
}
|
||||||
func (p *JdDirectDownHandler) CreatePromotionRules(infoId int64, outInfoId string, limitDevice, limitPin, limitCount, limitDaily int) (err error) {
|
func (p *JdDirectDownHandler) CreatePromotionRules(infoId int64, outInfoId string, limitDevice, limitPin, limitCount, limitDaily int) (err error) {
|
||||||
return api.JdAPI.CreatePromotionRules(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily)
|
return api.JdAPI.CreatePromotionRulesSingle(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily, "")
|
||||||
}
|
}
|
||||||
func (p *JdDirectDownHandler) CreatePromotionSku(infoId int64, outInfoId string, skus []map[string]interface{}) (skusResult []map[string]interface{}, err error) {
|
func (p *JdDirectDownHandler) CreatePromotionSku(infoId int64, outInfoId string, skus []*jdapi.PromotionSku) (skusResult []*jdapi.PromotionSku, err error) {
|
||||||
return api.JdAPI.CreatePromotionSkuSingle(infoId, outInfoId, skus)
|
return api.JdAPI.CreatePromotionSkuSingle(infoId, outInfoId, skus, "")
|
||||||
}
|
}
|
||||||
func (p *JdDirectDownHandler) ConfirmPromotion(infoId int64, outInfoId string) (err error) {
|
func (p *JdDirectDownHandler) ConfirmPromotion(infoId int64, outInfoId string) (err error) {
|
||||||
return api.JdAPI.ConfirmPromotionSingle(infoId, outInfoId)
|
return api.JdAPI.ConfirmPromotionSingle(infoId, outInfoId, "")
|
||||||
}
|
}
|
||||||
func (p *JdDirectDownHandler) CancelPromotion(infoId int64, outInfoId string) (err error) {
|
func (p *JdDirectDownHandler) CancelPromotion(infoId int64, outInfoId string) (err error) {
|
||||||
return api.JdAPI.CancelPromotionSingle(infoId, outInfoId)
|
return api.JdAPI.CancelPromotionSingle(infoId, outInfoId, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
type JdLimitedTimeHandler struct {
|
type JdLimitedTimeHandler struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *JdLimitedTimeHandler) CreatePromotionInfos(name string, beginDate, endDate time.Time, outInfoId, advertising string) (infoId int64, err error) {
|
func (p *JdLimitedTimeHandler) CreatePromotionInfos(name string, beginDate, endDate time.Time, outInfoId, advertising string) (infoId int64, err error) {
|
||||||
return api.JdAPI.CreatePromotionInfosLimitTime(name, beginDate, endDate, outInfoId, advertising)
|
return api.JdAPI.CreatePromotionInfosLimitTime(name, beginDate, endDate, outInfoId, advertising, "")
|
||||||
}
|
}
|
||||||
func (p *JdLimitedTimeHandler) CreatePromotionRules(infoId int64, outInfoId string, limitDevice, limitPin, limitCount, limitDaily int) (err error) {
|
func (p *JdLimitedTimeHandler) CreatePromotionRules(infoId int64, outInfoId string, limitDevice, limitPin, limitCount, limitDaily int) (err error) {
|
||||||
return api.JdAPI.CreatePromotionRules(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily)
|
return api.JdAPI.CreatePromotionRulesLimitTime(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily, "")
|
||||||
}
|
}
|
||||||
func (p *JdLimitedTimeHandler) CreatePromotionSku(infoId int64, outInfoId string, skus []map[string]interface{}) (skusResult []map[string]interface{}, err error) {
|
func (p *JdLimitedTimeHandler) CreatePromotionSku(infoId int64, outInfoId string, skus []*jdapi.PromotionSku) (skusResult []*jdapi.PromotionSku, err error) {
|
||||||
return api.JdAPI.CreatePromotionSkuLimitTime(infoId, outInfoId, skus)
|
return api.JdAPI.CreatePromotionSkuLimitTime(infoId, outInfoId, skus, "")
|
||||||
}
|
}
|
||||||
func (p *JdLimitedTimeHandler) ConfirmPromotion(infoId int64, outInfoId string) (err error) {
|
func (p *JdLimitedTimeHandler) ConfirmPromotion(infoId int64, outInfoId string) (err error) {
|
||||||
return api.JdAPI.ConfirmPromotionLimitTime(infoId, outInfoId)
|
return api.JdAPI.ConfirmPromotionLimitTime(infoId, outInfoId, "")
|
||||||
}
|
}
|
||||||
func (p *JdLimitedTimeHandler) CancelPromotion(infoId int64, outInfoId string) (err error) {
|
func (p *JdLimitedTimeHandler) CancelPromotion(infoId int64, outInfoId string) (err error) {
|
||||||
return api.JdAPI.CancelPromotionLimitTime(infoId, outInfoId)
|
return api.JdAPI.CancelPromotionLimitTime(infoId, outInfoId, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
type JdNullHandler struct {
|
type JdNullHandler struct {
|
||||||
@@ -183,7 +185,7 @@ func (p *JdNullHandler) CreatePromotionInfos(name string, beginDate, endDate tim
|
|||||||
func (p *JdNullHandler) CreatePromotionRules(infoId int64, outInfoId string, limitDevice, limitPin, limitCount, limitDaily int) (err error) {
|
func (p *JdNullHandler) CreatePromotionRules(infoId int64, outInfoId string, limitDevice, limitPin, limitCount, limitDaily int) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (p *JdNullHandler) CreatePromotionSku(infoId int64, outInfoId string, skus []map[string]interface{}) (skusResult []map[string]interface{}, err error) {
|
func (p *JdNullHandler) CreatePromotionSku(infoId int64, outInfoId string, skus []*jdapi.PromotionSku) (skusResult []*jdapi.PromotionSku, err error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
func (p *JdNullHandler) ConfirmPromotion(infoId int64, outInfoId string) (err error) {
|
func (p *JdNullHandler) ConfirmPromotion(infoId int64, outInfoId string) (err error) {
|
||||||
@@ -230,7 +232,10 @@ func Init() {
|
|||||||
// scheduleRoutine(true)
|
// scheduleRoutine(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateJdPromotion(ctx *jxcontext.Context, isIDJd bool, isAsync, isContinueWhenError bool, vendorPromotionID string, params *PromotionParams, mapData map[string]interface{}) (hint string, err error) {
|
func CreateJdPromotion(ctx *jxcontext.Context, vendorID int, isIDJd bool, isAsync, isContinueWhenError bool, vendorPromotionID string, params *PromotionParams, mapData map[string]interface{}) (hint string, err error) {
|
||||||
|
if vendorID != model.VendorIDJD && vendorID != model.VendorIDJX {
|
||||||
|
return "", fmt.Errorf("当前只支持京西与京东活动")
|
||||||
|
}
|
||||||
if vendorPromotionID != "" && len(vendorPromotionID) != len("14863853") {
|
if vendorPromotionID != "" && len(vendorPromotionID) != len("14863853") {
|
||||||
return "", fmt.Errorf("%s看起来不像是一个有效的京东活动ID,请仔细检查一下", vendorPromotionID)
|
return "", fmt.Errorf("%s看起来不像是一个有效的京东活动ID,请仔细检查一下", vendorPromotionID)
|
||||||
}
|
}
|
||||||
@@ -260,12 +265,12 @@ func CreateJdPromotion(ctx *jxcontext.Context, isIDJd bool, isAsync, isContinueW
|
|||||||
userName := ctx.GetUserName()
|
userName := ctx.GetUserName()
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
modifyPricesList := make(map[int][]*jdapi.SkuPriceInfo)
|
modifyPricesList := make(map[int][]*jdapi.SkuPriceInfo)
|
||||||
promotionPrices := make([]map[string]interface{}, len(params.StoreIDs)*len(params.SkuPrices))
|
promotionPrices := make([]*jdapi.PromotionSku, len(params.StoreIDs)*len(params.SkuPrices))
|
||||||
var jxStoreIDs []int
|
var jxStoreIDs []int
|
||||||
promotion := &model.Promotion{
|
promotion := &model.Promotion{
|
||||||
Name: params.Name,
|
Name: params.Name,
|
||||||
Advertising: params.Advertising,
|
Advertising: params.Advertising,
|
||||||
VendorID: model.VendorIDJD,
|
VendorID: vendorID,
|
||||||
Type: params.Type,
|
Type: params.Type,
|
||||||
Status: model.PromotionStatusLocalCreated,
|
Status: model.PromotionStatusLocalCreated,
|
||||||
LimitDevice: int8(limitDevice),
|
LimitDevice: int8(limitDevice),
|
||||||
@@ -278,7 +283,7 @@ func CreateJdPromotion(ctx *jxcontext.Context, isIDJd bool, isAsync, isContinueW
|
|||||||
Source: PromotionSourceOpenPlatform,
|
Source: PromotionSourceOpenPlatform,
|
||||||
}
|
}
|
||||||
|
|
||||||
if vendorPromotionID == "" {
|
if vendorPromotionID == "" && vendorID == model.VendorIDJD {
|
||||||
skuIDs := make([]int, len(params.SkuPrices))
|
skuIDs := make([]int, len(params.SkuPrices))
|
||||||
skuPriceMap := make(map[int64]*SkuPrice)
|
skuPriceMap := make(map[int64]*SkuPrice)
|
||||||
for k, v := range params.SkuPrices {
|
for k, v := range params.SkuPrices {
|
||||||
@@ -323,7 +328,7 @@ func CreateJdPromotion(ctx *jxcontext.Context, isIDJd bool, isAsync, isContinueW
|
|||||||
if promotionSkuPrice.PriceType == PriceTypePercentage {
|
if promotionSkuPrice.PriceType == PriceTypePercentage {
|
||||||
promotionSkuPrice.Price = skuBind.Price * promotionSkuPrice.Price / 100
|
promotionSkuPrice.Price = skuBind.Price * promotionSkuPrice.Price / 100
|
||||||
}
|
}
|
||||||
if promotionSkuPrice.Price >= skuBind.Price {
|
if vendorID != model.VendorIDJX && promotionSkuPrice.Price >= skuBind.Price {
|
||||||
errMsg += fmt.Sprintf("活动价大于等于原价,storeID:%d, skuID:%d\n", skuBind.StoreID, skuBind.SkuID)
|
errMsg += fmt.Sprintf("活动价大于等于原价,storeID:%d, skuID:%d\n", skuBind.StoreID, skuBind.SkuID)
|
||||||
}
|
}
|
||||||
if promotionSkuPrice.LimitSkuCount <= 0 {
|
if promotionSkuPrice.LimitSkuCount <= 0 {
|
||||||
@@ -338,13 +343,11 @@ func CreateJdPromotion(ctx *jxcontext.Context, isIDJd bool, isAsync, isContinueW
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
promotionPrices[index] = map[string]interface{}{
|
promotionPrices[index] = &jdapi.PromotionSku{
|
||||||
jdapi.KeyStationNo: utils.Str2Int64(skuBind.VendorStoreID),
|
StationNo: utils.Str2Int64(skuBind.VendorStoreID),
|
||||||
jdapi.KeySkuId: skuBind.JdSkuID,
|
SkuID: skuBind.JdSkuID,
|
||||||
// jdapi.KeyOutStationNo: utils.Int2Str(skuBind.StoreID),
|
PromotionPrice: int64(promotionSkuPrice.Price),
|
||||||
// jdapi.KeyOutSkuId: utils.Int2Str(skuBind.SkuID),
|
LimitSkuCount: promotionSkuPrice.LimitSkuCount,
|
||||||
jdapi.KeyPromotionPrice: promotionSkuPrice.Price,
|
|
||||||
jdapi.KeyLimitSkuCount: promotionSkuPrice.LimitSkuCount,
|
|
||||||
}
|
}
|
||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
@@ -402,6 +405,7 @@ func CreateJdPromotion(ctx *jxcontext.Context, isIDJd bool, isAsync, isContinueW
|
|||||||
Price: skuPrice.Price,
|
Price: skuPrice.Price,
|
||||||
LimitSkuCount: skuPrice.LimitSkuCount,
|
LimitSkuCount: skuPrice.LimitSkuCount,
|
||||||
IsLock: skuPrice.IsLock,
|
IsLock: skuPrice.IsLock,
|
||||||
|
EarningPrice: skuPrice.EarningPrice,
|
||||||
}
|
}
|
||||||
dao.WrapAddIDCULDEntity(promotionSku, ctx.GetUserName())
|
dao.WrapAddIDCULDEntity(promotionSku, ctx.GetUserName())
|
||||||
if err = dao.CreateEntity(db, promotionSku); err != nil {
|
if err = dao.CreateEntity(db, promotionSku); err != nil {
|
||||||
@@ -409,7 +413,7 @@ func CreateJdPromotion(ctx *jxcontext.Context, isIDJd bool, isAsync, isContinueW
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if vendorPromotionID == "" {
|
if vendorID != model.VendorIDJX && vendorPromotionID == "" {
|
||||||
promotionHandler := getPromotionHander(params.Type)
|
promotionHandler := getPromotionHander(params.Type)
|
||||||
if promotionHandler == nil {
|
if promotionHandler == nil {
|
||||||
return "", errors.New("非法的活动类型")
|
return "", errors.New("非法的活动类型")
|
||||||
@@ -436,7 +440,7 @@ func CreateJdPromotion(ctx *jxcontext.Context, isIDJd bool, isAsync, isContinueW
|
|||||||
for k, v := range modifyPrices {
|
for k, v := range modifyPrices {
|
||||||
modifyPrices2[k] = v.(*jdapi.SkuPriceInfo)
|
modifyPrices2[k] = v.(*jdapi.SkuPriceInfo)
|
||||||
}
|
}
|
||||||
if globals.EnableStoreWrite {
|
if globals.EnableJdStoreWrite {
|
||||||
if _, err = api.JdAPI.UpdateVendorStationPrice(utils.Int2Str(storeID), "", modifyPrices2); err != nil {
|
if _, err = api.JdAPI.UpdateVendorStationPrice(utils.Int2Str(storeID), "", modifyPrices2); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -451,9 +455,9 @@ func CreateJdPromotion(ctx *jxcontext.Context, isIDJd bool, isAsync, isContinueW
|
|||||||
} else if step == 2 {
|
} else if step == 2 {
|
||||||
task2 := tasksch.NewParallelTask("CreateJdPromotion CreatePromotionSku", tasksch.NewParallelConfig().SetBatchSize(MaxPromotionSkuCount).SetIsContinueWhenError(isContinueWhenError), ctx,
|
task2 := tasksch.NewParallelTask("CreateJdPromotion CreatePromotionSku", tasksch.NewParallelConfig().SetBatchSize(MaxPromotionSkuCount).SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params2 ...interface{}) (retVal interface{}, err error) {
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params2 ...interface{}) (retVal interface{}, err error) {
|
||||||
skus := make([]map[string]interface{}, len(batchItemList))
|
skus := make([]*jdapi.PromotionSku, len(batchItemList))
|
||||||
for k, v := range batchItemList {
|
for k, v := range batchItemList {
|
||||||
skus[k] = v.(map[string]interface{})
|
skus[k] = v.(*jdapi.PromotionSku)
|
||||||
}
|
}
|
||||||
_, err = promotionHandler.CreatePromotionSku(infoId, "", skus)
|
_, err = promotionHandler.CreatePromotionSku(infoId, "", skus)
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -510,7 +514,8 @@ func GetJdPromotions(ctx *jxcontext.Context, keyword string, params map[string]i
|
|||||||
t1.end_at,
|
t1.end_at,
|
||||||
t1.advertising,
|
t1.advertising,
|
||||||
CONCAT("[", GROUP_CONCAT(DISTINCT CONCAT('{"storeID":', t2.store_id, ', "name":"', REPLACE(REPLACE(t22.name, '\t', ''), '"', ''), '"}')), "]") store_str,
|
CONCAT("[", GROUP_CONCAT(DISTINCT CONCAT('{"storeID":', t2.store_id, ', "name":"', REPLACE(REPLACE(t22.name, '\t', ''), '"', ''), '"}')), "]") store_str,
|
||||||
CONCAT("[", GROUP_CONCAT(DISTINCT CONCAT('{"skuID":', t3.sku_id, ', "priceType":', t3.price_type, ', "price":', t3.price, ', "limitSkuCount":', t3.limit_sku_count, ', "isLock":', t3.is_lock, '}')), "]") sku_price_str
|
CONCAT("[", GROUP_CONCAT(DISTINCT CONCAT('{"skuID":', t3.sku_id, ', "priceType":', t3.price_type, ', "price":', t3.price,
|
||||||
|
', "limitSkuCount":', t3.limit_sku_count, ', "isLock":', t3.is_lock, ', "earningPrice":', t3.earning_price, '}')), "]") sku_price_str
|
||||||
FROM promotion t1
|
FROM promotion t1
|
||||||
JOIN promotion_store t2 ON t1.id = t2.promotion_id
|
JOIN promotion_store t2 ON t1.id = t2.promotion_id
|
||||||
JOIN store t22 ON t2.store_id = t22.id
|
JOIN store t22 ON t2.store_id = t22.id
|
||||||
@@ -881,6 +886,34 @@ func LockPromotionSkus(ctx *jxcontext.Context, promotionID int, isLock int, skuI
|
|||||||
return num, err
|
return num, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func UpdatePromotionSkusEarningPrice(ctx *jxcontext.Context, promotionID int, skuPriceList []*SkuPrice) (num int64, err error) {
|
||||||
|
db := dao.GetDB()
|
||||||
|
dao.Begin(db)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil || err != nil {
|
||||||
|
dao.Rollback(db)
|
||||||
|
if r != nil {
|
||||||
|
panic(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
for _, v := range skuPriceList {
|
||||||
|
var tmpNum int64
|
||||||
|
if tmpNum, err = dao.UpdateEntityLogically(db, &model.PromotionSku{}, map[string]interface{}{
|
||||||
|
"EarningPrice": v.EarningPrice,
|
||||||
|
}, ctx.GetUserName(), map[string]interface{}{
|
||||||
|
"PromotionID": promotionID,
|
||||||
|
model.FieldSkuID: v.SkuID,
|
||||||
|
model.FieldDeletedAt: utils.DefaultTimeValue,
|
||||||
|
}); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
num += tmpNum
|
||||||
|
}
|
||||||
|
dao.Commit(db)
|
||||||
|
return num, err
|
||||||
|
}
|
||||||
|
|
||||||
func OnStoreStockMsg(msg *jdapi.CallbackStoreStockMsg) (retVal *jdapi.CallbackResponse) {
|
func OnStoreStockMsg(msg *jdapi.CallbackStoreStockMsg) (retVal *jdapi.CallbackResponse) {
|
||||||
var err error
|
var err error
|
||||||
// globals.SugarLogger.Debugf("OnStoreStockMsg IsJdStoreSkuLocked:%t", storeskulock.IsJdStoreSkuLocked(msg.StationNo, msg.SkuId))
|
// globals.SugarLogger.Debugf("OnStoreStockMsg IsJdStoreSkuLocked:%t", storeskulock.IsJdStoreSkuLocked(msg.StationNo, msg.SkuId))
|
||||||
@@ -930,12 +963,12 @@ func createLocalPromotionFromRemote(promotionInfoId int64) (retVal *jdapi.Callba
|
|||||||
if err = dao.GetEntity(db, promotion, "VendorPromotionID"); dao.IsNoRowsError(err) {
|
if err = dao.GetEntity(db, promotion, "VendorPromotionID"); dao.IsNoRowsError(err) {
|
||||||
storeIDMap := make(map[int64]int)
|
storeIDMap := make(map[int64]int)
|
||||||
skuIDMap := make(map[int64]int)
|
skuIDMap := make(map[int64]int)
|
||||||
skuMap := make(map[int64]*jdapi.PromotionSkuResult)
|
skuMap := make(map[int64]*jdapi.PromotionLspQuerySkuResult)
|
||||||
// 注意,这样处理可能是有问题,我们假定的是门店信息与SKU信息的叉乘
|
// 注意,这样处理可能是有问题,我们假定的是门店信息与SKU信息的叉乘
|
||||||
for _, v := range result.SkuResultList {
|
for _, v := range result.SkuResultList {
|
||||||
storeIDMap[v.StationNo] = 1
|
storeIDMap[v.StationNo] = 1
|
||||||
skuIDMap[v.SkuId] = 1
|
skuIDMap[v.SkuID] = 1
|
||||||
skuMap[v.SkuId] = v
|
skuMap[v.SkuID] = v
|
||||||
}
|
}
|
||||||
jdStoreIDs := make([]string, len(storeIDMap))
|
jdStoreIDs := make([]string, len(storeIDMap))
|
||||||
index := 0
|
index := 0
|
||||||
@@ -970,7 +1003,7 @@ func createLocalPromotionFromRemote(promotionInfoId int64) (retVal *jdapi.Callba
|
|||||||
jxStoreIDs[k] = v.StoreID
|
jxStoreIDs[k] = v.StoreID
|
||||||
}
|
}
|
||||||
priceList := make([]*SkuPrice, len(skuList))
|
priceList := make([]*SkuPrice, len(skuList))
|
||||||
var skuResult *jdapi.PromotionSkuResult
|
var skuResult *jdapi.PromotionLspQuerySkuResult
|
||||||
for k, v := range skuList {
|
for k, v := range skuList {
|
||||||
skuResult = skuMap[v.JdID]
|
skuResult = skuMap[v.JdID]
|
||||||
priceList[k] = &SkuPrice{
|
priceList[k] = &SkuPrice{
|
||||||
@@ -985,11 +1018,11 @@ func createLocalPromotionFromRemote(promotionInfoId int64) (retVal *jdapi.Callba
|
|||||||
// globals.SugarLogger.Debugf("priceList:%s", utils.Format4Output(priceList, false))
|
// globals.SugarLogger.Debugf("priceList:%s", utils.Format4Output(priceList, false))
|
||||||
source := strings.Trim(result.Source, "来源")
|
source := strings.Trim(result.Source, "来源")
|
||||||
promotionParams := &PromotionParams{
|
promotionParams := &PromotionParams{
|
||||||
Name: source + "-" + utils.Int64ToStr(result.PromotionInfoId),
|
Name: source + "-" + utils.Int64ToStr(result.PromotionInfoID),
|
||||||
Advertising: "",
|
Advertising: "",
|
||||||
Type: result.PromotionType,
|
Type: result.PromotionType,
|
||||||
BeginAt: result.BeginTime,
|
BeginAt: result.BeginTime.GoTime(),
|
||||||
EndAt: result.EndTime,
|
EndAt: result.EndTime.GoTime(),
|
||||||
StoreIDs: jxStoreIDs,
|
StoreIDs: jxStoreIDs,
|
||||||
SkuPrices: priceList,
|
SkuPrices: priceList,
|
||||||
}
|
}
|
||||||
@@ -1002,7 +1035,7 @@ func createLocalPromotionFromRemote(promotionInfoId int64) (retVal *jdapi.Callba
|
|||||||
mapData[keyLimitDevice] = skuResult.LimitDevice
|
mapData[keyLimitDevice] = skuResult.LimitDevice
|
||||||
mapData[keyLimitPin] = skuResult.LimitPin
|
mapData[keyLimitPin] = skuResult.LimitPin
|
||||||
}
|
}
|
||||||
_, err = CreateJdPromotion(jxcontext.AdminCtx, false, true, false, utils.Int64ToStr(promotionInfoId), promotionParams, mapData)
|
_, err = CreateJdPromotion(jxcontext.AdminCtx, model.VendorIDJD, false, true, false, utils.Int64ToStr(promotionInfoId), promotionParams, mapData)
|
||||||
if dao.IsDuplicateError(err) || err == ErrLimitDeviceIsInvalid {
|
if dao.IsDuplicateError(err) || err == ErrLimitDeviceIsInvalid {
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
@@ -1048,7 +1081,7 @@ func getPromotionHander(promotionType int) JdPromotionHandler {
|
|||||||
// panic(fmt.Sprintf("unknown promotion type:%d", promotionType))
|
// panic(fmt.Sprintf("unknown promotion type:%d", promotionType))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if !globals.EnableStoreWrite {
|
if !globals.EnableJdStoreWrite {
|
||||||
promotionHandler = &JdNullHandler{}
|
promotionHandler = &JdNullHandler{}
|
||||||
}
|
}
|
||||||
return promotionHandler
|
return promotionHandler
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner/delivery"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxcallback/orderman"
|
"git.rosy.net.cn/jx-callback/business/jxcallback/orderman"
|
||||||
@@ -102,7 +104,7 @@ func Convert2JDSPU(ctx *jxcontext.Context, count int, isAsync, isContinueWhenErr
|
|||||||
skuNew2 := *sku
|
skuNew2 := *sku
|
||||||
skuNew := &skuNew2
|
skuNew := &skuNew2
|
||||||
dao.WrapAddIDCULEntity(skuNew, ctx.GetUserName())
|
dao.WrapAddIDCULEntity(skuNew, ctx.GetUserName())
|
||||||
skuNew.JdID = 0 //jxutils.GenFakeID()
|
skuNew.JdID = 0
|
||||||
skuNew.LinkID = sku.ID
|
skuNew.LinkID = sku.ID
|
||||||
skuNew.NameID = skuNameNew.ID
|
skuNew.NameID = skuNameNew.ID
|
||||||
skuNew.JdSyncStatus = model.SyncFlagNewMask
|
skuNew.JdSyncStatus = model.SyncFlagNewMask
|
||||||
@@ -277,7 +279,7 @@ func Change2JDSPU4Store(ctx *jxcontext.Context, storeIDs []int, step int, isAsyn
|
|||||||
if err = dao.GetRows(db, &skuIDs, sql, sqlParams...); err != nil {
|
if err = dao.GetRows(db, &skuIDs, sql, sqlParams...); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
hint, err = cms.CurVendorSync.SyncStoresSkus(ctx, db, []int{model.VendorIDJD}, storeIDs, skuIDs, isAsync, isContinueWhenError)
|
hint, err = cms.CurVendorSync.SyncStoresSkus(ctx, db, []int{model.VendorIDJD}, storeIDs, skuIDs, false, isAsync, isContinueWhenError)
|
||||||
return hint, err
|
return hint, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -706,7 +708,7 @@ func TransformJdSpu2Sku(ctx *jxcontext.Context, skuNameIDs []int, count int, isA
|
|||||||
subTask := tasksch.NewParallelTask(fmt.Sprintf("TransformJdSpu2Sku:%d", step), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
subTask := tasksch.NewParallelTask(fmt.Sprintf("TransformJdSpu2Sku:%d", step), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||||
func(subTask *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
func(subTask *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
skuName := batchItemList[0].(*model.SkuName)
|
skuName := batchItemList[0].(*model.SkuName)
|
||||||
if !jxutils.IsFakeID(skuName.JdID) {
|
if !jxutils.IsEmptyID(skuName.JdID) {
|
||||||
sql = `
|
sql = `
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM sku
|
FROM sku
|
||||||
@@ -727,8 +729,8 @@ func TransformJdSpu2Sku(ctx *jxcontext.Context, skuNameIDs []int, count int, isA
|
|||||||
locker.Lock()
|
locker.Lock()
|
||||||
skuIDs = append(skuIDs, sku.ID)
|
skuIDs = append(skuIDs, sku.ID)
|
||||||
locker.Unlock()
|
locker.Unlock()
|
||||||
if !jxutils.IsFakeID(sku.JdID) {
|
if !jxutils.IsEmptyID(sku.JdID) {
|
||||||
if globals.EnableStoreWrite {
|
if globals.EnableJdStoreWrite {
|
||||||
if err = api.JdAPI.UpdateSkuBaseInfo(utils.Int2Str(skuName.ID), utils.Int2Str(sku.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted)); err != nil {
|
if err = api.JdAPI.UpdateSkuBaseInfo(utils.Int2Str(skuName.ID), utils.Int2Str(sku.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted)); err != nil {
|
||||||
if errExt, ok := err.(*utils.ErrorWithCode); ok && errExt.IntCode() == 11004 {
|
if errExt, ok := err.(*utils.ErrorWithCode); ok && errExt.IntCode() == 11004 {
|
||||||
err = nil
|
err = nil
|
||||||
@@ -740,7 +742,7 @@ func TransformJdSpu2Sku(ctx *jxcontext.Context, skuNameIDs []int, count int, isA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err == nil && globals.EnableStoreWrite {
|
if err == nil && globals.EnableJdStoreWrite {
|
||||||
if err = api.JdAPI.UpdateSpu(utils.Int2Str(skuName.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusOffline)); err == nil {
|
if err = api.JdAPI.UpdateSpu(utils.Int2Str(skuName.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusOffline)); err == nil {
|
||||||
err = api.JdAPI.UpdateSpu(utils.Int2Str(skuName.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted))
|
err = api.JdAPI.UpdateSpu(utils.Int2Str(skuName.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted))
|
||||||
} else if errExt, ok := err.(*utils.ErrorWithCode); ok && errExt.IntCode() == 11035 {
|
} else if errExt, ok := err.(*utils.ErrorWithCode); ok && errExt.IntCode() == 11035 {
|
||||||
@@ -777,7 +779,7 @@ func TransformJdSpu2Sku(ctx *jxcontext.Context, skuNameIDs []int, count int, isA
|
|||||||
rootTask.AddChild(subTask).Run()
|
rootTask.AddChild(subTask).Run()
|
||||||
if _, err = subTask.GetResult(0); err == nil {
|
if _, err = subTask.GetResult(0); err == nil {
|
||||||
if len(skuIDs) > 0 {
|
if len(skuIDs) > 0 {
|
||||||
if _, err = dao.SetStoreSkuSyncStatus(db, model.VendorIDJD, -1, skuIDs, model.SyncFlagModifiedMask|model.SyncFlagPriceMask|model.SyncFlagSaleMask); err == nil {
|
if _, err = dao.SetStoreSkuSyncStatus(db, model.VendorIDJD, nil, skuIDs, model.SyncFlagStoreSkuModifiedMask); err == nil {
|
||||||
// time.Sleep(20 * time.Second)
|
// time.Sleep(20 * time.Second)
|
||||||
// _, err = cms.CurVendorSync.SyncStoresSkus(ctx, db, []int{model.VendorIDJD}, nil, skuIDs, false, isContinueWhenError)
|
// _, err = cms.CurVendorSync.SyncStoresSkus(ctx, db, []int{model.VendorIDJD}, nil, skuIDs, false, isContinueWhenError)
|
||||||
}
|
}
|
||||||
@@ -960,3 +962,29 @@ func RetrieveEbaiShopLicence(ctx *jxcontext.Context, isAsync, isContinueWhenErro
|
|||||||
}
|
}
|
||||||
return hint, err
|
return hint, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RefreshMtpsWaybillFee(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
|
var waybillList []*model.Waybill
|
||||||
|
db := dao.GetDB()
|
||||||
|
if err = dao.GetRows(db, &waybillList, `
|
||||||
|
SELECT *
|
||||||
|
FROM waybill
|
||||||
|
WHERE status_time > '2019-04-01' AND waybill_vendor_id = 102 AND desired_fee = 0
|
||||||
|
`); err == nil {
|
||||||
|
globals.SugarLogger.Debugf("RefreshMtpsWaybillFee, count:%d", len(waybillList))
|
||||||
|
rootTask := tasksch.NewParallelTask("RefreshMtpsWaybillFee", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
bill := batchItemList[0].(*model.Waybill)
|
||||||
|
bill.DesiredFee, _ = delivery.CalculateBillDeliveryFee(bill)
|
||||||
|
_, err = dao.UpdateEntity(db, bill, "DesiredFee")
|
||||||
|
return nil, err
|
||||||
|
}, waybillList)
|
||||||
|
tasksch.ManageTask(rootTask).Run()
|
||||||
|
if !isAsync {
|
||||||
|
_, err = rootTask.GetResult(0)
|
||||||
|
} else {
|
||||||
|
hint = rootTask.ID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hint, err
|
||||||
|
}
|
||||||
|
|||||||
@@ -45,19 +45,44 @@ func Obj2Excel(sheetList []*Obj2ExcelSheetConfig) []byte {
|
|||||||
} else {
|
} else {
|
||||||
excelFile.NewSheet(sheetConfig.Title)
|
excelFile.NewSheet(sheetConfig.Title)
|
||||||
}
|
}
|
||||||
for index, name := range sheetConfig.CaptionList {
|
isMemberStruct := typeInfo.Kind() == reflect.Struct
|
||||||
excelFile.SetCellStr(sheetConfig.Title, genAxis(0, index), name)
|
if isMemberStruct {
|
||||||
}
|
var indexSlice [][]int
|
||||||
for i := 0; i < valueInfo.Len(); i++ {
|
name2IndexMap := utils.GetStructNameIndex(typeInfo, "json")
|
||||||
var mapData map[string]interface{}
|
for col, name := range sheetConfig.CaptionList {
|
||||||
if typeInfo.Kind() == reflect.Struct {
|
if _, ok := name2IndexMap[name]; !ok {
|
||||||
mapData = utils.FlatMap(utils.Struct2MapByJson(valueInfo.Index(i).Interface()))
|
panic(fmt.Sprintf("col:%s不能找到相应的数据", name))
|
||||||
} else {
|
}
|
||||||
mapData = valueInfo.Index(i).Interface().(map[string]interface{})
|
indexSlice = append(indexSlice, name2IndexMap[name])
|
||||||
|
excelFile.SetCellStr(sheetConfig.Title, genAxis(0, col), name)
|
||||||
}
|
}
|
||||||
for index, name := range sheetConfig.CaptionList {
|
for i := 0; i < valueInfo.Len(); i++ {
|
||||||
// globals.SugarLogger.Debug(sheetConfig.Title, " ", genAxis(i+1, index), " ", fmt.Sprintf("%v", mapData[name]))
|
for col, index := range indexSlice {
|
||||||
excelFile.SetCellStr(sheetConfig.Title, genAxis(i+1, index), fmt.Sprintf("%v", mapData[name]))
|
excelFile.SetCellStr(sheetConfig.Title, genAxis(i+1, col), fmt.Sprint(reflect.Indirect(valueInfo.Index(i)).FieldByIndex(index).Interface()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var name2IndexMap map[string]int
|
||||||
|
if valueInfo.Len() > 0 {
|
||||||
|
oneData := valueInfo.Index(0).Interface().(map[string]interface{})
|
||||||
|
name2IndexMap = make(map[string]int)
|
||||||
|
for k := range oneData {
|
||||||
|
name2IndexMap[k] = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for col, name := range sheetConfig.CaptionList {
|
||||||
|
if name2IndexMap != nil {
|
||||||
|
if _, ok := name2IndexMap[name]; !ok {
|
||||||
|
panic(fmt.Sprintf("col:%s不能找到相应的数据", name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
excelFile.SetCellStr(sheetConfig.Title, genAxis(0, col), name)
|
||||||
|
}
|
||||||
|
for i := 0; i < valueInfo.Len(); i++ {
|
||||||
|
mapData := valueInfo.Index(i).Interface().(map[string]interface{})
|
||||||
|
for col, name := range sheetConfig.CaptionList {
|
||||||
|
excelFile.SetCellStr(sheetConfig.Title, genAxis(i+1, col), fmt.Sprint(mapData[name]))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,6 +102,10 @@ func Excel2Slice(reader io.Reader) (contents map[string][][]string) {
|
|||||||
return contents
|
return contents
|
||||||
}
|
}
|
||||||
|
|
||||||
func genAxis(row, col int) string {
|
func genAxis(row, col int) (pos string) {
|
||||||
return fmt.Sprintf("%c%d", col+65, row+1)
|
pos, err := excelize.CoordinatesToCellName(col+1, row+1)
|
||||||
|
if err != nil {
|
||||||
|
globals.SugarLogger.Debugf("err:%v", err)
|
||||||
|
}
|
||||||
|
return pos
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,47 @@
|
|||||||
package excel
|
package excel
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type XXXX struct {
|
||||||
|
ID int64 `orm:"column(id)" json:"id"`
|
||||||
|
VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"`
|
||||||
|
VendorOrderID2 string `orm:"column(vendor_order_id2);size(48);index" json:"vendorOrderID2"`
|
||||||
|
VendorID int `orm:"column(vendor_id)" json:"vendorID"`
|
||||||
|
VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"`
|
||||||
|
StoreID int `orm:"column(store_id)" json:"storeID"` // 外部系统里记录的 jxstoreid
|
||||||
|
JxStoreID int `orm:"column(jx_store_id)" json:"jxStoreID"` // 根据VendorStoreID在本地系统里查询出来的 jxstoreid
|
||||||
|
StoreName string `orm:"size(64)" json:"storeName"`
|
||||||
|
ShopPrice int64 `json:"shopPrice"` // 单位为分 门店标价
|
||||||
|
SalePrice int64 `json:"salePrice"` // 单位为分 售卖价
|
||||||
|
ActualPayPrice int64 `json:"actualPayPrice"` // 单位为分 顾客实际支付
|
||||||
|
Weight int `json:"weight"` // 单位为克
|
||||||
|
ConsigneeName string `orm:"size(32)" json:"consigneeName"`
|
||||||
|
ConsigneeMobile string `orm:"size(32)" json:"consigneeMobile"`
|
||||||
|
ConsigneeMobile2 string `orm:"size(32)" json:"consigneeMobile2"`
|
||||||
|
ConsigneeAddress string `orm:"size(255)" json:"consigneeAddress"`
|
||||||
|
CoordinateType int `json:"-"`
|
||||||
|
ConsigneeLng int `json:"-"` // 坐标 * (10的六次方)
|
||||||
|
ConsigneeLat int `json:"-"` // 坐标 * (10的六次方)
|
||||||
|
SkuCount int `json:"skuCount"` // 商品类别数量,即有多少种商品(注意在某些情况下,相同SKU的商品由于售价不同,也会当成不同商品在这个值里)
|
||||||
|
GoodsCount int `json:"goodsCount"` // 商品个数
|
||||||
|
Status int `json:"status"` // 参见OrderStatus*相关的常量定义
|
||||||
|
VendorStatus string `orm:"size(255)" json:"vendorStatus"`
|
||||||
|
LockStatus int `json:"lockStatus"`
|
||||||
|
OrderSeq int `json:"orderSeq"` // 门店订单序号
|
||||||
|
BuyerComment string `orm:"size(255)" json:"buyerComment"`
|
||||||
|
BusinessType int `json:"businessType"`
|
||||||
|
CancelApplyReason string `orm:"size(255)" json:"-"` // ""表示没有申请,不为null表示用户正在取消申请
|
||||||
|
VendorWaybillID string `orm:"column(vendor_waybill_id);size(48)" json:"vendorWaybillID"`
|
||||||
|
WaybillVendorID int `orm:"column(waybill_vendor_id)" json:"waybillVendorID"` // 表示当前承运商,-1表示还没有安排
|
||||||
|
DeliveryFlag int8 `json:"deliveryFlag"` // 第1位为1表示禁止调度器调度三方配送
|
||||||
|
DuplicatedCount int `json:"-"` // 重复新订单消息数,这个一般不是由于消息重发造成的(消息重发由OrderStatus过滤),一般是业务逻辑造成的
|
||||||
|
OriginalData string `orm:"-" json:"-"` // 只是用于传递数据
|
||||||
|
Flag int8 `json:"flag"` //非运单调整相关的其它状态
|
||||||
|
}
|
||||||
|
|
||||||
func TestObj2Excel(t *testing.T) {
|
func TestObj2Excel(t *testing.T) {
|
||||||
// kk := make([]*model.SkuName, 1)
|
// kk := make([]*model.SkuName, 1)
|
||||||
// kk[0] = &model.SkuName{
|
// kk[0] = &model.SkuName{
|
||||||
@@ -24,3 +62,49 @@ func TestObj2Excel(t *testing.T) {
|
|||||||
}
|
}
|
||||||
Obj2Excel([]*Obj2ExcelSheetConfig{cc})
|
Obj2Excel([]*Obj2ExcelSheetConfig{cc})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkObj2Excel(b *testing.B) {
|
||||||
|
const sliceLen = 1000
|
||||||
|
oneData := &XXXX{}
|
||||||
|
cc := &Obj2ExcelSheetConfig{
|
||||||
|
Title: "Title",
|
||||||
|
CaptionList: nil,
|
||||||
|
}
|
||||||
|
elmType := reflect.TypeOf(oneData)
|
||||||
|
if elmType.Kind() == reflect.Ptr {
|
||||||
|
elmType = elmType.Elem()
|
||||||
|
}
|
||||||
|
for i := 0; i < elmType.NumField(); i++ {
|
||||||
|
if jsonTag := elmType.Field(i).Tag.Get("json"); jsonTag != "" && jsonTag != "-" {
|
||||||
|
cc.CaptionList = append(cc.CaptionList, jsonTag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value := reflect.Indirect(reflect.ValueOf(oneData))
|
||||||
|
for i := 0; i < elmType.NumField(); i++ {
|
||||||
|
value2 := value.Field(i)
|
||||||
|
if value2.Kind() == reflect.String {
|
||||||
|
value2.SetString(elmType.Field(i).Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
data := make([]map[string]interface{}, sliceLen)
|
||||||
|
for k := range data {
|
||||||
|
data[k] = utils.Struct2MapByJson(oneData)
|
||||||
|
}
|
||||||
|
//*/
|
||||||
|
|
||||||
|
//*
|
||||||
|
data := make([]*XXXX, 1000)
|
||||||
|
for k := range data {
|
||||||
|
copied := *oneData
|
||||||
|
data[k] = &copied
|
||||||
|
}
|
||||||
|
//*/
|
||||||
|
|
||||||
|
cc.Data = data
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
Obj2Excel([]*Obj2ExcelSheetConfig{cc})
|
||||||
|
}
|
||||||
|
// b.Log(utils.Format4Output(data, false))
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import (
|
|||||||
"git.rosy.net.cn/jx-callback/business/jxcallback/auth"
|
"git.rosy.net.cn/jx-callback/business/jxcallback/auth"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
"github.com/astaxie/beego"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type IAuther interface {
|
type IAuther interface {
|
||||||
@@ -71,7 +70,7 @@ func New(notUsed interface{}, token string, w http.ResponseWriter, r *http.Reque
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err == model.ErrTokenIsInvalid {
|
if err == model.ErrTokenIsInvalid {
|
||||||
if beego.BConfig.RunMode != "prod" {
|
if !globals.IsProductEnv() {
|
||||||
err = nil
|
err = nil
|
||||||
} else {
|
} else {
|
||||||
errCode = model.ErrCodeTokenIsInvalid
|
errCode = model.ErrCodeTokenIsInvalid
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
package jxutils
|
package jxutils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -14,7 +17,9 @@ import (
|
|||||||
"git.rosy.net.cn/baseapi/utils/routinepool"
|
"git.rosy.net.cn/baseapi/utils/routinepool"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
|
"github.com/qiniu/api.v7/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -27,6 +32,25 @@ type SyncMapWithTimeout struct {
|
|||||||
timers sync.Map
|
timers sync.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OrderSkuList []*model.OrderSku
|
||||||
|
|
||||||
|
func (l OrderSkuList) Len() int {
|
||||||
|
return len(l)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Less reports whether the element with
|
||||||
|
// index i should sort before the element with index j.
|
||||||
|
func (l OrderSkuList) Less(i, j int) bool {
|
||||||
|
return l[i].SalePrice < l[j].SalePrice
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap swaps the elements with indexes i and j.
|
||||||
|
func (l OrderSkuList) Swap(i, j int) {
|
||||||
|
tmp := l[i]
|
||||||
|
l[i] = l[j]
|
||||||
|
l[j] = tmp
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rand.Seed(time.Now().Unix())
|
rand.Seed(time.Now().Unix())
|
||||||
routinePool = routinepool.New(1000, 1000)
|
routinePool = routinepool.New(1000, 1000)
|
||||||
@@ -82,6 +106,13 @@ func GetSkuIDFromOrderSku(sku *model.OrderSku) (skuID int) {
|
|||||||
return sku.SkuID
|
return sku.SkuID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetSaleStoreIDFromAfsOrder(order *model.AfsOrder) (retVal int) {
|
||||||
|
if order.JxStoreID > 0 {
|
||||||
|
return order.JxStoreID
|
||||||
|
}
|
||||||
|
return order.StoreID
|
||||||
|
}
|
||||||
|
|
||||||
func SplitUniversalOrderID(universalOrderID string) (orderID string, vendorID int) {
|
func SplitUniversalOrderID(universalOrderID string) (orderID string, vendorID int) {
|
||||||
index := strings.Index(universalOrderID, "|")
|
index := strings.Index(universalOrderID, "|")
|
||||||
if index != -1 {
|
if index != -1 {
|
||||||
@@ -122,6 +153,19 @@ func GetPossibleVendorIDFromVendorOrderID(vendorOrderID string) (vendorID int) {
|
|||||||
return vendorID
|
return vendorID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetPossibleVendorIDFromAfsOrderID(afsOrderID string) (vendorID int) {
|
||||||
|
vendorID = model.VendorIDUnknown
|
||||||
|
if afsOrderIDInt64 := utils.Str2Int64WithDefault(afsOrderID, 0); afsOrderIDInt64 > 0 {
|
||||||
|
orderIDLen := len(afsOrderID)
|
||||||
|
if orderIDLen == len("22586438") {
|
||||||
|
vendorID = model.VendorIDJD
|
||||||
|
} else if orderIDLen == len("579557034") {
|
||||||
|
vendorID = model.VendorIDEBAI
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vendorID
|
||||||
|
}
|
||||||
|
|
||||||
func ComposeUniversalOrderID(orderID string, vendorID int) string {
|
func ComposeUniversalOrderID(orderID string, vendorID int) string {
|
||||||
// return fmt.Sprintf("%s|%d", orderID, vendorID)
|
// return fmt.Sprintf("%s|%d", orderID, vendorID)
|
||||||
return orderID // 当前用长度就能区分,先不加上vendorID
|
return orderID // 当前用长度就能区分,先不加上vendorID
|
||||||
@@ -276,10 +320,7 @@ func ComposeSkuName(prefix, name, comment, unit string, spec_quality float32, sp
|
|||||||
skuName += "(" + comment + ")"
|
skuName += "(" + comment + ")"
|
||||||
}
|
}
|
||||||
if maxLen > 0 {
|
if maxLen > 0 {
|
||||||
runeList := []rune(skuName)
|
skuName = utils.LimitUTF8StringLen(skuName, maxLen)
|
||||||
if len(runeList) > maxLen {
|
|
||||||
skuName = string(runeList[:maxLen])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return skuName
|
return skuName
|
||||||
}
|
}
|
||||||
@@ -421,3 +462,122 @@ func HandleUserWXRemark(db *dao.DaoDB, mobile string) (err error) {
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RefreshOrderSkuRelated(order *model.GoodsOrder) *model.GoodsOrder {
|
||||||
|
order.SkuCount = 0
|
||||||
|
order.GoodsCount = 0
|
||||||
|
order.SalePrice = 0
|
||||||
|
order.VendorPrice = 0
|
||||||
|
order.Weight = 0
|
||||||
|
order.OrderCreatedAt = order.StatusTime
|
||||||
|
for _, sku := range order.Skus {
|
||||||
|
if sku.SkuID > math.MaxInt32 {
|
||||||
|
sku.SkuID = 0
|
||||||
|
}
|
||||||
|
sku.OrderCreatedAt = order.OrderCreatedAt
|
||||||
|
order.SkuCount++
|
||||||
|
order.GoodsCount += sku.Count
|
||||||
|
order.SalePrice += sku.SalePrice * int64(sku.Count)
|
||||||
|
order.VendorPrice += sku.VendorPrice * int64(sku.Count)
|
||||||
|
order.Weight += sku.Weight * sku.Count
|
||||||
|
}
|
||||||
|
return order
|
||||||
|
}
|
||||||
|
|
||||||
|
func RefreshAfsOrderSkuRelated(afsOrder *model.AfsOrder) *model.AfsOrder {
|
||||||
|
afsOrder.SkuUserMoney = 0
|
||||||
|
afsOrder.PmSkuSubsidyMoney = 0
|
||||||
|
for _, orderSku := range afsOrder.Skus {
|
||||||
|
if orderSku.SkuID > math.MaxInt32 {
|
||||||
|
orderSku.SkuID = 0
|
||||||
|
}
|
||||||
|
afsOrder.SkuUserMoney += orderSku.UserMoney
|
||||||
|
afsOrder.PmSkuSubsidyMoney += orderSku.PmSkuSubsidyMoney
|
||||||
|
}
|
||||||
|
return afsOrder
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemoveSkuFromOrder(order *model.GoodsOrder, removedSkuList []*model.OrderSku) *model.GoodsOrder {
|
||||||
|
removedSkuMap := make(map[int]*model.OrderSku)
|
||||||
|
removedSkuMap2 := make(map[string]*model.OrderSku)
|
||||||
|
for _, sku := range removedSkuList {
|
||||||
|
if skuID := GetSkuIDFromOrderSku(sku); skuID > 0 {
|
||||||
|
if removedSkuMap[skuID] == nil {
|
||||||
|
removedSkuMap[skuID] = sku
|
||||||
|
} else {
|
||||||
|
removedSkuMap[skuID].Count += sku.Count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if vendorSkuID := sku.VendorSkuID; vendorSkuID != "" {
|
||||||
|
if removedSkuMap2[vendorSkuID] == nil {
|
||||||
|
removedSkuMap2[vendorSkuID] = sku
|
||||||
|
} else {
|
||||||
|
removedSkuMap2[vendorSkuID].Count += sku.Count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var skuList []*model.OrderSku
|
||||||
|
sort.Sort(sort.Reverse(OrderSkuList(order.Skus)))
|
||||||
|
for _, sku := range order.Skus {
|
||||||
|
var removedSku *model.OrderSku
|
||||||
|
if skuID := GetSkuIDFromOrderSku(sku); skuID > 0 {
|
||||||
|
removedSku = removedSkuMap[skuID]
|
||||||
|
}
|
||||||
|
if removedSku == nil {
|
||||||
|
if vendorSkuID := sku.VendorSkuID; vendorSkuID != "" {
|
||||||
|
removedSku = removedSkuMap2[vendorSkuID]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
copiedSku := *sku
|
||||||
|
tmp := &copiedSku
|
||||||
|
if removedSku != nil {
|
||||||
|
if removedSku.Count >= sku.Count {
|
||||||
|
tmp = nil
|
||||||
|
removedSku.Count -= sku.Count
|
||||||
|
} else {
|
||||||
|
tmp.Count -= removedSku.Count
|
||||||
|
removedSku.Count = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if tmp != nil {
|
||||||
|
skuList = append(skuList, tmp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
order.Skus = skuList
|
||||||
|
return RefreshOrderSkuRelated(order)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UploadExportContent(content []byte, key string) (downloadURL string, err error) {
|
||||||
|
putPolicy := storage.PutPolicy{
|
||||||
|
Scope: globals.QiniuBucket,
|
||||||
|
Expires: 10 * 60,
|
||||||
|
DeleteAfterDays: 1,
|
||||||
|
}
|
||||||
|
upToken := putPolicy.UploadToken(api.QiniuAPI)
|
||||||
|
cfg := &storage.Config{}
|
||||||
|
formUploader := storage.NewFormUploader(cfg)
|
||||||
|
ret := storage.PutRet{}
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
if err = formUploader.Put(context.Background(), &ret, upToken, key, bytes.NewReader(content), int64(len(content)), &storage.PutExtra{}); err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
downloadURL = ComposeQiniuResURL(key)
|
||||||
|
}
|
||||||
|
return downloadURL, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func TaskResult2Hint(resultList []interface{}) (hint string) {
|
||||||
|
strList := make([]string, len(resultList))
|
||||||
|
for k, v := range resultList {
|
||||||
|
strList[k] = fmt.Sprint(v)
|
||||||
|
}
|
||||||
|
hint = strings.Join(strList, ",")
|
||||||
|
return hint
|
||||||
|
}
|
||||||
|
|
||||||
|
// 这个函数用于将两个整数合并为一单一int64,不要用于持久化的场景
|
||||||
|
func Combine2Int(int1, int2 int) (outInt int64) {
|
||||||
|
return int64(int1)*100000 + int64(int2)
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,11 +9,13 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi"
|
"git.rosy.net.cn/baseapi/platformapi"
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -82,9 +84,9 @@ func SplitStoreName(fullName, separator, defaultPrefix string) (prefix, bareName
|
|||||||
func ComposeStoreName(bareName string, vendorID int) (fullName string) {
|
func ComposeStoreName(bareName string, vendorID int) (fullName string) {
|
||||||
bareName = TrimDecorationChar(strings.Trim(bareName, "-"))
|
bareName = TrimDecorationChar(strings.Trim(bareName, "-"))
|
||||||
if vendorID == model.VendorIDJD {
|
if vendorID == model.VendorIDJD {
|
||||||
fullName = "京西菜市-" + bareName
|
fullName = globals.StoreName + "-" + bareName
|
||||||
} else {
|
} else {
|
||||||
fullName = "京西菜市(" + bareName + ")"
|
fullName = globals.StoreName + "(" + bareName + ")"
|
||||||
}
|
}
|
||||||
return fullName
|
return fullName
|
||||||
}
|
}
|
||||||
@@ -152,19 +154,24 @@ func Int64Map2List(int64Map map[int64]int) []int64 {
|
|||||||
return retVal
|
return retVal
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算SKU价格,unitPrice为一斤的单价,specQuality为质量,单位为克
|
func RegularizeSkuQuality(specQuality float32, specUnit string) (g int) {
|
||||||
func CaculateSkuPrice(unitPrice int, specQuality float32, specUnit string, skuNameUnit string) int {
|
|
||||||
if skuNameUnit != "份" {
|
|
||||||
return unitPrice
|
|
||||||
}
|
|
||||||
lowerSpecUnit := strings.ToLower(specUnit)
|
lowerSpecUnit := strings.ToLower(specUnit)
|
||||||
if lowerSpecUnit == "kg" || lowerSpecUnit == "l" {
|
if lowerSpecUnit == "kg" || lowerSpecUnit == "l" {
|
||||||
specQuality *= 1000
|
specQuality *= 1000
|
||||||
}
|
}
|
||||||
price := int(math.Round(float64(float32(unitPrice) * specQuality / 500)))
|
return int(specQuality)
|
||||||
if specQuality < 250 {
|
}
|
||||||
|
|
||||||
|
// 计算SKU价格,unitPrice为一斤的单价,specQuality为质量,单位为克
|
||||||
|
func CaculateSkuPrice(unitPrice int, specQuality float32, specUnit string, skuNameUnit string) int {
|
||||||
|
if skuNameUnit != model.SpecialUnit {
|
||||||
|
return unitPrice
|
||||||
|
}
|
||||||
|
specQuality2 := RegularizeSkuQuality(specQuality, specUnit)
|
||||||
|
price := int(math.Round(float64(unitPrice * specQuality2 / model.SpecialSpecQuality)))
|
||||||
|
if specQuality2 < 250 {
|
||||||
price = price * 110 / 100
|
price = price * 110 / 100
|
||||||
} else if specQuality < 500 {
|
} else if specQuality2 < 500 {
|
||||||
price = price * 105 / 100
|
price = price * 105 / 100
|
||||||
}
|
}
|
||||||
if price <= 0 {
|
if price <= 0 {
|
||||||
@@ -173,35 +180,100 @@ func CaculateSkuPrice(unitPrice int, specQuality float32, specUnit string, skuNa
|
|||||||
return price
|
return price
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 计算SKU标准价格,CaculateSkuPrice的逆过程
|
||||||
|
func CaculateUnitPrice(skuPrice int, specQuality float32, specUnit string, skuNameUnit string) (unitPrice int) {
|
||||||
|
if skuNameUnit != model.SpecialUnit {
|
||||||
|
return skuPrice
|
||||||
|
}
|
||||||
|
specQuality2 := RegularizeSkuQuality(specQuality, specUnit)
|
||||||
|
unitPrice = skuPrice * model.SpecialSpecQuality / specQuality2
|
||||||
|
if specQuality2 < 250 {
|
||||||
|
unitPrice = unitPrice * 100 / 110
|
||||||
|
} else if specQuality2 < 500 {
|
||||||
|
unitPrice = unitPrice * 100 / 105
|
||||||
|
}
|
||||||
|
if unitPrice <= 0 {
|
||||||
|
unitPrice = 1
|
||||||
|
}
|
||||||
|
return unitPrice
|
||||||
|
}
|
||||||
|
|
||||||
func GetSliceLen(list interface{}) int {
|
func GetSliceLen(list interface{}) int {
|
||||||
return reflect.ValueOf(list).Len()
|
return reflect.ValueOf(list).Len()
|
||||||
}
|
}
|
||||||
|
|
||||||
func CaculateSkuVendorPrice(price int, percentage int) int {
|
func CaculateSkuVendorPrice(price, percentage, catPercentage int) int {
|
||||||
storePrice := int(math.Round(float64(price*percentage) / 100))
|
if percentage <= 10 || percentage >= 400 {
|
||||||
if storePrice < 0 {
|
percentage = 100
|
||||||
storePrice = 0
|
|
||||||
}
|
}
|
||||||
return storePrice
|
if catPercentage <= 10 || catPercentage >= 400 {
|
||||||
|
catPercentage = 100
|
||||||
|
}
|
||||||
|
percentage = percentage * catPercentage / 100
|
||||||
|
vendorPrice := int(math.Round(float64(price*percentage) / 100))
|
||||||
|
if vendorPrice < 0 {
|
||||||
|
vendorPrice = 0
|
||||||
|
}
|
||||||
|
return vendorPrice
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CaculateSkuPriceFromVendor(vendorPrice, percentage, catPercentage int) int {
|
||||||
|
if percentage <= 10 || percentage >= 400 {
|
||||||
|
percentage = 100
|
||||||
|
}
|
||||||
|
if catPercentage <= 10 || catPercentage >= 400 {
|
||||||
|
catPercentage = 100
|
||||||
|
}
|
||||||
|
percentage = percentage * catPercentage / 100
|
||||||
|
price := int(math.Round(float64(vendorPrice * 100 / percentage)))
|
||||||
|
if price < 0 {
|
||||||
|
price = 0
|
||||||
|
}
|
||||||
|
return price
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsSkuSpecial(specQuality float32, specUnit string) bool {
|
||||||
|
return int(specQuality) == model.SpecialSpecQuality && (specUnit == model.SpecialSpecUnit || specUnit == model.SpecialSpecUnit2)
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastFakeID int64
|
||||||
|
var lastFakeIDMutex sync.RWMutex
|
||||||
|
|
||||||
// 生成一个不重复的临时ID
|
// 生成一个不重复的临时ID
|
||||||
func genFakeID1() int64 {
|
func genFakeID1() int64 {
|
||||||
return time.Now().UnixNano() / 1000000
|
for {
|
||||||
|
fakeID := time.Now().UnixNano() / 1000
|
||||||
|
lastFakeIDMutex.RLock()
|
||||||
|
if fakeID == lastFakeID {
|
||||||
|
lastFakeIDMutex.RUnlock()
|
||||||
|
time.Sleep(1 * time.Microsecond)
|
||||||
|
} else {
|
||||||
|
lastFakeIDMutex.RUnlock()
|
||||||
|
lastFakeIDMutex.Lock()
|
||||||
|
defer lastFakeIDMutex.Unlock()
|
||||||
|
lastFakeID = fakeID
|
||||||
|
return fakeID
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 这个用于没有打开远程同步时的假同步,生成ID使用
|
||||||
func GenFakeID() int64 {
|
func GenFakeID() int64 {
|
||||||
return genFakeID1() * 3
|
return genFakeID1() * 3
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsFakeID(id int64) bool {
|
func IsFakeID(id int64) bool {
|
||||||
if id == 0 {
|
if IsEmptyID(id) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
multiple := id / genFakeID1()
|
multiple := id / genFakeID1()
|
||||||
return multiple >= 2 && multiple <= 4
|
return multiple >= 2 && multiple <= 4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsEmptyID(id int64) bool {
|
||||||
|
return id == 0
|
||||||
|
}
|
||||||
|
|
||||||
func FormalizePageSize(pageSize int) int {
|
func FormalizePageSize(pageSize int) int {
|
||||||
if pageSize == 0 {
|
if pageSize == 0 {
|
||||||
return model.DefPageSize
|
return model.DefPageSize
|
||||||
@@ -238,11 +310,7 @@ func IsLegalStoreID(id int) bool {
|
|||||||
|
|
||||||
// 将规格转为重量
|
// 将规格转为重量
|
||||||
func FormatSkuWeight(specQuality float32, specUnit string) int {
|
func FormatSkuWeight(specQuality float32, specUnit string) int {
|
||||||
lowerSpecUnit := strings.ToLower(specUnit)
|
return RegularizeSkuQuality(specQuality, specUnit)
|
||||||
if lowerSpecUnit == "kg" || lowerSpecUnit == "l" {
|
|
||||||
specQuality *= 1000
|
|
||||||
}
|
|
||||||
return int(specQuality)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type SkuList []*model.Sku
|
type SkuList []*model.Sku
|
||||||
@@ -284,7 +352,7 @@ func DownloadFileByURL(fileURL string) (bodyData []byte, fileMD5 string, err err
|
|||||||
|
|
||||||
/////
|
/////
|
||||||
func GenPicFileName(suffix string) string {
|
func GenPicFileName(suffix string) string {
|
||||||
return fmt.Sprintf("%x%s", md5.Sum([]byte(utils.GetUUID()+suffix)), suffix)
|
return fmt.Sprintf("image/%x%s", md5.Sum([]byte(utils.GetUUID()+suffix)), suffix)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GuessVendorIDFromVendorStoreID(vendorStoreID int64) (vendorID int) {
|
func GuessVendorIDFromVendorStoreID(vendorStoreID int64) (vendorID int) {
|
||||||
@@ -293,7 +361,7 @@ func GuessVendorIDFromVendorStoreID(vendorStoreID int64) (vendorID int) {
|
|||||||
vendorID = model.VendorIDJD
|
vendorID = model.VendorIDJD
|
||||||
} else if vendorStoreID > 1234567 && vendorStoreID < 9876543 { // 美团外卖 2461713,7位
|
} else if vendorStoreID > 1234567 && vendorStoreID < 9876543 { // 美团外卖 2461713,7位
|
||||||
vendorID = model.VendorIDMTWM
|
vendorID = model.VendorIDMTWM
|
||||||
} else if vendorStoreID > 1234567890 && vendorStoreID < 9987654321 { // 饿百 2167002607,10位
|
} else if vendorStoreID > 1234567890 && vendorStoreID < 99876543210 { // 饿百 2167002607,10位,11位
|
||||||
vendorID = model.VendorIDEBAI
|
vendorID = model.VendorIDEBAI
|
||||||
} else if vendorStoreID > 123456789 && vendorStoreID < 987654321 { // 微盟微商城 132091048,9位
|
} else if vendorStoreID > 123456789 && vendorStoreID < 987654321 { // 微盟微商城 132091048,9位
|
||||||
vendorID = model.VendorIDWSC
|
vendorID = model.VendorIDWSC
|
||||||
@@ -306,10 +374,3 @@ func GuessVendorIDFromVendorStoreID(vendorStoreID int64) (vendorID int) {
|
|||||||
func GetVendorName(vendorID int) (vendorName string) {
|
func GetVendorName(vendorID int) (vendorName string) {
|
||||||
return model.VendorChineseNames[vendorID]
|
return model.VendorChineseNames[vendorID]
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddVendorInfo2Err(inErr error, vendorID int) (outErr error) {
|
|
||||||
if inErr != nil {
|
|
||||||
outErr = fmt.Errorf("处理平台%s, %s", model.VendorChineseNames[vendorID], inErr.Error())
|
|
||||||
}
|
|
||||||
return outErr
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ func SendUserMessage(userID, title, content string) (err error) {
|
|||||||
if len(content) > dingdingapi.MaxWorkContentLen {
|
if len(content) > dingdingapi.MaxWorkContentLen {
|
||||||
content = content[:dingdingapi.MaxWorkContentLen-4] + "..."
|
content = content[:dingdingapi.MaxWorkContentLen-4] + "..."
|
||||||
}
|
}
|
||||||
err = api.DingDingAPI.CorpAsyncSendSimple(auth.AuthID, content)
|
if globals.IsProductEnv() {
|
||||||
|
err = api.DingDingAPI.CorpAsyncSendSimple(auth.AuthID, content)
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
testVendorOrderID = "test"
|
testVendorOrderID = "test"
|
||||||
realTestVendorOrderID = "817102016000041"
|
realTestVendorOrderID = "901234567890123"
|
||||||
realTestOrderVendorID = model.VendorIDJD
|
realTestOrderVendorID = model.VendorIDJD
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -27,14 +27,6 @@ func PrintOrder(ctx *jxcontext.Context, vendorOrderID string, vendorID int) (pri
|
|||||||
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
|
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if vendorOrderID == realTestVendorOrderID {
|
if vendorOrderID == realTestVendorOrderID {
|
||||||
order.BuyerComment = "用户备注"
|
|
||||||
order.ConsigneeAddress = "四川省成都市某个地方"
|
|
||||||
order.ConsigneeLat = 30695171
|
|
||||||
order.ConsigneeLng = 104056984
|
|
||||||
order.ConsigneeName = "用户姓名"
|
|
||||||
order.ConsigneeMobile = "13812345678"
|
|
||||||
order.ConsigneeMobile2 = "13812345678"
|
|
||||||
order.StoreName = "京西菜市-测试门店"
|
|
||||||
order.StoreID = storeID
|
order.StoreID = storeID
|
||||||
order.JxStoreID = storeID
|
order.JxStoreID = storeID
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ func RefreshConfig(configKey string, expiresTime time.Duration, configGetter fun
|
|||||||
}
|
}
|
||||||
if handleType != 0 {
|
if handleType != 0 {
|
||||||
if curConfig.Token, curConfig.Date = configGetter(); curConfig.Token == "" {
|
if curConfig.Token, curConfig.Date = configGetter(); curConfig.Token == "" {
|
||||||
if beego.BConfig.RunMode == "prod" {
|
if globals.IsProductEnv() {
|
||||||
globals.SugarLogger.Errorf("RefreshConfig %s get empty token", configKey)
|
globals.SugarLogger.Errorf("RefreshConfig %s get empty token", configKey)
|
||||||
sleepDuration = errRefreshGap
|
sleepDuration = errRefreshGap
|
||||||
} else {
|
} else {
|
||||||
@@ -126,7 +126,7 @@ func RefreshWeixinToken() (err error) {
|
|||||||
if api.WeixinAPI != nil {
|
if api.WeixinAPI != nil {
|
||||||
err = RefreshConfig("wechat", weixinTokenExpires, func() (token string, expireTimeStr string) {
|
err = RefreshConfig("wechat", weixinTokenExpires, func() (token string, expireTimeStr string) {
|
||||||
globals.SugarLogger.Debugf("RefreshWeixinToken RunMode:%s", beego.BConfig.RunMode)
|
globals.SugarLogger.Debugf("RefreshWeixinToken RunMode:%s", beego.BConfig.RunMode)
|
||||||
if globals.IsProductEnv() {
|
if globals.IsProductEnv() || beego.BConfig.RunMode == "alpha" {
|
||||||
if globals.IsMainProductEnv() {
|
if globals.IsMainProductEnv() {
|
||||||
if tokenInfo, err := api.WeixinAPI.CBRetrieveToken(); err == nil {
|
if tokenInfo, err := api.WeixinAPI.CBRetrieveToken(); err == nil {
|
||||||
globals.SugarLogger.Debugf("RefreshWeixinToken tokenInfo:%s", utils.Format4Output(tokenInfo, true))
|
globals.SugarLogger.Debugf("RefreshWeixinToken tokenInfo:%s", utils.Format4Output(tokenInfo, true))
|
||||||
@@ -154,7 +154,7 @@ func RefreshWeixinToken() (err error) {
|
|||||||
func RefreshElmToken() (err error) {
|
func RefreshElmToken() (err error) {
|
||||||
if api.ElmAPI != nil {
|
if api.ElmAPI != nil {
|
||||||
err = RefreshConfig("eleme", elmTokenExpires, func() (string, string) {
|
err = RefreshConfig("eleme", elmTokenExpires, func() (string, string) {
|
||||||
if beego.BConfig.RunMode == "prod" {
|
if globals.IsProductEnv() {
|
||||||
if tokenInfo, err := api.ElmAPI.RefreshTokenIndividual(); err == nil {
|
if tokenInfo, err := api.ElmAPI.RefreshTokenIndividual(); err == nil {
|
||||||
tokenInfo2 := &ElmTokenForCompatible{
|
tokenInfo2 := &ElmTokenForCompatible{
|
||||||
Error: "",
|
Error: "",
|
||||||
@@ -183,7 +183,7 @@ func RefreshElmToken() (err error) {
|
|||||||
func RefreshWeimobToken() (err error) {
|
func RefreshWeimobToken() (err error) {
|
||||||
if api.WeimobAPI != nil {
|
if api.WeimobAPI != nil {
|
||||||
err = RefreshConfig("weimob", weimobTokenExpires, func() (string, string) {
|
err = RefreshConfig("weimob", weimobTokenExpires, func() (string, string) {
|
||||||
if beego.BConfig.RunMode == "prod" {
|
if globals.IsProductEnv() {
|
||||||
if tokenInfo, err := api.WeimobAPI.RefreshTokenByRefreshToken(); err == nil {
|
if tokenInfo, err := api.WeimobAPI.RefreshTokenByRefreshToken(); err == nil {
|
||||||
return string(utils.MustMarshal(tokenInfo)), utils.Time2Str(time.Now().Add((time.Duration(tokenInfo.ExpiresIn) - weimobTokenExpires/time.Second) * time.Second))
|
return string(utils.MustMarshal(tokenInfo)), utils.Time2Str(time.Now().Add((time.Duration(tokenInfo.ExpiresIn) - weimobTokenExpires/time.Second) * time.Second))
|
||||||
}
|
}
|
||||||
@@ -204,7 +204,7 @@ func RefreshDingDingToken() (err error) {
|
|||||||
api.DingDingAPI.RetrieveToken()
|
api.DingDingAPI.RetrieveToken()
|
||||||
return RefreshConfig("dingding", dingdingTokenExpires, func() (string, string) {
|
return RefreshConfig("dingding", dingdingTokenExpires, func() (string, string) {
|
||||||
globals.SugarLogger.Debugf("RefreshDingDingToken RunMode:%s", beego.BConfig.RunMode)
|
globals.SugarLogger.Debugf("RefreshDingDingToken RunMode:%s", beego.BConfig.RunMode)
|
||||||
if true { //beego.BConfig.RunMode == "prod" {
|
if true { //globals.IsProductEnv() {
|
||||||
if token, err := api.DingDingAPI.RetrieveToken(); err == nil {
|
if token, err := api.DingDingAPI.RetrieveToken(); err == nil {
|
||||||
globals.SugarLogger.Debugf("RefreshDingDingToken tokenInfo:%s", token)
|
globals.SugarLogger.Debugf("RefreshDingDingToken tokenInfo:%s", token)
|
||||||
return token, ""
|
return token, ""
|
||||||
@@ -232,12 +232,15 @@ func SaveWeimobToken(token *weimobapi.TokenInfo) (err error) {
|
|||||||
func RefreshYilianyunToken() (err error) {
|
func RefreshYilianyunToken() (err error) {
|
||||||
return RefreshConfig("yilianyun", yilianyunTokenExpires, func() (string, string) {
|
return RefreshConfig("yilianyun", yilianyunTokenExpires, func() (string, string) {
|
||||||
globals.SugarLogger.Debugf("RefreshYilianyunToken RunMode:%s", beego.BConfig.RunMode)
|
globals.SugarLogger.Debugf("RefreshYilianyunToken RunMode:%s", beego.BConfig.RunMode)
|
||||||
if beego.BConfig.RunMode == "prod" {
|
if globals.IsProductEnv() {
|
||||||
if tokenInfo, err := api.YilianyunAPI.RetrieveToken(); err == nil {
|
if globals.IsMainProductEnv() { // 只有京西菜市刷新易联云key
|
||||||
return string(utils.MustMarshal(tokenInfo)), ""
|
if tokenInfo, err := api.YilianyunAPI.RetrieveToken(); err == nil {
|
||||||
} else {
|
return string(utils.MustMarshal(tokenInfo)), ""
|
||||||
globals.SugarLogger.Errorf("RefreshYilianyunToken RefreshToken failed with error:%v", err)
|
} else {
|
||||||
|
globals.SugarLogger.Errorf("RefreshYilianyunToken RefreshToken failed with error:%v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return api.YilianyunAPI.GetToken(), ""
|
||||||
}
|
}
|
||||||
return "", ""
|
return "", ""
|
||||||
}, func(value string) {
|
}, func(value string) {
|
||||||
|
|||||||
@@ -134,13 +134,13 @@ func (task *ParallelTask) Run() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
globals.SugarLogger.Infof("ParallelTask.Run %s, subtask(job:%s, params:%s) result:%v, failed with error:%v", task.Name, utils.Format4Output(job, true), utils.Format4Output(task.params, true), result, err)
|
globals.SugarLogger.Infof("ParallelTask.Run %s, subtask(job:%s, params:%s) result:%v, failed with error:%v", task.Name, utils.Format4Output(job, true), utils.Format4Output(task.params, true), result, err)
|
||||||
|
task.locker.Lock()
|
||||||
|
task.detailErrList = append(task.detailErrList, err)
|
||||||
|
task.locker.Unlock()
|
||||||
if !task.IsContinueWhenError { // 出错
|
if !task.IsContinueWhenError { // 出错
|
||||||
chanRetVal = err
|
chanRetVal = err
|
||||||
goto end
|
goto end
|
||||||
}
|
}
|
||||||
task.locker.Lock()
|
|
||||||
task.detailErrMsgList = append(task.detailErrMsgList, err.Error())
|
|
||||||
task.locker.Unlock()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -188,12 +188,17 @@ func (task *ParallelTask) Run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if taskErr != nil {
|
if taskErr != nil {
|
||||||
|
task.OriginalErr = taskErr
|
||||||
task.Err = NewTaskError(task.Name, taskErr)
|
task.Err = NewTaskError(task.Name, taskErr)
|
||||||
} else {
|
} else {
|
||||||
|
if len(task.detailErrList) > 0 {
|
||||||
|
task.OriginalErr = task.detailErrList[0]
|
||||||
|
}
|
||||||
task.Err = task.buildTaskErrFromDetail()
|
task.Err = task.buildTaskErrFromDetail()
|
||||||
}
|
}
|
||||||
task.Result = taskResult
|
task.Result = taskResult
|
||||||
task.TerminatedAt = time.Now()
|
task.TerminatedAt = time.Now()
|
||||||
|
task.jobList = nil // 如果不释放,任务被管理的话,会导致内存不能释放
|
||||||
task.locker.Unlock()
|
task.locker.Unlock()
|
||||||
globals.SugarLogger.Debugf("ParallelTask.Run %s, err:%v", task.Name, task.Err)
|
globals.SugarLogger.Debugf("ParallelTask.Run %s, err:%v", task.Name, task.Err)
|
||||||
close(task.subFinishChan)
|
close(task.subFinishChan)
|
||||||
|
|||||||
@@ -44,13 +44,13 @@ func (task *SeqTask) Run() {
|
|||||||
})
|
})
|
||||||
task.finishedOneJob(1, err)
|
task.finishedOneJob(1, err)
|
||||||
if taskErr = err; taskErr != nil {
|
if taskErr = err; taskErr != nil {
|
||||||
|
task.locker.Lock()
|
||||||
|
task.detailErrList = append(task.detailErrList, err)
|
||||||
|
task.locker.Unlock()
|
||||||
globals.SugarLogger.Infof("SeqTask.Run %s step:%d failed with error:%v", task.Name, i, err)
|
globals.SugarLogger.Infof("SeqTask.Run %s step:%d failed with error:%v", task.Name, i, err)
|
||||||
if !task.IsContinueWhenError {
|
if !task.IsContinueWhenError {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
task.locker.Lock()
|
|
||||||
task.detailErrMsgList = append(task.detailErrMsgList, err.Error())
|
|
||||||
task.locker.Unlock()
|
|
||||||
} else if result != nil {
|
} else if result != nil {
|
||||||
taskResult = append(taskResult, utils.Interface2Slice(result)...)
|
taskResult = append(taskResult, utils.Interface2Slice(result)...)
|
||||||
}
|
}
|
||||||
@@ -68,8 +68,12 @@ func (task *SeqTask) Run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if taskErr != nil {
|
if taskErr != nil {
|
||||||
|
task.OriginalErr = taskErr
|
||||||
task.Err = NewTaskError(task.Name, taskErr)
|
task.Err = NewTaskError(task.Name, taskErr)
|
||||||
} else {
|
} else {
|
||||||
|
if len(task.detailErrList) > 0 {
|
||||||
|
task.OriginalErr = task.detailErrList[0]
|
||||||
|
}
|
||||||
task.Err = task.buildTaskErrFromDetail()
|
task.Err = task.buildTaskErrFromDetail()
|
||||||
}
|
}
|
||||||
task.Result = taskResult
|
task.Result = taskResult
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ type ITask interface {
|
|||||||
AddChild(task ITask) ITask
|
AddChild(task ITask) ITask
|
||||||
GetChildren() TaskList
|
GetChildren() TaskList
|
||||||
SetParent(parentTask ITask)
|
SetParent(parentTask ITask)
|
||||||
|
GetOriginalErr() error
|
||||||
|
GetDetailErrList() []error
|
||||||
|
|
||||||
json.Marshaler
|
json.Marshaler
|
||||||
}
|
}
|
||||||
@@ -103,15 +105,19 @@ type BaseTask struct {
|
|||||||
FailedJobCount int `json:"failedJobCount"`
|
FailedJobCount int `json:"failedJobCount"`
|
||||||
Status int `json:"status"`
|
Status int `json:"status"`
|
||||||
|
|
||||||
Result []interface{} `json:"-"`
|
NoticeMsg string `json:"noticeMsg"`
|
||||||
Children TaskList `json:"children"`
|
|
||||||
Err error `json:"err"`
|
|
||||||
|
|
||||||
detailErrMsgList []string
|
Result []interface{} `json:"-"`
|
||||||
finishChan chan struct{}
|
Children TaskList `json:"children"`
|
||||||
C <-chan struct{} `json:"-"`
|
Err error `json:"err"`
|
||||||
params []interface{}
|
OriginalErr error `json:"-"`
|
||||||
quitChan chan int
|
|
||||||
|
detailErrList []error
|
||||||
|
|
||||||
|
finishChan chan struct{}
|
||||||
|
C <-chan struct{} `json:"-"`
|
||||||
|
params []interface{}
|
||||||
|
quitChan chan int
|
||||||
|
|
||||||
locker sync.RWMutex
|
locker sync.RWMutex
|
||||||
parent ITask
|
parent ITask
|
||||||
@@ -161,7 +167,7 @@ func (t *BaseTask) GetID() string {
|
|||||||
|
|
||||||
func (t *BaseTask) GetResult(duration time.Duration) (retVal []interface{}, err error) {
|
func (t *BaseTask) GetResult(duration time.Duration) (retVal []interface{}, err error) {
|
||||||
if t.GetStatus() >= TaskStatusEndBegin {
|
if t.GetStatus() >= TaskStatusEndBegin {
|
||||||
return t.Result, t.Err
|
return t.Result, t.OriginalErr
|
||||||
}
|
}
|
||||||
if duration == 0 {
|
if duration == 0 {
|
||||||
duration = time.Hour * 10000 // duration为0表示无限等待
|
duration = time.Hour * 10000 // duration为0表示无限等待
|
||||||
@@ -171,7 +177,7 @@ func (t *BaseTask) GetResult(duration time.Duration) (retVal []interface{}, err
|
|||||||
case <-t.finishChan:
|
case <-t.finishChan:
|
||||||
t.isGetResultCalled = true
|
t.isGetResultCalled = true
|
||||||
timer.Stop()
|
timer.Stop()
|
||||||
return t.Result, t.Err
|
return t.Result, t.OriginalErr
|
||||||
case <-timer.C:
|
case <-timer.C:
|
||||||
}
|
}
|
||||||
return nil, ErrTaskNotFinished
|
return nil, ErrTaskNotFinished
|
||||||
@@ -257,6 +263,30 @@ func (t *BaseTask) SetParent(parentTask ITask) {
|
|||||||
t.parent = parentTask
|
t.parent = parentTask
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *BaseTask) SetNoticeMsg(noticeMsg string) {
|
||||||
|
t.locker.Lock()
|
||||||
|
defer t.locker.Unlock()
|
||||||
|
t.NoticeMsg = noticeMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *BaseTask) GetNoticeMsg() string {
|
||||||
|
t.locker.RLock()
|
||||||
|
defer t.locker.RUnlock()
|
||||||
|
return t.NoticeMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *BaseTask) GetOriginalErr() error {
|
||||||
|
t.locker.RLock()
|
||||||
|
defer t.locker.RUnlock()
|
||||||
|
return t.OriginalErr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *BaseTask) GetDetailErrList() []error {
|
||||||
|
t.locker.RLock()
|
||||||
|
defer t.locker.RUnlock()
|
||||||
|
return t.detailErrList
|
||||||
|
}
|
||||||
|
|
||||||
func AddChild(parentTask ITask, task ITask) ITask {
|
func AddChild(parentTask ITask, task ITask) ITask {
|
||||||
if parentTask != nil {
|
if parentTask != nil {
|
||||||
return parentTask.AddChild(task)
|
return parentTask.AddChild(task)
|
||||||
@@ -311,6 +341,10 @@ func (t *BaseTask) run(taskHandler func()) {
|
|||||||
taskDesc := fmt.Sprintf("你的异步任务[%s],ID[%s],开始于:%s,结束于:%s,", t.Name, t.ID, utils.Time2Str(t.CreatedAt), utils.Time2Str(t.TerminatedAt))
|
taskDesc := fmt.Sprintf("你的异步任务[%s],ID[%s],开始于:%s,结束于:%s,", t.Name, t.ID, utils.Time2Str(t.CreatedAt), utils.Time2Str(t.TerminatedAt))
|
||||||
if t.Err == nil {
|
if t.Err == nil {
|
||||||
content = fmt.Sprintf("%s执行%s", taskDesc, TaskStatusName[t.Status])
|
content = fmt.Sprintf("%s执行%s", taskDesc, TaskStatusName[t.Status])
|
||||||
|
noticeMsg := t.GetNoticeMsg()
|
||||||
|
if noticeMsg != "" {
|
||||||
|
content += ",通知消息:" + noticeMsg
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if t.Status == TaskStatusFinished {
|
if t.Status == TaskStatusFinished {
|
||||||
content = fmt.Sprintf("%s执行部分失败,%s", taskDesc, t.Err.Error())
|
content = fmt.Sprintf("%s执行部分失败,%s", taskDesc, t.Err.Error())
|
||||||
@@ -347,8 +381,12 @@ func (t *BaseTask) setStatus(status int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *BaseTask) buildTaskErrFromDetail() (err error) {
|
func (t *BaseTask) buildTaskErrFromDetail() (err error) {
|
||||||
if len(t.detailErrMsgList) > 0 {
|
if len(t.detailErrList) > 0 {
|
||||||
return NewTaskError(t.Name, fmt.Errorf("总共:%d, 失败:%d, 详情:\n%s", t.TotalItemCount, t.FailedItemCount, strings.Join(t.detailErrMsgList, "\n")))
|
strList := make([]string, len(t.detailErrList))
|
||||||
|
for k, v := range t.detailErrList {
|
||||||
|
strList[k] = v.Error()
|
||||||
|
}
|
||||||
|
return NewTaskError(t.Name, fmt.Errorf("总共:%d, 失败:%d, 详情:\n%s", t.TotalItemCount, t.FailedItemCount, strings.Join(strList, "\n")))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
@@ -49,7 +51,10 @@ const (
|
|||||||
WX_NORMAL_STORE_MSG_TEMPLATE_ID = "7ngcTFYiUFw66BMzIYntM1tpy-xZkJwlcCT5pVtXwtw"
|
WX_NORMAL_STORE_MSG_TEMPLATE_ID = "7ngcTFYiUFw66BMzIYntM1tpy-xZkJwlcCT5pVtXwtw"
|
||||||
WX_CHANGE_APPROVED_TEMPLATE_ID = "gIG2olBZtQbjXmp6doNB_dESu60By5xuXYOGxksLv3Y"
|
WX_CHANGE_APPROVED_TEMPLATE_ID = "gIG2olBZtQbjXmp6doNB_dESu60By5xuXYOGxksLv3Y"
|
||||||
WX_CHANGE_REJECTED_TEMPLATE_ID = "tn2QXWi4HtSIwaztmtN6Bb2uzNL-jBxWltCZTDNJuYE"
|
WX_CHANGE_REJECTED_TEMPLATE_ID = "tn2QXWi4HtSIwaztmtN6Bb2uzNL-jBxWltCZTDNJuYE"
|
||||||
WS_ORDER_CANCLED_TEMPLATE_ID = "iFozwiCsQdMs7VTiPXoBne45jKIQkoyxdGHSeAExP9U"
|
WX_ORDER_CANCLED_TEMPLATE_ID = "iFozwiCsQdMs7VTiPXoBne45jKIQkoyxdGHSeAExP9U"
|
||||||
|
|
||||||
|
WX_AFS_ORDER_WAIT4APPROVE_TEMPLATE_ID = "X29udtANvhX6x1Lyh-T40NGNjRXBbUj5oSBTfDhZAqU"
|
||||||
|
WX_AFS_ORDER_STATUS_CHANGED_TEMPLATE_ID = "99T33rrXX0VboO1hljs4x8dDoLiSj3QX_rOikPHIXkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -305,7 +310,7 @@ func NotifyUserApplyCancel(order *model.GoodsOrder, cancelReason string) (err er
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
storeID := jxutils.GetSaleStoreIDFromOrder(order)
|
storeID := jxutils.GetSaleStoreIDFromOrder(order)
|
||||||
return SendMsgToStore(storeID, WS_ORDER_CANCLED_TEMPLATE_ID, "", "", data)
|
return SendMsgToStore(storeID, WX_ORDER_CANCLED_TEMPLATE_ID, "", "", data)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,7 +352,7 @@ func NotifySaleBill(storeID int, title, shopName, fileURL string) (err error) {
|
|||||||
title = "当期账单"
|
title = "当期账单"
|
||||||
}
|
}
|
||||||
if shopName == "" {
|
if shopName == "" {
|
||||||
shopName = "京西菜市"
|
shopName = globals.StoreName
|
||||||
}
|
}
|
||||||
data := map[string]interface{}{
|
data := map[string]interface{}{
|
||||||
"first": map[string]interface{}{
|
"first": map[string]interface{}{
|
||||||
@@ -449,6 +454,54 @@ func NotifyStoreMessage(storeID, msgID, msgStatusID int, title, content string)
|
|||||||
return SendMsgToStore(storeID, templateID, fileURL, fmt.Sprintf(WX_MINI_TO_SHOW_MSG, msgID, msgStatusID), data)
|
return SendMsgToStore(storeID, templateID, fileURL, fmt.Sprintf(WX_MINI_TO_SHOW_MSG, msgID, msgStatusID), data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NotifyAfsOrderStatus(afsOrder *model.AfsOrder) (err error) {
|
||||||
|
globals.SugarLogger.Debugf("NotifyAfsOrderStatus orderID:%s", afsOrder.VendorOrderID)
|
||||||
|
if afsOrder.VendorID == model.VendorIDELM {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var templateID, comment string
|
||||||
|
if afsOrder.Status == model.AfsOrderStatusWait4Approve {
|
||||||
|
templateID = WX_AFS_ORDER_WAIT4APPROVE_TEMPLATE_ID
|
||||||
|
comment = "您有新售后单,请尽快处理"
|
||||||
|
} else if afsOrder.Status == model.AfsOrderStatusWait4ReceiveGoods {
|
||||||
|
templateID = WX_AFS_ORDER_STATUS_CHANGED_TEMPLATE_ID
|
||||||
|
comment = "商家您好!如顾客商品已成功退回,请点击确认收货"
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
order, err := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
data := map[string]interface{}{
|
||||||
|
"first": map[string]interface{}{
|
||||||
|
"value": fmt.Sprintf("%s 第%d号订单,订单编号:%s", model.VendorChineseNames[afsOrder.VendorID], order.OrderSeq, afsOrder.VendorOrderID),
|
||||||
|
"color": WX_HIGHLEVEL_TEMPLATE_COLOR2,
|
||||||
|
},
|
||||||
|
"keyword1": map[string]interface{}{
|
||||||
|
"value": afsOrder.AfsOrderID,
|
||||||
|
"color": WX_TEMPLATE_VENDERCOLOR_JDDJ,
|
||||||
|
},
|
||||||
|
"keyword2": map[string]interface{}{
|
||||||
|
"value": model.OrderStatusName[afsOrder.Status],
|
||||||
|
"color": WX_HIGHLEVEL_TEMPLATE_COLOR,
|
||||||
|
},
|
||||||
|
"keyword3": map[string]interface{}{
|
||||||
|
"value": utils.Time2Str(afsOrder.CreatedAt),
|
||||||
|
"color": venderColors[order.VendorID],
|
||||||
|
},
|
||||||
|
"remark": map[string]interface{}{
|
||||||
|
"value": comment,
|
||||||
|
"color": WX_NEW_ORDER_TEMPLATE_COLOR,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
storeID := jxutils.GetSaleStoreIDFromAfsOrder(afsOrder)
|
||||||
|
err = SendMsgToStore(storeID, templateID, globals.WxBackstageHost+fmt.Sprintf("%s%d", WX_TO_ORDER_PAGE_URL, storeID), WX_MINI_TO_ORDER_PAGE_URL, data)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func FormatDeliveryTime(order *model.GoodsOrder) string {
|
func FormatDeliveryTime(order *model.GoodsOrder) string {
|
||||||
var tmpTime time.Time
|
var tmpTime time.Time
|
||||||
if order.ExpectedDeliveredTime == utils.DefaultTimeValue {
|
if order.ExpectedDeliveredTime == utils.DefaultTimeValue {
|
||||||
|
|||||||
135
business/model/act.go
Normal file
135
business/model/act.go
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
const (
|
||||||
|
ActSkuDirectDown = 1
|
||||||
|
ActSkuSecKill = 2
|
||||||
|
|
||||||
|
ActOrderBegin = 10
|
||||||
|
ActOrderMoneyOff = 11
|
||||||
|
ActOrderMoneyOffCoupon = 12
|
||||||
|
ActOrderReduceFreight = 13
|
||||||
|
ActOrderReduceFreightCoupon = 14
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ActStatusCreated = 1 // 需同步
|
||||||
|
ActStatusCanceled = 2 // 需同步
|
||||||
|
ActStatusEnded = 3 // 不需要同步,根据活动时间自动刷新的
|
||||||
|
)
|
||||||
|
|
||||||
|
type Act struct {
|
||||||
|
ModelIDCULD
|
||||||
|
|
||||||
|
Name string `orm:"size(64)" json:"name"`
|
||||||
|
Advertising string `orm:"size(255)" json:"advertising"`
|
||||||
|
Type int `json:"type"`
|
||||||
|
Status int `json:"status"`
|
||||||
|
LimitDevice int `json:"limitDevice"`
|
||||||
|
LimitPin int `json:"limitPin"`
|
||||||
|
LimitDaily int `json:"limitDaily"`
|
||||||
|
LimitCount int `json:"limitCount"`
|
||||||
|
Source string `orm:"size(255)" json:"source"`
|
||||||
|
CreateType int `json:"createType"`
|
||||||
|
PricePercentage int `json:"pricePercentage"` // 单品级活动才有效
|
||||||
|
BeginAt time.Time `orm:"type(datetime);index;null" json:"beginAt"`
|
||||||
|
EndAt time.Time `orm:"type(datetime);index;null" json:"endAt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActMap struct {
|
||||||
|
ModelIDCULD
|
||||||
|
|
||||||
|
ActID int `orm:"column(act_id)" json:"actID"`
|
||||||
|
VendorID int `orm:"column(vendor_id)" json:"vendorID"`
|
||||||
|
|
||||||
|
VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"`
|
||||||
|
SyncStatus int `orm:"default(2)" json:"syncStatus"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Act2 struct {
|
||||||
|
MapID int `orm:"column(map_id)"`
|
||||||
|
|
||||||
|
Act
|
||||||
|
VendorID int `orm:"column(vendor_id)" json:"vendorID"`
|
||||||
|
|
||||||
|
VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"`
|
||||||
|
SyncStatus int `orm:"default(2)" json:"syncStatus"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActOrderRule struct {
|
||||||
|
ModelIDCULD
|
||||||
|
|
||||||
|
ActID int `orm:"column(act_id)" json:"actID"`
|
||||||
|
SalePrice int64 `orm:"" json:"salePrice"` // 满的价格
|
||||||
|
DeductPrice int64 `orm:"" json:"deductPrice"` // 减的价格
|
||||||
|
}
|
||||||
|
|
||||||
|
// type ActStore struct {
|
||||||
|
// ModelIDCULD
|
||||||
|
|
||||||
|
// ActID int `orm:"column(act_id)" json:"actID"`
|
||||||
|
// StoreID int `orm:"column(store_id)" json:"storeID"`
|
||||||
|
// }
|
||||||
|
|
||||||
|
type ActStoreMap struct {
|
||||||
|
ModelIDCULD
|
||||||
|
|
||||||
|
ActID int `orm:"column(act_id)" json:"actID"`
|
||||||
|
StoreID int `orm:"column(store_id)" json:"storeID"`
|
||||||
|
VendorID int `orm:"column(vendor_id)" json:"vendorID"`
|
||||||
|
|
||||||
|
VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"`
|
||||||
|
SyncStatus int `orm:"default(2)" json:"syncStatus"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActStore2 struct {
|
||||||
|
MapID int `orm:"column(map_id)"`
|
||||||
|
|
||||||
|
ActStoreMap
|
||||||
|
|
||||||
|
VendorStoreID string `orm:"column(vendor_store_id)" json:"vendorStoreID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActStoreSku struct {
|
||||||
|
ModelIDCULD
|
||||||
|
|
||||||
|
ActID int `orm:"column(act_id)" json:"actID"`
|
||||||
|
StoreID int `orm:"column(store_id)" json:"storeID"`
|
||||||
|
SkuID int `orm:"column(sku_id)" json:"skuID"`
|
||||||
|
|
||||||
|
// LocalStatus int // 这个状态是多个平台的
|
||||||
|
// RemoteStatus int // 这个状态是多个平台的
|
||||||
|
OriginalPrice int64 `orm:"" json:"originalPrice"` // 单品级活动用,创建活动时商品的原始京西价
|
||||||
|
PricePercentage int `orm:"" json:"pricePercentage"` // 单品级活动用,SKU级的价格比例,非0覆盖Act中的PricePercentage
|
||||||
|
ActPrice int64 `orm:"" json:"actPrice"` // 单品级活动用,SKU级指定的价格,非0覆盖CustomPricePercentage与Act中的PricePercentage
|
||||||
|
|
||||||
|
Stock int `orm:"" json:"stock"` // 订单级活动用
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActStoreSkuMap struct {
|
||||||
|
ModelIDCULD
|
||||||
|
|
||||||
|
ActID int `orm:"column(act_id)" json:"actID"`
|
||||||
|
StoreID int `orm:"column(store_id)" json:"storeID"`
|
||||||
|
SkuID int `orm:"column(sku_id)" json:"skuID"`
|
||||||
|
VendorID int `orm:"column(vendor_id)" json:"vendorID"`
|
||||||
|
|
||||||
|
VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"`
|
||||||
|
SyncStatus int `orm:"default(2)" json:"syncStatus"`
|
||||||
|
ActualActPrice int64 `orm:"" json:"actualActPrice"` // 单品级活动用,创建活动时商品的活动价格
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActStoreSku2 struct {
|
||||||
|
MapID int `orm:"column(map_id)"`
|
||||||
|
|
||||||
|
ActStoreSku
|
||||||
|
VendorID int `orm:"column(vendor_id)" json:"vendorID"`
|
||||||
|
|
||||||
|
VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"`
|
||||||
|
SyncStatus int `orm:"default(2)" json:"syncStatus"`
|
||||||
|
ActualActPrice int64 `orm:"" json:"actualActPrice"` // 单品级活动用,创建活动时商品的活动价格
|
||||||
|
|
||||||
|
VendorStoreID string `orm:"column(vendor_store_id)" json:"vendorStoreID"`
|
||||||
|
VendorSkuID string `orm:"column(vendor_sku_id)" json:"vendorSkuID"`
|
||||||
|
}
|
||||||
@@ -12,15 +12,25 @@ const (
|
|||||||
|
|
||||||
type GoodsOrderExt struct {
|
type GoodsOrderExt struct {
|
||||||
GoodsOrder
|
GoodsOrder
|
||||||
|
EarningPrice int64 `json:"earningPrice"` // 预估结算给门店老板的钱
|
||||||
|
|
||||||
WaybillStatus int `json:"waybillStatus"`
|
WaybillStatus int `json:"waybillStatus"`
|
||||||
CourierName string `orm:"size(32)" json:"courierName"`
|
CourierName string `orm:"size(32)" json:"courierName"`
|
||||||
CourierMobile string `orm:"size(32)" json:"courierMobile"`
|
CourierMobile string `orm:"size(32)" json:"courierMobile"`
|
||||||
CurrentConsigneeMobile string `orm:"-" json:"currentConsigneeMobile"`
|
CurrentConsigneeMobile string `orm:"-" json:"currentConsigneeMobile"`
|
||||||
|
CourierVendorName string `json:"courierVendorName"`
|
||||||
|
|
||||||
|
Status2 string `json:"status2"`
|
||||||
ActualFee int64 `json:"actualFee"` // 实际要支付给快递公司的费用
|
ActualFee int64 `json:"actualFee"` // 实际要支付给快递公司的费用
|
||||||
DesiredFee int64 `json:"desiredFee"` // 运单总费用
|
DesiredFee int64 `json:"desiredFee"` // 运单总费用
|
||||||
WaybillCreatedAt time.Time `orm:"type(datetime);index" json:"waybillCreatedAt"`
|
WaybillCreatedAt time.Time `orm:"type(datetime);index" json:"waybillCreatedAt"`
|
||||||
WaybillFinishedAt time.Time `orm:"type(datetime)" json:"waybillFinishedAt"`
|
WaybillFinishedAt time.Time `orm:"type(datetime)" json:"waybillFinishedAt"`
|
||||||
|
|
||||||
|
SkuID int `orm:"column(sku_id)" json:"skuID,omitempty"`
|
||||||
|
SkuShopPrice int `json:"skuShopPrice,omitempty"`
|
||||||
|
SkuSalePrice int `json:"skuSalePrice,omitempty"`
|
||||||
|
SkuCount2 int `json:"skuCount2,omitempty"`
|
||||||
|
SkuInfo string `json:"skuInfo,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OrderSkuExt struct {
|
type OrderSkuExt struct {
|
||||||
@@ -30,11 +40,6 @@ type OrderSkuExt struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GoodsOrderCountInfo struct {
|
type GoodsOrderCountInfo struct {
|
||||||
Status int `json:"status"`
|
|
||||||
Count int `json:"count"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type GoodsOrderCountInfo2 struct {
|
|
||||||
LockStatus int `json:"lockStatus"`
|
LockStatus int `json:"lockStatus"`
|
||||||
Status int `json:"status"`
|
Status int `json:"status"`
|
||||||
Count int `json:"count"`
|
Count int `json:"count"`
|
||||||
@@ -61,3 +66,8 @@ type OrderFinancialExt struct {
|
|||||||
Skus []*OrderSkuFinancial `orm:"-" json:"skus"` // 正向订单购买商品列表
|
Skus []*OrderSkuFinancial `orm:"-" json:"skus"` // 正向订单购买商品列表
|
||||||
Discounts []*OrderDiscountFinancial `orm:"-" json:"discounts"` // 正向订单享受优惠列表
|
Discounts []*OrderDiscountFinancial `orm:"-" json:"discounts"` // 正向订单享受优惠列表
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OrderFinancialSkuExt struct {
|
||||||
|
OrderSkuFinancial
|
||||||
|
Image string `json:"image"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ const (
|
|||||||
VendorIDMTWM = 1
|
VendorIDMTWM = 1
|
||||||
VendorIDELM = 2
|
VendorIDELM = 2
|
||||||
VendorIDEBAI = 3
|
VendorIDEBAI = 3
|
||||||
VendorIDJX = 9 // 这是一个假的京西VendorID
|
|
||||||
VendorIDWSC = 11 // 微盟微商城
|
VendorIDWSC = 11 // 微盟微商城
|
||||||
VendorIDPurchaseEnd = 11
|
VendorIDPurchaseEnd = 11
|
||||||
|
VendorIDJX = 99 // 这是一个假的京西VendorID
|
||||||
|
|
||||||
VendorIDDeliveryBegin = 101
|
VendorIDDeliveryBegin = 101
|
||||||
VendorIDDada = 101
|
VendorIDDada = 101
|
||||||
@@ -112,22 +112,34 @@ var (
|
|||||||
OrderStatusDeliverFailed: "投递失败",
|
OrderStatusDeliverFailed: "投递失败",
|
||||||
OrderStatusFinished: "完成",
|
OrderStatusFinished: "完成",
|
||||||
OrderStatusCanceled: "取消",
|
OrderStatusCanceled: "取消",
|
||||||
|
|
||||||
|
AfsOrderStatusWait4Approve: "待审核",
|
||||||
|
AfsOrderStatusNew: "已审核",
|
||||||
|
AfsOrderStatusWait4ReceiveGoods: "退货待确认",
|
||||||
|
AfsOrderStatusReceivedGoods: "退货已收到",
|
||||||
|
AfsOrderStatusFinished: "售后成功",
|
||||||
|
AfsOrderStatusFailed: "售后失败",
|
||||||
}
|
}
|
||||||
WaybillStatusName = map[int]string{
|
WaybillStatusName = map[int]string{
|
||||||
WaybillStatusUnknown: "一般事件",
|
WaybillStatusUnknown: "一般事件",
|
||||||
|
|
||||||
WaybillStatusNew: "新运单",
|
WaybillStatusNew: "新运单",
|
||||||
WaybillStatusAcceptCanceled: "取消接受",
|
WaybillStatusPending: "压单",
|
||||||
WaybillStatusAccepted: "已接单",
|
WaybillStatusAcceptCanceled: "取消接受",
|
||||||
WaybillStatusCourierArrived: "已到店",
|
WaybillStatusAccepted: "已接单",
|
||||||
WaybillStatusDelivering: "配送中",
|
WaybillStatusCourierArrived: "已到店",
|
||||||
WaybillStatusDelivered: "送达",
|
WaybillStatusApplyFailedGetGoods: "取货失败待审核",
|
||||||
WaybillStatusCanceled: "取消",
|
WaybillStatusAgreeFailedGetGoods: "取货失败",
|
||||||
WaybillStatusFailed: "失败",
|
WaybillStatusDelivering: "配送中",
|
||||||
|
WaybillStatusDeliverFailed: "投递失败",
|
||||||
|
WaybillStatusDelivered: "送达",
|
||||||
|
WaybillStatusCanceled: "取消",
|
||||||
|
WaybillStatusFailed: "失败",
|
||||||
}
|
}
|
||||||
OrderTypeName = map[int]string{
|
OrderTypeName = map[int]string{
|
||||||
OrderTypeOrder: "订单",
|
OrderTypeOrder: "订单",
|
||||||
OrderTypeWaybill: "运单",
|
OrderTypeWaybill: "运单",
|
||||||
|
OrderTypeAfsOrder: "售后单",
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiStoresVendorMap = map[int]int{
|
MultiStoresVendorMap = map[int]int{
|
||||||
@@ -159,11 +171,30 @@ var (
|
|||||||
"打印机密钥",
|
"打印机密钥",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
AfsReasonTypeName = map[int]string{
|
||||||
|
AfsReasonTypeGoodsQuality: "商品质量",
|
||||||
|
AfsReasonTypeWrongGoods: "错误的商品",
|
||||||
|
AfsReasonTypeMissingGoods: "缺少部分商品",
|
||||||
|
AfsReasonTypeNoGoods: "全部商品未收到",
|
||||||
|
AfsReasonTypeDamagedGoods: "商品有损伤",
|
||||||
|
AfsReasonTypeGoodsQuantity: "缺斤少两",
|
||||||
|
AfsReasonTypeAgreedByMerchant: "与商家协商一致",
|
||||||
|
AfsReasonTypeGoodsNoSame: "商品与描述不符",
|
||||||
|
AfsReasonWrongPurchase: "误购",
|
||||||
|
AfsReasonNotReceivedIntime: "未在时效内送达",
|
||||||
|
AfsReasonNotOthers: "其它",
|
||||||
|
}
|
||||||
|
AfsAppealTypeName = map[int]string{
|
||||||
|
AfsAppealTypeRefund: "仅退款",
|
||||||
|
AfsAppealTypeReturnAndRefund: "退货退款",
|
||||||
|
AfsAppealTypeNewGoods: "重发商品",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
OrderTypeOrder = 1
|
OrderTypeOrder = 1
|
||||||
OrderTypeWaybill = 2
|
OrderTypeWaybill = 2
|
||||||
|
OrderTypeAfsOrder = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
// https://blog.csdn.net/a13570320979/article/details/51366355
|
// https://blog.csdn.net/a13570320979/article/details/51366355
|
||||||
@@ -212,6 +243,14 @@ const (
|
|||||||
OrderStatusEndBegin = 100 // 以下的状态就是结束状态
|
OrderStatusEndBegin = 100 // 以下的状态就是结束状态
|
||||||
OrderStatusFinished = 110 // 订单已完成
|
OrderStatusFinished = 110 // 订单已完成
|
||||||
OrderStatusCanceled = 115 // 订单已取消
|
OrderStatusCanceled = 115 // 订单已取消
|
||||||
|
OrderStatusEndEnd = 120
|
||||||
|
|
||||||
|
AfsOrderStatusWait4Approve = 155 // 待审核售后单
|
||||||
|
AfsOrderStatusNew = 160 // 已审核或不需要审核售后单
|
||||||
|
AfsOrderStatusWait4ReceiveGoods = 165 // 退款退货的,需要商家确认收到货
|
||||||
|
AfsOrderStatusReceivedGoods = 167 // 已确认收到货
|
||||||
|
AfsOrderStatusFinished = 180 // 售后单成功完成
|
||||||
|
AfsOrderStatusFailed = 190 // 售后单失败
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -224,6 +263,7 @@ const (
|
|||||||
WaybillStatusUnknown = 0
|
WaybillStatusUnknown = 0
|
||||||
|
|
||||||
WaybillStatusNew = 5
|
WaybillStatusNew = 5
|
||||||
|
WaybillStatusPending = 7
|
||||||
WaybillStatusAcceptCanceled = 8
|
WaybillStatusAcceptCanceled = 8
|
||||||
WaybillStatusAccepted = 10
|
WaybillStatusAccepted = 10
|
||||||
WaybillStatusCourierArrived = 15 // 此状态是可选的,明确写出来是因为还是较重要的状态,但业务逻辑不应依赖此状态
|
WaybillStatusCourierArrived = 15 // 此状态是可选的,明确写出来是因为还是较重要的状态,但业务逻辑不应依赖此状态
|
||||||
@@ -238,7 +278,6 @@ const (
|
|||||||
WaybillStatusDelivered = 105 // todo 这个应该改为110,与订单对应
|
WaybillStatusDelivered = 105 // todo 这个应该改为110,与订单对应
|
||||||
WaybillStatusCanceled = 115
|
WaybillStatusCanceled = 115
|
||||||
WaybillStatusFailed = 120 // 这个状态存在的意义是区分于WaybillStatusCanceled,比如达达平台在这种状态下再次创建运单的方式不一样
|
WaybillStatusFailed = 120 // 这个状态存在的意义是区分于WaybillStatusCanceled,比如达达平台在这种状态下再次创建运单的方式不一样
|
||||||
WaybillStatusNeverSend = 125 // 这个状态指的是平台方不愿意配送,门店自己想办法。与WaybillStatusAcceptCanceled不一样,WaybillStatusAcceptCanceled可能之后还会尝试配送
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -261,6 +300,13 @@ const (
|
|||||||
const (
|
const (
|
||||||
OrderDeliveryFlagMaskScheduleDisabled = 1 // 禁止三方配送调度
|
OrderDeliveryFlagMaskScheduleDisabled = 1 // 禁止三方配送调度
|
||||||
OrderDeliveryFlagMaskPurcahseDisabled = 2 // 购物平台已不配送(一般为门店配送类型本身为自配送,或已经转自配送)
|
OrderDeliveryFlagMaskPurcahseDisabled = 2 // 购物平台已不配送(一般为门店配送类型本身为自配送,或已经转自配送)
|
||||||
|
|
||||||
|
OrderDeliveryFlagMaskDada = 16 // 创建达达运单中
|
||||||
|
OrderDeliveryFlagMaskMtps = 32 // 创建美团配送运单中
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
WaybillDeliveryFlagMaskActiveCancel = 1 // 主动取消
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -275,7 +321,42 @@ const (
|
|||||||
OrderFlagRefuseFailedGetGoods = 24
|
OrderFlagRefuseFailedGetGoods = 24
|
||||||
|
|
||||||
OrderFlagMaskFailedDeliver = 32
|
OrderFlagMaskFailedDeliver = 32
|
||||||
OrderFlagMaskCallPMCourier = 64 // 取货失败后召唤平台配送
|
OrderFlagMaskCallPMCourier = 64 // 取货失败后召唤平台配送
|
||||||
|
OrderFlagMaskSetDelivered = 128 // 设置送达
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AfsOrderFlagMaskUserRefund = 3 // 门店处理售后单申请
|
||||||
|
AfsOrderFlagAgreeUserRefund = 1 // 门店同意售后单申请
|
||||||
|
AfsOrderFlagRefuseUserRefund = 3 // 门店拒绝售后单申请
|
||||||
|
|
||||||
|
AfsOrderFlagMaskReturnGoods = 4 // 门店确认收到退货
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AfsAppealTypeRefund = 1 // 仅退款
|
||||||
|
AfsAppealTypeReturnAndRefund = 2 // 退货退款
|
||||||
|
AfsAppealTypeNewGoods = 3 // 重发新商品(即京东到家的直赔)
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AfsReasonTypeGoodsQuality = 1 // 商品质量
|
||||||
|
AfsReasonTypeWrongGoods = 2 // 错误的商品
|
||||||
|
AfsReasonTypeMissingGoods = 3 // 缺少部分商品
|
||||||
|
AfsReasonTypeNoGoods = 4 // 全部商品未收到
|
||||||
|
AfsReasonTypeDamagedGoods = 5 // 商品有损伤
|
||||||
|
AfsReasonTypeGoodsQuantity = 6 // 缺斤少两
|
||||||
|
AfsReasonTypeAgreedByMerchant = 7 // 与商家协商一致
|
||||||
|
AfsReasonTypeGoodsNoSame = 8 // 商品与描述不符
|
||||||
|
AfsReasonWrongPurchase = 9 // 误购
|
||||||
|
AfsReasonNotReceivedIntime = 10 // 未在时效内送达
|
||||||
|
AfsReasonNotOthers = 0 // 其它
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AfsTypeUnknown = 0 // 未知
|
||||||
|
AfsTypePartRefund = 1 // 部分退款
|
||||||
|
AfsTypeFullRefund = 2 // 全额退款
|
||||||
)
|
)
|
||||||
|
|
||||||
func IsPurchaseVendorExist(vendorID int) bool {
|
func IsPurchaseVendorExist(vendorID int) bool {
|
||||||
@@ -306,9 +387,22 @@ func IsOrderMainStatus(status int) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func IsOrderFinalStatus(status int) bool {
|
func IsOrderFinalStatus(status int) bool {
|
||||||
return status >= OrderStatusEndBegin
|
return status >= OrderStatusEndBegin && status <= OrderStatusEndEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsOrderImportantStatus(status int) bool {
|
func IsOrderImportantStatus(status int) bool {
|
||||||
return IsOrderMainStatus(status) || IsOrderLockStatus(status) || IsOrderUnlockStatus(status)
|
return IsOrderMainStatus(status) || IsOrderLockStatus(status) || IsOrderUnlockStatus(status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WaybillVendorID2Mask(vendorID int) (mask int8) {
|
||||||
|
if vendorID == VendorIDDada {
|
||||||
|
mask = OrderDeliveryFlagMaskDada
|
||||||
|
} else if vendorID == VendorIDMTPS {
|
||||||
|
mask = OrderDeliveryFlagMaskMtps
|
||||||
|
}
|
||||||
|
return mask
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsAfsOrderFinalStatus(status int) bool {
|
||||||
|
return status >= AfsOrderStatusFinished && status <= AfsOrderStatusFailed
|
||||||
|
}
|
||||||
|
|||||||
117
business/model/dao/act.go
Normal file
117
business/model/dao/act.go
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetActVendorInfo(db *DaoDB, actID int, vendorIDs []int) (actMap map[int]*model.Act2, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT t1.*,
|
||||||
|
t2.id map_id, t2.vendor_id, t2.vendor_act_id, t2.sync_status
|
||||||
|
FROM act t1
|
||||||
|
JOIN act_map t2 ON t2.act_id = t1.id AND t2.deleted_at = ?
|
||||||
|
WHERE t1.deleted_at = ? AND t1.id = ?
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
actID,
|
||||||
|
}
|
||||||
|
if len(vendorIDs) > 0 {
|
||||||
|
sql += " AND t2.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, vendorIDs)
|
||||||
|
}
|
||||||
|
var actList []*model.Act2
|
||||||
|
if err = GetRows(db, &actList, sql, sqlParams...); err == nil {
|
||||||
|
actMap = make(map[int]*model.Act2)
|
||||||
|
for _, v := range actList {
|
||||||
|
actMap[v.VendorID] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actMap, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetActStoreVendorInfo(db *DaoDB, actID int, vendorIDs, storeIDs []int) (actStoreMap map[int][]*model.ActStore2, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT t1.*,
|
||||||
|
t1.id map_id,
|
||||||
|
t2.vendor_store_id
|
||||||
|
FROM act_store_map t1
|
||||||
|
JOIN store_map t2 ON t2.store_id = t1.store_id AND t2.vendor_id = t1.vendor_id AND t2.deleted_at = ?
|
||||||
|
WHERE t1.deleted_at = ? AND t1.act_id = ?
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
actID,
|
||||||
|
}
|
||||||
|
if len(vendorIDs) > 0 {
|
||||||
|
sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, vendorIDs)
|
||||||
|
}
|
||||||
|
if len(storeIDs) > 0 {
|
||||||
|
sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, storeIDs)
|
||||||
|
}
|
||||||
|
var actStoreList []*model.ActStore2
|
||||||
|
if err = GetRows(db, &actStoreList, sql, sqlParams...); err == nil {
|
||||||
|
actStoreMap = make(map[int][]*model.ActStore2)
|
||||||
|
for _, v := range actStoreList {
|
||||||
|
actStoreMap[v.VendorID] = append(actStoreMap[v.VendorID], v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actStoreMap, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetActStoreSkuVendorInfo(db *DaoDB, actID int, vendorIDs, storeIDs, skuIDs []int) (actStoreSkuMap map[int][]*model.ActStoreSku2, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT t1.*,
|
||||||
|
t2.id map_id, t2.vendor_id, t2.vendor_act_id, t2.sync_status,
|
||||||
|
t3.vendor_store_id,
|
||||||
|
CASE t2.vendor_id
|
||||||
|
WHEN 0 THEN
|
||||||
|
t4.jd_id
|
||||||
|
WHEN 1 THEN
|
||||||
|
t5.mtwm_id
|
||||||
|
WHEN 3 THEN
|
||||||
|
t5.ebai_id
|
||||||
|
ELSE
|
||||||
|
''
|
||||||
|
END vendor_sku_id
|
||||||
|
FROM act_store_sku t1
|
||||||
|
JOIN act_store_sku_map t2 ON t2.act_id = t1.act_id AND t2.sku_id = t1.sku_id AND t2.store_id = t1.store_id AND t2.deleted_at = ?
|
||||||
|
JOIN store_map t3 ON t3.store_id = t1.store_id AND t3.vendor_id = t2.vendor_id AND t3.deleted_at = ?
|
||||||
|
JOIN sku t4 ON t4.id = t1.sku_id AND t4.deleted_at = ?
|
||||||
|
JOIN store_sku_bind t5 ON t5.sku_id = t1.sku_id AND t5.store_id = t1.store_id AND t5.deleted_at = ?
|
||||||
|
WHERE t1.deleted_at = ? AND t1.act_id = ?
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
actID,
|
||||||
|
}
|
||||||
|
if len(vendorIDs) > 0 {
|
||||||
|
sql += " AND t2.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, vendorIDs)
|
||||||
|
}
|
||||||
|
if len(storeIDs) > 0 {
|
||||||
|
sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, storeIDs)
|
||||||
|
}
|
||||||
|
if len(skuIDs) > 0 {
|
||||||
|
sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, skuIDs)
|
||||||
|
}
|
||||||
|
var actStoreSkuList []*model.ActStoreSku2
|
||||||
|
if err = GetRows(db, &actStoreSkuList, sql, sqlParams...); err == nil {
|
||||||
|
actStoreSkuMap = make(map[int][]*model.ActStoreSku2)
|
||||||
|
for _, v := range actStoreSkuList {
|
||||||
|
actStoreSkuMap[v.VendorID] = append(actStoreSkuMap[v.VendorID], v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actStoreSkuMap, err
|
||||||
|
}
|
||||||
@@ -58,7 +58,7 @@ func UpdateEntityByKV(db *DaoDB, item interface{}, kvs map[string]interface{}, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
func UpdateEntityLogically(db *DaoDB, item interface{}, kvs map[string]interface{}, userName string, conditions map[string]interface{}) (num int64, err error) {
|
func UpdateEntityLogically(db *DaoDB, item interface{}, kvs map[string]interface{}, userName string, conditions map[string]interface{}) (num int64, err error) {
|
||||||
if conditions != nil {
|
if conditions != nil && refutil.IsFieldExist(item, model.FieldDeletedAt) {
|
||||||
conditions = utils.MergeMaps(conditions, map[string]interface{}{
|
conditions = utils.MergeMaps(conditions, map[string]interface{}{
|
||||||
model.FieldDeletedAt: utils.DefaultTimeValue,
|
model.FieldDeletedAt: utils.DefaultTimeValue,
|
||||||
})
|
})
|
||||||
@@ -71,7 +71,7 @@ func UpdateEntityLogically(db *DaoDB, item interface{}, kvs map[string]interface
|
|||||||
|
|
||||||
// 此函数会更新同步标志
|
// 此函数会更新同步标志
|
||||||
func UpdateEntityLogicallyAndUpdateSyncStatus(db *DaoDB, item interface{}, kvs map[string]interface{}, userName string, conditions map[string]interface{}, syncStatusFieldName string, valueMask int) (num int64, err error) {
|
func UpdateEntityLogicallyAndUpdateSyncStatus(db *DaoDB, item interface{}, kvs map[string]interface{}, userName string, conditions map[string]interface{}, syncStatusFieldName string, valueMask int) (num int64, err error) {
|
||||||
if conditions != nil {
|
if conditions != nil && refutil.IsFieldExist(item, model.FieldDeletedAt) {
|
||||||
conditions = utils.MergeMaps(conditions, map[string]interface{}{
|
conditions = utils.MergeMaps(conditions, map[string]interface{}{
|
||||||
model.FieldDeletedAt: utils.DefaultTimeValue,
|
model.FieldDeletedAt: utils.DefaultTimeValue,
|
||||||
})
|
})
|
||||||
@@ -115,6 +115,7 @@ func AddStoreCategoryMap(db *DaoDB, storeID, categoryID int, vendorID int, vendo
|
|||||||
StoreID: storeID,
|
StoreID: storeID,
|
||||||
CategoryID: categoryID,
|
CategoryID: categoryID,
|
||||||
MtwmSyncStatus: model.SyncFlagNewMask,
|
MtwmSyncStatus: model.SyncFlagNewMask,
|
||||||
|
EbaiSyncStatus: model.SyncFlagNewMask,
|
||||||
WscSyncStatus: model.SyncFlagNewMask,
|
WscSyncStatus: model.SyncFlagNewMask,
|
||||||
}
|
}
|
||||||
storeCat.DeletedAt = utils.DefaultTimeValue
|
storeCat.DeletedAt = utils.DefaultTimeValue
|
||||||
|
|||||||
@@ -29,12 +29,12 @@ func SetOrderPrintFlag(db *DaoDB, userName string, vendorOrderID string, vendorI
|
|||||||
if isPrinted {
|
if isPrinted {
|
||||||
err = SetOrderFlag(db, userName, vendorOrderID, vendorID, model.OrderFlagMaskPrinted)
|
err = SetOrderFlag(db, userName, vendorOrderID, vendorID, model.OrderFlagMaskPrinted)
|
||||||
} else {
|
} else {
|
||||||
err = SetOrderFlag(db, userName, vendorOrderID, vendorID, ^int8(model.OrderFlagMaskPrinted))
|
err = SetOrderFlag(db, userName, vendorOrderID, vendorID, ^model.OrderFlagMaskPrinted)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetOrderFlag(db *DaoDB, userName string, vendorOrderID string, vendorID int, flag int8) (err error) {
|
func SetOrderFlag(db *DaoDB, userName string, vendorOrderID string, vendorID int, flag int) (err error) {
|
||||||
_, err = ExecuteSQL(db, `
|
_, err = ExecuteSQL(db, `
|
||||||
UPDATE goods_order
|
UPDATE goods_order
|
||||||
SET flag = flag | ?
|
SET flag = flag | ?
|
||||||
@@ -43,7 +43,7 @@ func SetOrderFlag(db *DaoDB, userName string, vendorOrderID string, vendorID int
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func ClearOrderFlag(db *DaoDB, userName string, vendorOrderID string, vendorID int, flag int8) (err error) {
|
func ClearOrderFlag(db *DaoDB, userName string, vendorOrderID string, vendorID int, flag int) (err error) {
|
||||||
_, err = ExecuteSQL(db, `
|
_, err = ExecuteSQL(db, `
|
||||||
UPDATE goods_order
|
UPDATE goods_order
|
||||||
SET flag = flag & ?
|
SET flag = flag & ?
|
||||||
@@ -51,3 +51,34 @@ func ClearOrderFlag(db *DaoDB, userName string, vendorOrderID string, vendorID i
|
|||||||
`, flag, vendorOrderID, vendorID)
|
`, flag, vendorOrderID, vendorID)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetAfsOrderFlag(db *DaoDB, userName string, afsOrderID string, vendorID int, flag int) (err error) {
|
||||||
|
_, err = ExecuteSQL(db, `
|
||||||
|
UPDATE afs_order
|
||||||
|
SET flag = flag | ?
|
||||||
|
WHERE afs_order_id = ? AND vendor_id = ?
|
||||||
|
`, flag, afsOrderID, vendorID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAfsOrders(db *DaoDB, vendorID int, vendorOrderID, afsOrderID string) (afsOrderList []*model.AfsOrder, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT *
|
||||||
|
FROM afs_order t1
|
||||||
|
WHERE t1.vendor_id = ?
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
vendorID,
|
||||||
|
}
|
||||||
|
if vendorOrderID != "" {
|
||||||
|
sql += " AND t1.vendor_order_id = ?"
|
||||||
|
sqlParams = append(sqlParams, vendorOrderID)
|
||||||
|
}
|
||||||
|
if afsOrderID != "" {
|
||||||
|
sql += " AND t1.afs_order_id = ?"
|
||||||
|
sqlParams = append(sqlParams, afsOrderID)
|
||||||
|
}
|
||||||
|
sql += " ORDER BY t1.afs_order_id DESC"
|
||||||
|
err = GetRows(db, &afsOrderList, sql, sqlParams...)
|
||||||
|
return afsOrderList, err
|
||||||
|
}
|
||||||
|
|||||||
@@ -168,3 +168,7 @@ func value2Value(srcValue, dstValue reflect.Value, copyType int) {
|
|||||||
// func ObjNull2Normal(src, dst interface{}) {
|
// func ObjNull2Normal(src, dst interface{}) {
|
||||||
// copyBetweenNoramAndNullObj(src, dst, 2)
|
// copyBetweenNoramAndNullObj(src, dst, 2)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
func IsVendorThingIDEmpty(vendorThingID string) bool {
|
||||||
|
return vendorThingID == "" || vendorThingID == "0"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package dao
|
package dao
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetSellCities(db *DaoDB, nameID int, vendorID int) (cities []*model.Place, err error) {
|
func GetSellCities(db *DaoDB, nameID int, vendorID int) (cities []*model.Place, err error) {
|
||||||
@@ -52,6 +55,47 @@ func GetSkuNameByHashCode(db *DaoDB, hashCode string) (skuName *model.SkuName, e
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetSkus(db *DaoDB, skuIDs, nameIDs, statuss, catIDs []int) (skuList []*model.SkuAndName, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT t1.*, t2.name, t2.unit
|
||||||
|
FROM sku t1
|
||||||
|
JOIN sku_name t2 ON t2.id = t1.name_id AND t2.deleted_at = ?
|
||||||
|
`
|
||||||
|
sqlWhere := `
|
||||||
|
WHERE t1.deleted_at = ?
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
}
|
||||||
|
if len(skuIDs) > 0 {
|
||||||
|
sqlWhere += " AND t1.id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, skuIDs)
|
||||||
|
}
|
||||||
|
if len(nameIDs) > 0 {
|
||||||
|
sqlWhere += " AND t1.name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, nameIDs)
|
||||||
|
}
|
||||||
|
if len(statuss) > 0 {
|
||||||
|
sqlWhere += " AND t1.status IN (" + GenQuestionMarks(len(statuss)) + ") AND t2.status IN (" + GenQuestionMarks(len(statuss)) + ")"
|
||||||
|
sqlParams = append(sqlParams, statuss, statuss)
|
||||||
|
}
|
||||||
|
if len(catIDs) > 0 {
|
||||||
|
sql += `
|
||||||
|
JOIN sku_category t3 ON t3.id = t2.category_id
|
||||||
|
LEFT JOIN sku_category t3p ON t3p.id = t3.parent_id
|
||||||
|
`
|
||||||
|
sqlWhere += " AND (t3.id IN (" + GenQuestionMarks(len(catIDs)) + ")"
|
||||||
|
sqlWhere += " OR t3p.id IN (" + GenQuestionMarks(len(catIDs)) + ") )"
|
||||||
|
sqlParams = append(sqlParams, catIDs, catIDs)
|
||||||
|
}
|
||||||
|
sql += sqlWhere
|
||||||
|
if err = GetRows(db, &skuList, sql, sqlParams...); err == nil {
|
||||||
|
return skuList, nil
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
func GetSkuNames(db *DaoDB, nameIDs []int) (skuNameList []*model.SkuName, err error) {
|
func GetSkuNames(db *DaoDB, nameIDs []int) (skuNameList []*model.SkuName, err error) {
|
||||||
sql := `
|
sql := `
|
||||||
SELECT *
|
SELECT *
|
||||||
@@ -70,3 +114,76 @@ func GetSkuNames(db *DaoDB, nameIDs []int) (skuNameList []*model.SkuName, err er
|
|||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetSkuByNames(db *DaoDB, nameIDs []int) (skuList []*model.Sku, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT *
|
||||||
|
FROM sku t1
|
||||||
|
WHERE t1.deleted_at = ?
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
}
|
||||||
|
if len(nameIDs) > 0 {
|
||||||
|
sql += " AND t1.name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, nameIDs)
|
||||||
|
}
|
||||||
|
if err = GetRows(db, &skuList, sql, sqlParams...); err == nil {
|
||||||
|
return skuList, nil
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSkuIDByNames(db *DaoDB, nameIDs []int) (skuIDs []int, err error) {
|
||||||
|
skuList, err := GetSkuByNames(db, nameIDs)
|
||||||
|
if err == nil {
|
||||||
|
for _, sku := range skuList {
|
||||||
|
skuIDs = append(skuIDs, sku.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return skuIDs, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSkuByCats(db *DaoDB, catIDs []int) (skuList []*model.Sku, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT t1.*
|
||||||
|
FROM sku t1
|
||||||
|
JOIN sku_name t2 ON t2.id = t1.name_id
|
||||||
|
WHERE t1.deleted_at = ?
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
}
|
||||||
|
if len(catIDs) > 0 {
|
||||||
|
sql += " AND t2.category_id IN (" + GenQuestionMarks(len(catIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, catIDs)
|
||||||
|
}
|
||||||
|
err = GetRows(db, &skuList, sql, sqlParams...)
|
||||||
|
globals.SugarLogger.Debugf("GetSkuByCats err:%v", err)
|
||||||
|
return skuList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetSkuSyncStatus(db *DaoDB, vendorID int, skuIDs []int, syncStatus int) (num int64, err error) {
|
||||||
|
globals.SugarLogger.Debugf("SetSkuSyncStatus, vendorID:%d", vendorID)
|
||||||
|
|
||||||
|
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
||||||
|
sql := fmt.Sprintf(`
|
||||||
|
UPDATE sku t1
|
||||||
|
SET t1.%s_sync_status = IF(t1.deleted_at = ?, t1.%s_sync_status | ?, 0)
|
||||||
|
`, fieldPrefix, fieldPrefix)
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
syncStatus,
|
||||||
|
}
|
||||||
|
if (syncStatus & model.SyncFlagNewMask) != 0 {
|
||||||
|
sql += fmt.Sprintf(`,
|
||||||
|
t1.%s_id = 0
|
||||||
|
`, fieldPrefix)
|
||||||
|
}
|
||||||
|
sql += " WHERE 1 = 1"
|
||||||
|
if len(skuIDs) > 0 {
|
||||||
|
sql += " AND t1.id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, skuIDs)
|
||||||
|
}
|
||||||
|
return ExecuteSQL(db, sql, sqlParams...)
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ type StoreDetail struct {
|
|||||||
|
|
||||||
type StoreDetail2 struct {
|
type StoreDetail2 struct {
|
||||||
model.Store
|
model.Store
|
||||||
VendorStoreID string `orm:"column(vendor_store_id)` // 这个在GetMissingDadaStores返回中指的是到家的vendorStoreID
|
VendorStoreID string `orm:"column(vendor_store_id)"` // 这个在GetMissingDadaStores返回中指的是到家的vendorStoreID
|
||||||
DadaStoreID string `orm:"column(dada_store_id)`
|
DadaStoreID string `orm:"column(dada_store_id)"`
|
||||||
DistrictName string
|
DistrictName string
|
||||||
CityName string
|
CityName string
|
||||||
}
|
}
|
||||||
@@ -136,8 +136,8 @@ func GetMissingDadaStores(db *DaoDB, storeID int, isMustHaveJdStore bool) (store
|
|||||||
t3.vendor_store_id dada_store_id
|
t3.vendor_store_id dada_store_id
|
||||||
FROM store t1
|
FROM store t1
|
||||||
LEFT JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? AND t2.deleted_at = ?
|
LEFT JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? AND t2.deleted_at = ?
|
||||||
JOIN place city ON city.code = t1.city_code
|
LEFT JOIN place city ON city.code = t1.city_code
|
||||||
JOIN place district ON district.code = t1.district_code
|
LEFT JOIN place district ON district.code = t1.district_code
|
||||||
LEFT JOIN store_courier_map t3 ON t3.store_id = t1.id AND t3.vendor_id = ? AND t3.deleted_at = ?
|
LEFT JOIN store_courier_map t3 ON t3.store_id = t1.id AND t3.vendor_id = ? AND t3.deleted_at = ?
|
||||||
WHERE t1.deleted_at = ?
|
WHERE t1.deleted_at = ?
|
||||||
`
|
`
|
||||||
@@ -181,6 +181,33 @@ func GetStoreCourierList(db *DaoDB, storeID, status int) (courierStoreList []*mo
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetStoresMapList(db *DaoDB, vendorIDs, storeIDs []int, status int) (storeMapList []*model.StoreMap, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT t1.*
|
||||||
|
FROM store_map t1
|
||||||
|
WHERE t1.deleted_at = ?
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
}
|
||||||
|
if len(vendorIDs) > 0 {
|
||||||
|
sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, vendorIDs)
|
||||||
|
}
|
||||||
|
if len(storeIDs) > 0 {
|
||||||
|
sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, storeIDs)
|
||||||
|
}
|
||||||
|
if status != model.StoreStatusAll {
|
||||||
|
sql += " AND t1.status = ?"
|
||||||
|
sqlParams = append(sqlParams, status)
|
||||||
|
}
|
||||||
|
if err = GetRows(db, &storeMapList, sql, sqlParams...); err == nil {
|
||||||
|
return storeMapList, nil
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// 此函数在检测到一个门店的所有平台状态一样,且不为StoreStatusOpened时,
|
// 此函数在检测到一个门店的所有平台状态一样,且不为StoreStatusOpened时,
|
||||||
// 将平台门店状态全部改为StoreStatusOpened,则把京西门店状态改为之前那个统一的平台门店状态
|
// 将平台门店状态全部改为StoreStatusOpened,则把京西门店状态改为之前那个统一的平台门店状态
|
||||||
func FormalizeStoreStatus(db *DaoDB, storeID, storeStatus int) (err error) {
|
func FormalizeStoreStatus(db *DaoDB, storeID, storeStatus int) (err error) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package dao
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
@@ -13,13 +14,16 @@ var (
|
|||||||
model.VendorIDWSC: "img_weimob",
|
model.VendorIDWSC: "img_weimob",
|
||||||
model.VendorIDEBAI: "img_ebai",
|
model.VendorIDEBAI: "img_ebai",
|
||||||
}
|
}
|
||||||
|
descImgFieldMap = map[int]string{
|
||||||
|
model.VendorIDEBAI: "desc_img_ebai",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
type SkuStoreCatInfo struct {
|
type SkuStoreCatInfo struct {
|
||||||
model.SkuCategory
|
model.SkuCategory
|
||||||
MapID int `orm:"column(map_id)"` // 这个主要用于判断是否有store_sku_category_map
|
MapID int `orm:"column(map_id)"` // 这个主要用于判断是否有store_sku_category_map
|
||||||
VendorCatID string `orm:"column(vendor_cat_id)"`
|
VendorCatID string `orm:"column(vendor_cat_id)"`
|
||||||
CatSyncStatus int8
|
StoreCatSyncStatus int8
|
||||||
|
|
||||||
ParentCatName string
|
ParentCatName string
|
||||||
ParentMapID int `orm:"column(parent_map_id)"` // 这个主要用于判断是否有父store_sku_category_map
|
ParentMapID int `orm:"column(parent_map_id)"` // 这个主要用于判断是否有父store_sku_category_map
|
||||||
@@ -27,47 +31,63 @@ type SkuStoreCatInfo struct {
|
|||||||
ParentCatSyncStatus int8
|
ParentCatSyncStatus int8
|
||||||
}
|
}
|
||||||
|
|
||||||
type StoreCatSyncInfo struct {
|
|
||||||
CatName string
|
|
||||||
Seq int `json:"seq"`
|
|
||||||
model.StoreSkuCategoryMap
|
|
||||||
|
|
||||||
ParentCatName string
|
|
||||||
ParentCatID int `orm:"column(parent_cat_id)"` // 这个主要用于判断是否有父store_sku_category_map
|
|
||||||
ParentVendorCatID string `orm:"column(parent_vendor_cat_id)"`
|
|
||||||
ParentCatSyncStatus int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type StoreSkuSyncInfo struct {
|
type StoreSkuSyncInfo struct {
|
||||||
BindID int `orm:"column(bind_id)"`
|
// 平台无关的store sku信息
|
||||||
Price int64
|
BindID int `orm:"column(bind_id)"` // 换名的原因是与Sku.ID同名区别
|
||||||
UnitPrice int64
|
StoreID int `orm:"column(store_id)"`
|
||||||
StoreSkuStatus int
|
SkuID int `orm:"column(sku_id)"` // 这个与Sku.ID的区别是SkuID是必然存在的
|
||||||
SkuSyncStatus int8
|
Price int64
|
||||||
|
UnitPrice int64
|
||||||
|
|
||||||
|
// 平台相关的store sku信息
|
||||||
|
StoreSkuStatus int
|
||||||
|
StoreSkuSyncStatus int8
|
||||||
|
VendorSkuID string `orm:"column(vendor_sku_id)"`
|
||||||
|
|
||||||
model.Sku
|
model.Sku
|
||||||
VendorSkuID string `orm:"column(vendor_sku_id)"`
|
|
||||||
|
// sku_name
|
||||||
Prefix string
|
Prefix string
|
||||||
NameID int `orm:"column(name_id)"`
|
NameID int `orm:"column(name_id)"`
|
||||||
VendorNameID string `orm:"column(vendor_name_id)"`
|
VendorNameID string `orm:"column(vendor_name_id)"`
|
||||||
Name string
|
Name string
|
||||||
Unit string
|
Unit string
|
||||||
Img string
|
|
||||||
Upc string
|
Upc string
|
||||||
Seq int
|
|
||||||
|
|
||||||
VendorVendorCatID int64 `orm:"column(vendor_vendor_cat_id)"`
|
// 平台相关的图片信息
|
||||||
|
Img string
|
||||||
|
DescImg string
|
||||||
|
|
||||||
CatSyncStatus int8
|
VendorVendorCatID int64 `orm:"column(vendor_vendor_cat_id)"` // 平台商品分类(叶子结点)
|
||||||
VendorCatID string `orm:"column(vendor_cat_id)"`
|
VendorVendorCatID2 int64 `orm:"column(vendor_vendor_cat_id2)"` // 平台商品分类上一级
|
||||||
|
VendorVendorCatID3 int64 `orm:"column(vendor_vendor_cat_id3)"` // 平台商品分类再上一级
|
||||||
|
|
||||||
SkuCatSyncStatus int8
|
// sku的商家分类信息
|
||||||
SkuVendorCatID string `orm:"column(sku_vendor_cat_id)"`
|
SkuStoreCatSyncStatus int8
|
||||||
|
SkuVendorCatID string `orm:"column(sku_vendor_cat_id)"`
|
||||||
|
|
||||||
|
// sku_name的商家分类信息
|
||||||
|
StoreCatSyncStatus int8
|
||||||
|
VendorCatID string `orm:"column(vendor_cat_id)"`
|
||||||
|
|
||||||
|
CatPricePercentage int
|
||||||
|
}
|
||||||
|
|
||||||
|
type MissingStoreSkuInfo struct {
|
||||||
|
StoreID int `orm:"column(store_id)"`
|
||||||
|
NameID int `orm:"column(name_id)"`
|
||||||
|
SkuID int `orm:"column(sku_id)"`
|
||||||
|
SpecQuality float32
|
||||||
|
SpecUnit string
|
||||||
|
Unit string
|
||||||
|
RefPrice int
|
||||||
}
|
}
|
||||||
|
|
||||||
// 单门店模式厂商适用
|
// 单门店模式厂商适用
|
||||||
|
// 从store_sku_bind中,得到所有依赖的商家分类信息
|
||||||
func GetSkusCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level int) (cats []*SkuStoreCatInfo, err error) {
|
func GetSkusCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level int) (cats []*SkuStoreCatInfo, err error) {
|
||||||
sql := `
|
sql := `
|
||||||
SELECT DISTINCT t4.*, t5.id map_id, t5.%s_id vendor_cat_id, t5.%s_sync_status cat_sync_status, t4p.name parent_cat_name, t5p.id parent_map_id, t5p.%s_id parent_vendor_cat_id, t5p.%s_sync_status parent_cat_sync_status
|
SELECT DISTINCT t4.*, t5.id map_id, t5.%s_id vendor_cat_id, t5.%s_sync_status store_cat_sync_status, t4p.name parent_cat_name, t5p.id parent_map_id, t5p.%s_id parent_vendor_cat_id, t5p.%s_sync_status parent_cat_sync_status
|
||||||
FROM store_sku_bind t1
|
FROM store_sku_bind t1
|
||||||
JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ? AND t2.status = ?
|
JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ? AND t2.status = ?
|
||||||
JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ? AND t3.status = ?
|
JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ? AND t3.status = ?
|
||||||
@@ -86,7 +106,7 @@ func GetSkusCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level int
|
|||||||
LEFT JOIN store_sku_category_map t5 ON t4.id = t5.category_id AND t5.store_id = t1.store_id AND t5.deleted_at = ?
|
LEFT JOIN store_sku_category_map t5 ON t4.id = t5.category_id AND t5.store_id = t1.store_id AND t5.deleted_at = ?
|
||||||
LEFT JOIN sku_category t4p ON t4.parent_id = t4p.id
|
LEFT JOIN sku_category t4p ON t4.parent_id = t4p.id
|
||||||
LEFT JOIN store_sku_category_map t5p ON t4p.id = t5p.category_id AND t5p.store_id = t1.store_id AND t5p.deleted_at = ?
|
LEFT JOIN store_sku_category_map t5p ON t4p.id = t5p.category_id AND t5p.store_id = t1.store_id AND t5p.deleted_at = ?
|
||||||
WHERE t1.deleted_at = ? AND t1.store_id = ?
|
WHERE t1.deleted_at = ? AND t1.store_id = ? AND t1.status = ?
|
||||||
`
|
`
|
||||||
sqlParams := []interface{}{
|
sqlParams := []interface{}{
|
||||||
utils.DefaultTimeValue,
|
utils.DefaultTimeValue,
|
||||||
@@ -98,6 +118,7 @@ func GetSkusCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level int
|
|||||||
utils.DefaultTimeValue,
|
utils.DefaultTimeValue,
|
||||||
utils.DefaultTimeValue,
|
utils.DefaultTimeValue,
|
||||||
storeID,
|
storeID,
|
||||||
|
model.SkuStatusNormal,
|
||||||
}
|
}
|
||||||
if len(skuIDs) > 0 {
|
if len(skuIDs) > 0 {
|
||||||
sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
|
sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
|
||||||
@@ -112,93 +133,132 @@ func GetSkusCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level int
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 单门店模式厂商适用
|
// 单门店模式厂商适用
|
||||||
func GetStoreCategories(db *DaoDB, vendorID, storeID int, level int) (cats []*StoreCatSyncInfo, err error) {
|
// 单纯的从已经创建的store_sku_category_map中,得到相关的同步信息
|
||||||
|
func GetStoreCategories(db *DaoDB, vendorID, storeID int, level int) (cats []*SkuStoreCatInfo, err error) {
|
||||||
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
||||||
sql := fmt.Sprintf(`
|
sql := fmt.Sprintf(`
|
||||||
SELECT t5.*, t4.name cat_name, t4.seq, t4p.name parent_cat_name, t5p.category_id parent_cat_id, t5p.%s_id parent_vendor_cat_id, t5p.%s_sync_status parent_cat_sync_status
|
SELECT t4.*,
|
||||||
|
t5.id map_id, t5.%s_id vendor_cat_id, t5.%s_sync_status store_cat_sync_status,
|
||||||
|
t4p.name parent_cat_name,
|
||||||
|
t5p.id parent_map_id, t5p.%s_id parent_vendor_cat_id, t5p.%s_sync_status parent_cat_sync_status
|
||||||
FROM store_sku_category_map t5
|
FROM store_sku_category_map t5
|
||||||
JOIN sku_category t4 ON t5.category_id = t4.id AND t4.deleted_at = ?
|
JOIN sku_category t4 ON t5.category_id = t4.id AND t4.deleted_at = ?
|
||||||
LEFT JOIN sku_category t4p ON t4.parent_id = t4p.id
|
LEFT JOIN sku_category t4p ON t4.parent_id = t4p.id
|
||||||
LEFT JOIN store_sku_category_map t5p ON t4p.id = t5p.category_id AND t5.store_id = t5p.store_id AND t5p.deleted_at = ?
|
LEFT JOIN store_sku_category_map t5p ON t4p.id = t5p.category_id AND t5.store_id = t5p.store_id AND t5p.deleted_at = ?
|
||||||
WHERE t5.store_id = ? AND t4.level = ? AND t5.%s_sync_status <> 0 AND t5.deleted_at = ?
|
WHERE t5.store_id = ? AND t4.level = ? AND t5.%s_sync_status <> 0 AND t5.deleted_at = ?
|
||||||
`, fieldPrefix, fieldPrefix, fieldPrefix)
|
`, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix)
|
||||||
if err = GetRows(db, &cats, sql, utils.DefaultTimeValue, utils.DefaultTimeValue, storeID, level, utils.DefaultTimeValue); err != nil {
|
if err = GetRows(db, &cats, sql, utils.DefaultTimeValue, utils.DefaultTimeValue, storeID, level, utils.DefaultTimeValue); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return cats, err
|
return cats, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 单门店模式厂商适用
|
// 以store_sku_bind为基础来做同步,正常情况下使用
|
||||||
func GetStoreSkus(db *DaoDB, vendorID, storeID int, skuIDs []int) (skus []*StoreSkuSyncInfo, err error) {
|
// 单多门店模式厂商通用
|
||||||
|
func GetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, isDirty bool) (skus []*StoreSkuSyncInfo, err error) {
|
||||||
|
isSingleStorePF := model.MultiStoresVendorMap[vendorID] != 1
|
||||||
tableName := "t1"
|
tableName := "t1"
|
||||||
if model.MultiStoresVendorMap[vendorID] == 1 { // 多店模式平台
|
if !isSingleStorePF {
|
||||||
tableName = "t2"
|
tableName = "t2"
|
||||||
}
|
}
|
||||||
vendorSkuNameField := "0"
|
vendorSkuNameField := "0"
|
||||||
if vendorID == model.VendorIDWSC {
|
if vendorID == model.VendorIDWSC {
|
||||||
vendorSkuNameField = "t1.wsc_id2"
|
vendorSkuNameField = "t1.wsc_id2"
|
||||||
}
|
}
|
||||||
|
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
||||||
sql := `
|
sql := `
|
||||||
SELECT t1.id bind_id, t1.price, t1.unit_price, t1.status store_sku_status, %s.%s_id vendor_sku_id, t1.%s_sync_status sku_sync_status, %s vendor_name_id,
|
SELECT t1.id bind_id, t1.sku_id, t1.price, t1.unit_price, t1.status store_sku_status, %s.%s_id vendor_sku_id, t1.%s_sync_status store_sku_sync_status, %s vendor_name_id, t1.store_id,
|
||||||
t2.*,
|
t2.*,
|
||||||
t3.id name_id, t3.prefix, t3.name, t3.unit, t3.%s img, t3.upc,
|
t3.id name_id, t3.prefix, t3.name, t3.unit, IF(t3.%s <> '', t3.%s, t3.img) img, t3.upc, t3.%s desc_img,
|
||||||
t4.%s_category_id vendor_vendor_cat_id,
|
t4.%s_category_id vendor_vendor_cat_id, t4.%s_price_percentage cat_price_percentage
|
||||||
t5.%s_sync_status cat_sync_status, t5.%s_id vendor_cat_id,
|
`
|
||||||
t5sku.%s_sync_status sku_cat_sync_status, t5sku.%s_id sku_vendor_cat_id
|
fmtParams := []interface{}{
|
||||||
|
tableName, fieldPrefix, fieldPrefix, vendorSkuNameField, GetImgFieldName(vendorID), GetImgFieldName(vendorID), GetDescImgFieldName(vendorID),
|
||||||
|
fieldPrefix, fieldPrefix,
|
||||||
|
}
|
||||||
|
if vendorID == model.VendorIDEBAI {
|
||||||
|
sql += `,
|
||||||
|
t4vp.vendor_category_id vendor_vendor_cat_id2, t4vp.parent_id vendor_vendor_cat_id3`
|
||||||
|
}
|
||||||
|
if isSingleStorePF {
|
||||||
|
sql += `,
|
||||||
|
t5.%s_sync_status store_cat_sync_status, t5.%s_id vendor_cat_id,
|
||||||
|
t5sku.%s_sync_status sku_store_cat_sync_status, t5sku.%s_id sku_vendor_cat_id`
|
||||||
|
fmtParams = append(fmtParams, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix)
|
||||||
|
}
|
||||||
|
sql += `
|
||||||
FROM store_sku_bind t1
|
FROM store_sku_bind t1
|
||||||
LEFT JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ? AND t2.status = ?
|
LEFT JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ? AND t2.status = ?
|
||||||
LEFT JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ? AND t3.status = ?
|
LEFT JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ? AND t3.status = ?
|
||||||
JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ?
|
LEFT JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ?`
|
||||||
JOIN store_sku_category_map t5 ON t4.id = t5.category_id AND t5.store_id = t1.store_id AND t5.deleted_at = ?
|
|
||||||
LEFT JOIN store_sku_category_map t5sku ON t2.category_id = t5sku.category_id AND t5sku.store_id = t1.store_id AND t5sku.deleted_at = ?
|
|
||||||
WHERE t1.store_id = ? AND t1.%s_sync_status <> 0
|
|
||||||
`
|
|
||||||
sqlParams := []interface{}{
|
sqlParams := []interface{}{
|
||||||
utils.DefaultTimeValue,
|
utils.DefaultTimeValue,
|
||||||
model.SkuStatusNormal,
|
model.SkuStatusNormal,
|
||||||
utils.DefaultTimeValue,
|
utils.DefaultTimeValue,
|
||||||
model.SkuStatusNormal,
|
model.SkuStatusNormal,
|
||||||
utils.DefaultTimeValue,
|
utils.DefaultTimeValue,
|
||||||
utils.DefaultTimeValue,
|
}
|
||||||
utils.DefaultTimeValue,
|
if vendorID == model.VendorIDEBAI {
|
||||||
storeID,
|
sql += `
|
||||||
|
LEFT JOIN sku_vendor_category t4v ON t4v.vendor_category_id = t4.%s_category_id AND t4v.vendor_id = ?
|
||||||
|
LEFT JOIN sku_vendor_category t4vp ON t4vp.vendor_category_id = t4v.parent_id AND t4v.vendor_id = ?`
|
||||||
|
fmtParams = append(fmtParams, fieldPrefix)
|
||||||
|
sqlParams = append(sqlParams, vendorID, vendorID)
|
||||||
|
}
|
||||||
|
if isSingleStorePF {
|
||||||
|
sql += `
|
||||||
|
LEFT JOIN store_sku_category_map t5 ON t4.id = t5.category_id AND t5.store_id = t1.store_id AND t5.deleted_at = ?
|
||||||
|
LEFT JOIN store_sku_category_map t5sku ON t2.category_id = t5sku.category_id AND t5sku.store_id = t1.store_id AND t5sku.deleted_at = ?`
|
||||||
|
sqlParams = append(sqlParams, utils.DefaultTimeValue, utils.DefaultTimeValue)
|
||||||
|
}
|
||||||
|
sql += " WHERE t1.store_id = ?"
|
||||||
|
sqlParams = append(sqlParams, storeID)
|
||||||
|
if isDirty {
|
||||||
|
sql += " AND (t1.%s_sync_status <> 0 OR (%s.%s_id <> 0 AND t3.id IS NULL))"
|
||||||
|
fmtParams = append(fmtParams, fieldPrefix, tableName, fieldPrefix)
|
||||||
|
} else {
|
||||||
|
sql += " AND t1.deleted_at = ?"
|
||||||
|
sqlParams = append(sqlParams, utils.DefaultTimeValue)
|
||||||
}
|
}
|
||||||
if len(skuIDs) > 0 {
|
if len(skuIDs) > 0 {
|
||||||
sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
|
sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
|
||||||
sqlParams = append(sqlParams, skuIDs)
|
sqlParams = append(sqlParams, skuIDs)
|
||||||
}
|
}
|
||||||
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
if !isSingleStorePF {
|
||||||
sql = fmt.Sprintf(sql, tableName, fieldPrefix, fieldPrefix, vendorSkuNameField, GetImgFieldName(vendorID), fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix)
|
sql += " AND t2.%s_id <> 0"
|
||||||
|
fmtParams = append(fmtParams, fieldPrefix)
|
||||||
|
}
|
||||||
|
sql = fmt.Sprintf(sql, fmtParams...)
|
||||||
sql += " ORDER BY t1.price"
|
sql += " ORDER BY t1.price"
|
||||||
// globals.SugarLogger.Debug(sql)
|
// globals.SugarLogger.Debug(sql)
|
||||||
if err = GetRows(db, &skus, sql, sqlParams...); err != nil {
|
if err = GetRows(db, &skus, sql, sqlParams...); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
index := 1
|
|
||||||
for _, sku := range skus {
|
|
||||||
sku.Seq = index
|
|
||||||
index++
|
|
||||||
}
|
|
||||||
return skus, err
|
return skus, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetStoreSkus(db *DaoDB, vendorID, storeID int, skuIDs []int) (skus []*StoreSkuSyncInfo, err error) {
|
||||||
|
return GetStoreSkus2(db, vendorID, storeID, skuIDs, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 以sku为基础来做全同步,
|
||||||
// 多门店模式厂商适用
|
// 多门店模式厂商适用
|
||||||
func GetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSyncInfo, err error) {
|
func GetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSyncInfo, err error) {
|
||||||
globals.SugarLogger.Debugf("GetFullStoreSkus, storeID:%d, vendorID:%d", storeID, vendorID)
|
globals.SugarLogger.Debugf("GetFullStoreSkus, storeID:%d, vendorID:%d", storeID, vendorID)
|
||||||
|
|
||||||
sql := `
|
sql := `
|
||||||
SELECT t1.id bind_id, t1.price, t1.unit_price, t1.status store_sku_status, t2.%s_id vendor_sku_id, t1.%s_sync_status sku_sync_status,
|
SELECT t1.id bind_id, t1.price, t1.unit_price, t1.status store_sku_status, t2.%s_id vendor_sku_id, t1.%s_sync_status store_sku_sync_status, t1.store_id,
|
||||||
t2.*,
|
t2.*, t2.id sku_id,
|
||||||
t3.id name_id, t3.prefix, t3.name, t3.unit, t3.%s img,
|
t3.id name_id, t3.prefix, t3.name, t3.unit, IF(t3.%s <> '', t3.%s, t3.img) img,
|
||||||
t4.%s_category_id vendor_vendor_cat_id,
|
t4.%s_category_id vendor_vendor_cat_id,
|
||||||
t4.%s_sync_status cat_sync_status, t4.%s_id vendor_cat_id,
|
t4.%s_sync_status store_cat_sync_status, t4.%s_id vendor_cat_id,
|
||||||
t5sku.%s_sync_status sku_cat_sync_status, t5sku.%s_id sku_vendor_cat_id
|
t5sku.%s_sync_status sku_store_cat_sync_status, t5sku.%s_id sku_vendor_cat_id
|
||||||
FROM sku t2
|
FROM sku t2
|
||||||
LEFT JOIN store_sku_bind t1 ON t1.sku_id = t2.id AND t1.store_id = ? AND t1.deleted_at = ?
|
LEFT JOIN store_sku_bind t1 ON t1.sku_id = t2.id AND t1.store_id = ? AND t1.deleted_at = ?
|
||||||
JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ? AND t3.status = ?
|
JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ? AND t3.status = ?
|
||||||
JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ?
|
JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ?
|
||||||
LEFT JOIN sku_category t5sku ON t2.category_id = t5sku.id
|
LEFT JOIN sku_category t5sku ON t2.category_id = t5sku.id
|
||||||
WHERE t2.deleted_at = ? AND t2.status = ?
|
WHERE t2.deleted_at = ? AND t2.status = ? AND t2.%s_id <> 0
|
||||||
`
|
`
|
||||||
sqlParams := []interface{}{
|
sqlParams := []interface{}{
|
||||||
storeID,
|
storeID,
|
||||||
@@ -210,7 +270,8 @@ func GetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSyncInf
|
|||||||
model.SkuStatusNormal,
|
model.SkuStatusNormal,
|
||||||
}
|
}
|
||||||
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
||||||
sql = fmt.Sprintf(sql, fieldPrefix, fieldPrefix, GetImgFieldName(vendorID), fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix)
|
sql = fmt.Sprintf(sql, fieldPrefix, fieldPrefix, GetImgFieldName(vendorID), GetImgFieldName(vendorID),
|
||||||
|
fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix)
|
||||||
// globals.SugarLogger.Debug(sql)
|
// globals.SugarLogger.Debug(sql)
|
||||||
// globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false))
|
// globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false))
|
||||||
if err = GetRows(db, &skus, sql, sqlParams...); err != nil {
|
if err = GetRows(db, &skus, sql, sqlParams...); err != nil {
|
||||||
@@ -219,53 +280,79 @@ func GetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSyncInf
|
|||||||
return skus, err
|
return skus, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetStoreSkuSyncStatus(db *DaoDB, vendorID, storeID int, skuIDs []int, syncStatus int) (num int64, err error) {
|
// 这个函数之前是要设置没有删除或同步标志不为0的,会导致将同步标志不为0且删除了的把标志去掉,现在改为只设置没有删除的
|
||||||
globals.SugarLogger.Debugf("SetStoreSkuSyncStatus, storeID:%d, vendorID:%d", storeID, vendorID)
|
func SetStoreSkuSyncStatus(db *DaoDB, vendorID int, storeIDs []int, skuIDs []int, syncStatus int) (num int64, err error) {
|
||||||
|
globals.SugarLogger.Debugf("SetStoreSkuSyncStatus, storeIDs:%v, vendorID:%d", storeIDs, vendorID)
|
||||||
|
|
||||||
|
isSingleStorePF := model.MultiStoresVendorMap[vendorID] != 1
|
||||||
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
||||||
sql := fmt.Sprintf(`
|
sql := `
|
||||||
UPDATE store_sku_bind
|
UPDATE store_sku_bind t1
|
||||||
SET %s_sync_status = IF(deleted_at = ?, %s_sync_status | ?, 0)
|
SET t1.%s_sync_status = t1.%s_sync_status | ?
|
||||||
`, fieldPrefix, fieldPrefix)
|
`
|
||||||
|
fmtParams := []interface{}{
|
||||||
|
fieldPrefix,
|
||||||
|
fieldPrefix,
|
||||||
|
}
|
||||||
sqlParams := []interface{}{
|
sqlParams := []interface{}{
|
||||||
utils.DefaultTimeValue,
|
|
||||||
syncStatus,
|
syncStatus,
|
||||||
}
|
}
|
||||||
if (syncStatus & model.SyncFlagNewMask) != 0 {
|
if isSingleStorePF && (syncStatus&model.SyncFlagNewMask) != 0 {
|
||||||
sql += fmt.Sprintf(`,
|
sql += `,
|
||||||
%s_id = 0
|
t1.%s_id = 0
|
||||||
`, fieldPrefix)
|
`
|
||||||
|
fmtParams = append(fmtParams, fieldPrefix)
|
||||||
}
|
}
|
||||||
sql += " WHERE 1 = 1"
|
sql += " WHERE (t1.deleted_at = ?)"
|
||||||
if storeID > 0 {
|
// fmtParams = append(fmtParams, fieldPrefix)
|
||||||
sql += " AND store_id = ?"
|
sqlParams = append(sqlParams, utils.DefaultTimeValue)
|
||||||
sqlParams = append(sqlParams, storeID)
|
if len(storeIDs) > 0 {
|
||||||
|
sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, storeIDs)
|
||||||
}
|
}
|
||||||
if len(skuIDs) > 0 {
|
if len(skuIDs) > 0 {
|
||||||
sql += " AND sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
|
sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
|
||||||
sqlParams = append(sqlParams, skuIDs)
|
sqlParams = append(sqlParams, skuIDs)
|
||||||
}
|
}
|
||||||
|
sql = fmt.Sprintf(sql, fmtParams...)
|
||||||
return ExecuteSQL(db, sql, sqlParams...)
|
return ExecuteSQL(db, sql, sqlParams...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetStoreCategorySyncStatus(db *DaoDB, vendorID, storeID int, catIDs []int, syncStatus int) (num int64, err error) {
|
func SetStoreCategorySyncStatus(db *DaoDB, vendorID int, storeIDs []int, catIDs []int, syncStatus int) (num int64, err error) {
|
||||||
globals.SugarLogger.Debugf("SetStoreCategorySyncStatus, storeID:%d, vendorID:%d", storeID, vendorID)
|
globals.SugarLogger.Debugf("SetStoreCategorySyncStatus, storeIDs:%v, vendorID:%d", storeIDs, vendorID)
|
||||||
|
|
||||||
|
isSingleStorePF := model.MultiStoresVendorMap[vendorID] != 1
|
||||||
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
||||||
sql := fmt.Sprintf(`
|
sql := `
|
||||||
UPDATE store_sku_category_map
|
UPDATE store_sku_category_map t1
|
||||||
SET %s_sync_status = %s_sync_status | ?
|
SET t1.%s_sync_status = IF(t1.deleted_at = ?, t1.%s_sync_status | ?, 0)
|
||||||
WHERE deleted_at = ? AND store_id = ?
|
`
|
||||||
`, fieldPrefix, fieldPrefix)
|
fmtParams := []interface{}{
|
||||||
|
fieldPrefix,
|
||||||
|
fieldPrefix,
|
||||||
|
}
|
||||||
sqlParams := []interface{}{
|
sqlParams := []interface{}{
|
||||||
syncStatus,
|
|
||||||
utils.DefaultTimeValue,
|
utils.DefaultTimeValue,
|
||||||
storeID,
|
syncStatus,
|
||||||
|
}
|
||||||
|
if isSingleStorePF && (syncStatus&model.SyncFlagNewMask) != 0 {
|
||||||
|
sql += `,
|
||||||
|
t1.%s_id = 0
|
||||||
|
`
|
||||||
|
fmtParams = append(fmtParams, fieldPrefix)
|
||||||
|
}
|
||||||
|
sql += " WHERE (t1.deleted_at = ? OR t1.%s_sync_status <> 0)"
|
||||||
|
fmtParams = append(fmtParams, fieldPrefix)
|
||||||
|
sqlParams = append(sqlParams, utils.DefaultTimeValue)
|
||||||
|
if len(storeIDs) > 0 {
|
||||||
|
sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, storeIDs)
|
||||||
}
|
}
|
||||||
if len(catIDs) > 0 {
|
if len(catIDs) > 0 {
|
||||||
sql += " AND category_id IN (" + GenQuestionMarks(len(catIDs)) + ")"
|
sql += " AND t1.category_id IN (" + GenQuestionMarks(len(catIDs)) + ")"
|
||||||
sqlParams = append(sqlParams, catIDs)
|
sqlParams = append(sqlParams, catIDs)
|
||||||
}
|
}
|
||||||
|
sql = fmt.Sprintf(sql, fmtParams...)
|
||||||
return ExecuteSQL(db, sql, sqlParams...)
|
return ExecuteSQL(db, sql, sqlParams...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,3 +363,66 @@ func GetImgFieldName(vendorID int) (fieldName string) {
|
|||||||
}
|
}
|
||||||
return fieldName
|
return fieldName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetDescImgFieldName(vendorID int) (fieldName string) {
|
||||||
|
fieldName = descImgFieldMap[vendorID]
|
||||||
|
if fieldName == "" {
|
||||||
|
fieldName = "desc_img"
|
||||||
|
}
|
||||||
|
return fieldName
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetStoresSkusInfo(db *DaoDB, storeIDs, skuIDs []int) (storeSkuList []*model.StoreSkuBind, err error) {
|
||||||
|
sql := `
|
||||||
|
SELECT *
|
||||||
|
FROM store_sku_bind t1
|
||||||
|
WHERE t1.deleted_at = ?
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
}
|
||||||
|
if len(storeIDs) > 0 {
|
||||||
|
sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, storeIDs)
|
||||||
|
}
|
||||||
|
if len(skuIDs) > 0 {
|
||||||
|
sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, skuIDs)
|
||||||
|
}
|
||||||
|
err = GetRows(db, &storeSkuList, sql, sqlParams...)
|
||||||
|
return storeSkuList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMissingStoreSkuFromOrder(db *DaoDB, storeIDs []int, fromTime time.Time) (storeSkuList []*MissingStoreSkuInfo, err error) {
|
||||||
|
if time.Now().Sub(fromTime) > 24*time.Hour*60 {
|
||||||
|
return nil, fmt.Errorf("GetMissingStoreSkuFromOrder,时间超过60天")
|
||||||
|
}
|
||||||
|
sql := `
|
||||||
|
SELECT IF(t2.jx_store_id <> 0, t2.jx_store_id, t2.store_id) store_id, t4.name_id, t1.sku_id,
|
||||||
|
t4.spec_quality, t4.spec_unit, t5.unit,
|
||||||
|
COUNT(*) ct, CAST(AVG(IF(t1.vendor_price <> 0, t1.vendor_price, t1.sale_price)) AS SIGNED) ref_price
|
||||||
|
FROM order_sku t1
|
||||||
|
JOIN goods_order t2 ON t2.vendor_order_id = t1.vendor_order_id
|
||||||
|
LEFT JOIN store_sku_bind t3 ON t3.store_id = IF(t2.jx_store_id <> 0, t2.jx_store_id, t2.store_id) AND
|
||||||
|
t3.sku_id = t1.sku_id AND t3.deleted_at = ?
|
||||||
|
JOIN sku t4 ON t4.id = t1.sku_id
|
||||||
|
JOIN sku_name t5 ON t5.id = t4.name_id
|
||||||
|
WHERE t2.status = ? AND IF(t2.jx_store_id <> 0, t2.jx_store_id, t2.store_id) > 0 AND t1.sku_id > 0 AND t1.shop_price = 0 AND
|
||||||
|
t1.order_created_at > ? AND t3.id IS NULL
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
model.OrderStatusFinished,
|
||||||
|
fromTime,
|
||||||
|
}
|
||||||
|
if len(storeIDs) > 0 {
|
||||||
|
sql += " AND IF(t2.jx_store_id <> 0, t2.jx_store_id, t2.store_id) IN (" + GenQuestionMarks(len(storeIDs)) + ")"
|
||||||
|
sqlParams = append(sqlParams, storeIDs)
|
||||||
|
}
|
||||||
|
sql += `
|
||||||
|
GROUP BY 1,2,3,4,5,6
|
||||||
|
ORDER BY 1,2,3,4,5,6
|
||||||
|
`
|
||||||
|
err = GetRows(db, &storeSkuList, sql, sqlParams...)
|
||||||
|
return storeSkuList, err
|
||||||
|
}
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ const (
|
|||||||
|
|
||||||
FieldVendorOrderID = "VendorOrderID"
|
FieldVendorOrderID = "VendorOrderID"
|
||||||
FieldVendorOrderID2 = "VendorOrderID2"
|
FieldVendorOrderID2 = "VendorOrderID2"
|
||||||
|
|
||||||
|
FieldActID = "ActID"
|
||||||
|
FieldVendorActID = "VendorActID"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ModelIDCUL struct {
|
type ModelIDCUL struct {
|
||||||
@@ -67,16 +70,43 @@ const (
|
|||||||
SyncFlagModifiedMask = 1
|
SyncFlagModifiedMask = 1
|
||||||
SyncFlagNewMask = 2
|
SyncFlagNewMask = 2
|
||||||
SyncFlagDeletedMask = 4
|
SyncFlagDeletedMask = 4
|
||||||
SyncFlagChangedMask = SyncFlagModifiedMask | SyncFlagNewMask | SyncFlagDeletedMask
|
|
||||||
|
|
||||||
SyncFlagSaleMask = 8
|
SyncFlagSaleMask = 8 // 改了门店商品可售状态必须设置此标志
|
||||||
SyncFlagPriceMask = 16
|
SyncFlagPriceMask = 16 // 改了门店商品价格必须设置此标志
|
||||||
SyncFlagSpecMask = 32
|
SyncFlagSpecMask = 32
|
||||||
|
|
||||||
|
SyncFlagStoreSkuOnlyMask = SyncFlagSaleMask | SyncFlagPriceMask
|
||||||
|
SyncFlagStoreSkuModifiedMask = SyncFlagStoreSkuOnlyMask | SyncFlagModifiedMask
|
||||||
|
SyncFlagChangedMask = SyncFlagSpecMask | SyncFlagNewMask | SyncFlagDeletedMask | SyncFlagStoreSkuModifiedMask
|
||||||
|
|
||||||
SyncFlagStoreName = 8
|
SyncFlagStoreName = 8
|
||||||
SyncFlagStoreAddress = 16
|
SyncFlagStoreAddress = 16
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func IsSyncStatusNew(syncStatus int) bool {
|
||||||
|
return (syncStatus & SyncFlagNewMask) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsSyncStatusDelete(syncStatus int) bool {
|
||||||
|
return (syncStatus & SyncFlagDeletedMask) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsSyncStatusUpdate(syncStatus int) bool {
|
||||||
|
return (syncStatus & SyncFlagModifiedMask) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsSyncStatusNeedCreate(syncStatus int) bool {
|
||||||
|
return IsSyncStatusNew(syncStatus) && !IsSyncStatusDelete(syncStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsSyncStatusNeedDelete(syncStatus int) bool {
|
||||||
|
return !IsSyncStatusNew(syncStatus) && IsSyncStatusDelete(syncStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsSyncStatusNeedUpdate(syncStatus int) bool {
|
||||||
|
return !IsSyncStatusNew(syncStatus) && !IsSyncStatusDelete(syncStatus) && IsSyncStatusUpdate(syncStatus)
|
||||||
|
}
|
||||||
|
|
||||||
// const (
|
// const (
|
||||||
// KeyJdFlag = "jdFlag"
|
// KeyJdFlag = "jdFlag"
|
||||||
// KeyJdSyncedAt = "jdSyncedAt"
|
// KeyJdSyncedAt = "jdSyncedAt"
|
||||||
|
|||||||
@@ -16,9 +16,12 @@ type GoodsOrder struct {
|
|||||||
StoreID int `orm:"column(store_id)" json:"storeID"` // 外部系统里记录的 jxstoreid
|
StoreID int `orm:"column(store_id)" json:"storeID"` // 外部系统里记录的 jxstoreid
|
||||||
JxStoreID int `orm:"column(jx_store_id)" json:"jxStoreID"` // 根据VendorStoreID在本地系统里查询出来的 jxstoreid
|
JxStoreID int `orm:"column(jx_store_id)" json:"jxStoreID"` // 根据VendorStoreID在本地系统里查询出来的 jxstoreid
|
||||||
StoreName string `orm:"size(64)" json:"storeName"`
|
StoreName string `orm:"size(64)" json:"storeName"`
|
||||||
ShopPrice int64 `json:"shopPrice"` // 单位为分 门店标价
|
ShopPrice int64 `json:"shopPrice"` // 京西价
|
||||||
SalePrice int64 `json:"salePrice"` // 单位为分 售卖价
|
VendorPrice int64 `json:"vendorPrice"` // 平台价
|
||||||
|
SalePrice int64 `json:"salePrice"` // 售卖价
|
||||||
ActualPayPrice int64 `json:"actualPayPrice"` // 单位为分 顾客实际支付
|
ActualPayPrice int64 `json:"actualPayPrice"` // 单位为分 顾客实际支付
|
||||||
|
TotalShopMoney int64 `json:"shopMoney"` // 应结金额-第三方平台结算给京西的金额(包括了所有的补贴,扣除)
|
||||||
|
PmSubsidyMoney int64 `json:"pmSubsidyMoney"` // 平台活动补贴(订单主体活动补贴+订单单条sku补贴)1+
|
||||||
Weight int `json:"weight"` // 单位为克
|
Weight int `json:"weight"` // 单位为克
|
||||||
ConsigneeName string `orm:"size(32)" json:"consigneeName"`
|
ConsigneeName string `orm:"size(32)" json:"consigneeName"`
|
||||||
ConsigneeMobile string `orm:"size(32)" json:"consigneeMobile"`
|
ConsigneeMobile string `orm:"size(32)" json:"consigneeMobile"`
|
||||||
@@ -30,10 +33,10 @@ type GoodsOrder struct {
|
|||||||
SkuCount int `json:"skuCount"` // 商品类别数量,即有多少种商品(注意在某些情况下,相同SKU的商品由于售价不同,也会当成不同商品在这个值里)
|
SkuCount int `json:"skuCount"` // 商品类别数量,即有多少种商品(注意在某些情况下,相同SKU的商品由于售价不同,也会当成不同商品在这个值里)
|
||||||
GoodsCount int `json:"goodsCount"` // 商品个数
|
GoodsCount int `json:"goodsCount"` // 商品个数
|
||||||
Status int `json:"status"` // 参见OrderStatus*相关的常量定义
|
Status int `json:"status"` // 参见OrderStatus*相关的常量定义
|
||||||
VendorStatus string `orm:"size(255)" json:"-"`
|
VendorStatus string `orm:"size(255)" json:"vendorStatus"`
|
||||||
LockStatus int `json:"lockStatus"`
|
LockStatus int `json:"lockStatus"`
|
||||||
LockStatusTime time.Time `orm:"type(datetime);null" json:"-"` // last lock status time
|
LockStatusTime time.Time `orm:"type(datetime);null" json:"lockStatusTime"` // last lock status time
|
||||||
OrderSeq int `json:"orderSeq"` // 门店订单序号
|
OrderSeq int `json:"orderSeq"` // 门店订单序号
|
||||||
BuyerComment string `orm:"size(255)" json:"buyerComment"`
|
BuyerComment string `orm:"size(255)" json:"buyerComment"`
|
||||||
BusinessType int `json:"businessType"`
|
BusinessType int `json:"businessType"`
|
||||||
ExpectedDeliveredTime time.Time `orm:"type(datetime)" json:"expectedDeliveredTime"` // 预期送达时间
|
ExpectedDeliveredTime time.Time `orm:"type(datetime)" json:"expectedDeliveredTime"` // 预期送达时间
|
||||||
@@ -44,19 +47,12 @@ type GoodsOrder struct {
|
|||||||
DuplicatedCount int `json:"-"` // 重复新订单消息数,这个一般不是由于消息重发造成的(消息重发由OrderStatus过滤),一般是业务逻辑造成的
|
DuplicatedCount int `json:"-"` // 重复新订单消息数,这个一般不是由于消息重发造成的(消息重发由OrderStatus过滤),一般是业务逻辑造成的
|
||||||
OrderCreatedAt time.Time `orm:"type(datetime);index" json:"orderCreatedAt"` // 这里记录的是订单生效时间,即用户支付完成(货到付款即为下单时间)
|
OrderCreatedAt time.Time `orm:"type(datetime);index" json:"orderCreatedAt"` // 这里记录的是订单生效时间,即用户支付完成(货到付款即为下单时间)
|
||||||
OrderFinishedAt time.Time `orm:"type(datetime)" json:"orderFinishedAt"`
|
OrderFinishedAt time.Time `orm:"type(datetime)" json:"orderFinishedAt"`
|
||||||
StatusTime time.Time `orm:"type(datetime)" json:"-"` // last status time
|
StatusTime time.Time `orm:"type(datetime)" json:"statusTime"` // last status time
|
||||||
PickDeadline time.Time `orm:"type(datetime)" json:"pickDeadline"`
|
PickDeadline time.Time `orm:"type(datetime)" json:"pickDeadline"`
|
||||||
ModelTimeInfo `json:"-"`
|
ModelTimeInfo `json:"-"`
|
||||||
OriginalData string `orm:"-" json:"-"` // 只是用于传递数据
|
OriginalData string `orm:"-" json:"-"` // 只是用于传递数据
|
||||||
Skus []*OrderSku `orm:"-" json:"-"`
|
Skus []*OrderSku `orm:"-" json:"-"`
|
||||||
Flag int8 `json:"flag"` //非运单调整相关的其它状态
|
Flag int `json:"flag"` //非运单调整相关的其它状态
|
||||||
SkuPmFee int64 `json:"-"` //门店商品活动总支出
|
|
||||||
OrderPmFee int64 `json:"-"` //门店订单活动支出
|
|
||||||
SkuPmSubsidy int64 `json:"-"` //平台商品活动总补贴
|
|
||||||
OrderPmSubsidy int64 `json:"-"` //平台订单活动补贴
|
|
||||||
BoxFee int64 `json:"-"` //餐盒费
|
|
||||||
PlatformFeeRate int16 `json:"-"` //平台费
|
|
||||||
BillStoreFreightFee int64 `json:"-"` //需要回调,门店所承担的运费
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *GoodsOrder) TableUnique() [][]string {
|
func (o *GoodsOrder) TableUnique() [][]string {
|
||||||
@@ -88,18 +84,18 @@ type OrderSku struct {
|
|||||||
StoreSubID int `orm:"column(store_sub_id)" json:"storeSubID"`
|
StoreSubID int `orm:"column(store_sub_id)" json:"storeSubID"`
|
||||||
StoreSubName string `orm:"size(64)" json:"storeSubName"`
|
StoreSubName string `orm:"size(64)" json:"storeSubName"`
|
||||||
Count int `json:"count"`
|
Count int `json:"count"`
|
||||||
VendorSkuID string `orm:"column(vendor_sku_id);size(48)" json:"-"`
|
VendorSkuID string `orm:"column(vendor_sku_id);size(48)" json:"vendorSkuID"`
|
||||||
SkuID int `orm:"column(sku_id)" json:"skuID"` // 外部系统里记录的 jxskuid
|
SkuID int `orm:"column(sku_id)" json:"skuID"` // 外部系统里记录的 jxskuid
|
||||||
JxSkuID int `orm:"column(jx_sku_id)" json:"jxSkuID"` // 根据VendorSkuID在本地系统里查询出来的 jxskuid
|
JxSkuID int `orm:"column(jx_sku_id)" json:"jxSkuID"` // 根据VendorSkuID在本地系统里查询出来的 jxskuid
|
||||||
SkuName string `orm:"size(255)" json:"skuName"`
|
SkuName string `orm:"size(255)" json:"skuName"`
|
||||||
ShopPrice int64 `json:"shopPrice"` // 门店标价
|
ShopPrice int64 `json:"shopPrice"` // 京西价
|
||||||
|
VendorPrice int64 `json:"vendorPrice"` // 平台价
|
||||||
SalePrice int64 `json:"salePrice"` // 售卖价
|
SalePrice int64 `json:"salePrice"` // 售卖价
|
||||||
Weight int `json:"-"` // 单位为克
|
EarningPrice int64 `json:"earningPrice"` // 活动商品设置,结算给门店老板的钱
|
||||||
SkuType int `json:"-"` // 当前如果为gift就为1,否则缺省为0
|
Weight int `json:"weight"` // 单位为克
|
||||||
PromotionType int `json:"-"` // todo 当前是用于记录京东的PromotionType(生成jxorder用),没有做转换
|
SkuType int `json:"skuType"` // 当前如果为gift就为1,否则缺省为0
|
||||||
|
PromotionType int `json:"promotionType"` // todo 当前是用于记录京东的PromotionType(生成jxorder用),没有做转换
|
||||||
OrderCreatedAt time.Time `orm:"type(datetime);index" json:"-"` // 分区考虑
|
OrderCreatedAt time.Time `orm:"type(datetime);index" json:"-"` // 分区考虑
|
||||||
SkuPmSubsidy int64 `json:"-"` //平台商品活动补贴
|
|
||||||
SkuPmFee int64 `json:"-"` //门店商品活动支出
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 同样商品在一个订单中可能重复出现(比如搞活动时,相同商品价格不一样,第一个有优惠)
|
// 同样商品在一个订单中可能重复出现(比如搞活动时,相同商品价格不一样,第一个有优惠)
|
||||||
@@ -124,6 +120,7 @@ type Waybill struct {
|
|||||||
ActualFee int64 `json:"actualFee"` // 实际要支付给快递公司的费用
|
ActualFee int64 `json:"actualFee"` // 实际要支付给快递公司的费用
|
||||||
DesiredFee int64 `json:"desiredFee"` // 运单总费用
|
DesiredFee int64 `json:"desiredFee"` // 运单总费用
|
||||||
DuplicatedCount int `json:"-"` // 重复新订单消息数,这个一般不是由于消息重发造成的(消息重发由OrderStatus过滤),一般是业务逻辑造成的
|
DuplicatedCount int `json:"-"` // 重复新订单消息数,这个一般不是由于消息重发造成的(消息重发由OrderStatus过滤),一般是业务逻辑造成的
|
||||||
|
DeliveryFlag int8 `json:"deliveryFlag"`
|
||||||
WaybillCreatedAt time.Time `orm:"type(datetime);index" json:"waybillCreatedAt"`
|
WaybillCreatedAt time.Time `orm:"type(datetime);index" json:"waybillCreatedAt"`
|
||||||
WaybillFinishedAt time.Time `orm:"type(datetime)" json:"waybillFinishedAt"`
|
WaybillFinishedAt time.Time `orm:"type(datetime)" json:"waybillFinishedAt"`
|
||||||
StatusTime time.Time `orm:"type(datetime)" json:"-"` // last status time
|
StatusTime time.Time `orm:"type(datetime)" json:"-"` // last status time
|
||||||
@@ -240,3 +237,24 @@ type OrderComment struct {
|
|||||||
CommentUpdatedAt time.Time
|
CommentUpdatedAt time.Time
|
||||||
UpdatedOriginalMsg string `orm:"type(text)" json:"-"`
|
UpdatedOriginalMsg string `orm:"type(text)" json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 判断是否是购买平台自有物流
|
||||||
|
// 对于京东,饿百来说,就是其自有的物流,对于微商城来说,是达达
|
||||||
|
func IsWaybillPlatformOwn(bill *Waybill) bool {
|
||||||
|
return bill.OrderVendorID == bill.WaybillVendorID || IsSpecialOrderPlatformWaybill(bill)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 是否是特殊物流
|
||||||
|
func IsSpecialOrderPlatformWaybill(bill *Waybill) bool {
|
||||||
|
return (bill.OrderVendorID == VendorIDWSC && bill.WaybillVendorID == VendorIDDada)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 订单是否已经有了有效运单
|
||||||
|
func IsOrderHaveWaybill(order *GoodsOrder) bool {
|
||||||
|
return order.WaybillVendorID != VendorIDUnknown && order.VendorWaybillID != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// 订单是否有自己平台的有效运单
|
||||||
|
func IsOrderHaveOwnWaybill(order *GoodsOrder) bool {
|
||||||
|
return order.VendorID == order.WaybillVendorID && order.VendorWaybillID != ""
|
||||||
|
}
|
||||||
|
|||||||
@@ -70,25 +70,40 @@ func (o *OrderDiscountFinancial) TableUnique() [][]string {
|
|||||||
type AfsOrder struct {
|
type AfsOrder struct {
|
||||||
ModelIDCUL
|
ModelIDCUL
|
||||||
|
|
||||||
VendorID int `orm:"column(vendor_id)" json:"vendorID"`
|
VendorID int `orm:"column(vendor_id)" json:"vendorID"`
|
||||||
VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"` // 关联原始订单ID
|
VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"` // 关联原始订单ID
|
||||||
VendorOrderID2 string `orm:"column(vendor_order_id2);size(48);index" json:"vendorOrderID2"` // 关联原始订单ID2,饿百独有
|
VendorOrderID2 string `orm:"column(vendor_order_id2);size(48);index" json:"vendorOrderID2"` // 关联原始订单ID2,饿百独有
|
||||||
AfsOrderID string `orm:"column(afs_order_id);size(48)" json:"afsOrderID"` // 售后订单ID
|
AfsOrderID string `orm:"column(afs_order_id);size(48)" json:"afsOrderID"` // 售后订单ID
|
||||||
AfsCreateAt time.Time `orm:"type(datetime);index" json:"afsCreateAt"` // 订单生成时间
|
AfsCreatedAt time.Time `orm:"type(datetime);null;index" json:"afsCreatedAt"` // 售后单生成时间
|
||||||
VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` // 外部系统里记录的storeid
|
AfsFinishedAt time.Time `orm:"type(datetime);null;index" json:"afsFinishedAt"` // 售后单结束时间
|
||||||
StoreID int `orm:"column(store_id)" json:"storeID"` // 接口返回的京西门店ID
|
VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` // 外部系统里记录的storeid
|
||||||
JxStoreID int `orm:"column(jx_store_id)" json:"jxStoreID"` // 根据VendorStoreID在本地系统里查询出来的 jxstoreid
|
StoreID int `orm:"column(store_id)" json:"storeID"` // 接口返回的京西门店ID
|
||||||
SkuUserMoney int64 `json:"skuUserMoney"` // 用户支付菜品金额
|
JxStoreID int `orm:"column(jx_store_id)" json:"jxStoreID"` // 根据VendorStoreID在本地系统里查询出来的 jxstoreid
|
||||||
FreightUserMoney int64 `json:"freightUserMoney"` // 用户支付运费金额
|
|
||||||
AfsFreightMoney int64 `json:"afsFreightMoney"` // 退货取件费
|
// IsNeedApprove int8 `json:"isNeedApprove"` // 售后单是否需要商家审核
|
||||||
BoxMoney int64 `json:"boxMoney"` // 应退包装费金额
|
Status int `json:"status"`
|
||||||
TongchengFreightMoney int64 `json:"tongchengFreightMoney"` // 退货单产生的同城送费用
|
VendorStatus string `orm:"size(255)" json:"vendorStatus"`
|
||||||
SkuBoxMoney int64 `json:"skuBoxMoney"` // 应退订单餐盒费
|
ReasonType int8 `json:"reasonType"` // 售后原因
|
||||||
PmSubsidyMoney int64 `json:"pmSubsidyMoney"` // 平台总补贴金额
|
VendorReasonType string `orm:"size(255)" json:"vendorReasonType"`
|
||||||
PmSkuSubsidyMoney int64 `json:"pmSkuSubsidyMoney"` // 平台sku补贴金额
|
ReasonDesc string `orm:"size(1024)" json:"reasonDesc"` // 售后原因描述
|
||||||
PmRefundMoney int64 `json:"pmRefundMoney"` // 订单取消后可能存在佣金减少,平台退回部分金额的情况
|
ReasonImgList string `orm:"size(1024)" json:"reasonImgList"` // 售后描述图片
|
||||||
RefundMoney int64 `json:"refundMoney"` // 平台扣款总额 1
|
AppealType int8 `json:"appealType"` // 售后方式
|
||||||
RefundMoneyByCal int64 `json:"refundMoneyByCal"` // 平台扣款总额-通过公式计算平台扣除京西的金额M
|
VendorAppealType string `orm:"size(255)" json:"vendorAppealType"`
|
||||||
|
Flag int `json:"flag"`
|
||||||
|
RefundType int8 `json:"refundType"`
|
||||||
|
RefuseReason string `orm:"size(1024)" json:"refuseReason"`
|
||||||
|
|
||||||
|
SkuUserMoney int64 `json:"skuUserMoney"` // 用户支付菜品金额
|
||||||
|
FreightUserMoney int64 `json:"freightUserMoney"` // 用户支付运费金额
|
||||||
|
AfsFreightMoney int64 `json:"afsFreightMoney"` // 退货取件费
|
||||||
|
BoxMoney int64 `json:"boxMoney"` // 应退包装费金额
|
||||||
|
TongchengFreightMoney int64 `json:"tongchengFreightMoney"` // 退货单产生的同城送费用
|
||||||
|
SkuBoxMoney int64 `json:"skuBoxMoney"` // 应退订单餐盒费
|
||||||
|
PmSubsidyMoney int64 `json:"pmSubsidyMoney"` // 平台总补贴金额
|
||||||
|
PmSkuSubsidyMoney int64 `json:"pmSkuSubsidyMoney"` // 平台sku补贴金额
|
||||||
|
PmRefundMoney int64 `json:"pmRefundMoney"` // 订单取消后可能存在佣金减少,平台退回部分金额的情况
|
||||||
|
RefundMoney int64 `json:"refundMoney"` // 平台扣款总额 1
|
||||||
|
RefundMoneyByCal int64 `json:"refundMoneyByCal"` // 平台扣款总额-通过公式计算平台扣除京西的金额M
|
||||||
// JxSkuMoney int64 `json:"jxSkuMoney"` // 京西补贴金额,现阶段是平台扣京西多少钱,京西扣商家多少钱,暂不考虑撤回京西补贴
|
// JxSkuMoney int64 `json:"jxSkuMoney"` // 京西补贴金额,现阶段是平台扣京西多少钱,京西扣商家多少钱,暂不考虑撤回京西补贴
|
||||||
Skus []*OrderSkuFinancial `orm:"-" json:"skus"`
|
Skus []*OrderSkuFinancial `orm:"-" json:"skus"`
|
||||||
}
|
}
|
||||||
@@ -102,11 +117,10 @@ func (o *AfsOrder) TableUnique() [][]string {
|
|||||||
type OrderSkuFinancial struct {
|
type OrderSkuFinancial struct {
|
||||||
ModelIDCUL
|
ModelIDCUL
|
||||||
|
|
||||||
VendorID int `orm:"column(vendor_id)" json:"vendorID"` // 平台id
|
VendorID int `orm:"column(vendor_id)" json:"vendorID"` // 平台id
|
||||||
VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"` // 关联原始订单ID
|
VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"` // 关联原始订单ID
|
||||||
VendorOrderID2 string `orm:"column(vendor_order_id2);size(48);index" json:"vendorOrderID2"` // 关联原始订单ID2,饿百独有
|
AfsOrderID string `orm:"column(afs_order_id);size(48)" json:"afsOrderID"` // 售后单ID
|
||||||
AfsOrderID string `orm:"column(order_financial_id);size(48)" json:"afsOrderID"` // 订单结账ID
|
IsAfsOrder int8 `json:"isAfsOrder"` // 0--正向单, 1--售后单
|
||||||
IsAfsOrder int8 `json:"isAfsOrder"` // 0--正向单, 1--售后单
|
|
||||||
|
|
||||||
// ConfirmTime time.Time `orm:"type(datetime)" json:"confirmTime"` // 订单生成/完成时间
|
// ConfirmTime time.Time `orm:"type(datetime)" json:"confirmTime"` // 订单生成/完成时间
|
||||||
VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` // 外部系统里记录的storeid
|
VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` // 外部系统里记录的storeid
|
||||||
@@ -141,7 +155,8 @@ type OrderSkuFinancial struct {
|
|||||||
|
|
||||||
func (o *OrderSkuFinancial) TableIndex() [][]string {
|
func (o *OrderSkuFinancial) TableIndex() [][]string {
|
||||||
return [][]string{
|
return [][]string{
|
||||||
[]string{"VendorOrderID", "VendorSkuID", "PromotionType", "IsAfsOrder", "VendorID"},
|
[]string{"VendorOrderID", "VendorSkuID"},
|
||||||
|
[]string{"AfsOrderID", "VendorSkuID"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ var (
|
|||||||
type Promotion struct {
|
type Promotion struct {
|
||||||
ModelIDCULD
|
ModelIDCULD
|
||||||
|
|
||||||
VendorID int `orm:"column(vendor_id)"`
|
VendorID int `orm:"column(vendor_id)" json:"vendorID"`
|
||||||
Name string `orm:"size(64)" json:"name"`
|
Name string `orm:"size(64)" json:"name"`
|
||||||
Advertising string `orm:"size(255)" json:"advertising"`
|
Advertising string `orm:"size(255)" json:"advertising"`
|
||||||
Type int `json:"type"`
|
Type int `json:"type"`
|
||||||
@@ -75,6 +75,8 @@ type PromotionSku struct {
|
|||||||
Price int `json:"price"` // 分,活动价,这个不是单价
|
Price int `json:"price"` // 分,活动价,这个不是单价
|
||||||
LimitSkuCount int `json:"limitSkuCount"`
|
LimitSkuCount int `json:"limitSkuCount"`
|
||||||
IsLock int8 `json:"isLock"` // 是否锁定门店商品信息
|
IsLock int8 `json:"isLock"` // 是否锁定门店商品信息
|
||||||
|
|
||||||
|
EarningPrice int `json:"earningPrice"` // 活动商品设置,结算给门店老板的钱
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*PromotionSku) TableUnique() [][]string {
|
func (*PromotionSku) TableUnique() [][]string {
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ var (
|
|||||||
SpecialUnit = "份"
|
SpecialUnit = "份"
|
||||||
SpecialSpecQuality = 500
|
SpecialSpecQuality = 500
|
||||||
SpecialSpecUnit = "g"
|
SpecialSpecUnit = "g"
|
||||||
|
SpecialSpecUnit2 = "ml"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -131,7 +132,12 @@ type SkuCategory struct {
|
|||||||
Type int8 `json:"type"` // 类别类型,即是普通类别还是特殊用于做活动的类别
|
Type int8 `json:"type"` // 类别类型,即是普通类别还是特殊用于做活动的类别
|
||||||
Seq int `json:"seq"`
|
Seq int `json:"seq"`
|
||||||
|
|
||||||
JdCategoryID int `orm:"column(jd_category_id)" json:"jdCategoryID"` // 这个是指对应的京东商品类别
|
JdPricePercentage int16 `orm:"default(100)" json:"jdPricePercentage"`
|
||||||
|
EbaiPricePercentage int16 `orm:"default(100)" json:"ebaiPricePercentage"`
|
||||||
|
MtwmPricePercentage int16 `orm:"default(100)" json:"mtwmPricePercentage"`
|
||||||
|
WscPricePercentage int16 `orm:"default(100)" json:"wscPricePercentage"`
|
||||||
|
|
||||||
|
JdCategoryID int64 `orm:"column(jd_category_id)" json:"jdCategoryID"` // 这个是指对应的京东商品类别
|
||||||
ElmCategoryID int64 `orm:"column(elm_category_id)" json:"elmCategoryID"` // 这个是指对应的饿了么商品类别
|
ElmCategoryID int64 `orm:"column(elm_category_id)" json:"elmCategoryID"` // 这个是指对应的饿了么商品类别
|
||||||
EbaiCategoryID int64 `orm:"column(ebai_category_id)" json:"ebaiCategoryID"` // 这个是指对应的饿百商品类别
|
EbaiCategoryID int64 `orm:"column(ebai_category_id)" json:"ebaiCategoryID"` // 这个是指对应的饿百商品类别
|
||||||
MtwmCategoryID int64 `orm:"column(mtwm_category_id)" json:"mtwmCategoryID"` // 这个是指对应的美团外卖商品类别
|
MtwmCategoryID int64 `orm:"column(mtwm_category_id)" json:"mtwmCategoryID"` // 这个是指对应的美团外卖商品类别
|
||||||
@@ -159,8 +165,9 @@ type SkuName struct {
|
|||||||
Prefix string `orm:"size(255)" json:"prefix"`
|
Prefix string `orm:"size(255)" json:"prefix"`
|
||||||
Name string `orm:"size(255);index" json:"name"`
|
Name string `orm:"size(255);index" json:"name"`
|
||||||
|
|
||||||
BrandID int `orm:"column(brand_id);default(0)" json:"brandID"` // todo,此属性暂时没有使用,且有问题,应该是不同平台都有一个brandid
|
BrandID int `orm:"column(brand_id);default(0)" json:"brandID"` // todo,此属性暂时没有使用,且有问题,应该是不同平台都有一个brandid
|
||||||
CategoryID int `orm:"column(category_id);index" json:"categoryID"` // 标准类别
|
CategoryID int `orm:"column(category_id);index" json:"categoryID"` // 标准类别
|
||||||
|
JdCategoryID int64 `orm:"column(jd_category_id)" json:"jdCategoryID"` // 这个是指对应的京东商品类别
|
||||||
|
|
||||||
IsGlobal int8 `orm:"default(1)" json:"isGlobal"` // 是否是全部(全国)可见,如果否的话,可见性由SkuPlace决定
|
IsGlobal int8 `orm:"default(1)" json:"isGlobal"` // 是否是全部(全国)可见,如果否的话,可见性由SkuPlace决定
|
||||||
Unit string `orm:"size(8)" json:"unit"`
|
Unit string `orm:"size(8)" json:"unit"`
|
||||||
@@ -176,6 +183,9 @@ type SkuName struct {
|
|||||||
Status int `orm:"default(1)" json:"status"` // skuname状态,取值同sku.Status
|
Status int `orm:"default(1)" json:"status"` // skuname状态,取值同sku.Status
|
||||||
IsSpu int8 `orm:"column(is_spu)" json:"isSpu"` // 用于指明是否SKUNAME当成SPU
|
IsSpu int8 `orm:"column(is_spu)" json:"isSpu"` // 用于指明是否SKUNAME当成SPU
|
||||||
|
|
||||||
|
DescImg string `orm:"size(255)" json:"descImg"` // 商品详情图片描述
|
||||||
|
DescImgEbai string `orm:"size(255)" json:"descImgEbai"` // 饿百的商品详情图片描述RTF
|
||||||
|
|
||||||
JdID int64 `orm:"column(jd_id);null;index" json:"jdID"`
|
JdID int64 `orm:"column(jd_id);null;index" json:"jdID"`
|
||||||
JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"`
|
JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"`
|
||||||
|
|
||||||
@@ -206,6 +216,12 @@ type Sku struct {
|
|||||||
LinkID int `orm:"column(link_id);null;index" json:"linkID"`
|
LinkID int `orm:"column(link_id);null;index" json:"linkID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SkuAndName struct {
|
||||||
|
Sku
|
||||||
|
Name string
|
||||||
|
Unit string
|
||||||
|
}
|
||||||
|
|
||||||
// func (*Sku) TableUnique() [][]string {
|
// func (*Sku) TableUnique() [][]string {
|
||||||
// return [][]string{
|
// return [][]string{
|
||||||
// []string{"JdID", "DeletedAt"},
|
// []string{"JdID", "DeletedAt"},
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ package model
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
StoreStatusAll = -9
|
StoreStatusAll = -9
|
||||||
StoreStatusDisabled = -1
|
StoreStatusDisabled = -2
|
||||||
StoreStatusClosed = 0
|
StoreStatusClosed = -1
|
||||||
|
StoreStatusHaveRest = 0
|
||||||
StoreStatusOpened = 1
|
StoreStatusOpened = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -32,7 +33,8 @@ const (
|
|||||||
var (
|
var (
|
||||||
StoreStatusName = map[int]string{
|
StoreStatusName = map[int]string{
|
||||||
StoreStatusDisabled: "禁用",
|
StoreStatusDisabled: "禁用",
|
||||||
StoreStatusClosed: "休息",
|
StoreStatusClosed: "长期休息",
|
||||||
|
StoreStatusHaveRest: "临时休息",
|
||||||
StoreStatusOpened: "营业中",
|
StoreStatusOpened: "营业中",
|
||||||
}
|
}
|
||||||
DeliveryRangeTypeName = map[int]string{
|
DeliveryRangeTypeName = map[int]string{
|
||||||
@@ -62,6 +64,7 @@ var (
|
|||||||
"NBB": "宁波银行",
|
"NBB": "宁波银行",
|
||||||
"SPDB": "浦发银行",
|
"SPDB": "浦发银行",
|
||||||
"GDB": "广发银行",
|
"GDB": "广发银行",
|
||||||
|
"BOCOM": "交通银行",
|
||||||
"SPAB": "平安银行",
|
"SPAB": "平安银行",
|
||||||
"BSB": "包商银行",
|
"BSB": "包商银行",
|
||||||
"CSCB": "长沙银行",
|
"CSCB": "长沙银行",
|
||||||
@@ -131,6 +134,8 @@ type Store struct {
|
|||||||
Status int `json:"status"`
|
Status int `json:"status"`
|
||||||
ChangePriceType int8 `json:"changePriceType"` // 修改价格类型,即是否需要审核
|
ChangePriceType int8 `json:"changePriceType"` // 修改价格类型,即是否需要审核
|
||||||
|
|
||||||
|
DeliveryType int8 `orm:"-" json:"deliveryType"` // 仅用于传值
|
||||||
|
|
||||||
PrinterVendorID int `orm:"column(printer_vendor_id);" json:"printerVendorID"`
|
PrinterVendorID int `orm:"column(printer_vendor_id);" json:"printerVendorID"`
|
||||||
PrinterSN string `orm:"size(32);column(printer_sn);index" json:"printerSN"`
|
PrinterSN string `orm:"size(32);column(printer_sn);index" json:"printerSN"`
|
||||||
PrinterKey string `orm:"size(32)" json:"printerKey"`
|
PrinterKey string `orm:"size(32)" json:"printerKey"`
|
||||||
@@ -138,10 +143,39 @@ type Store struct {
|
|||||||
IDCardFront string `orm:"size(255);column(id_card_front)" json:"idCardFront"`
|
IDCardFront string `orm:"size(255);column(id_card_front)" json:"idCardFront"`
|
||||||
IDCardBack string `orm:"size(255);column(id_card_back)" json:"idCardBack"`
|
IDCardBack string `orm:"size(255);column(id_card_back)" json:"idCardBack"`
|
||||||
IDCardHand string `orm:"size(255);column(id_card_hand)" json:"idCardHand"`
|
IDCardHand string `orm:"size(255);column(id_card_hand)" json:"idCardHand"`
|
||||||
Licence string `orm:"size(255)" json:"licence"`
|
Licence string `orm:"size(255)" json:"licence"` // 营业执照图片
|
||||||
LicenceCode string `orm:"size(32)" json:"licenceCode"`
|
LicenceCode string `orm:"size(32)" json:"licenceCode"`
|
||||||
|
|
||||||
DeliveryType int8 `orm:"-" json:"deliveryType"` // 仅用于传值
|
LicenceType int8 `json:"licenceType"` // 营业执照类型,0:个人,1:公司
|
||||||
|
LicenceCorpName string `orm:"size(64)" json:"licenceCorpName"` // 营业执照公司名称
|
||||||
|
LicenceOwnerName string `orm:"size(8)" json:"licenceOwnerName"` // 法人姓名
|
||||||
|
LicenceAddress string `orm:"size(255)" json:"licenceAddress"` // 地址
|
||||||
|
LicenceValid string `orm:"size(32)" json:"licenceValid"` // 有效期开始
|
||||||
|
LicenceExpire string `orm:"size(32)" json:"licenceExpire"` // 有效期结束
|
||||||
|
|
||||||
|
IDName string `orm:"size(8);column(id_name)" json:"idName"` // 身份证姓名
|
||||||
|
IDCode string `orm:"size(32);column(id_code)" json:"idCode"` // 身份证号
|
||||||
|
IDValid string `orm:"column(id_valid);size(32)" json:"idValid"` // 有效期开始
|
||||||
|
IDExpire string `orm:"column(id_expire);size(32)" json:"idExpire"` // 有效期结束
|
||||||
|
|
||||||
|
Licence2Image string `orm:"size(255)" json:"licence2Image"` // 食品经营许可证
|
||||||
|
Licence2Code string `orm:"size(32)" json:"licence2Code"` // 食品经营许可证编号
|
||||||
|
Licence2Valid string `orm:"size(32)" json:"licence2Valid"` // 有效期开始
|
||||||
|
Licence2Expire string `orm:"size(32)" json:"licence2Expire"` // 有效期结束
|
||||||
|
|
||||||
|
MarketManName string `orm:"size(8)" json:"marketManName"` // 市场负责人姓名
|
||||||
|
MarketManPhone string `orm:"size(16)" json:"marketManPhone"` // 市场负责人电话
|
||||||
|
JxBrandFeeFactor int `json:"jxBrandFeeFactor"` // 京西品牌费因子
|
||||||
|
MarketAddFeeFactor int `json:"marketAddFeeFactor"` // 市场附加费因子
|
||||||
|
|
||||||
|
PayeeName string `orm:"size(8)" json:"payeeName"` // 收款人姓名
|
||||||
|
PayeeAccountNo string `orm:"size(255)" json:"payeeAccountNo"` // 收款账号
|
||||||
|
PayeeBankBranchName string `orm:"size(255)" json:"payeeBankBranchName"` // 开户银行
|
||||||
|
PayeeBankName string `orm:"size(255)" json:"payeeBankName"` // 开户支行
|
||||||
|
PayPercentage int `json:"payPercentage"`
|
||||||
|
|
||||||
|
OperatorName string `orm:"size(8)" json:"operatorName"` // 运营人姓名
|
||||||
|
OperatorPhone string `orm:"size(16)" json:"operatorPhone"` // 运营人电话
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Store) TableUnique() [][]string {
|
func (*Store) TableUnique() [][]string {
|
||||||
|
|||||||
@@ -58,6 +58,29 @@ func (*StoreSkuCategoryMap) TableUnique() [][]string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*StoreSkuCategoryMap) TableIndex() [][]string {
|
||||||
|
return [][]string{
|
||||||
|
[]string{"CategoryID", "StoreID", "DeletedAt"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// type StoreSkuCategoryMap2 struct {
|
||||||
|
// ModelIDCULD
|
||||||
|
|
||||||
|
// StoreID int `orm:"column(store_id)"`
|
||||||
|
// VendorID int `orm:"column(vendor_id)"`
|
||||||
|
// CategoryID int `orm:"column(category_id)"`
|
||||||
|
|
||||||
|
// VendorCatID string `orm:"column(vendor_cat_id);size(48)" json:"vendorCatID"`
|
||||||
|
// SyncStatus int8 `orm:"default(2)"`
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (*StoreSkuCategoryMap2) TableUnique() [][]string {
|
||||||
|
// return [][]string{
|
||||||
|
// []string{"StoreID", "VendorID", "CategoryID", "DeletedAt"},
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
type StoreSkuBind struct {
|
type StoreSkuBind struct {
|
||||||
ModelIDCULD
|
ModelIDCULD
|
||||||
|
|
||||||
@@ -88,6 +111,12 @@ func (*StoreSkuBind) TableUnique() [][]string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*StoreSkuBind) TableIndex() [][]string {
|
||||||
|
return [][]string{
|
||||||
|
[]string{"SkuID", "StoreID", "DeletedAt"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type StoreOpRequest struct {
|
type StoreOpRequest struct {
|
||||||
ModelIDCULD // DeletedAt用于表示请求操作结束,而并不一定是删除
|
ModelIDCULD // DeletedAt用于表示请求操作结束,而并不一定是删除
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,11 @@ const (
|
|||||||
ServerMsgPing = "ping"
|
ServerMsgPing = "ping"
|
||||||
|
|
||||||
ServerMsgNewOrder = "newOrder"
|
ServerMsgNewOrder = "newOrder"
|
||||||
|
ServerMsgFinishedPickup = "finishedPickup"
|
||||||
ServerMsgKeyOrderStatusChanged = "keyOrderStatusChanged" // 重要订单状态变化
|
ServerMsgKeyOrderStatusChanged = "keyOrderStatusChanged" // 重要订单状态变化
|
||||||
|
|
||||||
|
ServerMsgNewWait4ApproveAfsOrder = "newWait4ApproveAfsOrder"
|
||||||
|
ServerMsgKeyAfsOrderStatusChanged = "keyAfsOrderStatusChanged" // 重要售后单状态变化
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -67,8 +71,8 @@ func routinueFunc() {
|
|||||||
registerMsg := msg.MsgData.(*MsgOp)
|
registerMsg := msg.MsgData.(*MsgOp)
|
||||||
delete(channelMap[registerMsg.StoreID], registerMsg.Chan2Listen)
|
delete(channelMap[registerMsg.StoreID], registerMsg.Chan2Listen)
|
||||||
close(registerMsg.Chan2Close)
|
close(registerMsg.Chan2Close)
|
||||||
case ServerMsgNewOrder, ServerMsgKeyOrderStatusChanged:
|
case ServerMsgNewOrder, ServerMsgFinishedPickup, ServerMsgKeyOrderStatusChanged, ServerMsgNewWait4ApproveAfsOrder, ServerMsgKeyAfsOrderStatusChanged:
|
||||||
globals.SugarLogger.Debugf("msghub routinueFunc, msg:%s", utils.Format4Output(msg, false))
|
globals.SugarLogger.Debugf("msghub routinueFunc, msg:%s", utils.Format4Output(msg, true))
|
||||||
utils.CallFuncAsync(func() {
|
utils.CallFuncAsync(func() {
|
||||||
for chan2Send := range channelMap[msg.StoreID] {
|
for chan2Send := range channelMap[msg.StoreID] {
|
||||||
chan2Send <- msg
|
chan2Send <- msg
|
||||||
@@ -138,7 +142,7 @@ func GetMsg(ctx *jxcontext.Context, storeID int, lastOrderTime time.Time, lastOr
|
|||||||
case msg2, ok := <-chan2Listen:
|
case msg2, ok := <-chan2Listen:
|
||||||
timer.Stop()
|
timer.Stop()
|
||||||
if ok {
|
if ok {
|
||||||
msg.MsgData = msg2.MsgData
|
msg = msg2
|
||||||
}
|
}
|
||||||
case <-timer.C:
|
case <-timer.C:
|
||||||
unregisterChan(storeID, chan2Listen)
|
unregisterChan(storeID, chan2Listen)
|
||||||
@@ -152,7 +156,7 @@ func GetMsg(ctx *jxcontext.Context, storeID int, lastOrderTime time.Time, lastOr
|
|||||||
}
|
}
|
||||||
|
|
||||||
func OnNewOrder(order *model.GoodsOrder) {
|
func OnNewOrder(order *model.GoodsOrder) {
|
||||||
globals.SugarLogger.Debugf("msghub OnNewOrder, order:%s", utils.Format4Output(order, false))
|
globals.SugarLogger.Debugf("msghub OnNewOrder, order:%s", utils.Format4Output(order, true))
|
||||||
utils.CallFuncAsync(func() {
|
utils.CallFuncAsync(func() {
|
||||||
msgChan <- &ServerMsg{
|
msgChan <- &ServerMsg{
|
||||||
Type: ServerMsgNewOrder,
|
Type: ServerMsgNewOrder,
|
||||||
@@ -167,13 +171,13 @@ func OnNewOrder(order *model.GoodsOrder) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func OnKeyOrderStatusChanged(order *model.GoodsOrder) {
|
func OnFinishedPickup(order *model.GoodsOrder) {
|
||||||
globals.SugarLogger.Debugf("msghub OnKeyOrderStatusChanged, order:%s", utils.Format4Output(order, false))
|
globals.SugarLogger.Debugf("msghub OnFinishedPickup, order:%s", utils.Format4Output(order, true))
|
||||||
utils.CallFuncAsync(func() {
|
utils.CallFuncAsync(func() {
|
||||||
msgChan <- &ServerMsg{
|
msgChan <- &ServerMsg{
|
||||||
Type: ServerMsgKeyOrderStatusChanged,
|
Type: ServerMsgFinishedPickup,
|
||||||
StoreID: jxutils.GetSaleStoreIDFromOrder(order),
|
StoreID: jxutils.GetSaleStoreIDFromOrder(order),
|
||||||
MsgData: order,
|
MsgData: 1,
|
||||||
// MsgData: []*model.GoodsOrderExt{
|
// MsgData: []*model.GoodsOrderExt{
|
||||||
// &model.GoodsOrderExt{
|
// &model.GoodsOrderExt{
|
||||||
// GoodsOrder: *order,
|
// GoodsOrder: *order,
|
||||||
@@ -182,3 +186,36 @@ func OnKeyOrderStatusChanged(order *model.GoodsOrder) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func OnKeyOrderStatusChanged(order *model.GoodsOrder) {
|
||||||
|
globals.SugarLogger.Debugf("msghub OnKeyOrderStatusChanged, order:%s", utils.Format4Output(order, true))
|
||||||
|
utils.CallFuncAsync(func() {
|
||||||
|
msgChan <- &ServerMsg{
|
||||||
|
Type: ServerMsgKeyOrderStatusChanged,
|
||||||
|
StoreID: jxutils.GetSaleStoreIDFromOrder(order),
|
||||||
|
MsgData: order,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func OnNewWait4ApproveAfsOrder(order *model.AfsOrder) {
|
||||||
|
globals.SugarLogger.Debugf("msghub OnNewWait4ApproveAfsOrder, order:%s", utils.Format4Output(order, true))
|
||||||
|
utils.CallFuncAsync(func() {
|
||||||
|
msgChan <- &ServerMsg{
|
||||||
|
Type: ServerMsgNewWait4ApproveAfsOrder,
|
||||||
|
StoreID: jxutils.GetSaleStoreIDFromAfsOrder(order),
|
||||||
|
MsgData: order,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func OnKeyAfsOrderStatusChanged(order *model.AfsOrder) {
|
||||||
|
globals.SugarLogger.Debugf("msghub OnKeyAfsOrderStatusChanged, order:%s", utils.Format4Output(order, true))
|
||||||
|
utils.CallFuncAsync(func() {
|
||||||
|
msgChan <- &ServerMsg{
|
||||||
|
Type: ServerMsgKeyAfsOrderStatusChanged,
|
||||||
|
StoreID: jxutils.GetSaleStoreIDFromAfsOrder(order),
|
||||||
|
MsgData: order,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func (c *DeliveryHandler) GetVendorID() int {
|
|||||||
func (c *DeliveryHandler) OnWaybillMsg(msg *dadaapi.CallbackMsg) (retVal *dadaapi.CallbackResponse) {
|
func (c *DeliveryHandler) OnWaybillMsg(msg *dadaapi.CallbackMsg) (retVal *dadaapi.CallbackResponse) {
|
||||||
jxutils.CallMsgHandler(func() {
|
jxutils.CallMsgHandler(func() {
|
||||||
retVal = c.onWaybillMsg(msg)
|
retVal = c.onWaybillMsg(msg)
|
||||||
}, msg.OrderID)
|
}, jxutils.ComposeUniversalOrderID(msg.OrderID, model.VendorIDDada))
|
||||||
return retVal
|
return retVal
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,12 +58,16 @@ func (c *DeliveryHandler) onWaybillMsg(msg *dadaapi.CallbackMsg) (retVal *dadaap
|
|||||||
order := c.callbackMsg2Waybill(msg)
|
order := c.callbackMsg2Waybill(msg)
|
||||||
switch msg.OrderStatus {
|
switch msg.OrderStatus {
|
||||||
case dadaapi.OrderStatusWaitingForAccept:
|
case dadaapi.OrderStatusWaitingForAccept:
|
||||||
order.Status = model.WaybillStatusNew
|
|
||||||
case dadaapi.OrderStatusAccepted:
|
|
||||||
if result, err := api.DadaAPI.QueryOrderInfo(msg.OrderID); err == nil {
|
if result, err := api.DadaAPI.QueryOrderInfo(msg.OrderID); err == nil {
|
||||||
order.ActualFee = jxutils.StandardPrice2Int(utils.Interface2Float64WithDefault(result["actualFee"], 0.0))
|
order.ActualFee = jxutils.StandardPrice2Int(utils.Interface2Float64WithDefault(result["actualFee"], 0.0))
|
||||||
order.DesiredFee = jxutils.StandardPrice2Int(utils.Interface2Float64WithDefault(result["deliveryFee"], 0.0))
|
order.DesiredFee = jxutils.StandardPrice2Int(utils.Interface2Float64WithDefault(result["deliveryFee"], 0.0))
|
||||||
}
|
}
|
||||||
|
order.Status = model.WaybillStatusNew
|
||||||
|
case dadaapi.OrderStatusAccepted:
|
||||||
|
// if result, err := api.DadaAPI.QueryOrderInfo(msg.OrderID); err == nil {
|
||||||
|
// order.ActualFee = jxutils.StandardPrice2Int(utils.Interface2Float64WithDefault(result["actualFee"], 0.0))
|
||||||
|
// order.DesiredFee = jxutils.StandardPrice2Int(utils.Interface2Float64WithDefault(result["deliveryFee"], 0.0))
|
||||||
|
// }
|
||||||
order.Status = model.WaybillStatusAccepted
|
order.Status = model.WaybillStatusAccepted
|
||||||
case dadaapi.OrderStatusDelivering:
|
case dadaapi.OrderStatusDelivering:
|
||||||
order.Status = model.WaybillStatusDelivering
|
order.Status = model.WaybillStatusDelivering
|
||||||
@@ -99,17 +103,23 @@ func (c *DeliveryHandler) callbackMsg2Waybill(msg *dadaapi.CallbackMsg) (retVal
|
|||||||
return retVal
|
return retVal
|
||||||
}
|
}
|
||||||
|
|
||||||
// IDeliveryPlatformHandler
|
func (c *DeliveryHandler) GetWaybillFee(order *model.GoodsOrder) (deliveryFeeInfo *partner.WaybillFeeInfo, err error) {
|
||||||
func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, policy partner.CreateWaybillPolicy) (bill *model.Waybill, err error) {
|
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
deliveryFee, addFee, err := delivery.CalculateOrderDeliveryFee(order, time.Now(), db)
|
deliveryFeeInfo = &partner.WaybillFeeInfo{}
|
||||||
if err != nil {
|
deliveryFeeInfo.RefDeliveryFee, deliveryFeeInfo.RefAddFee, err = delivery.CalculateOrderDeliveryFee(order, time.Now(), db)
|
||||||
return nil, err
|
billParams, addParams, err := c.getBillParams(db, order)
|
||||||
|
if err == nil {
|
||||||
|
var result *dadaapi.CreateOrderResponse
|
||||||
|
if result, err = api.DadaAPI.QueryDeliverFee(billParams, addParams); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
deliveryFeeInfo.DeliveryFee = jxutils.StandardPrice2Int(result.Fee)
|
||||||
}
|
}
|
||||||
if err = delivery.CallCreateWaybillPolicy(policy, deliveryFee, addFee, deliveryFee, order, model.VendorIDDada); err != nil {
|
return deliveryFeeInfo, err
|
||||||
return nil, err
|
}
|
||||||
}
|
|
||||||
billParams := &dadaapi.OperateOrderRequiredParams{
|
func (c *DeliveryHandler) getBillParams(db *dao.DaoDB, order *model.GoodsOrder) (billParams *dadaapi.OperateOrderRequiredParams, addParams map[string]interface{}, err error) {
|
||||||
|
billParams = &dadaapi.OperateOrderRequiredParams{
|
||||||
// ShopNo: utils.Int2Str(order.StoreID), // 当前达达的门店号与京西是一样的
|
// ShopNo: utils.Int2Str(order.StoreID), // 当前达达的门店号与京西是一样的
|
||||||
OriginID: jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID),
|
OriginID: jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID),
|
||||||
CargoPrice: jxutils.IntPrice2Standard(limitOrderPrice(order.ActualPayPrice)),
|
CargoPrice: jxutils.IntPrice2Standard(limitOrderPrice(order.ActualPayPrice)),
|
||||||
@@ -121,7 +131,7 @@ func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, policy partner.
|
|||||||
if billParams.ShopNo, err = c.getDadaShopID(order, db); err == nil {
|
if billParams.ShopNo, err = c.getDadaShopID(order, db); err == nil {
|
||||||
if billParams.CityCode, err = c.getDataCityCodeFromOrder(order, db); err == nil {
|
if billParams.CityCode, err = c.getDataCityCodeFromOrder(order, db); err == nil {
|
||||||
billParams.ReceiverLng, billParams.ReceiverLat, _ = jxutils.IntCoordinate2MarsStandard(order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType)
|
billParams.ReceiverLng, billParams.ReceiverLat, _ = jxutils.IntCoordinate2MarsStandard(order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType)
|
||||||
addParams := map[string]interface{}{
|
addParams = map[string]interface{}{
|
||||||
"info": fmt.Sprintf("%s第%d号订单, %s", model.VendorChineseNames[order.VendorID], order.OrderSeq, utils.FilterMb4(order.BuyerComment)),
|
"info": fmt.Sprintf("%s第%d号订单, %s", model.VendorChineseNames[order.VendorID], order.OrderSeq, utils.FilterMb4(order.BuyerComment)),
|
||||||
// "origin_mark": model.VendorNames[order.VendorID], // 订单来源标示(该字段可以显示在达达app订单详情页面,只支持字母,最大长度为10)
|
// "origin_mark": model.VendorNames[order.VendorID], // 订单来源标示(该字段可以显示在达达app订单详情页面,只支持字母,最大长度为10)
|
||||||
// "origin_mark_no": fmt.Sprintf("%d", order.OrderSeq), // 订单来源编号(该字段可以显示在达达app订单详情页面,支持字母和数字,最大长度为30)
|
// "origin_mark_no": fmt.Sprintf("%d", order.OrderSeq), // 订单来源编号(该字段可以显示在达达app订单详情页面,支持字母和数字,最大长度为30)
|
||||||
@@ -129,11 +139,27 @@ func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, policy partner.
|
|||||||
"cargo_weight": jxutils.IntWeight2Float(limitOrderWeight(order.Weight)),
|
"cargo_weight": jxutils.IntWeight2Float(limitOrderWeight(order.Weight)),
|
||||||
"cargo_num": order.GoodsCount,
|
"cargo_num": order.GoodsCount,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return billParams, addParams, err
|
||||||
|
}
|
||||||
|
|
||||||
if globals.EnableStoreWrite {
|
// IDeliveryPlatformHandler
|
||||||
// 达达要求第二次创建运单,调用函数不同。所以查找两天内有无相同订单号的运单
|
func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, policy partner.CreateWaybillPolicy) (bill *model.Waybill, err error) {
|
||||||
var waybillList []*model.Waybill
|
db := dao.GetDB()
|
||||||
err2 := dao.GetRows(db, &waybillList, `
|
deliveryFee, addFee, err := delivery.CalculateOrderDeliveryFee(order, time.Now(), db)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err = delivery.CallCreateWaybillPolicy(policy, deliveryFee, addFee, deliveryFee, order, model.VendorIDDada); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
billParams, addParams, err := c.getBillParams(db, order)
|
||||||
|
if err == nil {
|
||||||
|
if globals.EnableStoreWrite {
|
||||||
|
// 达达要求第二次创建运单,调用函数不同。所以查找两天内有无相同订单号的运单
|
||||||
|
var waybillList []*model.Waybill
|
||||||
|
err2 := dao.GetRows(db, &waybillList, `
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM waybill
|
FROM waybill
|
||||||
WHERE waybill_created_at > DATE_ADD(NOW(), interval -2 day)
|
WHERE waybill_created_at > DATE_ADD(NOW(), interval -2 day)
|
||||||
@@ -141,39 +167,38 @@ func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, policy partner.
|
|||||||
AND waybill_vendor_id = ?
|
AND waybill_vendor_id = ?
|
||||||
ORDER BY id DESC
|
ORDER BY id DESC
|
||||||
`, jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID), model.VendorIDDada)
|
`, jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID), model.VendorIDDada)
|
||||||
var result *dadaapi.CreateOrderResponse
|
var result *dadaapi.CreateOrderResponse
|
||||||
if err = err2; err == nil && len(waybillList) > 0 && waybillList[0].Status != model.WaybillStatusFailed {
|
if err = err2; err == nil && len(waybillList) > 0 && waybillList[0].Status != model.WaybillStatusFailed {
|
||||||
globals.SugarLogger.Debugf("CreateWaybill orderID:%s len(waybillList)=%d use ReaddOrder", order.VendorOrderID, len(waybillList))
|
globals.SugarLogger.Debugf("CreateWaybill orderID:%s len(waybillList)=%d use ReaddOrder", order.VendorOrderID, len(waybillList))
|
||||||
result, err = api.DadaAPI.ReaddOrder(billParams, addParams)
|
result, err = api.DadaAPI.ReaddOrder(billParams, addParams)
|
||||||
} else {
|
|
||||||
if err != nil {
|
|
||||||
globals.SugarLogger.Warnf("CreateWaybill orderID:%s error:%v", order.VendorOrderID, err)
|
|
||||||
}
|
|
||||||
if false {
|
|
||||||
result, err = api.DadaAPI.AddOrder(billParams, addParams)
|
|
||||||
} else {
|
|
||||||
if result, err = api.DadaAPI.QueryDeliverFee(billParams, addParams); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
dadaFee := jxutils.StandardPrice2Int(result.Fee)
|
|
||||||
if err = delivery.CallCreateWaybillPolicy(policy, deliveryFee, addFee, dadaFee, order, model.VendorIDDada); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = api.DadaAPI.AddOrderAfterQuery(result.DeliveryNo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == nil && result != nil {
|
|
||||||
bill = &model.Waybill{
|
|
||||||
VendorOrderID: order.VendorOrderID,
|
|
||||||
OrderVendorID: order.VendorID,
|
|
||||||
WaybillVendorID: model.VendorIDDada,
|
|
||||||
DesiredFee: deliveryFee,
|
|
||||||
ActualFee: jxutils.StandardPrice2Int(result.Fee),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
err = fmt.Errorf("测试环境不能真正创建运单")
|
if err != nil {
|
||||||
|
globals.SugarLogger.Warnf("CreateWaybill orderID:%s error:%v", order.VendorOrderID, err)
|
||||||
|
}
|
||||||
|
if false {
|
||||||
|
result, err = api.DadaAPI.AddOrder(billParams, addParams)
|
||||||
|
} else {
|
||||||
|
if result, err = api.DadaAPI.QueryDeliverFee(billParams, addParams); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dadaFee := jxutils.StandardPrice2Int(result.Fee)
|
||||||
|
if err = delivery.CallCreateWaybillPolicy(policy, deliveryFee, addFee, dadaFee, order, model.VendorIDDada); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = api.DadaAPI.AddOrderAfterQuery(result.DeliveryNo)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if err == nil && result != nil {
|
||||||
|
bill = &model.Waybill{
|
||||||
|
VendorOrderID: order.VendorOrderID,
|
||||||
|
OrderVendorID: order.VendorID,
|
||||||
|
WaybillVendorID: model.VendorIDDada,
|
||||||
|
DesiredFee: deliveryFee,
|
||||||
|
ActualFee: jxutils.StandardPrice2Int(result.Fee),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("测试环境不能真正创建运单")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bill, err
|
return bill, err
|
||||||
|
|||||||
@@ -17,21 +17,33 @@ import (
|
|||||||
const (
|
const (
|
||||||
warningDistance = 10 // 公里
|
warningDistance = 10 // 公里
|
||||||
warningWeight = 50 * 1000 // 克
|
warningWeight = 50 * 1000 // 克
|
||||||
maxDiffFee2Mtps = 150 // 与美团配送最多差价
|
maxDiffFee2Mtps = 500 // 与美团配送最多差价
|
||||||
maxAddFee = 300 // 最大增加费用,单位为分,超过不发三方配送了
|
maxAddFee = 200 // 最大增加费用,单位为分,超过不发三方配送了
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
DefCreateWaybillPolicy = CreateWaybillPolicy(maxDiffFee2Mtps, maxAddFee)
|
||||||
)
|
)
|
||||||
|
|
||||||
func NullCreateWaybillPolicy(refDeliveryFee, refAddFee, deliveryFee int64) (errStr string) {
|
func NullCreateWaybillPolicy(refDeliveryFee, refAddFee, deliveryFee int64) (errStr string) {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefCreateWaybillPolicy(refDeliveryFee, refAddFee, deliveryFee int64) (errStr string) {
|
func CreateWaybillPolicy(maxDiffFee2Mtps2, maxAddFee2 int64) func(refDeliveryFee, refAddFee, deliveryFee int64) (errStr string) {
|
||||||
if refDeliveryFee-deliveryFee > maxDiffFee2Mtps {
|
if maxDiffFee2Mtps2 == 0 {
|
||||||
errStr = fmt.Sprintf("超参考价太多, 费用:%d,参考价:%d, 最高超价:%d", deliveryFee, refDeliveryFee, maxDiffFee2Mtps)
|
maxDiffFee2Mtps2 = maxDiffFee2Mtps
|
||||||
} else if refAddFee > maxAddFee {
|
}
|
||||||
errStr = fmt.Sprintf("超基础价太多, 当前加价:%d, 最高加价:%d", refAddFee, maxAddFee)
|
if maxAddFee2 == 0 {
|
||||||
|
maxAddFee2 = maxAddFee
|
||||||
|
}
|
||||||
|
return func(refDeliveryFee, refAddFee, deliveryFee int64) (errStr string) {
|
||||||
|
if deliveryFee-refDeliveryFee > maxDiffFee2Mtps2 {
|
||||||
|
errStr = fmt.Sprintf("超参考价太多, 费用:%d,参考价:%d, 最高超价:%d", deliveryFee, refDeliveryFee, maxDiffFee2Mtps2)
|
||||||
|
} else if refAddFee > maxAddFee2 {
|
||||||
|
errStr = fmt.Sprintf("超基础价太多, 当前加价:%d, 最高加价:%d", refAddFee, maxAddFee2)
|
||||||
|
}
|
||||||
|
return errStr
|
||||||
}
|
}
|
||||||
return errStr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddPolicy(prevPolicy, newPolicy partner.CreateWaybillPolicy) (outPolicy partner.CreateWaybillPolicy) {
|
func AddPolicy(prevPolicy, newPolicy partner.CreateWaybillPolicy) (outPolicy partner.CreateWaybillPolicy) {
|
||||||
@@ -43,11 +55,11 @@ func AddPolicy(prevPolicy, newPolicy partner.CreateWaybillPolicy) (outPolicy par
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallCreateWaybillPolicy(policy partner.CreateWaybillPolicy, refDeliveryFee, deliveryFee, addFee int64, order *model.GoodsOrder, waybillVendorID int) (err error) {
|
func CallCreateWaybillPolicy(policy partner.CreateWaybillPolicy, refDeliveryFee, refAddFee, deliveryFee int64, order *model.GoodsOrder, waybillVendorID int) (err error) {
|
||||||
if policy == nil {
|
if policy == nil {
|
||||||
policy = NullCreateWaybillPolicy
|
policy = NullCreateWaybillPolicy
|
||||||
}
|
}
|
||||||
if errStr := policy(deliveryFee, deliveryFee, addFee); errStr != "" {
|
if errStr := policy(refDeliveryFee, refAddFee, deliveryFee); errStr != "" {
|
||||||
waybillVendorName := jxutils.GetVendorName(waybillVendorID)
|
waybillVendorName := jxutils.GetVendorName(waybillVendorID)
|
||||||
errStr = fmt.Sprintf("oderID:%s创建运单出错:%s", order.VendorOrderID, errStr)
|
errStr = fmt.Sprintf("oderID:%s创建运单出错:%s", order.VendorOrderID, errStr)
|
||||||
globals.SugarLogger.Debugf("%s CallCreateWaybillPolicy failed with %s", waybillVendorName, errStr)
|
globals.SugarLogger.Debugf("%s CallCreateWaybillPolicy failed with %s", waybillVendorName, errStr)
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ func OnWaybillExcept(msg *mtpsapi.CallbackOrderExceptionMsg) (retVal *mtpsapi.Ca
|
|||||||
func (c *DeliveryHandler) OnWaybillMsg(msg *mtpsapi.CallbackOrderMsg) (retVal *mtpsapi.CallbackResponse) {
|
func (c *DeliveryHandler) OnWaybillMsg(msg *mtpsapi.CallbackOrderMsg) (retVal *mtpsapi.CallbackResponse) {
|
||||||
jxutils.CallMsgHandler(func() {
|
jxutils.CallMsgHandler(func() {
|
||||||
retVal = c.onWaybillMsg(msg)
|
retVal = c.onWaybillMsg(msg)
|
||||||
}, msg.OrderID)
|
}, jxutils.ComposeUniversalOrderID(msg.OrderID, model.VendorIDMTPS))
|
||||||
return retVal
|
return retVal
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ func (c *DeliveryHandler) OnWaybillExcept(msg *mtpsapi.CallbackOrderExceptionMsg
|
|||||||
}
|
}
|
||||||
order.VendorOrderID, order.OrderVendorID = jxutils.SplitUniversalOrderID(msg.OrderID)
|
order.VendorOrderID, order.OrderVendorID = jxutils.SplitUniversalOrderID(msg.OrderID)
|
||||||
retVal = mtpsapi.Err2CallbackResponse(partner.CurOrderManager.OnWaybillStatusChanged(order), "mtps OnWaybillExcept")
|
retVal = mtpsapi.Err2CallbackResponse(partner.CurOrderManager.OnWaybillStatusChanged(order), "mtps OnWaybillExcept")
|
||||||
}, msg.OrderID)
|
}, jxutils.ComposeUniversalOrderID(msg.OrderID, model.VendorIDDada))
|
||||||
return retVal
|
return retVal
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,9 +81,10 @@ func (c *DeliveryHandler) onWaybillMsg(msg *mtpsapi.CallbackOrderMsg) (retVal *m
|
|||||||
order := c.callbackMsg2Waybill(msg)
|
order := c.callbackMsg2Waybill(msg)
|
||||||
switch msg.Status {
|
switch msg.Status {
|
||||||
case mtpsapi.OrderStatusWaitingForSchedule:
|
case mtpsapi.OrderStatusWaitingForSchedule:
|
||||||
|
order.DesiredFee, _ = delivery.CalculateBillDeliveryFee(order)
|
||||||
order.Status = model.WaybillStatusNew
|
order.Status = model.WaybillStatusNew
|
||||||
case mtpsapi.OrderStatusAccepted:
|
case mtpsapi.OrderStatusAccepted:
|
||||||
order.DesiredFee, _ = delivery.CalculateBillDeliveryFee(order)
|
order.DesiredFee, _ = delivery.CalculateBillDeliveryFee(order) // 美团外卖可能会丢失新运单事件,这里补一下
|
||||||
order.Status = model.WaybillStatusAccepted
|
order.Status = model.WaybillStatusAccepted
|
||||||
case mtpsapi.OrderStatusPickedUp:
|
case mtpsapi.OrderStatusPickedUp:
|
||||||
order.Status = model.WaybillStatusDelivering
|
order.Status = model.WaybillStatusDelivering
|
||||||
@@ -113,6 +114,18 @@ func (c *DeliveryHandler) callbackMsg2Waybill(msg *mtpsapi.CallbackOrderMsg) (re
|
|||||||
return retVal
|
return retVal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *DeliveryHandler) GetWaybillFee(order *model.GoodsOrder) (deliveryFeeInfo *partner.WaybillFeeInfo, err error) {
|
||||||
|
db := dao.GetDB()
|
||||||
|
deliveryFeeInfo = &partner.WaybillFeeInfo{}
|
||||||
|
deliveryFeeInfo.RefDeliveryFee, deliveryFeeInfo.RefAddFee, err = delivery.CalculateOrderDeliveryFee(order, time.Now(), db)
|
||||||
|
if err == nil {
|
||||||
|
if _, err = c.getMTPSShopID(order, db); err == nil {
|
||||||
|
deliveryFeeInfo.DeliveryFee = deliveryFeeInfo.RefDeliveryFee
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deliveryFeeInfo, err
|
||||||
|
}
|
||||||
|
|
||||||
// IDeliveryPlatformHandler
|
// IDeliveryPlatformHandler
|
||||||
func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, policy partner.CreateWaybillPolicy) (bill *model.Waybill, err error) {
|
func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, policy partner.CreateWaybillPolicy) (bill *model.Waybill, err error) {
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
@@ -167,7 +180,6 @@ func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, policy partner.
|
|||||||
if globals.EnableStoreWrite {
|
if globals.EnableStoreWrite {
|
||||||
result, err2 := api.MtpsAPI.CreateOrderByShop(billParams, addParams)
|
result, err2 := api.MtpsAPI.CreateOrderByShop(billParams, addParams)
|
||||||
if err = err2; err == nil {
|
if err = err2; err == nil {
|
||||||
globals.SugarLogger.Debugf("CreateWaybill failed, orderID:%s, billParams:%v, addParams:%v, error:%v", order.VendorOrderID, billParams, addParams, err)
|
|
||||||
bill = &model.Waybill{
|
bill = &model.Waybill{
|
||||||
VendorOrderID: order.VendorOrderID,
|
VendorOrderID: order.VendorOrderID,
|
||||||
OrderVendorID: order.VendorID,
|
OrderVendorID: order.VendorID,
|
||||||
@@ -176,6 +188,8 @@ func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, policy partner.
|
|||||||
WaybillVendorID: model.VendorIDMTPS,
|
WaybillVendorID: model.VendorIDMTPS,
|
||||||
DesiredFee: deliveryFee,
|
DesiredFee: deliveryFee,
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
globals.SugarLogger.Debugf("CreateWaybill failed, orderID:%s, billParams:%v, addParams:%v, error:%v", order.VendorOrderID, billParams, addParams, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err = fmt.Errorf("测试环境不能真正创建运单")
|
err = fmt.Errorf("测试环境不能真正创建运单")
|
||||||
|
|||||||
@@ -33,6 +33,12 @@ const (
|
|||||||
PrinterStatusOnlineAbnormal = 3
|
PrinterStatusOnlineAbnormal = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AfsApproveTypeRefund = 1 // 退款
|
||||||
|
AfsApproveTypeReturnGoods = 2 // 退货
|
||||||
|
AfsApproveTypeRefused = 3 // 驳回
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PrintResultSuccess = 0
|
PrintResultSuccess = 0
|
||||||
PrintResultNoPrinter = 1
|
PrintResultNoPrinter = 1
|
||||||
@@ -51,10 +57,11 @@ type PrinterStatus struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TimerTypeNoOverride = 0 // GetStatusActionConfig 返回表示不修改缺省配置
|
TimerTypeNoOverride = 0 // GetStatusActionConfig 返回表示不修改缺省配置
|
||||||
TimerTypeByPass = 1
|
TimerTypeByPass = 1
|
||||||
TimerTypeBaseNow = 2
|
TimerTypeBaseNow = 2
|
||||||
TimerTypeBaseStatusTime = 3
|
TimerTypeBaseStatusTime = 3
|
||||||
|
TimerTypeBaseOrderCreatedAt = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
type StatusActionParams struct {
|
type StatusActionParams struct {
|
||||||
@@ -63,15 +70,37 @@ type StatusActionParams struct {
|
|||||||
TimeoutGap int // 以秒为单位的随机时间,0在GetStatusActionConfig返回时表示不修改缺省
|
TimeoutGap int // 以秒为单位的随机时间,0在GetStatusActionConfig返回时表示不修改缺省
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StatusActionParams) GetRefTimeout(statusTime time.Time) (timeout time.Duration) {
|
const (
|
||||||
|
WaybillFeeErrCodeCourierNotOpen = 1 //配送门店没有启用
|
||||||
|
WaybillFeeErrCodeCourierNotSupported = 2 //配送门店不被系统支持
|
||||||
|
WaybillFeeErrCodeCourierForbidden = 3 //配送门店内部禁用
|
||||||
|
WaybillFeeErrCodeCourierOthers = 10 //其它错误
|
||||||
|
)
|
||||||
|
|
||||||
|
type WaybillFeeInfo struct {
|
||||||
|
ErrCode int `json:"errCode"`
|
||||||
|
ErrStr string `json:"errStr"`
|
||||||
|
RefDeliveryFee int64 `json:"refDeliveryFee"`
|
||||||
|
RefAddFee int64 `json:"refAddFee"`
|
||||||
|
DeliveryFee int64 `json:"deliveryFee"`
|
||||||
|
TimeoutSecond int `json:"timeoutSecond"` // 系统会自动发运单的倒计时
|
||||||
|
Waybill *model.Waybill `json:"waybill"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StatusActionParams) GetRefTimeout(statusTime time.Time, orderCreatedAt time.Time) (timeout time.Duration) {
|
||||||
switch s.TimerType {
|
switch s.TimerType {
|
||||||
case TimerTypeBaseNow:
|
case TimerTypeBaseNow:
|
||||||
timeout = s.Timeout
|
timeout = s.Timeout
|
||||||
case TimerTypeBaseStatusTime:
|
case TimerTypeBaseStatusTime:
|
||||||
timeout = statusTime.Sub(time.Now()) + s.Timeout
|
timeout = statusTime.Sub(time.Now()) + s.Timeout
|
||||||
|
case TimerTypeBaseOrderCreatedAt:
|
||||||
|
timeout = orderCreatedAt.Sub(time.Now()) + s.Timeout
|
||||||
default:
|
default:
|
||||||
timeout = 0
|
timeout = 0
|
||||||
}
|
}
|
||||||
|
if timeout < 0 {
|
||||||
|
timeout = 0
|
||||||
|
}
|
||||||
return timeout
|
return timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,8 +129,8 @@ var (
|
|||||||
type IOrderManager interface {
|
type IOrderManager interface {
|
||||||
SaveOrder(order *model.GoodsOrder, isAdjust bool, db *dao.DaoDB) (isDuplicated bool, err error)
|
SaveOrder(order *model.GoodsOrder, isAdjust bool, db *dao.DaoDB) (isDuplicated bool, err error)
|
||||||
|
|
||||||
OnOrderNew(order *model.GoodsOrder, msgVendorStatus string) (err error)
|
OnOrderNew(order *model.GoodsOrder, orderStatus *model.OrderStatus) (err error)
|
||||||
OnOrderAdjust(order *model.GoodsOrder, msgVendorStatus string) (err error)
|
OnOrderAdjust(order *model.GoodsOrder, orderStatus *model.OrderStatus) (err error)
|
||||||
OnOrderStatusChanged(orderStatus *model.OrderStatus) (err error)
|
OnOrderStatusChanged(orderStatus *model.OrderStatus) (err error)
|
||||||
OnOrderMsg(order *model.GoodsOrder, vendorStatus, remark string) (err error)
|
OnOrderMsg(order *model.GoodsOrder, vendorStatus, remark string) (err error)
|
||||||
|
|
||||||
@@ -113,14 +142,25 @@ type IOrderManager interface {
|
|||||||
LoadOrderFinancial(vendorOrderID string, vendorID int) (order *model.OrderFinancial, err error)
|
LoadOrderFinancial(vendorOrderID string, vendorID int) (order *model.OrderFinancial, err error)
|
||||||
LoadOrderFinancial2(vendorOrderID2 string, vendorID int) (order *model.OrderFinancial, err error)
|
LoadOrderFinancial2(vendorOrderID2 string, vendorID int) (order *model.OrderFinancial, err error)
|
||||||
|
|
||||||
UpdateWaybillVendorID(bill *model.Waybill, revertStatus bool) (err error)
|
UpdateOrderStatusAndDeliveryFlag(order *model.GoodsOrder) (err error)
|
||||||
UpdateOrderStatusAndFlag(order *model.GoodsOrder) (err error)
|
UpdateOrderFields(order *model.GoodsOrder, fieldList []string) (err error)
|
||||||
|
|
||||||
LoadWaybill(vendorWaybillID string, waybillVendorID int) (bill *model.Waybill, err error)
|
LoadWaybill(vendorWaybillID string, waybillVendorID int) (bill *model.Waybill, err error)
|
||||||
OnOrderComments(orderCommentList []*model.OrderComment) (err error)
|
OnOrderComments(orderCommentList []*model.OrderComment) (err error)
|
||||||
|
|
||||||
SaveOrderFinancialInfo(order *model.OrderFinancial, operation string) (err error)
|
SaveOrderFinancialInfo(order *model.OrderFinancial, operation string) (err error)
|
||||||
SaveAfsOrderFinancialInfo(afsOrder *model.AfsOrder) (err error)
|
SaveAfsOrderFinancialInfo(afsOrder *model.AfsOrder) (err error)
|
||||||
|
|
||||||
|
GetOrderWaybillInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID int, isNotEnded bool) (bills []*model.Waybill, err error)
|
||||||
|
|
||||||
|
// afs order
|
||||||
|
OnAfsOrderAdjust(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus) (err error)
|
||||||
|
OnAfsOrderNew(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus) (err error)
|
||||||
|
OnAfsOrderStatusChanged(orderStatus *model.OrderStatus) (err error)
|
||||||
|
LoadAfsOrder(vendorAfsOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error)
|
||||||
|
UpdateAfsOrderFields(afsOrder *model.AfsOrder, fieldList []string) (err error)
|
||||||
|
|
||||||
|
GetStatusDuplicatedCount(status *model.OrderStatus) (duplicatedCount int)
|
||||||
}
|
}
|
||||||
|
|
||||||
type IStoreManager interface {
|
type IStoreManager interface {
|
||||||
@@ -132,6 +172,7 @@ type IStoreManager interface {
|
|||||||
// 所有非以Sync,Refresh开头的函数不用自己清理sync_status标记(VendorSync统一处理)
|
// 所有非以Sync,Refresh开头的函数不用自己清理sync_status标记(VendorSync统一处理)
|
||||||
|
|
||||||
type IPurchasePlatformHandler interface {
|
type IPurchasePlatformHandler interface {
|
||||||
|
IPurchasePlatformPromotionHandler
|
||||||
GetVendorID() int
|
GetVendorID() int
|
||||||
|
|
||||||
GetStatusFromVendorStatus(vendorStatus string) int
|
GetStatusFromVendorStatus(vendorStatus string) int
|
||||||
@@ -167,6 +208,16 @@ type IPurchasePlatformHandler interface {
|
|||||||
// order.Skus要包含原始订单中的Sku信息,removedSkuList中是要移除的Sku信息
|
// order.Skus要包含原始订单中的Sku信息,removedSkuList中是要移除的Sku信息
|
||||||
AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error)
|
AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error)
|
||||||
|
|
||||||
|
// 售后
|
||||||
|
// // 发起全款退款
|
||||||
|
// RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error)
|
||||||
|
// // 发起部分退款
|
||||||
|
// PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error)
|
||||||
|
// 审核售后单申请
|
||||||
|
AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error)
|
||||||
|
// // 确认收到退货
|
||||||
|
ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error)
|
||||||
|
|
||||||
////////
|
////////
|
||||||
// Store
|
// Store
|
||||||
ReadStore(vendorStoreID string) (store *model.Store, err error)
|
ReadStore(vendorStoreID string) (store *model.Store, err error)
|
||||||
@@ -184,6 +235,10 @@ type IPurchasePlatformHandler interface {
|
|||||||
UploadImg(ctx *jxcontext.Context, imgURL string, imgData []byte, imgName string) (imgHint string, err error)
|
UploadImg(ctx *jxcontext.Context, imgURL string, imgData []byte, imgName string) (imgHint string, err error)
|
||||||
GetStoreStatus(ctx *jxcontext.Context, vendorStoreID string) (storeStatus int, err error)
|
GetStoreStatus(ctx *jxcontext.Context, vendorStoreID string) (storeStatus int, err error)
|
||||||
GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error)
|
GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error)
|
||||||
|
|
||||||
|
// todo 如下两个函数需要合并一下s
|
||||||
|
GetStoresSku(ctx *jxcontext.Context, parentTask tasksch.ITask, storeIDs []int) (storeSkuList []*model.StoreSkuBind, err error)
|
||||||
|
GetStoreSkusInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*BareStoreSkuInfo) (outStoreSkuList []*BareStoreSkuInfo, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// db *dao.DaoDB,
|
// db *dao.DaoDB,
|
||||||
@@ -219,6 +274,7 @@ type IDeliveryPlatformHandler interface {
|
|||||||
CancelWaybill(bill *model.Waybill, cancelReasonID int, cancelReason string) (err error)
|
CancelWaybill(bill *model.Waybill, cancelReasonID int, cancelReason string) (err error)
|
||||||
|
|
||||||
GetVendorID() int
|
GetVendorID() int
|
||||||
|
GetWaybillFee(order *model.GoodsOrder) (deliveryFeeInfo *WaybillFeeInfo, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type IPrinterHandler interface {
|
type IPrinterHandler interface {
|
||||||
|
|||||||
24
business/partner/partner_act.go
Normal file
24
business/partner/partner_act.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package partner
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IPurchasePlatformPromotionHandler interface {
|
||||||
|
// 如果是单品级活动,actOrderRules为空
|
||||||
|
// 如果是订单级活动,actStoreSku可以为空(表示不限制SKU)
|
||||||
|
CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error)
|
||||||
|
UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error)
|
||||||
|
// 取消整个京西活动
|
||||||
|
CancelAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ActStoreSku2Map(actStoreSku []*model.ActStoreSku2) (actStoreSkuMap map[int][]*model.ActStoreSku2) {
|
||||||
|
actStoreSkuMap = make(map[int][]*model.ActStoreSku2)
|
||||||
|
for _, storeSku := range actStoreSku {
|
||||||
|
actStoreSkuMap[storeSku.StoreID] = append(actStoreSkuMap[storeSku.StoreID], storeSku)
|
||||||
|
}
|
||||||
|
return actStoreSkuMap
|
||||||
|
}
|
||||||
89
business/partner/partner_err.go
Normal file
89
business/partner/partner_err.go
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
package partner
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ErrCodeUnknown = 1
|
||||||
|
ErrCodeChangePriceFailed = 100
|
||||||
|
)
|
||||||
|
|
||||||
|
type ErrorWithCode struct {
|
||||||
|
errMsg string
|
||||||
|
intCode int
|
||||||
|
vendorID int
|
||||||
|
storeID int
|
||||||
|
skuID int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewErrorCode(errMsg string, code, vendorID int) *ErrorWithCode {
|
||||||
|
retVal := &ErrorWithCode{
|
||||||
|
errMsg: errMsg,
|
||||||
|
intCode: code,
|
||||||
|
vendorID: vendorID,
|
||||||
|
}
|
||||||
|
return retVal
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrorWithCode) SetStoreID(storeID int) {
|
||||||
|
e.storeID = storeID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrorWithCode) SetSkuID(skuID int) {
|
||||||
|
e.skuID = skuID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrorWithCode) Error() string {
|
||||||
|
return fmt.Sprintf("平台:%s, code:%d, %s", model.VendorChineseNames[e.VendorID()], e.intCode, e.errMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrorWithCode) String() string {
|
||||||
|
return e.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrorWithCode) Code() int {
|
||||||
|
return e.intCode
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrorWithCode) ErrMsg() string {
|
||||||
|
return e.errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrorWithCode) VendorID() int {
|
||||||
|
return e.vendorID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrorWithCode) StoreID() int {
|
||||||
|
return e.storeID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrorWithCode) SkuID() int {
|
||||||
|
return e.skuID
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsErrChangePriceFailed(err error) *ErrorWithCode {
|
||||||
|
if vendorErr, ok := err.(*ErrorWithCode); ok && vendorErr.Code() == ErrCodeChangePriceFailed {
|
||||||
|
return vendorErr
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsErrVendorError(err error) *ErrorWithCode {
|
||||||
|
if vendorErr, ok := err.(*ErrorWithCode); ok {
|
||||||
|
return vendorErr
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddVendorInfo2Err(inErr error, vendorID int) (outErr error) {
|
||||||
|
outErr = inErr
|
||||||
|
if inErr != nil {
|
||||||
|
if IsErrVendorError(inErr) == nil {
|
||||||
|
outErr = NewErrorCode(inErr.Error(), ErrCodeUnknown, vendorID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return outErr
|
||||||
|
}
|
||||||
82
business/partner/partner_store_sku.go
Normal file
82
business/partner/partner_store_sku.go
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package partner
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
FuncCreateStoreSkus = 1
|
||||||
|
FuncDeleteStoreSkus = 2
|
||||||
|
FuncUpdateStoreSkusStatus = 3
|
||||||
|
FuncUpdateStoreSkusPrice = 4
|
||||||
|
FuncUpdateStoreSkus = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
type BareStoreSkuInfo struct {
|
||||||
|
SkuID int `json:"skuID,omitempty"`
|
||||||
|
VendorSkuID string `json:"vendorSkuID,omitempty"`
|
||||||
|
NameID int `json:"nameID,omitempty"`
|
||||||
|
VendorNameID string `json:"vendorNameID,omitempty"`
|
||||||
|
|
||||||
|
Price int64 `json:"price,omitempty"`
|
||||||
|
Status int `json:"status,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BareStoreSkuInfoList []*BareStoreSkuInfo
|
||||||
|
|
||||||
|
func (l BareStoreSkuInfoList) GetVendorSkuIDList() (vendorSkuIDList []string) {
|
||||||
|
for _, v := range l {
|
||||||
|
if !dao.IsVendorThingIDEmpty(v.VendorSkuID) {
|
||||||
|
vendorSkuIDList = append(vendorSkuIDList, v.VendorSkuID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vendorSkuIDList
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l BareStoreSkuInfoList) GetVendorSkuIDIntList() (vendorSkuIDIntList []int64) {
|
||||||
|
for _, v := range l {
|
||||||
|
if !dao.IsVendorThingIDEmpty(v.VendorSkuID) {
|
||||||
|
vendorSkuIDIntList = append(vendorSkuIDIntList, utils.Str2Int64(v.VendorSkuID))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vendorSkuIDIntList
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l BareStoreSkuInfoList) GetSkuIDList() (skuIDList []int) {
|
||||||
|
for k, v := range l {
|
||||||
|
if v.SkuID > 0 {
|
||||||
|
skuIDList[k] = v.SkuID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return skuIDList
|
||||||
|
}
|
||||||
|
|
||||||
|
type BareCategoryInfo struct {
|
||||||
|
VendorCatID string `json:"vendorCatID"`
|
||||||
|
|
||||||
|
Level int `json:"level"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Seq int `json:"seq,omitempty"`
|
||||||
|
Children []*BareCategoryInfo `json:"children,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type IPurchasePlatformStoreSkuHandler interface {
|
||||||
|
GetStoreSkusBatchSize(funcID int) int
|
||||||
|
|
||||||
|
CreateStoreSkus(ctx *jxcontext.Context, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (err error)
|
||||||
|
DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*BareStoreSkuInfo) (err error)
|
||||||
|
UpdateStoreSkusStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*BareStoreSkuInfo) (err error)
|
||||||
|
UpdateStoreSkusPrice(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*BareStoreSkuInfo) (err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ISingleStoreStoreSkuHandler interface {
|
||||||
|
IPurchasePlatformStoreSkuHandler
|
||||||
|
|
||||||
|
ReadStoreCategory(ctx *jxcontext.Context, vendorStoreID string) (cats []*BareCategoryInfo, err error)
|
||||||
|
CreateStoreSkuCategory(ctx *jxcontext.Context, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error)
|
||||||
|
UpdateStoreSkuCategory(ctx *jxcontext.Context, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error)
|
||||||
|
DeleteStoreSkuCategory(ctx *jxcontext.Context, vendorStoreID, vendorCatID string) (err error)
|
||||||
|
UpdateStoreSkus(ctx *jxcontext.Context, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (err error)
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
|||||||
expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour)
|
expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour)
|
||||||
}
|
}
|
||||||
orderFmt := `
|
orderFmt := `
|
||||||
<CB>京西菜市</CB><BR><BR>
|
<CB>%s</CB><BR><BR>
|
||||||
<C>手机买菜上京西</C><BR>
|
<C>手机买菜上京西</C><BR>
|
||||||
<C>极速到家送惊喜</C><BR>
|
<C>极速到家送惊喜</C><BR>
|
||||||
--------------------------------<BR>
|
--------------------------------<BR>
|
||||||
@@ -59,6 +59,7 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
|||||||
品名 数量 单价 小计<BR>
|
品名 数量 单价 小计<BR>
|
||||||
--------------------------------<BR>`
|
--------------------------------<BR>`
|
||||||
orderParams := []interface{}{
|
orderParams := []interface{}{
|
||||||
|
globals.StoreName,
|
||||||
utils.Time2Str(order.OrderCreatedAt),
|
utils.Time2Str(order.OrderCreatedAt),
|
||||||
utils.Time2Str(expectedDeliveryTime),
|
utils.Time2Str(expectedDeliveryTime),
|
||||||
order.VendorOrderID,
|
order.VendorOrderID,
|
||||||
@@ -84,7 +85,7 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
|||||||
<C><L><BOLD>商品质量问题请联系:</BOLD></L><BR></C>
|
<C><L><BOLD>商品质量问题请联系:</BOLD></L><BR></C>
|
||||||
<C><L><BOLD>%s:%s</BOLD></L><BR></C><BR>
|
<C><L><BOLD>%s:%s</BOLD></L><BR></C><BR>
|
||||||
<BR>
|
<BR>
|
||||||
更多信息请关注官方微信: 京西菜市<BR>
|
更多信息请关注官方微信: %s<BR>
|
||||||
<BR>
|
<BR>
|
||||||
<BR><BR>
|
<BR><BR>
|
||||||
--------------------------------<BR>
|
--------------------------------<BR>
|
||||||
@@ -92,7 +93,7 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
|||||||
<BR><BR>
|
<BR><BR>
|
||||||
`
|
`
|
||||||
// <QR>http://weixin.qq.com/r/tkkDGzTERmk5rXB49xyk</QR>
|
// <QR>http://weixin.qq.com/r/tkkDGzTERmk5rXB49xyk</QR>
|
||||||
orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel)
|
orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel, globals.StoreName)
|
||||||
return fmt.Sprintf(strings.Replace(orderFmt, "\n", "", -1), orderParams...)
|
return fmt.Sprintf(strings.Replace(orderFmt, "\n", "", -1), orderParams...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
|||||||
expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour)
|
expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour)
|
||||||
}
|
}
|
||||||
orderFmt := `
|
orderFmt := `
|
||||||
<big> 京西菜市**
|
<big> %s**
|
||||||
手机买菜上京西*
|
手机买菜上京西*
|
||||||
极速到家送惊喜*
|
极速到家送惊喜*
|
||||||
------------------------------*
|
------------------------------*
|
||||||
@@ -58,6 +58,7 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
|||||||
--------------------------------*
|
--------------------------------*
|
||||||
`
|
`
|
||||||
orderParams := []interface{}{
|
orderParams := []interface{}{
|
||||||
|
globals.StoreName,
|
||||||
utils.Time2Str(order.OrderCreatedAt),
|
utils.Time2Str(order.OrderCreatedAt),
|
||||||
utils.Time2Str(expectedDeliveryTime),
|
utils.Time2Str(expectedDeliveryTime),
|
||||||
order.VendorOrderID,
|
order.VendorOrderID,
|
||||||
@@ -82,16 +83,80 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
|||||||
<S020>商品质量问题请联系:*
|
<S020>商品质量问题请联系:*
|
||||||
<S020>%s:%s*
|
<S020>%s:%s*
|
||||||
*
|
*
|
||||||
更多信息请关注官方微信: 京西菜市*
|
更多信息请关注官方微信: %s*
|
||||||
--------------------------------
|
--------------------------------
|
||||||
--------------------------------
|
--------------------------------
|
||||||
*<BEEP13500,3,2,1>*
|
*<BEEP13500,3,2,1>*
|
||||||
`
|
`
|
||||||
// <QR>http://weixin.qq.com/r/tkkDGzTERmk5rXB49xyk</QR>
|
// <QR>http://weixin.qq.com/r/tkkDGzTERmk5rXB49xyk</QR>
|
||||||
orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel)
|
orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel, globals.StoreName)
|
||||||
return fmt.Sprintf(strings.Replace(orderFmt, "\n", "", -1), escapeString4Printer(orderParams)...)
|
return fmt.Sprintf(strings.Replace(orderFmt, "\n", "", -1), escapeString4Printer(orderParams)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *PrinterHandler) getOrderContent2(order *model.GoodsOrder, storeTel string) (content string) {
|
||||||
|
expectedDeliveryTime := order.ExpectedDeliveredTime
|
||||||
|
if utils.IsTimeZero(expectedDeliveryTime) {
|
||||||
|
expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour)
|
||||||
|
}
|
||||||
|
orderFmt := `
|
||||||
|
|7 %s
|
||||||
|
|5 手机买菜上京西
|
||||||
|
|5 极速到家送惊喜
|
||||||
|
|5--------------------------------
|
||||||
|
|5下单时间: %s
|
||||||
|
|5预计送达: %s
|
||||||
|
|5订单编号: %s
|
||||||
|
|5
|
||||||
|
|7%s\#%d
|
||||||
|
|5
|
||||||
|
|2%s
|
||||||
|
|5客户: %s
|
||||||
|
|5电话: %s
|
||||||
|
|5地址: %s
|
||||||
|
|5
|
||||||
|
|5客户备注:
|
||||||
|
|7%s
|
||||||
|
|5
|
||||||
|
|6实际支付: %s
|
||||||
|
|5
|
||||||
|
|5商品明细:
|
||||||
|
|5品名 数量 单价 小计
|
||||||
|
|5--------------------------------
|
||||||
|
`
|
||||||
|
orderParams := []interface{}{
|
||||||
|
globals.StoreName,
|
||||||
|
utils.Time2Str(order.OrderCreatedAt),
|
||||||
|
utils.Time2Str(expectedDeliveryTime),
|
||||||
|
order.VendorOrderID,
|
||||||
|
jxutils.GetVendorName(order.VendorID),
|
||||||
|
order.OrderSeq,
|
||||||
|
order.VendorOrderID,
|
||||||
|
order.ConsigneeName,
|
||||||
|
order.ConsigneeMobile,
|
||||||
|
order.ConsigneeAddress,
|
||||||
|
order.BuyerComment,
|
||||||
|
jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice),
|
||||||
|
}
|
||||||
|
for _, sku := range order.Skus {
|
||||||
|
orderFmt += `|5%s`
|
||||||
|
orderFmt += `|5%8s%10s%10s`
|
||||||
|
orderParams = append(orderParams, sku.SkuName, "x"+utils.Int2Str(sku.Count), jxutils.IntPrice2StandardCurrencyString(sku.SalePrice), jxutils.IntPrice2StandardCurrencyString(sku.SalePrice*int64(sku.Count)))
|
||||||
|
}
|
||||||
|
orderFmt += `
|
||||||
|
|5
|
||||||
|
|6共%d种%d件商品
|
||||||
|
|5--------------------------------
|
||||||
|
|5商品质量问题请联系:
|
||||||
|
|5%s:%s
|
||||||
|
|5
|
||||||
|
|5更多信息请关注官方微信: %s
|
||||||
|
|5--------------------------------
|
||||||
|
|5--------------------------------
|
||||||
|
`
|
||||||
|
orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel, globals.StoreName)
|
||||||
|
return fmt.Sprintf(orderFmt, escapeString4Printer(orderParams)...)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *PrinterHandler) GetVendorID() int {
|
func (c *PrinterHandler) GetVendorID() int {
|
||||||
return model.VendorIDXiaoWM
|
return model.VendorIDXiaoWM
|
||||||
}
|
}
|
||||||
@@ -131,10 +196,20 @@ func (c *PrinterHandler) GetPrinterStatus(ctx *jxcontext.Context, printerNumber,
|
|||||||
|
|
||||||
func (c *PrinterHandler) PrintOrder(ctx *jxcontext.Context, store *model.Store, order *model.GoodsOrder) (printerStatus *partner.PrinterStatus, err error) {
|
func (c *PrinterHandler) PrintOrder(ctx *jxcontext.Context, store *model.Store, order *model.GoodsOrder) (printerStatus *partner.PrinterStatus, err error) {
|
||||||
globals.SugarLogger.Debugf("xiaowm PrintOrderByOrder orderID:%s", order.VendorOrderID)
|
globals.SugarLogger.Debugf("xiaowm PrintOrderByOrder orderID:%s", order.VendorOrderID)
|
||||||
content := c.getOrderContent(order, store.Tel1)
|
var content string
|
||||||
|
if isV500(store.PrinterSN) {
|
||||||
|
content = c.getOrderContent2(order, store.Tel1)
|
||||||
|
} else {
|
||||||
|
content = c.getOrderContent(order, store.Tel1)
|
||||||
|
}
|
||||||
return c.PrintMsg(ctx, store.PrinterSN, store.PrinterKey, order.VendorOrderID, content)
|
return c.PrintMsg(ctx, store.PrinterSN, store.PrinterKey, order.VendorOrderID, content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isV500(printerNo string) bool {
|
||||||
|
printerNoNum := utils.Str2Int64WithDefault("1"+printerNo, 0)
|
||||||
|
return printerNoNum > 1000000000
|
||||||
|
}
|
||||||
|
|
||||||
func (c *PrinterHandler) RegisterPrinter(ctx *jxcontext.Context, printerNumber, notUsed, printerName string) (newID1, printerToken string, err error) {
|
func (c *PrinterHandler) RegisterPrinter(ctx *jxcontext.Context, printerNumber, notUsed, printerName string) (newID1, printerToken string, err error) {
|
||||||
globals.SugarLogger.Debugf("xiaowm RegisterPrinter printerNumber:%s", printerNumber)
|
globals.SugarLogger.Debugf("xiaowm RegisterPrinter printerNumber:%s", printerNumber)
|
||||||
if printerNumber == "" { //len(printerNumber) != len("7JizmSyiXNzkggaqU") {
|
if printerNumber == "" { //len(printerNumber) != len("7JizmSyiXNzkggaqU") {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
|||||||
expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour)
|
expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour)
|
||||||
}
|
}
|
||||||
orderFmt := `
|
orderFmt := `
|
||||||
<FS2><center>京西菜市</center></FS2>\n\n
|
<FS2><center>%s</center></FS2>\n\n
|
||||||
<center>手机买菜上京西</center>
|
<center>手机买菜上京西</center>
|
||||||
<center>极速到家送惊喜</center>\n
|
<center>极速到家送惊喜</center>\n
|
||||||
--------------------------------
|
--------------------------------
|
||||||
@@ -57,6 +57,7 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
|||||||
品名 数量 单价 小计\n
|
品名 数量 单价 小计\n
|
||||||
--------------------------------\n`
|
--------------------------------\n`
|
||||||
orderParams := []interface{}{
|
orderParams := []interface{}{
|
||||||
|
globals.StoreName,
|
||||||
utils.Time2Str(order.OrderCreatedAt),
|
utils.Time2Str(order.OrderCreatedAt),
|
||||||
utils.Time2Str(expectedDeliveryTime),
|
utils.Time2Str(expectedDeliveryTime),
|
||||||
order.VendorOrderID,
|
order.VendorOrderID,
|
||||||
@@ -81,12 +82,12 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
|||||||
--------------------------------\n
|
--------------------------------\n
|
||||||
<center><FH2>商品质量问题请联系:</FH2></center>
|
<center><FH2>商品质量问题请联系:</FH2></center>
|
||||||
<center><FH2>%s:%s</FH2></center>\n
|
<center><FH2>%s:%s</FH2></center>\n
|
||||||
更多信息请关注官方微信: 京西菜市\n
|
更多信息请关注官方微信: %s\n
|
||||||
--------------------------------\n
|
--------------------------------\n
|
||||||
--------------------------------\n
|
--------------------------------\n
|
||||||
`
|
`
|
||||||
// <QR>http://weixin.qq.com/r/tkkDGzTERmk5rXB49xyk</QR>
|
// <QR>http://weixin.qq.com/r/tkkDGzTERmk5rXB49xyk</QR>
|
||||||
orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel)
|
orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel, globals.StoreName)
|
||||||
return strings.Replace(fmt.Sprintf(strings.Replace(orderFmt, "\n", "", -1), orderParams...), "\\n", "\r\n", -1)
|
return strings.Replace(fmt.Sprintf(strings.Replace(orderFmt, "\n", "", -1), orderParams...), "\\n", "\r\n", -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
|||||||
expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour)
|
expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour)
|
||||||
}
|
}
|
||||||
orderFmt := `
|
orderFmt := `
|
||||||
<S2><C>京西菜市</C></S2><RN><RN>
|
<S2><C>%s</C></S2><RN><RN>
|
||||||
<C>手机买菜上京西</C>
|
<C>手机买菜上京西</C>
|
||||||
<C>极速到家送惊喜</C><RN>
|
<C>极速到家送惊喜</C><RN>
|
||||||
********************************
|
********************************
|
||||||
@@ -58,6 +58,7 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
|||||||
品名 数量 单价 小计<RN>
|
品名 数量 单价 小计<RN>
|
||||||
********************************<RN>`
|
********************************<RN>`
|
||||||
orderParams := []interface{}{
|
orderParams := []interface{}{
|
||||||
|
globals.StoreName,
|
||||||
utils.Time2Str(order.OrderCreatedAt),
|
utils.Time2Str(order.OrderCreatedAt),
|
||||||
utils.Time2Str(expectedDeliveryTime),
|
utils.Time2Str(expectedDeliveryTime),
|
||||||
order.VendorOrderID,
|
order.VendorOrderID,
|
||||||
@@ -82,12 +83,12 @@ func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel strin
|
|||||||
********************************<RN>
|
********************************<RN>
|
||||||
<C><H2>商品质量问题请联系:</H2></C>
|
<C><H2>商品质量问题请联系:</H2></C>
|
||||||
<C><H2>%s:%s</H2></C><RN>
|
<C><H2>%s:%s</H2></C><RN>
|
||||||
更多信息请关注官方微信: 京西菜市<RN>
|
更多信息请关注官方微信: %s<RN>
|
||||||
********************************<RN>
|
********************************<RN>
|
||||||
********************************<RN>
|
********************************<RN>
|
||||||
`
|
`
|
||||||
// <QR>http://weixin.qq.com/r/tkkDGzTERmk5rXB49xyk</QR>
|
// <QR>http://weixin.qq.com/r/tkkDGzTERmk5rXB49xyk</QR>
|
||||||
orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel)
|
orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel, globals.StoreName)
|
||||||
return fmt.Sprintf(strings.Replace(orderFmt, "\n", "", -1), orderParams...)
|
return fmt.Sprintf(strings.Replace(orderFmt, "\n", "", -1), orderParams...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
186
business/partner/purchase/ebai/act.go
Normal file
186
business/partner/purchase/ebai/act.go
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
package ebai
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi/ebaiapi"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
func actType2Ebai(actType int) int {
|
||||||
|
if actType < model.ActOrderBegin {
|
||||||
|
return ebaiapi.ActivityTypeDirectDown
|
||||||
|
}
|
||||||
|
return ebaiapi.ActivityTypeFullDiscount
|
||||||
|
}
|
||||||
|
|
||||||
|
func actOrderRules2Ebai(actOrderRules []*model.ActOrderRule) (ebaiRules []*ebaiapi.ActivityRule) {
|
||||||
|
for _, v := range actOrderRules {
|
||||||
|
ebaiRules = append(ebaiRules, &ebaiapi.ActivityRule{
|
||||||
|
Accords: int(jxutils.IntPrice2Standard(v.SalePrice)),
|
||||||
|
Sale: int(jxutils.IntPrice2Standard(v.DeductPrice)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return ebaiRules
|
||||||
|
}
|
||||||
|
|
||||||
|
func actStoreSu2Ebai4Add(oneStoreActSku []*model.ActStoreSku2) (skus []*ebaiapi.ActivitySkuInfo4Add) {
|
||||||
|
for _, v := range oneStoreActSku {
|
||||||
|
if model.IsSyncStatusNeedCreate(v.SyncStatus) {
|
||||||
|
skus = append(skus, &ebaiapi.ActivitySkuInfo4Add{
|
||||||
|
SkuID: v.VendorSkuID,
|
||||||
|
SpecialPrice: v.ActPrice,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return skus
|
||||||
|
}
|
||||||
|
|
||||||
|
func actStoreSu2Ebai4Update(oneStoreActSku []*model.ActStoreSku2) (skus []*ebaiapi.ActivitySkuInfo4Update) {
|
||||||
|
for _, v := range oneStoreActSku {
|
||||||
|
if model.IsSyncStatusNeedUpdate(v.SyncStatus) {
|
||||||
|
skus = append(skus, &ebaiapi.ActivitySkuInfo4Update{
|
||||||
|
ShopID: utils.Int2Str(v.StoreID),
|
||||||
|
SkuID: v.VendorSkuID,
|
||||||
|
SpecialPrice: v.ActPrice,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return skus
|
||||||
|
}
|
||||||
|
|
||||||
|
func actStoreSu2Ebai4Delete(oneStoreActSku []*model.ActStoreSku2) (skus []string) {
|
||||||
|
for _, v := range oneStoreActSku {
|
||||||
|
if model.IsSyncStatusNeedDelete(v.SyncStatus) {
|
||||||
|
skus = append(skus, v.VendorSkuID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return skus
|
||||||
|
}
|
||||||
|
|
||||||
|
func act2EbaiActivity(act *model.Act2, actOrderRules []*model.ActOrderRule) (activity *ebaiapi.ActivityInfo) {
|
||||||
|
activity = &ebaiapi.ActivityInfo{
|
||||||
|
ActivityName: act.Name,
|
||||||
|
ActivityType: actType2Ebai(act.Type),
|
||||||
|
StartTime: act.BeginAt.Unix(),
|
||||||
|
EndTime: act.EndAt.Unix(),
|
||||||
|
ActivityDesc: act.Advertising,
|
||||||
|
ShowCategory: act.Name,
|
||||||
|
PromotionSkuDesc: act.Name,
|
||||||
|
Rule: actOrderRules2Ebai(actOrderRules),
|
||||||
|
}
|
||||||
|
return activity
|
||||||
|
}
|
||||||
|
|
||||||
|
func createOneShopAct(shopID string, activity *ebaiapi.ActivityInfo, oneStoreActSku []*model.ActStoreSku2) (ebaiActIDStr string, err error) {
|
||||||
|
if globals.EnableEbaiStoreWrite {
|
||||||
|
ebaiActID, err := api.EbaiAPI.ActivityCreate(shopID, 0, 0, activity)
|
||||||
|
if err == nil {
|
||||||
|
ebaiActIDStr = utils.Int64ToStr(ebaiActID)
|
||||||
|
_, err = ActivitySkuAddBatch(ebaiActID, shopID, 0, activity.ActivityType, actStoreSu2Ebai4Add(oneStoreActSku), false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ebaiActIDStr = utils.Int64ToStr(jxutils.GenFakeID())
|
||||||
|
}
|
||||||
|
return ebaiActIDStr, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ActivitySkuAddBatch(activityID int64, shopID string, baiduShopID int64, activityType int, skuList []*ebaiapi.ActivitySkuInfo4Add, isSkuIDCustom bool) (successIDs []string, err error) {
|
||||||
|
return api.EbaiAPI.ActivitySkuAddBatch(activityID, shopID, baiduShopID, activityType, skuList, isSkuIDCustom)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ActivitySkuDeleteBatch(activityID int64, shopID string, baiduShopID int64, skuIDs []string, isSkuIDCustom bool) (successIDs []string, err error) {
|
||||||
|
return api.EbaiAPI.ActivitySkuDeleteBatch(activityID, shopID, baiduShopID, skuIDs, isSkuIDCustom)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ActivitySkuUpdateBatch(activityID int64, actSkuInfoList []*ebaiapi.ActivitySkuInfo4Update) (faildInfoList []string, err error) {
|
||||||
|
return api.EbaiAPI.ActivitySkuUpdateBatch(activityID, actSkuInfoList)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
|
||||||
|
activity := act2EbaiActivity(act, actOrderRules)
|
||||||
|
if act.Type < model.ActOrderBegin {
|
||||||
|
actStoreSkuMap := partner.ActStoreSku2Map(actStoreSku)
|
||||||
|
task := tasksch.NewParallelTask("ebai CreateAct", nil, ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
store := batchItemList[0].(*model.ActStore2)
|
||||||
|
store.VendorActID, err = createOneShopAct(utils.Int2Str(store.StoreID), activity, actStoreSkuMap[store.StoreID])
|
||||||
|
return nil, err
|
||||||
|
}, actStoreMap)
|
||||||
|
tasksch.HandleTask(task, parentTask, true).Run()
|
||||||
|
_, err = task.GetResult(0)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
|
||||||
|
if act.Type < model.ActOrderBegin {
|
||||||
|
actStoreSkuMap := partner.ActStoreSku2Map(actStoreSku)
|
||||||
|
if len(actStoreMap2Remove) > 0 {
|
||||||
|
if err = c.CancelAct(ctx, parentTask, act, actStoreMap2Remove, nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, v := range actStoreMap2Remove {
|
||||||
|
delete(actStoreSkuMap, v.StoreID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(actStoreMap2Add) > 0 {
|
||||||
|
if err = c.CreateAct(ctx, parentTask, act, actOrderRules, actStoreMap2Add, actStoreSku); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, v := range actStoreMap2Add {
|
||||||
|
delete(actStoreSkuMap, v.StoreID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
task := tasksch.NewParallelTask("ebai UpdateAct", nil, ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
v := batchItemList[0].(*model.ActStore2)
|
||||||
|
if storeSkus := actStoreSkuMap[v.StoreID]; storeSkus != nil {
|
||||||
|
if list := actStoreSu2Ebai4Delete(storeSkus); len(list) > 0 {
|
||||||
|
if _, err = ActivitySkuDeleteBatch(utils.Str2Int64(v.VendorActID), utils.Int2Str(v.StoreID), 0, list, false); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if list := actStoreSu2Ebai4Add(storeSkus); len(list) > 0 {
|
||||||
|
if _, err = ActivitySkuAddBatch(utils.Str2Int64(v.VendorActID), utils.Int2Str(v.StoreID), 0, actType2Ebai(act.Type), list, false); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if list := actStoreSu2Ebai4Update(storeSkus); len(list) > 0 {
|
||||||
|
if _, err = ActivitySkuUpdateBatch(utils.Str2Int64(v.VendorActID), list); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}, actStoreMap2Update)
|
||||||
|
tasksch.HandleTask(task, parentTask, true).Run()
|
||||||
|
_, err = task.GetResult(0)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) CancelAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
|
||||||
|
if act.Type < model.ActOrderBegin {
|
||||||
|
task := tasksch.NewParallelTask("ebai DeleteAct", nil, ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
v := batchItemList[0].(*model.ActStore2)
|
||||||
|
if globals.EnableEbaiStoreWrite {
|
||||||
|
err = api.EbaiAPI.ActivityDisable(utils.Str2Int64(v.VendorActID), utils.Int2Str(v.StoreID), 0, 0)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}, actStoreMap)
|
||||||
|
tasksch.HandleTask(task, parentTask, true).Run()
|
||||||
|
_, err = task.GetResult(0)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -19,10 +19,8 @@ func OnCallbackMsg(msg *ebaiapi.CallbackMsg) (response *ebaiapi.CallbackResponse
|
|||||||
}
|
}
|
||||||
}, jxutils.ComposeUniversalOrderID(orderID, model.VendorIDEBAI))
|
}, jxutils.ComposeUniversalOrderID(orderID, model.VendorIDEBAI))
|
||||||
}
|
}
|
||||||
if msg.Cmd == ebaiapi.CmdOrderPartRefund || msg.Cmd == ebaiapi.CmdOrderUserCancel || msg.Cmd == ebaiapi.CmdOrderDeliveryStatus {
|
if /*msg.Cmd == ebaiapi.CmdOrderPartRefund || msg.Cmd == ebaiapi.CmdOrderUserCancel || */ msg.Cmd == ebaiapi.CmdOrderDeliveryStatus {
|
||||||
utils.CallFuncAsync(func() {
|
response = CurPurchaseHandler.OnFinancialMsg(msg)
|
||||||
OnFinancialMsg(msg)
|
|
||||||
})
|
|
||||||
} else if msg.Cmd == ebaiapi.CmdShopMsgPush {
|
} else if msg.Cmd == ebaiapi.CmdShopMsgPush {
|
||||||
response = CurPurchaseHandler.onShopMsgPush(msg)
|
response = CurPurchaseHandler.onShopMsgPush(msg)
|
||||||
}
|
}
|
||||||
@@ -31,7 +29,11 @@ func OnCallbackMsg(msg *ebaiapi.CallbackMsg) (response *ebaiapi.CallbackResponse
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetOrderIDFromMsg(msg *ebaiapi.CallbackMsg) string {
|
func GetOrderIDFromMsg(msg *ebaiapi.CallbackMsg) string {
|
||||||
if orderID := msg.Body["order_id"]; orderID != nil {
|
return GetOrderIDFromMap(msg.Body)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetOrderIDFromMap(orderMap map[string]interface{}) string {
|
||||||
|
if orderID := orderMap["order_id"]; orderID != nil {
|
||||||
if tryOrderID, ok := orderID.(string); ok {
|
if tryOrderID, ok := orderID.(string); ok {
|
||||||
return tryOrderID
|
return tryOrderID
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ func init() {
|
|||||||
|
|
||||||
func EbaiBusStatus2JxStatus(ebaiStatus int) int {
|
func EbaiBusStatus2JxStatus(ebaiStatus int) int {
|
||||||
if ebaiStatus == ebaiapi.ShopBusStatusHaveRest || ebaiStatus == ebaiapi.ShopBusStatusSuspended {
|
if ebaiStatus == ebaiapi.ShopBusStatusHaveRest || ebaiStatus == ebaiapi.ShopBusStatusSuspended {
|
||||||
return model.StoreStatusClosed
|
return model.StoreStatusHaveRest
|
||||||
}
|
}
|
||||||
return model.StoreStatusOpened
|
return model.StoreStatusOpened
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,25 +9,33 @@ import (
|
|||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) OnFinancialMsg(msg *ebaiapi.CallbackMsg) (response *ebaiapi.CallbackResponse) {
|
||||||
|
utils.CallFuncAsync(func() {
|
||||||
|
response = p.onFinancialMsg(msg)
|
||||||
|
})
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
// 存储饿百退款订单结账信息
|
// 存储饿百退款订单结账信息
|
||||||
func OnFinancialMsg(msg *ebaiapi.CallbackMsg) (err error) {
|
func (p *PurchaseHandler) onFinancialMsg(msg *ebaiapi.CallbackMsg) (response *ebaiapi.CallbackResponse) {
|
||||||
|
var err error
|
||||||
if msg.Cmd == ebaiapi.CmdOrderPartRefund { // 部分退款处理
|
if msg.Cmd == ebaiapi.CmdOrderPartRefund { // 部分退款处理
|
||||||
if utils.Int64ToStr(utils.MustInterface2Int64(msg.Body["status"])) == ebaiapi.OrderPartRefundSuccess {
|
if int(utils.MustInterface2Int64(msg.Body["status"])) == ebaiapi.OrderPartRefundSuccess {
|
||||||
// 获取到部分退款订单id
|
// 获取到部分退款订单id
|
||||||
afsOrderID := utils.Interface2String(msg.Body["order_id"])
|
afsOrderID := GetOrderIDFromMsg(msg)
|
||||||
// 处理部分退款信息
|
// 处理部分退款信息
|
||||||
orderData, err2 := api.EbaiAPI.OrderPartrefundGet(afsOrderID)
|
orderData, err2 := api.EbaiAPI.OrderPartRefundGet(afsOrderID)
|
||||||
if err = err2; err == nil {
|
if err = err2; err == nil {
|
||||||
afsOrder := CurPurchaseHandler.AfsOrderDetail2Financial(orderData)
|
afsOrder := CurPurchaseHandler.AfsOrderDetail2Financial(orderData)
|
||||||
err = partner.CurOrderManager.SaveAfsOrderFinancialInfo(afsOrder)
|
err = partner.CurOrderManager.SaveAfsOrderFinancialInfo(afsOrder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if msg.Cmd == ebaiapi.CmdOrderUserCancel { // 全额退款处理
|
} else if msg.Cmd == ebaiapi.CmdOrderUserCancel { // 全额退款处理
|
||||||
messageType := utils.Int64ToStr(utils.MustInterface2Int64(msg.Body["type"]))
|
messageType := int(utils.MustInterface2Int64(msg.Body["type"]))
|
||||||
if utils.Int64ToStr(utils.MustInterface2Int64(msg.Body["cancel_type"])) == ebaiapi.OrderUserCancelTypeAfterSale &&
|
if int(utils.MustInterface2Int64(msg.Body["cancel_type"])) == ebaiapi.OrderUserCancelTypeAfterSale &&
|
||||||
(messageType == ebaiapi.OrderUserCancelCSAgreed || messageType == ebaiapi.OrderUserCancelMerchantAgreed) {
|
(messageType == ebaiapi.OrderUserCancelCSAgreed || messageType == ebaiapi.OrderUserCancelMerchantAgreed) {
|
||||||
globals.SugarLogger.Debug(utils.Interface2String(msg.Body["order_id"])) // 获得退款订单ID,去本地数据库拿?饿百消息推送只给了订单号,但是没有查询全额退款的接口,只有部分退款才可以查询
|
afsOrderID := GetOrderIDFromMsg(msg)
|
||||||
afsOrderID := utils.Interface2String(msg.Body["order_id"])
|
// 获得退款订单ID,去本地数据库拿?饿百消息推送只给了订单号,但是没有查询全额退款的接口,只有部分退款才可以查询
|
||||||
orderFinancial, err := partner.CurOrderManager.LoadOrderFinancial(afsOrderID, model.VendorIDEBAI)
|
orderFinancial, err := partner.CurOrderManager.LoadOrderFinancial(afsOrderID, model.VendorIDEBAI)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
globals.SugarLogger.Debug(utils.Format4Output(orderFinancial, false))
|
globals.SugarLogger.Debug(utils.Format4Output(orderFinancial, false))
|
||||||
@@ -45,15 +53,15 @@ func OnFinancialMsg(msg *ebaiapi.CallbackMsg) (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, msg.Cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PurchaseHandler) OrderFinancialDetail2Refund(orderFinancial *model.OrderFinancial, msg *ebaiapi.CallbackMsg) (afsOrder *model.AfsOrder) {
|
func (p *PurchaseHandler) OrderFinancialDetail2Refund(orderFinancial *model.OrderFinancial, msg *ebaiapi.CallbackMsg) (afsOrder *model.AfsOrder) {
|
||||||
afsOrder = &model.AfsOrder{
|
afsOrder = &model.AfsOrder{
|
||||||
VendorID: model.VendorIDEBAI,
|
VendorID: model.VendorIDEBAI,
|
||||||
AfsOrderID: utils.Interface2String(msg.Body["order_id"]),
|
AfsOrderID: GetOrderIDFromMsg(msg),
|
||||||
VendorOrderID: utils.Interface2String(msg.Body["order_id"]),
|
VendorOrderID: GetOrderIDFromMsg(msg),
|
||||||
AfsCreateAt: utils.Timestamp2Time(msg.Timestamp),
|
AfsCreatedAt: utils.Timestamp2Time(msg.Timestamp),
|
||||||
// BoxMoney: orderFinancial.BoxMoney, // 饿百的餐盒费已经拆分到单条Sku里面,退款时直接计算用户支付sku金额就好了
|
// BoxMoney: orderFinancial.BoxMoney, // 饿百的餐盒费已经拆分到单条Sku里面,退款时直接计算用户支付sku金额就好了
|
||||||
// SkuBoxMoney: orderFinancial.SkuBoxMoney,
|
// SkuBoxMoney: orderFinancial.SkuBoxMoney,
|
||||||
FreightUserMoney: orderFinancial.FreightMoney,
|
FreightUserMoney: orderFinancial.FreightMoney,
|
||||||
@@ -78,10 +86,9 @@ func (p *PurchaseHandler) OrderFinancialDetail2Refund(orderFinancial *model.Orde
|
|||||||
}
|
}
|
||||||
for _, sku := range orderFinancial.Skus {
|
for _, sku := range orderFinancial.Skus {
|
||||||
orderSkuFinancial := &model.OrderSkuFinancial{
|
orderSkuFinancial := &model.OrderSkuFinancial{
|
||||||
VendorID: sku.VendorID,
|
VendorID: sku.VendorID,
|
||||||
VendorOrderID: sku.VendorOrderID,
|
VendorOrderID: sku.VendorOrderID,
|
||||||
VendorOrderID2: sku.VendorOrderID2,
|
AfsOrderID: sku.VendorOrderID,
|
||||||
AfsOrderID: sku.VendorOrderID,
|
|
||||||
// ConfirmTime: afsOrder.AfsCreateAt,
|
// ConfirmTime: afsOrder.AfsCreateAt,
|
||||||
VendorStoreID: afsOrder.VendorStoreID,
|
VendorStoreID: afsOrder.VendorStoreID,
|
||||||
StoreID: afsOrder.StoreID,
|
StoreID: afsOrder.StoreID,
|
||||||
@@ -106,8 +113,8 @@ func (p *PurchaseHandler) OrderFinancialDetail2Refund(orderFinancial *model.Orde
|
|||||||
func (p *PurchaseHandler) AfsOrderDetail2Financial(orderData map[string]interface{}) (afsOrder *model.AfsOrder) {
|
func (p *PurchaseHandler) AfsOrderDetail2Financial(orderData map[string]interface{}) (afsOrder *model.AfsOrder) {
|
||||||
afsOrder = &model.AfsOrder{
|
afsOrder = &model.AfsOrder{
|
||||||
VendorID: model.VendorIDEBAI,
|
VendorID: model.VendorIDEBAI,
|
||||||
AfsOrderID: utils.Interface2String(orderData["order_id"]),
|
AfsOrderID: GetOrderIDFromMap(orderData),
|
||||||
VendorOrderID: utils.Interface2String(orderData["order_id"]),
|
VendorOrderID: GetOrderIDFromMap(orderData),
|
||||||
}
|
}
|
||||||
order, err := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID)
|
order, err := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -125,7 +132,7 @@ func (p *PurchaseHandler) AfsOrderDetail2Financial(orderData map[string]interfac
|
|||||||
afsOrder.PmRefundMoney = orderFinancial.PmMoney - utils.MustInterface2Int64(orderData["commission"])
|
afsOrder.PmRefundMoney = orderFinancial.PmMoney - utils.MustInterface2Int64(orderData["commission"])
|
||||||
} else {
|
} else {
|
||||||
// 此处应该报错
|
// 此处应该报错
|
||||||
globals.SugarLogger.Warnf("ebai AfsOrderDetail2Financial, afsOrderID:%s is not found from partner.CurOrderManager.LoadOrderFinancial", afsOrder.VendorOrderID)
|
// globals.SugarLogger.Warnf("ebai AfsOrderDetail2Financial, afsOrderID:%s is not found from partner.CurOrderManager.LoadOrderFinancial", afsOrder.VendorOrderID)
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
if orderData["refund_detail"] != nil {
|
if orderData["refund_detail"] != nil {
|
||||||
@@ -149,7 +156,7 @@ func (p *PurchaseHandler) AfsOrderDetail2Financial(orderData map[string]interfac
|
|||||||
afsOrder.PmSubsidyMoney += orderSkuFinancial.PmSubsidyMoney
|
afsOrder.PmSubsidyMoney += orderSkuFinancial.PmSubsidyMoney
|
||||||
}
|
}
|
||||||
if len(refundDetail) > 0 {
|
if len(refundDetail) > 0 {
|
||||||
afsOrder.AfsCreateAt = getTimeFromInterface(refundDetail[0].(map[string]interface{})["apply_time"])
|
afsOrder.AfsCreatedAt = getTimeFromInterface(refundDetail[0].(map[string]interface{})["apply_time"])
|
||||||
} else {
|
} else {
|
||||||
globals.SugarLogger.Warnf("ebai AfsOrderDetail2Financial, orderID:%s have no refund_detail", afsOrder.VendorOrderID)
|
globals.SugarLogger.Warnf("ebai AfsOrderDetail2Financial, orderID:%s have no refund_detail", afsOrder.VendorOrderID)
|
||||||
}
|
}
|
||||||
@@ -168,7 +175,7 @@ func (p *PurchaseHandler) OnOrderDetail(result map[string]interface{}, operation
|
|||||||
// func (p *PurchaseHandler) GetTrueEbaiOrder(result1 map[string]interface{}) (result2 map[string]interface{}) {
|
// func (p *PurchaseHandler) GetTrueEbaiOrder(result1 map[string]interface{}) (result2 map[string]interface{}) {
|
||||||
// order := result1["order"].(map[string]interface{})
|
// order := result1["order"].(map[string]interface{})
|
||||||
// if utils.MustInterface2Int64(order["down_flag"]) == 1 {
|
// if utils.MustInterface2Int64(order["down_flag"]) == 1 {
|
||||||
// result, err := api.EbaiAPI.OrderGet(utils.Interface2String(order["order_id"]))
|
// result, err := api.EbaiAPI.OrderGet(GetOrderIDFromMap(order))
|
||||||
// if err == nil {
|
// if err == nil {
|
||||||
// return p.GetTrueEbaiOrder(result)
|
// return p.GetTrueEbaiOrder(result)
|
||||||
// }
|
// }
|
||||||
@@ -181,7 +188,7 @@ func (p *PurchaseHandler) OrderDetail2Financial(result map[string]interface{}) (
|
|||||||
VendorID: model.VendorIDEBAI,
|
VendorID: model.VendorIDEBAI,
|
||||||
}
|
}
|
||||||
order1 := result["order"].(map[string]interface{})
|
order1 := result["order"].(map[string]interface{})
|
||||||
orderFinancial.VendorOrderID = utils.Interface2String(order1["order_id"])
|
orderFinancial.VendorOrderID = GetOrderIDFromMap(order1)
|
||||||
orderFinancial.VendorOrderID2 = utils.Interface2String(order1["eleme_order_id"])
|
orderFinancial.VendorOrderID2 = utils.Interface2String(order1["eleme_order_id"])
|
||||||
// orderFinancial.DeliveryConfirmTime = getTimeFromInterface(order1["finished_time"])
|
// orderFinancial.DeliveryConfirmTime = getTimeFromInterface(order1["finished_time"])
|
||||||
orderFinancial.TotalDiscountMoney = utils.MustInterface2Int64(order1["discount_fee"])
|
orderFinancial.TotalDiscountMoney = utils.MustInterface2Int64(order1["discount_fee"])
|
||||||
@@ -224,9 +231,8 @@ func (p *PurchaseHandler) OrderDetail2Financial(result map[string]interface{}) (
|
|||||||
for _, y := range x.([]interface{}) {
|
for _, y := range x.([]interface{}) {
|
||||||
product := y.(map[string]interface{})
|
product := y.(map[string]interface{})
|
||||||
orderSkuFinancial := &model.OrderSkuFinancial{
|
orderSkuFinancial := &model.OrderSkuFinancial{
|
||||||
VendorID: orderFinancial.VendorID,
|
VendorID: orderFinancial.VendorID,
|
||||||
VendorOrderID: orderFinancial.VendorOrderID,
|
VendorOrderID: orderFinancial.VendorOrderID,
|
||||||
VendorOrderID2: orderFinancial.VendorOrderID2,
|
|
||||||
// OrderFinancialID: orderFinancial.VendorOrderID,
|
// OrderFinancialID: orderFinancial.VendorOrderID,
|
||||||
// ConfirmTime: getTimeFromInterface(order1["create_time"]),
|
// ConfirmTime: getTimeFromInterface(order1["create_time"]),
|
||||||
VendorStoreID: utils.Interface2String(shop["baidu_shop_id"]),
|
VendorStoreID: utils.Interface2String(shop["baidu_shop_id"]),
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ func TestOnFinancialMsg(t *testing.T) {
|
|||||||
// msg.Body["type"] = json.Number("40")
|
// msg.Body["type"] = json.Number("40")
|
||||||
// msg.Body["cancel_type"] = json.Number("2")
|
// msg.Body["cancel_type"] = json.Number("2")
|
||||||
|
|
||||||
res := OnFinancialMsg(msg)
|
res := CurPurchaseHandler.onAfsOrderMsg(msg)
|
||||||
fmt.Println(res)
|
fmt.Println(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/autonavi"
|
"git.rosy.net.cn/baseapi/platformapi/autonavi"
|
||||||
"git.rosy.net.cn/baseapi/platformapi/ebaiapi"
|
"git.rosy.net.cn/baseapi/platformapi/ebaiapi"
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
@@ -19,7 +21,8 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// acceptOrderDelay = 180 * time.Second
|
// acceptOrderDelay = 180 * time.Second
|
||||||
pickupOrderDelay = 260 * time.Second
|
// pickupOrderDelay = 260 * time.Second
|
||||||
|
pickupOrderDelay = 1 * time.Second
|
||||||
|
|
||||||
callDeliveryDelay = 10 * time.Minute
|
callDeliveryDelay = 10 * time.Minute
|
||||||
callDeliveryDelayGap = 30
|
callDeliveryDelayGap = 30
|
||||||
@@ -34,6 +37,7 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
VendorStatus2StatusMap = map[string]int{
|
VendorStatus2StatusMap = map[string]int{
|
||||||
|
ebaiapi.CmdOrderCreate: model.OrderStatusNew,
|
||||||
ebaiapi.OrderStatusNew: model.OrderStatusNew,
|
ebaiapi.OrderStatusNew: model.OrderStatusNew,
|
||||||
fakeAcceptOrder: model.OrderStatusAccepted,
|
fakeAcceptOrder: model.OrderStatusAccepted,
|
||||||
ebaiapi.OrderStatusAccepted: model.OrderStatusFinishedPickup,
|
ebaiapi.OrderStatusAccepted: model.OrderStatusFinishedPickup,
|
||||||
@@ -46,6 +50,11 @@ var (
|
|||||||
fakeUserApplyCancel: model.OrderStatusApplyCancel,
|
fakeUserApplyCancel: model.OrderStatusApplyCancel,
|
||||||
fakeUserUndoApplyCancel: model.OrderStatusUndoApplyCancel,
|
fakeUserUndoApplyCancel: model.OrderStatusUndoApplyCancel,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skuActTypeMap = map[string]int{
|
||||||
|
ebaiapi.OrderSkuDiscountTypeZhe: 1,
|
||||||
|
ebaiapi.OrderSkuDiscountTypeReduce: 1,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *PurchaseHandler) GetStatusFromVendorStatus(vendorStatus string) int {
|
func (p *PurchaseHandler) GetStatusFromVendorStatus(vendorStatus string) int {
|
||||||
@@ -68,6 +77,65 @@ func (p *PurchaseHandler) getOrder(vendorOrderID string) (order *model.GoodsOrde
|
|||||||
return order, result, err
|
return order, result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetOrder4PartRefund(vendorOrderID string) (order *model.GoodsOrder, err error) {
|
||||||
|
taskIDs := []int{1, 2}
|
||||||
|
var (
|
||||||
|
err1, err2 error
|
||||||
|
result1, result2 map[string]interface{}
|
||||||
|
)
|
||||||
|
task := tasksch.NewParallelTask("GetOrder4PartRefund", nil, jxcontext.AdminCtx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
taskID := batchItemList[0].(int)
|
||||||
|
if taskID == 1 {
|
||||||
|
result1, err1 = api.EbaiAPI.OrderGet(vendorOrderID)
|
||||||
|
} else if taskID == 2 {
|
||||||
|
result2, err2 = api.EbaiAPI.OrderPartRefundGet(vendorOrderID)
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}, taskIDs)
|
||||||
|
task.Run()
|
||||||
|
task.GetResult(0)
|
||||||
|
if err1 == nil {
|
||||||
|
order = p.Map2Order(result1)
|
||||||
|
if err2 == nil {
|
||||||
|
order.Skus = p.partRefund2OrderDetailSkuList(utils.Interface2String(result2["order_id"]), result2["order_detail"])
|
||||||
|
order.ActualPayPrice = utils.MustInterface2Int64(result2["user_fee"])
|
||||||
|
jxutils.RefreshOrderSkuRelated(order)
|
||||||
|
} else if err2Ext, ok := err2.(*utils.ErrorWithCode); !ok || err2Ext.IntCode() != ebaiapi.ErrOrderIsNotPartRefund {
|
||||||
|
err = err2
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = err1
|
||||||
|
}
|
||||||
|
return order, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) partRefund2OrderDetailSkuList(orderID string, orderDetail2 interface{}) (skuList []*model.OrderSku) {
|
||||||
|
orderDetail := orderDetail2.([]interface{})
|
||||||
|
for _, product2 := range orderDetail {
|
||||||
|
product := product2.(map[string]interface{})
|
||||||
|
skuName := product["name"].(string)
|
||||||
|
_, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(skuName)
|
||||||
|
number := int(utils.MustInterface2Int64(product["number"]))
|
||||||
|
sku := &model.OrderSku{
|
||||||
|
VendorOrderID: orderID,
|
||||||
|
VendorID: model.VendorIDEBAI,
|
||||||
|
Count: number,
|
||||||
|
SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(product[ebaiapi.KeyCustomSkuID]), 0)),
|
||||||
|
VendorSkuID: utils.Interface2String(product[ebaiapi.KeySkuID]),
|
||||||
|
SkuName: skuName,
|
||||||
|
// Weight: int(utils.Interface2Int64WithDefault(product["total_weight"], 0)) / number, // 退单这里的total_weight有BUG,这里的total_weight还是没有退单时的值
|
||||||
|
VendorPrice: utils.MustInterface2Int64(product["product_price"]),
|
||||||
|
}
|
||||||
|
sku.SalePrice, _, sku.StoreSubName = getSkuSalePrice(product)
|
||||||
|
if sku.Weight == 0 {
|
||||||
|
sku.Weight = jxutils.FormatSkuWeight(specQuality, specUnit) // 订单信息里没有重量,只有名字里尝试找
|
||||||
|
}
|
||||||
|
skuList = append(skuList, sku)
|
||||||
|
}
|
||||||
|
return skuList
|
||||||
|
}
|
||||||
|
|
||||||
func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) {
|
func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) {
|
||||||
result := orderData
|
result := orderData
|
||||||
shopMap := result["shop"].(map[string]interface{})
|
shopMap := result["shop"].(map[string]interface{})
|
||||||
@@ -93,7 +161,7 @@ func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo
|
|||||||
StatusTime: getTimeFromInterface(orderMap["create_time"]),
|
StatusTime: getTimeFromInterface(orderMap["create_time"]),
|
||||||
OriginalData: string(utils.MustMarshal(result)),
|
OriginalData: string(utils.MustMarshal(result)),
|
||||||
ActualPayPrice: utils.MustInterface2Int64(orderMap["user_fee"]),
|
ActualPayPrice: utils.MustInterface2Int64(orderMap["user_fee"]),
|
||||||
Skus: []*model.OrderSku{},
|
TotalShopMoney: utils.MustInterface2Int64(orderMap["shop_fee"]),
|
||||||
}
|
}
|
||||||
if utils.IsTimeZero(order.PickDeadline) && !utils.IsTimeZero(order.StatusTime) {
|
if utils.IsTimeZero(order.PickDeadline) && !utils.IsTimeZero(order.StatusTime) {
|
||||||
order.PickDeadline = order.StatusTime.Add(pickupOrderDelay) // 饿百要求在5分钟内拣货,不然订单会被取消
|
order.PickDeadline = order.StatusTime.Add(pickupOrderDelay) // 饿百要求在5分钟内拣货,不然订单会被取消
|
||||||
@@ -134,33 +202,58 @@ func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo
|
|||||||
product := product2.(map[string]interface{})
|
product := product2.(map[string]interface{})
|
||||||
skuName := product["product_name"].(string)
|
skuName := product["product_name"].(string)
|
||||||
_, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(skuName)
|
_, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(skuName)
|
||||||
|
productAmount := int(utils.MustInterface2Int64(product["product_amount"]))
|
||||||
sku := &model.OrderSku{
|
sku := &model.OrderSku{
|
||||||
VendorOrderID: order.VendorOrderID,
|
VendorOrderID: order.VendorOrderID,
|
||||||
VendorID: model.VendorIDEBAI,
|
VendorID: model.VendorIDEBAI,
|
||||||
Count: int(utils.MustInterface2Int64(product["product_amount"])),
|
Count: productAmount,
|
||||||
SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(product[ebaiapi.KeyCustomSkuID]), 0)),
|
SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(product[ebaiapi.KeyCustomSkuID]), 0)),
|
||||||
VendorSkuID: utils.Interface2String(product["baidu_product_id"]),
|
VendorSkuID: utils.Interface2String(product["baidu_product_id"]),
|
||||||
SkuName: skuName,
|
SkuName: skuName,
|
||||||
Weight: jxutils.FormatSkuWeight(specQuality, specUnit), // 订单信息里没有重量,只有名字里尝试找
|
Weight: int(utils.Interface2Int64WithDefault(product["total_weight"], 0)) / productAmount,
|
||||||
SalePrice: utils.MustInterface2Int64(product["product_price"]),
|
VendorPrice: utils.MustInterface2Int64(product["product_price"]),
|
||||||
// PromotionType: int(utils.MustInterface2Int64(product["promotionType"])),
|
|
||||||
}
|
}
|
||||||
|
var baiduRate int64
|
||||||
|
sku.SalePrice, baiduRate, sku.StoreSubName = getSkuSalePrice(product)
|
||||||
|
order.PmSubsidyMoney += baiduRate
|
||||||
if sku.Weight == 0 {
|
if sku.Weight == 0 {
|
||||||
sku.Weight = 222 // 如果名字里找不到缺省给半斤左右的一个特别值
|
sku.Weight = jxutils.FormatSkuWeight(specQuality, specUnit) // 订单信息里没有重量,只有名字里尝试找
|
||||||
}
|
}
|
||||||
// if product["isGift"].(bool) {
|
// if product["isGift"].(bool) {
|
||||||
// sku.SkuType = 1
|
// sku.SkuType = 1
|
||||||
// }
|
// }
|
||||||
order.Skus = append(order.Skus, sku)
|
order.Skus = append(order.Skus, sku)
|
||||||
order.SkuCount++
|
|
||||||
order.GoodsCount += sku.Count
|
|
||||||
order.SalePrice += sku.SalePrice * int64(sku.Count)
|
|
||||||
order.Weight += sku.Weight * sku.Count
|
|
||||||
}
|
}
|
||||||
// setOrederDetailFee(result, order)
|
jxutils.RefreshOrderSkuRelated(order)
|
||||||
return order
|
return order
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getSkuSalePrice(product map[string]interface{}) (salePrice, baiduRate int64, vendorActType string) {
|
||||||
|
var product2 *ebaiapi.OrderProductInfo
|
||||||
|
if err := utils.Map2StructByJson(product, &product2, true); err != nil {
|
||||||
|
return utils.MustInterface2Int64(product["product_price"]), 0, ""
|
||||||
|
}
|
||||||
|
return getSkuSalePrice2(product2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSkuSalePrice2(product *ebaiapi.OrderProductInfo) (salePrice, baiduRate int64, vendorActType string) {
|
||||||
|
salePrice = int64(product.ProductPrice)
|
||||||
|
if product.ProductSubsidy != nil {
|
||||||
|
for _, v := range product.ProductSubsidy.DiscountDetail {
|
||||||
|
if skuActTypeMap[v.Type] == 1 {
|
||||||
|
skuCount := product.ProductAmount
|
||||||
|
if skuCount == 0 {
|
||||||
|
skuCount = product.Number
|
||||||
|
}
|
||||||
|
salePrice -= int64(math.Round(float64(v.BaiduRate+v.ShopRate) / float64(skuCount))) // 饿百同一SKU的优惠与非优惠没有拆开,平均摊销处理
|
||||||
|
vendorActType = v.Type
|
||||||
|
}
|
||||||
|
baiduRate += int64(v.BaiduRate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return salePrice, baiduRate, vendorActType
|
||||||
|
}
|
||||||
|
|
||||||
func (p *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) {
|
func (p *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) {
|
||||||
globals.SugarLogger.Debugf("ebai AcceptOrRefuseOrder orderID:%s, isAcceptIt:%t", order.VendorOrderID, isAcceptIt)
|
globals.SugarLogger.Debugf("ebai AcceptOrRefuseOrder orderID:%s, isAcceptIt:%t", order.VendorOrderID, isAcceptIt)
|
||||||
if isAcceptIt {
|
if isAcceptIt {
|
||||||
@@ -239,24 +332,38 @@ func (p *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName
|
|||||||
|
|
||||||
//
|
//
|
||||||
func (c *PurchaseHandler) onOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaiapi.CallbackResponse) {
|
func (c *PurchaseHandler) onOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaiapi.CallbackResponse) {
|
||||||
if ebaiapi.CmdOrderCreate == msg.Cmd {
|
if c.isAfsMsg(msg) {
|
||||||
retVal = c.onOrderNew(msg)
|
retVal = c.OnAfsOrderMsg(msg)
|
||||||
} else {
|
} else {
|
||||||
status := c.callbackMsg2Status(msg)
|
status := c.callbackMsg2Status(msg)
|
||||||
var err error
|
if partner.CurOrderManager.GetStatusDuplicatedCount(status) > 0 {
|
||||||
if status != nil {
|
return nil
|
||||||
err = partner.CurOrderManager.OnOrderStatusChanged(status)
|
}
|
||||||
|
if ebaiapi.CmdOrderCreate == msg.Cmd {
|
||||||
|
retVal = c.onOrderNew(msg, status)
|
||||||
|
} else {
|
||||||
|
var err error
|
||||||
|
if status != nil {
|
||||||
|
if status.Status == model.OrderStatusAdjust {
|
||||||
|
var order *model.GoodsOrder
|
||||||
|
if order, err = c.GetOrder4PartRefund(GetOrderIDFromMsg(msg)); err == nil {
|
||||||
|
err = partner.CurOrderManager.OnOrderAdjust(order, status)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = partner.CurOrderManager.OnOrderStatusChanged(status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
retVal = api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, nil)
|
||||||
}
|
}
|
||||||
retVal = api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, nil)
|
|
||||||
}
|
}
|
||||||
return retVal
|
return retVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PurchaseHandler) onOrderNew(msg *ebaiapi.CallbackMsg) (response *ebaiapi.CallbackResponse) {
|
func (c *PurchaseHandler) onOrderNew(msg *ebaiapi.CallbackMsg, orderStatus *model.OrderStatus) (response *ebaiapi.CallbackResponse) {
|
||||||
vendorOrderID := GetOrderIDFromMsg(msg)
|
vendorOrderID := GetOrderIDFromMsg(msg)
|
||||||
order, orderMap, err := c.getOrder(vendorOrderID)
|
order, orderMap, err := c.getOrder(vendorOrderID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if err = partner.CurOrderManager.OnOrderNew(order, order.VendorStatus); err == nil {
|
if err = partner.CurOrderManager.OnOrderNew(order, orderStatus); err == nil {
|
||||||
utils.CallFuncAsync(func() {
|
utils.CallFuncAsync(func() {
|
||||||
c.OnOrderDetail(orderMap, partner.CreatedPeration)
|
c.OnOrderDetail(orderMap, partner.CreatedPeration)
|
||||||
})
|
})
|
||||||
@@ -279,27 +386,24 @@ func (c *PurchaseHandler) callbackMsg2Status(msg *ebaiapi.CallbackMsg) (orderSta
|
|||||||
VendorStatus: msg.Cmd,
|
VendorStatus: msg.Cmd,
|
||||||
}
|
}
|
||||||
if msg.Cmd == ebaiapi.CmdOrderUserCancel {
|
if msg.Cmd == ebaiapi.CmdOrderUserCancel {
|
||||||
msgType := utils.Int64ToStr(utils.MustInterface2Int64(msg.Body["type"]))
|
msgType := int(utils.MustInterface2Int64(msg.Body["type"]))
|
||||||
cancelType := utils.Int64ToStr(utils.MustInterface2Int64(msg.Body["cancel_type"]))
|
cancelType := int(utils.MustInterface2Int64(msg.Body["cancel_type"]))
|
||||||
orderStatus.Remark = utils.Interface2String(msg.Body["cancel_reason"])
|
orderStatus.Remark = buildFullReason(utils.Interface2String(msg.Body["cancel_reason"]), utils.Interface2String(msg.Body["addition_reason"]))
|
||||||
orderStatus.VendorStatus = msg.Cmd + "-" + msgType
|
orderStatus.VendorStatus = msg.Cmd + "-" + utils.Int2Str(msgType)
|
||||||
if additionReason := utils.Interface2String(msg.Body["addition_reason"]); additionReason != "" {
|
|
||||||
orderStatus.Remark += ",额外原因:" + additionReason
|
|
||||||
}
|
|
||||||
if cancelType == ebaiapi.OrderUserCancelTypeBeforeSale {
|
if cancelType == ebaiapi.OrderUserCancelTypeBeforeSale {
|
||||||
if msgType == ebaiapi.OrderUserCancelApply {
|
if msgType == ebaiapi.OrderUserCancelApply ||
|
||||||
|
msgType == ebaiapi.OrderUserCancelCSIntervene {
|
||||||
orderStatus.VendorStatus = fakeUserApplyCancel
|
orderStatus.VendorStatus = fakeUserApplyCancel
|
||||||
} else if msgType == ebaiapi.OrderUserCancelInvalid {
|
} else if msgType == ebaiapi.OrderUserCancelInvalid ||
|
||||||
|
msgType == ebaiapi.OrderUserCancelMerchantRefused ||
|
||||||
|
msgType == ebaiapi.OrderUserCancelCSRefused {
|
||||||
orderStatus.VendorStatus = fakeUserUndoApplyCancel
|
orderStatus.VendorStatus = fakeUserUndoApplyCancel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if msg.Cmd == ebaiapi.CmdOrderPartRefund {
|
} else if msg.Cmd == ebaiapi.CmdOrderPartRefund {
|
||||||
msgType := utils.Int64ToStr(utils.MustInterface2Int64(msg.Body["type"]))
|
msgType := int(utils.MustInterface2Int64(msg.Body["type"]))
|
||||||
status := utils.Int64ToStr(utils.MustInterface2Int64(msg.Body["status"]))
|
status := int(utils.MustInterface2Int64(msg.Body["status"]))
|
||||||
orderStatus.Remark = utils.Interface2String(msg.Body["reason"])
|
orderStatus.Remark = buildFullReason(utils.Interface2String(msg.Body["reason"]), utils.Interface2String(msg.Body["addition_reason"]))
|
||||||
if additionReason := utils.Interface2String(msg.Body["addition_reason"]); additionReason != "" {
|
|
||||||
orderStatus.Remark += ",额外原因:" + additionReason
|
|
||||||
}
|
|
||||||
if msgType == ebaiapi.OrderPartRefuncTypeMerchant && status == ebaiapi.OrderPartRefundSuccess {
|
if msgType == ebaiapi.OrderPartRefuncTypeMerchant && status == ebaiapi.OrderPartRefundSuccess {
|
||||||
orderStatus.VendorStatus = fakeOrderAdjustFinished
|
orderStatus.VendorStatus = fakeOrderAdjustFinished
|
||||||
}
|
}
|
||||||
@@ -315,6 +419,14 @@ func (c *PurchaseHandler) callbackMsg2Status(msg *ebaiapi.CallbackMsg) (orderSta
|
|||||||
return orderStatus
|
return orderStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func buildFullReason(reason, addReason string) (fullReason string) {
|
||||||
|
fullReason = reason
|
||||||
|
if addReason != "" {
|
||||||
|
fullReason += ",额外原因:" + addReason
|
||||||
|
}
|
||||||
|
return fullReason
|
||||||
|
}
|
||||||
|
|
||||||
func (c *PurchaseHandler) GetStatusActionTimeout(order *model.GoodsOrder, statusType, status int) (params *partner.StatusActionParams) {
|
func (c *PurchaseHandler) GetStatusActionTimeout(order *model.GoodsOrder, statusType, status int) (params *partner.StatusActionParams) {
|
||||||
if statusType == scheduler.TimerStatusTypeOrder && status == model.OrderStatusAccepted {
|
if statusType == scheduler.TimerStatusTypeOrder && status == model.OrderStatusAccepted {
|
||||||
params = &partner.StatusActionParams{ // PickDeadline没有设置时才有效,饿百要求在5分钟内拣货,不然订单会被取消
|
params = &partner.StatusActionParams{ // PickDeadline没有设置时才有效,饿百要求在5分钟内拣货,不然订单会被取消
|
||||||
@@ -398,15 +510,21 @@ func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.Goods
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
|
func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
|
||||||
var skuList []*ebaiapi.RefundSku
|
// 饿百必须要确认订单后才能调整单
|
||||||
for _, sku := range removedSkuList {
|
if order.Status < model.OrderStatusFinishedPickup {
|
||||||
skuList = append(skuList, &ebaiapi.RefundSku{
|
err = c.PickupGoods(order, false, ctx.GetUserName())
|
||||||
CustomeSkuID: utils.Int2Str(jxutils.GetSkuIDFromOrderSku(sku)),
|
|
||||||
Number: utils.Int2Str(sku.Count),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
if globals.EnableEbaiStoreWrite {
|
if err == nil {
|
||||||
err = api.EbaiAPI.OrderPartRefund(order.VendorOrderID, skuList)
|
var skuList []*ebaiapi.RefundSku
|
||||||
|
for _, sku := range removedSkuList {
|
||||||
|
skuList = append(skuList, &ebaiapi.RefundSku{
|
||||||
|
CustomeSkuID: utils.Int2Str(jxutils.GetSkuIDFromOrderSku(sku)),
|
||||||
|
Number: utils.Int2Str(sku.Count),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if globals.EnableEbaiStoreWrite {
|
||||||
|
err = api.EbaiAPI.OrderPartRefund(order.VendorOrderID, skuList)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
189
business/partner/purchase/ebai/order_afs.go
Normal file
189
business/partner/purchase/ebai/order_afs.go
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
package ebai
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi/ebaiapi"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
AfsVendorStatus2Status4PartRefundMap = map[int]int{
|
||||||
|
ebaiapi.OrderPartRefundApply: model.AfsOrderStatusWait4Approve,
|
||||||
|
ebaiapi.OrderPartRefundSuccess: model.AfsOrderStatusFinished,
|
||||||
|
ebaiapi.OrderPartRefundUserApplyArbitration: model.OrderStatusUnknown, // 是否是中间状态
|
||||||
|
ebaiapi.OrderPartRefundFailed: model.AfsOrderStatusFailed,
|
||||||
|
ebaiapi.OrderPartRefundMerchantRefused: model.AfsOrderStatusFailed, // 是否是中间状态
|
||||||
|
}
|
||||||
|
AfsVendorStatus2Status4UserCancel = map[int]int{
|
||||||
|
ebaiapi.OrderUserCancelApply: model.AfsOrderStatusWait4Approve,
|
||||||
|
ebaiapi.OrderUserCancelCSIntervene: model.OrderStatusUnknown,
|
||||||
|
ebaiapi.OrderUserCancelCSRefused: model.AfsOrderStatusFailed,
|
||||||
|
ebaiapi.OrderUserCancelCSAgreed: model.AfsOrderStatusFinished,
|
||||||
|
ebaiapi.OrderUserCancelMerchantRefused: model.AfsOrderStatusFailed,
|
||||||
|
ebaiapi.OrderUserCancelMerchantAgreed: model.AfsOrderStatusFinished,
|
||||||
|
ebaiapi.OrderUserCancelInvalid: model.AfsOrderStatusFailed,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) isAfsMsg(msg *ebaiapi.CallbackMsg) bool {
|
||||||
|
if msg.Cmd == ebaiapi.CmdOrderPartRefund {
|
||||||
|
msgType := int(utils.MustInterface2Int64(msg.Body["type"]))
|
||||||
|
return msgType == ebaiapi.OrderPartRefuncTypeCustomer
|
||||||
|
} else if msg.Cmd == ebaiapi.CmdOrderUserCancel {
|
||||||
|
cancelType := int(utils.MustInterface2Int64(msg.Body["cancel_type"]))
|
||||||
|
return cancelType == ebaiapi.OrderUserCancelTypeAfterSale
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) OnAfsOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaiapi.CallbackResponse) {
|
||||||
|
jxutils.CallMsgHandlerAsync(func() {
|
||||||
|
retVal = c.onAfsOrderMsg(msg)
|
||||||
|
}, jxutils.ComposeUniversalOrderID(GetOrderIDFromMsg(msg), model.VendorIDEBAI))
|
||||||
|
return retVal
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) onAfsOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaiapi.CallbackResponse) {
|
||||||
|
if orderStatus := c.callbackAfsMsg2Status(msg); orderStatus != nil {
|
||||||
|
var err error
|
||||||
|
if orderStatus.Status == model.AfsOrderStatusWait4Approve || orderStatus.Status == model.AfsOrderStatusNew {
|
||||||
|
var afsOrder *model.AfsOrder
|
||||||
|
if msg.Cmd == ebaiapi.CmdOrderPartRefund {
|
||||||
|
partRefundData := msg.Data.(*ebaiapi.CBPartRefundInfo)
|
||||||
|
afsOrder = &model.AfsOrder{
|
||||||
|
VendorID: model.VendorIDEBAI,
|
||||||
|
AfsOrderID: orderStatus.VendorOrderID,
|
||||||
|
VendorOrderID: orderStatus.RefVendorOrderID,
|
||||||
|
VendorStoreID: "",
|
||||||
|
StoreID: 0,
|
||||||
|
AfsCreatedAt: utils.Timestamp2Time(msg.Timestamp),
|
||||||
|
VendorAppealType: "",
|
||||||
|
AppealType: model.AfsAppealTypeRefund,
|
||||||
|
VendorReasonType: partRefundData.ReasonType,
|
||||||
|
ReasonType: c.convertAfsReasonType(partRefundData.ReasonType),
|
||||||
|
ReasonDesc: utils.LimitUTF8StringLen(buildFullReason(partRefundData.Reason, partRefundData.AdditionReason), 1024),
|
||||||
|
ReasonImgList: utils.LimitUTF8StringLen(strings.Join(partRefundData.Photos, ","), 1024),
|
||||||
|
RefundType: model.AfsTypePartRefund,
|
||||||
|
|
||||||
|
// FreightUserMoney: afsInfo.OrderFreightMoney,
|
||||||
|
// AfsFreightMoney: afsInfo.AfsFreight,
|
||||||
|
// BoxMoney: afsInfo.PackagingMoney,
|
||||||
|
// TongchengFreightMoney: afsInfo.TongchengFreightMoney,
|
||||||
|
// SkuBoxMoney: afsInfo.MealBoxMoney,
|
||||||
|
}
|
||||||
|
for _, sku := range partRefundData.RefundProducts {
|
||||||
|
orderSku := &model.OrderSkuFinancial{
|
||||||
|
// VendorID: model.VendorIDEBAI,
|
||||||
|
// AfsOrderID: afsOrder.AfsOrderID,
|
||||||
|
// VendorOrderID: afsOrder.VendorOrderID,
|
||||||
|
// VendorStoreID: afsOrder.VendorStoreID,
|
||||||
|
// StoreID: afsOrder.StoreID,
|
||||||
|
// IsAfsOrder: 1,
|
||||||
|
|
||||||
|
Count: sku.Number,
|
||||||
|
// ConfirmTime: afsOrder.AfsCreateAt,
|
||||||
|
VendorSkuID: sku.SkuID,
|
||||||
|
SkuID: int(utils.Str2Int64WithDefault(sku.CustomSkuID, 0)),
|
||||||
|
Name: sku.Name,
|
||||||
|
UserMoney: sku.TotalRefund,
|
||||||
|
PmSkuSubsidyMoney: sku.ShopEleRefund,
|
||||||
|
}
|
||||||
|
afsOrder.SkuUserMoney += orderSku.UserMoney
|
||||||
|
afsOrder.PmSubsidyMoney += orderSku.PmSubsidyMoney
|
||||||
|
afsOrder.Skus = append(afsOrder.Skus, orderSku)
|
||||||
|
}
|
||||||
|
} else if msg.Cmd == ebaiapi.CmdOrderUserCancel {
|
||||||
|
if orderFinancial, err2 := partner.CurOrderManager.LoadOrderFinancial(orderStatus.RefVendorOrderID, model.VendorIDEBAI); err2 == nil {
|
||||||
|
afsOrder = c.OrderFinancialDetail2Refund(orderFinancial, msg)
|
||||||
|
cancelData := msg.Data.(*ebaiapi.CBUserCancelInfo)
|
||||||
|
afsOrder.AfsOrderID = orderStatus.VendorOrderID
|
||||||
|
afsOrder.RefundType = model.AfsTypeFullRefund
|
||||||
|
afsOrder.AppealType = model.AfsAppealTypeRefund
|
||||||
|
afsOrder.VendorReasonType = ""
|
||||||
|
afsOrder.ReasonType = model.AfsReasonNotOthers
|
||||||
|
afsOrder.ReasonDesc = utils.LimitUTF8StringLen(buildFullReason(cancelData.CancelReason, cancelData.AdditionReason), 1024)
|
||||||
|
afsOrder.ReasonImgList = utils.LimitUTF8StringLen(strings.Join(cancelData.Pictures, ","), 1024)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if afsOrder != nil {
|
||||||
|
err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, orderStatus)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = partner.CurOrderManager.OnAfsOrderStatusChanged(orderStatus)
|
||||||
|
}
|
||||||
|
retVal = api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, nil)
|
||||||
|
}
|
||||||
|
return retVal
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) convertAfsReasonType(vendorReasonType string) int8 {
|
||||||
|
return model.AfsReasonNotOthers
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) GetAfsStatusFromVendorStatus4PartRefund(vendorStatus int) int {
|
||||||
|
return AfsVendorStatus2Status4PartRefundMap[vendorStatus]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) GetAfsStatusFromVendorStatus4UserCancel(vendorStatus int) int {
|
||||||
|
return AfsVendorStatus2Status4UserCancel[vendorStatus]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) callbackAfsMsg2Status(msg *ebaiapi.CallbackMsg) (orderStatus *model.OrderStatus) {
|
||||||
|
if msg.Cmd == ebaiapi.CmdOrderPartRefund {
|
||||||
|
partRefundData := msg.Data.(*ebaiapi.CBPartRefundInfo)
|
||||||
|
orderStatus = &model.OrderStatus{
|
||||||
|
VendorOrderID: partRefundData.RefundID, // 是售后单ID,不是订单ID,订单ID在RefVendorOrderID中
|
||||||
|
VendorID: model.VendorIDEBAI,
|
||||||
|
OrderType: model.OrderTypeAfsOrder,
|
||||||
|
RefVendorOrderID: utils.Int64ToStr(partRefundData.OrderID),
|
||||||
|
RefVendorID: model.VendorIDEBAI,
|
||||||
|
VendorStatus: utils.Int2Str(partRefundData.Status),
|
||||||
|
Status: c.GetAfsStatusFromVendorStatus4PartRefund(partRefundData.Status),
|
||||||
|
StatusTime: utils.Timestamp2Time(msg.Timestamp),
|
||||||
|
Remark: buildFullReason(partRefundData.Reason, partRefundData.AdditionReason),
|
||||||
|
}
|
||||||
|
if orderStatus.Status == model.AfsOrderStatusWait4Approve && partRefundData.Type != ebaiapi.OrderPartRefuncTypeCustomer {
|
||||||
|
orderStatus.Status = model.AfsOrderStatusNew
|
||||||
|
}
|
||||||
|
} else if msg.Cmd == ebaiapi.CmdOrderUserCancel {
|
||||||
|
cancelData := msg.Data.(*ebaiapi.CBUserCancelInfo)
|
||||||
|
orderStatus = &model.OrderStatus{
|
||||||
|
VendorOrderID: utils.Int64ToStr(cancelData.OrderID), // 是售后单ID,不是订单ID,订单ID在RefVendorOrderID中
|
||||||
|
VendorID: model.VendorIDEBAI,
|
||||||
|
OrderType: model.OrderTypeAfsOrder,
|
||||||
|
RefVendorOrderID: utils.Int64ToStr(cancelData.OrderID),
|
||||||
|
RefVendorID: model.VendorIDEBAI,
|
||||||
|
VendorStatus: utils.Int2Str(cancelData.Type),
|
||||||
|
Status: c.GetAfsStatusFromVendorStatus4UserCancel(cancelData.Type),
|
||||||
|
StatusTime: utils.Timestamp2Time(msg.Timestamp),
|
||||||
|
Remark: buildFullReason(cancelData.CancelReason, cancelData.AdditionReason),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return orderStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
// 审核售后单申请
|
||||||
|
func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) {
|
||||||
|
if globals.EnableEbaiStoreWrite {
|
||||||
|
if approveType == partner.AfsApproveTypeRefused {
|
||||||
|
err = api.EbaiAPI.OrderDisagreeRefund(order.VendorOrderID, reason)
|
||||||
|
} else {
|
||||||
|
err = api.EbaiAPI.OrderAgreeRefund(order.VendorOrderID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认收到退货
|
||||||
|
func (c *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) {
|
||||||
|
err = fmt.Errorf("内部错误,饿百平台不支持确认收到退货操作")
|
||||||
|
return err
|
||||||
|
}
|
||||||
16
business/partner/purchase/ebai/order_test.go
Normal file
16
business/partner/purchase/ebai/order_test.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package ebai
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetOrder4PartRefund(t *testing.T) {
|
||||||
|
order, err := new(PurchaseHandler).GetOrder4PartRefund("1556529608021993938")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err.Error())
|
||||||
|
} else {
|
||||||
|
t.Log(utils.Format4Output(order, false))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -59,7 +59,7 @@ func (p *PurchaseHandler) CreateStore(db *dao.DaoDB, storeID int, userName strin
|
|||||||
params["category1"] = ""
|
params["category1"] = ""
|
||||||
params["category2"] = ""
|
params["category2"] = ""
|
||||||
params["category3"] = ""
|
params["category3"] = ""
|
||||||
if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite {
|
if globals.EnableEbaiStoreWrite {
|
||||||
intVendorStoreID, err2 := api.EbaiAPI.ShopCreate(params)
|
intVendorStoreID, err2 := api.EbaiAPI.ShopCreate(params)
|
||||||
if err = err2; err == nil {
|
if err = err2; err == nil {
|
||||||
return utils.Int64ToStr(intVendorStoreID), err
|
return utils.Int64ToStr(intVendorStoreID), err
|
||||||
@@ -160,7 +160,7 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin
|
|||||||
if err = dao.GetRows(db, &stores, sql, model.VendorIDEBAI, utils.DefaultTimeValue, storeID); err == nil {
|
if err = dao.GetRows(db, &stores, sql, model.VendorIDEBAI, utils.DefaultTimeValue, storeID); err == nil {
|
||||||
for _, store := range stores {
|
for _, store := range stores {
|
||||||
// globals.SugarLogger.Debug(utils.Format4Output(params, false))
|
// globals.SugarLogger.Debug(utils.Format4Output(params, false))
|
||||||
if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite {
|
if globals.EnableEbaiStoreWrite {
|
||||||
shopID := 0
|
shopID := 0
|
||||||
if store.SyncStatus&model.SyncFlagDeletedMask == 0 {
|
if store.SyncStatus&model.SyncFlagDeletedMask == 0 {
|
||||||
shopID = store.ID
|
shopID = store.ID
|
||||||
@@ -181,10 +181,10 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin
|
|||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
mergeStatus := jxutils.MergeStoreStatus(store.Status, store.EbaiStoreStatus)
|
mergeStatus := jxutils.MergeStoreStatus(store.Status, store.EbaiStoreStatus)
|
||||||
if store2.Status != mergeStatus {
|
if !isStoreStatusSame(store2.Status, mergeStatus) {
|
||||||
if mergeStatus == model.StoreStatusOpened {
|
if mergeStatus == model.StoreStatusOpened {
|
||||||
err = api.EbaiAPI.ShopOpen("", utils.Str2Int64(store.VendorStoreID))
|
err = api.EbaiAPI.ShopOpen("", utils.Str2Int64(store.VendorStoreID))
|
||||||
} else if mergeStatus == model.StoreStatusClosed {
|
} else if mergeStatus == model.StoreStatusHaveRest || mergeStatus == model.StoreStatusClosed {
|
||||||
err = api.EbaiAPI.ShopClose("", utils.Str2Int64(store.VendorStoreID))
|
err = api.EbaiAPI.ShopClose("", utils.Str2Int64(store.VendorStoreID))
|
||||||
} else if mergeStatus == model.StoreStatusDisabled {
|
} else if mergeStatus == model.StoreStatusDisabled {
|
||||||
err = api.EbaiAPI.ShopOffline("", utils.Str2Int64(store.VendorStoreID))
|
err = api.EbaiAPI.ShopOffline("", utils.Str2Int64(store.VendorStoreID))
|
||||||
@@ -204,10 +204,9 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// todo 饿百 开店审核通过后不允许修改商户信息
|
params := genStoreMapFromStore(store)
|
||||||
// params := genStoreMapFromStore(store)
|
if err = api.EbaiAPI.ShopUpdate(params); err == nil {
|
||||||
// if err = api.EbaiAPI.ShopUpdate(params); err == nil {
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -215,6 +214,16 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isStoreStatusSame(status1, status2 int) bool {
|
||||||
|
if status1 == model.StoreStatusClosed {
|
||||||
|
status1 = model.StoreStatusHaveRest
|
||||||
|
}
|
||||||
|
if status2 == model.StoreStatusClosed {
|
||||||
|
status2 = model.StoreStatusHaveRest
|
||||||
|
}
|
||||||
|
return status1 == status2
|
||||||
|
}
|
||||||
|
|
||||||
func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) {
|
func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) {
|
||||||
globals.SugarLogger.Debugf("ebai RefreshAllStoresID")
|
globals.SugarLogger.Debugf("ebai RefreshAllStoresID")
|
||||||
const batchSize = 50
|
const batchSize = 50
|
||||||
@@ -248,7 +257,7 @@ func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask
|
|||||||
shopIDs[k] = utils.GetUUID()
|
shopIDs[k] = utils.GetUUID()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite {
|
if globals.EnableEbaiStoreWrite {
|
||||||
err = api.EbaiAPI.ShopIDBatchUpdate(baiduShopIDs, shopIDs)
|
err = api.EbaiAPI.ShopIDBatchUpdate(baiduShopIDs, shopIDs)
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -311,7 +320,7 @@ func EbaiDeliveryRegion2Jx(deliveryRegion interface{}) string {
|
|||||||
func JxDeliveryRegion2Ebai(store *model.Store) (deliveryRegion interface{}) {
|
func JxDeliveryRegion2Ebai(store *model.Store) (deliveryRegion interface{}) {
|
||||||
rangeStr := strings.Trim(store.DeliveryRange, ";")
|
rangeStr := strings.Trim(store.DeliveryRange, ";")
|
||||||
if store.DeliveryRangeType == model.DeliveryRangeTypeRadius {
|
if store.DeliveryRangeType == model.DeliveryRangeTypeRadius {
|
||||||
if utils.Str2Int64(store.DeliveryRange) > 100 { // todo 如果小于100米,表示禁用,不更新
|
if utils.Str2Int64WithDefault(store.DeliveryRange, 0) > 100 { // todo 如果小于100米,表示禁用,不更新
|
||||||
rangeStr = jxutils.GetPolygonFromCircleStr(jxutils.IntCoordinate2Standard(store.Lng), jxutils.IntCoordinate2Standard(store.Lat), utils.Str2Float64(store.DeliveryRange), 8)
|
rangeStr = jxutils.GetPolygonFromCircleStr(jxutils.IntCoordinate2Standard(store.Lng), jxutils.IntCoordinate2Standard(store.Lat), utils.Str2Float64(store.DeliveryRange), 8)
|
||||||
} else {
|
} else {
|
||||||
rangeStr = ""
|
rangeStr = ""
|
||||||
@@ -363,19 +372,20 @@ func JxBusinessTime2Ebai(store *model.Store) interface{} {
|
|||||||
|
|
||||||
func genStoreMapFromStore(store *tEbaiStoreInfo) map[string]interface{} {
|
func genStoreMapFromStore(store *tEbaiStoreInfo) map[string]interface{} {
|
||||||
params := map[string]interface{}{
|
params := map[string]interface{}{
|
||||||
"phone": store.Tel1,
|
|
||||||
"business_time": JxBusinessTime2Ebai(&store.Store),
|
"business_time": JxBusinessTime2Ebai(&store.Store),
|
||||||
}
|
}
|
||||||
|
// if store.Tel2 != "" {
|
||||||
|
// params["ivr_phone"] = store.Tel2
|
||||||
|
// }
|
||||||
|
// params["phone"] = store.Tel1
|
||||||
if store.VendorStoreID != "" {
|
if store.VendorStoreID != "" {
|
||||||
params["baidu_shop_id"] = store.VendorStoreID
|
params["baidu_shop_id"] = store.VendorStoreID
|
||||||
}
|
}
|
||||||
if store.Tel2 != "" {
|
if store.SyncStatus&(model.SyncFlagNewMask /*|model.SyncFlagStoreName*/) != 0 {
|
||||||
params["ivr_phone"] = store.Tel2
|
params["name"] = jxutils.ComposeStoreName(store.Name, model.VendorIDEBAI)
|
||||||
}
|
}
|
||||||
if store.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreName) != 0 {
|
// todo 饿百 开店审核通过后不允许修改商户信息
|
||||||
// params["name"] = jxutils.ComposeStoreName(store.Name, model.VendorIDEBAI)
|
if store.SyncStatus&(model.SyncFlagNewMask /*|model.SyncFlagStoreAddress*/) != 0 {
|
||||||
}
|
|
||||||
if store.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreAddress) != 0 {
|
|
||||||
params["longitude"] = jxutils.IntCoordinate2Standard(store.Lng)
|
params["longitude"] = jxutils.IntCoordinate2Standard(store.Lng)
|
||||||
params["latitude"] = jxutils.IntCoordinate2Standard(store.Lat)
|
params["latitude"] = jxutils.IntCoordinate2Standard(store.Lat)
|
||||||
params["address"] = store.Address
|
params["address"] = store.Address
|
||||||
@@ -415,7 +425,7 @@ func (c *PurchaseHandler) onShopMsgPush(msg *ebaiapi.CallbackMsg) (response *eba
|
|||||||
if int(utils.ForceInterface2Int64(msg.Body["business_ele"])) == 1 {
|
if int(utils.ForceInterface2Int64(msg.Body["business_ele"])) == 1 {
|
||||||
storeStatus = model.StoreStatusOpened
|
storeStatus = model.StoreStatusOpened
|
||||||
} else {
|
} else {
|
||||||
storeStatus = model.StoreStatusClosed
|
storeStatus = model.StoreStatusHaveRest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -423,3 +433,11 @@ func (c *PurchaseHandler) onShopMsgPush(msg *ebaiapi.CallbackMsg) (response *eba
|
|||||||
}
|
}
|
||||||
return api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, nil)
|
return api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) GetShopHealthInfo(vendorShopID string) (shopHealthInfo map[string]interface{}, err error) {
|
||||||
|
result, err := api.EbaiAPI.GetShopHealthByDetail(utils.Str2Int64(vendorShopID))
|
||||||
|
if err == nil {
|
||||||
|
shopHealthInfo = utils.Struct2FlatMap(result)
|
||||||
|
}
|
||||||
|
return shopHealthInfo, err
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/ebaiapi"
|
"git.rosy.net.cn/baseapi/platformapi/ebaiapi"
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
@@ -12,6 +13,7 @@ import (
|
|||||||
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
"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"
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
)
|
)
|
||||||
@@ -23,7 +25,6 @@ const (
|
|||||||
type tStoreSkuFullInfo struct {
|
type tStoreSkuFullInfo struct {
|
||||||
model.StoreSkuBind
|
model.StoreSkuBind
|
||||||
|
|
||||||
SkuID int `orm:"column(sku_id)"`
|
|
||||||
NameID int `orm:"column(name_id)"`
|
NameID int `orm:"column(name_id)"`
|
||||||
|
|
||||||
SpecQuality float32 `json:"specQuality"`
|
SpecQuality float32 `json:"specQuality"`
|
||||||
@@ -31,14 +32,15 @@ type tStoreSkuFullInfo struct {
|
|||||||
Weight int `json:"weight"` // 重量/质量,单位为克,当相应的SkuName的SpecUnit为g或kg时,必须等于SpecQuality
|
Weight int `json:"weight"` // 重量/质量,单位为克,当相应的SkuName的SpecUnit为g或kg时,必须等于SpecQuality
|
||||||
SkuStatus int
|
SkuStatus int
|
||||||
|
|
||||||
Prefix string `orm:"size(255)" json:"prefix"`
|
Prefix string `orm:"size(255)" json:"prefix"`
|
||||||
Name string `orm:"size(255);index" json:"name"`
|
Name string `orm:"size(255);index" json:"name"`
|
||||||
Comment string `orm:"size(255)" json:"comment"`
|
Comment string `orm:"size(255)" json:"comment"`
|
||||||
IsGlobal int8 `orm:"default(1)" json:"isGlobal"` // 是否是全部(全国)可见,如果否的话,可见性由SkuPlace决定
|
IsGlobal int8 `orm:"default(1)" json:"isGlobal"` // 是否是全部(全国)可见,如果否的话,可见性由SkuPlace决定
|
||||||
Unit string `orm:"size(8)" json:"unit"`
|
Unit string `orm:"size(8)" json:"unit"`
|
||||||
Img string `orm:"size(255)" json:"img"`
|
Img string `orm:"size(255)" json:"img"`
|
||||||
PlaceStr string
|
PlaceStr string
|
||||||
Upc string
|
Upc string
|
||||||
|
DescImgEbai string
|
||||||
|
|
||||||
CatName string `orm:"size(255)"`
|
CatName string `orm:"size(255)"`
|
||||||
|
|
||||||
@@ -54,7 +56,8 @@ type tStoreSkuFullInfo struct {
|
|||||||
EbaiCat2ID int64 `orm:"column(ebai_cat2_id)"`
|
EbaiCat2ID int64 `orm:"column(ebai_cat2_id)"`
|
||||||
EbaiCat3ID int64 `orm:"column(ebai_cat3_id)"`
|
EbaiCat3ID int64 `orm:"column(ebai_cat3_id)"`
|
||||||
|
|
||||||
PricePercentage int
|
PricePercentage int
|
||||||
|
CatPricePercentage int
|
||||||
}
|
}
|
||||||
|
|
||||||
type tStoreCatInfo struct {
|
type tStoreCatInfo struct {
|
||||||
@@ -80,23 +83,23 @@ var (
|
|||||||
|
|
||||||
func (p *PurchaseHandler) getDirtyStoreSkus(db *dao.DaoDB, storeID int, skuIDs []int) (storeSkuInfoList []*tStoreSkuFullInfo, err error) {
|
func (p *PurchaseHandler) getDirtyStoreSkus(db *dao.DaoDB, storeID int, skuIDs []int) (storeSkuInfoList []*tStoreSkuFullInfo, err error) {
|
||||||
sql := `
|
sql := `
|
||||||
SELECT t8.price_percentage, t1.*, t2.id sku_id, t2.spec_quality, t2.spec_unit, t2.weight, t2.status sku_status,
|
SELECT t8.price_percentage, t1.*, t2.spec_quality, t2.spec_unit, t2.weight, t2.status sku_status,
|
||||||
t3.id name_id, t3.prefix, t3.name, t2.comment, t3.is_global, t3.unit, IF(t3.img_ebai <> '', t3.img_ebai, t3.img) img, t3.upc,
|
t3.id name_id, t3.prefix, t3.name, t2.comment, t3.is_global, t3.unit, IF(t3.img_ebai <> '', t3.img_ebai, t3.img) img, t3.upc, t3.desc_img_ebai,
|
||||||
t4.name cat_name,
|
t4.name cat_name, t4.ebai_price_percentage cat_price_percentage,
|
||||||
t4.id cat_id, t4.level cat_level, t5.ebai_id cat_ebai_id,
|
t4.id cat_id, t4.level cat_level, t5.ebai_id cat_ebai_id,
|
||||||
t4p.id parent_cat_id, t5p.ebai_id parent_cat_ebai_id, t5p.ebai_sync_status parent_cat_ebai_sync_status,
|
t4p.id parent_cat_id, t5p.ebai_id parent_cat_ebai_id, t5p.ebai_sync_status parent_cat_ebai_sync_status,
|
||||||
cat1.vendor_category_id ebai_cat3_id, cat2.vendor_category_id ebai_cat2_id, cat2.parent_id ebai_cat1_id
|
cat1.vendor_category_id ebai_cat3_id, cat2.vendor_category_id ebai_cat2_id, cat2.parent_id ebai_cat1_id
|
||||||
FROM store_sku_bind t1
|
FROM store_sku_bind t1
|
||||||
LEFT JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ? AND t2.status = ?
|
LEFT JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ? AND t2.status = ?
|
||||||
LEFT JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ? AND t3.status = ?
|
LEFT JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ? AND t3.status = ?
|
||||||
JOIN sku_category t4 ON t3.category_id = t4.id
|
LEFT JOIN sku_category t4 ON t3.category_id = t4.id
|
||||||
LEFT JOIN sku_category t4p ON t4p.id = t4.parent_id
|
LEFT JOIN sku_category t4p ON t4p.id = t4.parent_id
|
||||||
LEFT JOIN store_sku_category_map t5 ON t5.store_id = t1.store_id AND t5.category_id = t4.id AND t5.deleted_at = ?
|
LEFT JOIN store_sku_category_map t5 ON t5.store_id = t1.store_id AND t5.category_id = t4.id AND t5.deleted_at = ?
|
||||||
LEFT JOIN store_sku_category_map t5p ON t5p.store_id = t1.store_id AND t5p.category_id = t4p.id AND t5p.deleted_at = ?
|
LEFT JOIN store_sku_category_map t5p ON t5p.store_id = t1.store_id AND t5p.category_id = t4p.id AND t5p.deleted_at = ?
|
||||||
LEFT JOIN sku_vendor_category cat1 ON t4.ebai_category_id = cat1.vendor_category_id AND cat1.vendor_id = ?
|
LEFT JOIN sku_vendor_category cat1 ON t4.ebai_category_id = cat1.vendor_category_id AND cat1.vendor_id = ?
|
||||||
LEFT JOIN sku_vendor_category cat2 ON cat1.parent_id = cat2.vendor_category_id AND cat1.vendor_id = ?
|
LEFT JOIN sku_vendor_category cat2 ON cat1.parent_id = cat2.vendor_category_id AND cat1.vendor_id = ?
|
||||||
JOIN store_map t8 ON t8.store_id = t1.store_id AND t8.vendor_id = ? AND t8.deleted_at = ?
|
JOIN store_map t8 ON t8.store_id = t1.store_id AND t8.vendor_id = ? AND t8.deleted_at = ?
|
||||||
WHERE t1.store_id = ? AND (t1.ebai_sync_status <> 0)
|
WHERE t1.store_id = ? AND (t1.ebai_sync_status <> 0 OR (t1.ebai_id <> 0 AND t3.id IS NULL))
|
||||||
`
|
`
|
||||||
sqlParams := []interface{}{
|
sqlParams := []interface{}{
|
||||||
utils.DefaultTimeValue,
|
utils.DefaultTimeValue,
|
||||||
@@ -115,7 +118,7 @@ func (p *PurchaseHandler) getDirtyStoreSkus(db *dao.DaoDB, storeID int, skuIDs [
|
|||||||
sql += " AND t1.sku_id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ")"
|
sql += " AND t1.sku_id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ")"
|
||||||
sqlParams = append(sqlParams, skuIDs)
|
sqlParams = append(sqlParams, skuIDs)
|
||||||
}
|
}
|
||||||
sql += " ORDER BY t1.price"
|
sql += " ORDER BY t1.price DESC"
|
||||||
err = dao.GetRows(db, &storeSkuInfoList, sql, sqlParams...)
|
err = dao.GetRows(db, &storeSkuInfoList, sql, sqlParams...)
|
||||||
return storeSkuInfoList, err
|
return storeSkuInfoList, err
|
||||||
}
|
}
|
||||||
@@ -123,7 +126,7 @@ func (p *PurchaseHandler) getDirtyStoreSkus(db *dao.DaoDB, storeID int, skuIDs [
|
|||||||
func (p *PurchaseHandler) createCatByStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, db *dao.DaoDB, storeID int, storeSkuInfoList []*tStoreSkuFullInfo) (num int64, err error) {
|
func (p *PurchaseHandler) createCatByStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, db *dao.DaoDB, storeID int, storeSkuInfoList []*tStoreSkuFullInfo) (num int64, err error) {
|
||||||
catList2Add := make(map[int]int)
|
catList2Add := make(map[int]int)
|
||||||
for _, storeSku := range storeSkuInfoList {
|
for _, storeSku := range storeSkuInfoList {
|
||||||
if storeSku.SkuID != 0 && storeSku.EbaiSyncStatus&(model.SyncFlagNewMask|model.SyncFlagModifiedMask) != 0 {
|
if storeSku.CatID != 0 && storeSku.EbaiSyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreSkuModifiedMask) != 0 && storeSku.Status == model.SkuStatusNormal {
|
||||||
if storeSku.ParentCatEbaiID == 0 && storeSku.ParentCatID != 0 {
|
if storeSku.ParentCatEbaiID == 0 && storeSku.ParentCatID != 0 {
|
||||||
catList2Add[storeSku.ParentCatID] = 1
|
catList2Add[storeSku.ParentCatID] = 1
|
||||||
}
|
}
|
||||||
@@ -164,7 +167,7 @@ func (p *PurchaseHandler) FullSyncStoreSkus(ctx *jxcontext.Context, parentTask t
|
|||||||
_, err = p.setStoreSkuSyncStatus(ctx, db, storeID, nil, model.SyncFlagNewMask)
|
_, err = p.setStoreSkuSyncStatus(ctx, db, storeID, nil, model.SyncFlagNewMask)
|
||||||
case 2:
|
case 2:
|
||||||
if err = p.DeleteRemoteCategories(ctx, rootTask, storeID, nil); err == nil {
|
if err = p.DeleteRemoteCategories(ctx, rootTask, storeID, nil); err == nil {
|
||||||
_, err = dao.SetStoreCategorySyncStatus(db, model.VendorIDEBAI, storeID, nil, model.SyncFlagNewMask)
|
_, err = dao.SetStoreCategorySyncStatus(db, model.VendorIDEBAI, []int{storeID}, nil, model.SyncFlagNewMask)
|
||||||
}
|
}
|
||||||
case 3:
|
case 3:
|
||||||
err = p.SyncLocalStoreCategory(db, storeID, userName)
|
err = p.SyncLocalStoreCategory(db, storeID, userName)
|
||||||
@@ -202,7 +205,7 @@ func (p *PurchaseHandler) DeleteRemoteStoreSkus(ctx *jxcontext.Context, parentTa
|
|||||||
_, err = p.setStoreSkuSyncStatus(ctx, db, storeID, nil, model.SyncFlagNewMask)
|
_, err = p.setStoreSkuSyncStatus(ctx, db, storeID, nil, model.SyncFlagNewMask)
|
||||||
case 2:
|
case 2:
|
||||||
if err = p.DeleteRemoteCategories(ctx, rootTask, storeID, nil); err == nil {
|
if err = p.DeleteRemoteCategories(ctx, rootTask, storeID, nil); err == nil {
|
||||||
_, err = dao.SetStoreCategorySyncStatus(db, model.VendorIDEBAI, storeID, nil, model.SyncFlagNewMask)
|
_, err = dao.SetStoreCategorySyncStatus(db, model.VendorIDEBAI, []int{storeID}, nil, model.SyncFlagNewMask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -248,34 +251,65 @@ func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasks
|
|||||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
storeSku := batchItemList[0].(*tStoreSkuFullInfo)
|
storeSku := batchItemList[0].(*tStoreSkuFullInfo)
|
||||||
updateFields := []string{model.FieldEbaiSyncStatus}
|
updateFields := []string{model.FieldEbaiSyncStatus}
|
||||||
if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite {
|
if storeSku.NameID == 0 || storeSku.EbaiSyncStatus&model.SyncFlagDeletedMask != 0 {
|
||||||
if storeSku.SkuID == 0 || storeSku.EbaiSyncStatus&model.SyncFlagDeletedMask != 0 {
|
if storeSku.EbaiSyncStatus&model.SyncFlagNewMask == 0 && !jxutils.IsEmptyID(storeSku.EbaiID) {
|
||||||
if storeSku.EbaiSyncStatus&model.SyncFlagNewMask == 0 && storeSku.EbaiID != 0 {
|
if globals.EnableEbaiStoreWrite {
|
||||||
err = api.EbaiAPI.SkuDelete(strStoreID, utils.Int64ToStr(storeSku.EbaiID))
|
err = api.EbaiAPI.SkuDelete(strStoreID, utils.Int64ToStr(storeSku.EbaiID))
|
||||||
|
err = ignoreNoSkuErr(err)
|
||||||
}
|
}
|
||||||
} else if storeSku.EbaiSyncStatus&model.SyncFlagNewMask != 0 {
|
}
|
||||||
|
if err == nil {
|
||||||
|
if utils.IsTimeZero(storeSku.DeletedAt) {
|
||||||
|
storeSku.DeletedAt = time.Now()
|
||||||
|
updateFields = append(updateFields, model.FieldDeletedAt)
|
||||||
|
}
|
||||||
|
storeSku.EbaiID = 0
|
||||||
|
updateFields = append(updateFields, model.FieldEbaiID)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if storeSku.EbaiSyncStatus&model.SyncFlagNewMask != 0 {
|
||||||
// globals.SugarLogger.Debug(utils.Format4Output(genSkuParamsFromStoreSkuInfo(storeSku), false))
|
// globals.SugarLogger.Debug(utils.Format4Output(genSkuParamsFromStoreSkuInfo(storeSku), false))
|
||||||
// todo 适当处理重复(即已经创建)的情况
|
// todo 适当处理重复(即已经创建)的情况
|
||||||
if storeSku.EbaiID, err = api.EbaiAPI.SkuCreate(strStoreID, storeSku.SkuID, genSkuParamsFromStoreSkuInfo(storeSku)); err == nil {
|
mergedStoreSkuStatus := jxutils.MergeSkuStatus(storeSku.SkuStatus, storeSku.Status)
|
||||||
updateFields = append(updateFields, model.FieldEbaiID)
|
if mergedStoreSkuStatus == model.SkuStatusNormal { // 待创建且不可售的,暂不新建
|
||||||
} else if storeSku.EbaiID = ebaiapi.GetEbaiSkuIDFromError(err); storeSku.EbaiID > 0 {
|
if storeSku.Img != "" {
|
||||||
// globals.SugarLogger.Debugf("SyncStoreSkus test storeSku.EbaiID:%d, err:%v", storeSku.EbaiID, err)
|
if globals.EnableEbaiStoreWrite {
|
||||||
updateFields = append(updateFields, model.FieldEbaiID)
|
storeSku.EbaiID, err = api.EbaiAPI.SkuCreate(strStoreID, storeSku.SkuID, genSkuParamsFromStoreSkuInfo(storeSku))
|
||||||
_, err = api.EbaiAPI.SkuUpdate(strStoreID, storeSku.EbaiID, genSkuParamsFromStoreSkuInfo(storeSku))
|
} else {
|
||||||
|
storeSku.EbaiID = jxutils.GenFakeID()
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
updateFields = append(updateFields, model.FieldEbaiID)
|
||||||
|
} else if storeSku.EbaiID = ebaiapi.GetEbaiSkuIDFromError(err); storeSku.EbaiID > 0 {
|
||||||
|
// globals.SugarLogger.Debugf("SyncStoreSkus test storeSku.EbaiID:%d, err:%v", storeSku.EbaiID, err)
|
||||||
|
updateFields = append(updateFields, model.FieldEbaiID)
|
||||||
|
err = skuUpdate(strStoreID, storeSku)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("SKUANME%d:%s没有图片,同步失败", storeSku.NameID, storeSku.Name)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
updateFields = nil
|
||||||
}
|
}
|
||||||
} else if storeSku.EbaiSyncStatus&model.SyncFlagModifiedMask != 0 {
|
} else if storeSku.EbaiSyncStatus&model.SyncFlagStoreSkuModifiedMask != 0 {
|
||||||
if jxutils.IsFakeID(storeSku.EbaiID) {
|
if jxutils.IsEmptyID(storeSku.EbaiID) {
|
||||||
err = fmt.Errorf("京西数据异常,修改一个没有创建的饿百商品:%d, store:%s", storeSku.SkuID, strStoreID)
|
err = fmt.Errorf("京西数据异常,修改一个没有创建的饿百商品:%d, store:%s", storeSku.SkuID, strStoreID)
|
||||||
} else {
|
} else {
|
||||||
if _, err = api.EbaiAPI.SkuUpdate(strStoreID, storeSku.EbaiID, genSkuParamsFromStoreSkuInfo(storeSku)); err == nil {
|
if storeSku.Img != "" {
|
||||||
// err = api.EbaiAPI.SkuShopCategoryMap(strStoreID, storeSku.EbaiID, utils.Int64ToStr(storeSku.CatEbaiID))
|
err = skuUpdate(strStoreID, storeSku)
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("SKUANME%d:%s没有图片,同步失败", storeSku.NameID, storeSku.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
storeSku.EbaiSyncStatus = 0
|
if len(updateFields) > 0 {
|
||||||
_, err = dao.UpdateEntity(nil, &storeSku.StoreSkuBind, updateFields...)
|
storeSku.EbaiSyncStatus = 0
|
||||||
|
_, err = dao.UpdateEntity(nil, &storeSku.StoreSkuBind, updateFields...)
|
||||||
|
}
|
||||||
|
} else if isErrModifyPrice(err) {
|
||||||
|
err = partner.NewErrorCode(err.Error(), partner.ErrCodeChangePriceFailed, model.VendorIDEBAI)
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}, storeSkuInfoList)
|
}, storeSkuInfoList)
|
||||||
@@ -291,9 +325,58 @@ func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasks
|
|||||||
return rootTask.ID, err
|
return rootTask.ID, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PurchaseHandler) GetAllRemoteSkus(ctx *jxcontext.Context, storeID int, parentTask tasksch.ITask) (skus []map[string]interface{}, err error) {
|
func ignoreNoSkuErr(err error) error {
|
||||||
|
if err != nil {
|
||||||
|
if codeErr, ok := err.(*utils.ErrorWithCode); ok {
|
||||||
|
if codeErr.IntCode() == 1 {
|
||||||
|
for _, v := range []string{"SKU不存在或者已经被删除", "sku_id与shop_id不匹配"} {
|
||||||
|
if strings.Index(codeErr.ErrMsg(), v) > 0 {
|
||||||
|
err = nil
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func skuUpdate(strStoreID string, storeSku *tStoreSkuFullInfo) (err error) {
|
||||||
|
if globals.EnableEbaiStoreWrite {
|
||||||
|
if _, err = api.EbaiAPI.SkuUpdate(strStoreID, storeSku.EbaiID, genSkuParamsFromStoreSkuInfo(storeSku)); err != nil {
|
||||||
|
// 如果是改价错误,尝试把价格标志去掉再同步
|
||||||
|
if isErrModifyPrice(err) {
|
||||||
|
storeSku.EbaiSyncStatus = storeSku.EbaiSyncStatus & ^model.SyncFlagPriceMask
|
||||||
|
if storeSku.EbaiSyncStatus != 0 {
|
||||||
|
if _, err2 := api.EbaiAPI.SkuUpdate(strStoreID, storeSku.EbaiID, genSkuParamsFromStoreSkuInfo(storeSku)); err2 != nil {
|
||||||
|
err = err2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func isErrModifyPrice(err error) bool {
|
||||||
|
if errExt, ok := err.(*utils.ErrorWithCode); ok && errExt.IntCode() == 1 {
|
||||||
|
for _, v := range []string{
|
||||||
|
"无法修改价格",
|
||||||
|
"sku_参加营销活动",
|
||||||
|
} {
|
||||||
|
if strings.Index(errExt.ErrMsg(), v) >= 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetAllRemoteSkus(ctx *jxcontext.Context, storeID int, parentTask tasksch.ITask) (skus []*ebaiapi.SkuInfo, err error) {
|
||||||
globals.SugarLogger.Debugf("ebai GetAllRemoteSkus storeID:%d, userName:%s", storeID, ctx.GetUserName())
|
globals.SugarLogger.Debugf("ebai GetAllRemoteSkus storeID:%d, userName:%s", storeID, ctx.GetUserName())
|
||||||
page1, err := api.EbaiAPI.SkuList(utils.Int2Str(storeID), utils.Params2Map("pagesize", MaxPageSize))
|
page1, err := api.EbaiAPI.SkuList(utils.Int2Str(storeID), &ebaiapi.SkuListParams{
|
||||||
|
PageSize: MaxPageSize,
|
||||||
|
})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
skus = append(skus, page1.List...)
|
skus = append(skus, page1.List...)
|
||||||
if page1.Pages > 1 {
|
if page1.Pages > 1 {
|
||||||
@@ -303,9 +386,9 @@ func (p *PurchaseHandler) GetAllRemoteSkus(ctx *jxcontext.Context, storeID int,
|
|||||||
}
|
}
|
||||||
task := tasksch.NewParallelTask("GetAllRemoteSkus", nil, ctx,
|
task := tasksch.NewParallelTask("GetAllRemoteSkus", nil, ctx,
|
||||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
callParams := map[string]interface{}{
|
callParams := &ebaiapi.SkuListParams{
|
||||||
"pagesize": MaxPageSize,
|
PageSize: MaxPageSize,
|
||||||
"page": batchItemList[0],
|
Page: batchItemList[0].(int),
|
||||||
}
|
}
|
||||||
pageSku, err2 := api.EbaiAPI.SkuList(utils.Int2Str(storeID), callParams)
|
pageSku, err2 := api.EbaiAPI.SkuList(utils.Int2Str(storeID), callParams)
|
||||||
if err2 == nil {
|
if err2 == nil {
|
||||||
@@ -318,7 +401,7 @@ func (p *PurchaseHandler) GetAllRemoteSkus(ctx *jxcontext.Context, storeID int,
|
|||||||
result, err2 := task.GetResult(0)
|
result, err2 := task.GetResult(0)
|
||||||
if err = err2; err == nil {
|
if err = err2; err == nil {
|
||||||
for _, v := range result {
|
for _, v := range result {
|
||||||
skus = append(skus, v.(map[string]interface{}))
|
skus = append(skus, v.(*ebaiapi.SkuInfo))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -334,7 +417,7 @@ func (p *PurchaseHandler) DeleteRemoteSkus(ctx *jxcontext.Context, parentTask ta
|
|||||||
if err = err2; err == nil {
|
if err = err2; err == nil {
|
||||||
vendorSkuIDs = make([]string, len(result))
|
vendorSkuIDs = make([]string, len(result))
|
||||||
for k, v := range result {
|
for k, v := range result {
|
||||||
vendorSkuIDs[k] = utils.Interface2String(v[ebaiapi.KeySkuID])
|
vendorSkuIDs[k] = utils.Int64ToStr(v.SkuID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -344,7 +427,7 @@ func (p *PurchaseHandler) DeleteRemoteSkus(ctx *jxcontext.Context, parentTask ta
|
|||||||
for k, v := range batchItemList {
|
for k, v := range batchItemList {
|
||||||
strList[k] = v.(string)
|
strList[k] = v.(string)
|
||||||
}
|
}
|
||||||
if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite {
|
if globals.EnableEbaiStoreWrite {
|
||||||
err = api.EbaiAPI.SkuDelete(utils.Int2Str(storeID), strings.Join(strList, ","))
|
err = api.EbaiAPI.SkuDelete(utils.Int2Str(storeID), strings.Join(strList, ","))
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -369,7 +452,7 @@ func (p *PurchaseHandler) DeleteRemoteCategories(ctx *jxcontext.Context, parentT
|
|||||||
}
|
}
|
||||||
task := tasksch.NewParallelTask("DeleteRemoteCategories", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx,
|
task := tasksch.NewParallelTask("DeleteRemoteCategories", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx,
|
||||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite {
|
if globals.EnableEbaiStoreWrite {
|
||||||
err = api.EbaiAPI.ShopCategoryDelete(strStoreID, batchItemList[0].(int64))
|
err = api.EbaiAPI.ShopCategoryDelete(strStoreID, batchItemList[0].(int64))
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -385,11 +468,12 @@ func (p *PurchaseHandler) RefreshStoresAllSkusID(ctx *jxcontext.Context, parentT
|
|||||||
|
|
||||||
///////////
|
///////////
|
||||||
func genSkuParamsFromStoreSkuInfo(storeSku *tStoreSkuFullInfo) (params map[string]interface{}) {
|
func genSkuParamsFromStoreSkuInfo(storeSku *tStoreSkuFullInfo) (params map[string]interface{}) {
|
||||||
price := jxutils.CaculateSkuVendorPrice(storeSku.Price, storeSku.PricePercentage)
|
price := jxutils.CaculateSkuVendorPrice(storeSku.Price, storeSku.PricePercentage, storeSku.CatPricePercentage)
|
||||||
params = map[string]interface{}{
|
params = map[string]interface{}{
|
||||||
"name": jxutils.ComposeSkuName(storeSku.Prefix, storeSku.Name, storeSku.Comment, storeSku.Unit, storeSku.SpecQuality, storeSku.SpecUnit, 0),
|
"name": utils.LimitMixedStringLen(jxutils.ComposeSkuName(storeSku.Prefix, storeSku.Name, storeSku.Comment, storeSku.Unit, storeSku.SpecQuality, storeSku.SpecUnit, 0), ebaiapi.MaxSkuNameByteCount),
|
||||||
"left_num": model.MaxStoreSkuStockQty,
|
"left_num": model.MaxStoreSkuStockQty,
|
||||||
"category_id": storeSku.CatEbaiID,
|
"category_id": storeSku.CatEbaiID,
|
||||||
|
"predict_cat": 0, // 不使用推荐类目
|
||||||
"cat1_id": getEbaiCat(storeSku.EbaiCat1ID, 1),
|
"cat1_id": getEbaiCat(storeSku.EbaiCat1ID, 1),
|
||||||
"cat2_id": getEbaiCat(storeSku.EbaiCat2ID, 2),
|
"cat2_id": getEbaiCat(storeSku.EbaiCat2ID, 2),
|
||||||
"cat3_id": getEbaiCat(storeSku.EbaiCat3ID, 3),
|
"cat3_id": getEbaiCat(storeSku.EbaiCat3ID, 3),
|
||||||
@@ -401,6 +485,9 @@ func genSkuParamsFromStoreSkuInfo(storeSku *tStoreSkuFullInfo) (params map[strin
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
if storeSku.DescImgEbai != "" {
|
||||||
|
params["rtf"] = storeSku.DescImgEbai
|
||||||
|
}
|
||||||
if storeSku.EbaiSyncStatus&(model.SyncFlagPriceMask|model.SyncFlagNewMask) != 0 {
|
if storeSku.EbaiSyncStatus&(model.SyncFlagPriceMask|model.SyncFlagNewMask) != 0 {
|
||||||
params["sale_price"] = price
|
params["sale_price"] = price
|
||||||
params["market_price"] = price
|
params["market_price"] = price
|
||||||
@@ -516,18 +603,23 @@ func (p *PurchaseHandler) SyncStoreCategory(ctx *jxcontext.Context, parentTask t
|
|||||||
updateFields := []string{model.FieldEbaiSyncStatus}
|
updateFields := []string{model.FieldEbaiSyncStatus}
|
||||||
catInfo := batchItemList[0].(*tStoreCatInfo)
|
catInfo := batchItemList[0].(*tStoreCatInfo)
|
||||||
// globals.SugarLogger.Debug(utils.Format4Output(catInfo, false))
|
// globals.SugarLogger.Debug(utils.Format4Output(catInfo, false))
|
||||||
if globals.EnableStoreWrite && globals.EnableEbaiStoreWrite {
|
if catInfo.EbaiSyncStatus&model.SyncFlagDeletedMask != 0 { // 删除
|
||||||
if catInfo.EbaiSyncStatus&model.SyncFlagDeletedMask != 0 { // 删除
|
if catInfo.EbaiSyncStatus&model.SyncFlagNewMask == 0 && catInfo.EbaiID != 0 {
|
||||||
if catInfo.EbaiSyncStatus&model.SyncFlagNewMask == 0 && catInfo.EbaiID != 0 {
|
if globals.EnableEbaiStoreWrite {
|
||||||
err = api.EbaiAPI.ShopCategoryDelete(strStoreID, catInfo.EbaiID)
|
err = api.EbaiAPI.ShopCategoryDelete(strStoreID, catInfo.EbaiID)
|
||||||
}
|
}
|
||||||
} else if catInfo.EbaiSyncStatus&model.SyncFlagNewMask != 0 { // 新增
|
}
|
||||||
ebaiID, err2 := api.EbaiAPI.ShopCategoryCreate(strStoreID, catInfo.ParentEbaiID, formatName(catInfo.Name), jxCatSeq2Ebai(catInfo.Seq))
|
} else if catInfo.EbaiSyncStatus&model.SyncFlagNewMask != 0 { // 新增
|
||||||
if err = err2; err == nil {
|
if globals.EnableEbaiStoreWrite {
|
||||||
catInfo.EbaiID = ebaiID
|
catInfo.EbaiID, err = api.EbaiAPI.ShopCategoryCreate(strStoreID, catInfo.ParentEbaiID, formatName(catInfo.Name), jxCatSeq2Ebai(catInfo.Seq))
|
||||||
updateFields = append(updateFields, model.FieldEbaiID)
|
} else {
|
||||||
}
|
catInfo.EbaiID = jxutils.GenFakeID()
|
||||||
} else if catInfo.EbaiSyncStatus&model.SyncFlagModifiedMask != 0 { // 修改
|
}
|
||||||
|
if err == nil {
|
||||||
|
updateFields = append(updateFields, model.FieldEbaiID)
|
||||||
|
}
|
||||||
|
} else if catInfo.EbaiSyncStatus&model.SyncFlagModifiedMask != 0 { // 修改
|
||||||
|
if globals.EnableEbaiStoreWrite {
|
||||||
err = api.EbaiAPI.ShopCategoryUpdate(strStoreID, catInfo.EbaiID, formatName(catInfo.Name), jxCatSeq2Ebai(catInfo.Seq))
|
err = api.EbaiAPI.ShopCategoryUpdate(strStoreID, catInfo.EbaiID, formatName(catInfo.Name), jxCatSeq2Ebai(catInfo.Seq))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -603,7 +695,7 @@ func (p *PurchaseHandler) updateLocalCatAsNew(db *dao.DaoDB, localCatMap map[str
|
|||||||
|
|
||||||
func (p *PurchaseHandler) setStoreSkuSyncStatus(ctx *jxcontext.Context, db *dao.DaoDB, storeID int, skuIDs []int, syncStatus int) (num int64, err error) {
|
func (p *PurchaseHandler) setStoreSkuSyncStatus(ctx *jxcontext.Context, db *dao.DaoDB, storeID int, skuIDs []int, syncStatus int) (num int64, err error) {
|
||||||
globals.SugarLogger.Debugf("ebai setStoreSkuSyncStatus storeID:%d, userName:%s", storeID, ctx.GetUserName())
|
globals.SugarLogger.Debugf("ebai setStoreSkuSyncStatus storeID:%d, userName:%s", storeID, ctx.GetUserName())
|
||||||
return dao.SetStoreSkuSyncStatus(db, model.VendorIDEBAI, storeID, skuIDs, syncStatus)
|
return dao.SetStoreSkuSyncStatus(db, model.VendorIDEBAI, []int{storeID}, skuIDs, syncStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatName(name string) string {
|
func formatName(name string) string {
|
||||||
@@ -614,3 +706,7 @@ func formatName(name string) string {
|
|||||||
func jxCatSeq2Ebai(seq int) int {
|
func jxCatSeq2Ebai(seq int) int {
|
||||||
return 10000 - seq
|
return 10000 - seq
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetStoresSku(ctx *jxcontext.Context, parentTask tasksch.ITask, storeIDs []int) (storeSkuList []*model.StoreSkuBind, err error) {
|
||||||
|
return storeSkuList, err
|
||||||
|
}
|
||||||
|
|||||||
248
business/partner/purchase/ebai/store_sku2.go
Normal file
248
business/partner/purchase/ebai/store_sku2.go
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
package ebai
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi/ebaiapi"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
minBatchSize = 5 // 使用batch相关的API最少的处理数量,因为饿百批处理API的调用频率限制得更低
|
||||||
|
)
|
||||||
|
|
||||||
|
// 门店分类
|
||||||
|
func (p *PurchaseHandler) ReadStoreCategory(ctx *jxcontext.Context, vendorStoreID string) (cats []*partner.BareCategoryInfo, err error) {
|
||||||
|
remoteCats, err := api.EbaiAPI.ShopCategoryGet(vendorStoreID)
|
||||||
|
if err == nil {
|
||||||
|
cats = convertVendorCatList(remoteCats)
|
||||||
|
}
|
||||||
|
return cats, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertVendorCatList(remoteCats []*ebaiapi.CategoryInfo) (cats []*partner.BareCategoryInfo) {
|
||||||
|
for _, rCat := range remoteCats {
|
||||||
|
cat := &partner.BareCategoryInfo{
|
||||||
|
VendorCatID: utils.Int64ToStr(rCat.CategoryID),
|
||||||
|
Name: rCat.Name,
|
||||||
|
Level: rCat.Level,
|
||||||
|
Seq: jxCatSeq2Ebai(rCat.Rank),
|
||||||
|
Children: convertVendorCatList(rCat.Children),
|
||||||
|
}
|
||||||
|
cats = append(cats, cat)
|
||||||
|
}
|
||||||
|
return cats
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) CreateStoreSkuCategory(ctx *jxcontext.Context, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) {
|
||||||
|
var vendorCatID int64
|
||||||
|
if globals.EnableEbaiStoreWrite {
|
||||||
|
vendorCatID, err = api.EbaiAPI.ShopCategoryCreate(vendorStoreID, utils.Str2Int64WithDefault(storeCat.ParentVendorCatID, 0), storeCat.Name, jxCatSeq2Ebai(storeCat.Seq))
|
||||||
|
} else {
|
||||||
|
vendorCatID = jxutils.GenFakeID()
|
||||||
|
}
|
||||||
|
storeCat.VendorCatID = utils.Int64ToStr(vendorCatID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) UpdateStoreSkuCategory(ctx *jxcontext.Context, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) {
|
||||||
|
if globals.EnableEbaiStoreWrite {
|
||||||
|
err = api.EbaiAPI.ShopCategoryUpdate(vendorStoreID, utils.Str2Int64WithDefault(storeCat.VendorCatID, 0), storeCat.Name, jxCatSeq2Ebai(storeCat.Seq))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) DeleteStoreSkuCategory(ctx *jxcontext.Context, vendorStoreID, vendorCatID string) (err error) {
|
||||||
|
if globals.EnableEbaiStoreWrite {
|
||||||
|
err = api.EbaiAPI.ShopCategoryDelete(vendorStoreID, utils.Str2Int64WithDefault(vendorCatID, 0))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 门店商品
|
||||||
|
|
||||||
|
// 多门店平台不需要实现这个接口
|
||||||
|
func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (err error) {
|
||||||
|
storeSku := storeSkuList[0]
|
||||||
|
if globals.EnableEbaiStoreWrite {
|
||||||
|
_, err = api.EbaiAPI.SkuUpdate(vendorStoreID, utils.Str2Int64(storeSku.VendorSkuID), genSkuParamsFromStoreSkuInfo2(storeSku))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通用
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对于多门店平台来说,storeSkuList中只有SkuID与VendorSkuID有意义
|
||||||
|
func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (err error) {
|
||||||
|
storeSku := storeSkuList[0]
|
||||||
|
var vendorSkuID int64
|
||||||
|
if globals.EnableEbaiStoreWrite {
|
||||||
|
vendorSkuID, err = api.EbaiAPI.SkuCreate(vendorStoreID, storeSku.SkuID, genSkuParamsFromStoreSkuInfo2(storeSku))
|
||||||
|
} else {
|
||||||
|
vendorSkuID = jxutils.GenFakeID()
|
||||||
|
}
|
||||||
|
storeSku.VendorSkuID = utils.Int64ToStr(vendorSkuID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.BareStoreSkuInfo) (err error) {
|
||||||
|
if globals.EnableEbaiStoreWrite {
|
||||||
|
err = api.EbaiAPI.SkuDelete(vendorStoreID, strings.Join(partner.BareStoreSkuInfoList(storeSkuList).GetVendorSkuIDList(), ","))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.BareStoreSkuInfo) (err error) {
|
||||||
|
var validSkus, invalidSkus []string
|
||||||
|
for _, storeSku := range storeSkuList {
|
||||||
|
if storeSku.Status == model.SkuStatusNormal {
|
||||||
|
validSkus = append(validSkus, storeSku.VendorSkuID)
|
||||||
|
} else {
|
||||||
|
invalidSkus = append(invalidSkus, storeSku.VendorSkuID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if globals.EnableEbaiStoreWrite {
|
||||||
|
if len(invalidSkus) > minBatchSize {
|
||||||
|
err = api.EbaiAPI.SkuOffline(utils.Int2Str(storeID), strings.Join(invalidSkus, ","))
|
||||||
|
} else if len(invalidSkus) > 0 {
|
||||||
|
for _, v := range invalidSkus {
|
||||||
|
if err = api.EbaiAPI.SkuOfflineOne(utils.Int2Str(storeID), utils.Str2Int64(v), "", ""); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
if len(validSkus) > minBatchSize {
|
||||||
|
err = api.EbaiAPI.SkuOnline(utils.Int2Str(storeID), strings.Join(validSkus, ","))
|
||||||
|
} else if len(validSkus) > 0 {
|
||||||
|
for _, v := range invalidSkus {
|
||||||
|
if err = api.EbaiAPI.SkuOnlineOne(utils.Int2Str(storeID), utils.Str2Int64(v), "", ""); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.BareStoreSkuInfo) (err error) {
|
||||||
|
skuPriceList := make([]string, len(storeSkuList))
|
||||||
|
for k, v := range storeSkuList {
|
||||||
|
skuPriceList[k] = fmt.Sprintf("%s:%d", v.VendorSkuID, v.Price)
|
||||||
|
}
|
||||||
|
if globals.EnableEbaiStoreWrite {
|
||||||
|
if len(skuPriceList) > minBatchSize {
|
||||||
|
err = api.EbaiAPI.SkuPriceUpdateBatch(utils.Int2Str(storeID), strings.Join(skuPriceList, ";"), "", "")
|
||||||
|
} else {
|
||||||
|
for _, v := range skuPriceList {
|
||||||
|
if err = api.EbaiAPI.SkuPriceUpdateOne(utils.Int2Str(storeID), v, "", ""); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func genSkuParamsFromStoreSkuInfo2(storeSku *dao.StoreSkuSyncInfo) (params map[string]interface{}) {
|
||||||
|
params = map[string]interface{}{
|
||||||
|
"name": storeSku.Name,
|
||||||
|
"left_num": model.MaxStoreSkuStockQty,
|
||||||
|
"category_id": utils.Str2Int64(storeSku.VendorCatID),
|
||||||
|
"predict_cat": 0, // 不使用推荐类目
|
||||||
|
"cat1_id": getEbaiCat(storeSku.VendorVendorCatID3, 1),
|
||||||
|
"cat2_id": getEbaiCat(storeSku.VendorVendorCatID2, 2),
|
||||||
|
"cat3_id": getEbaiCat(storeSku.VendorVendorCatID, 3),
|
||||||
|
"weight": storeSku.Weight,
|
||||||
|
"photos": []map[string]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"is_master": true,
|
||||||
|
"url": storeSku.Img,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if storeSku.DescImg != "" {
|
||||||
|
params["rtf"] = storeSku.DescImg
|
||||||
|
}
|
||||||
|
if storeSku.StoreSkuSyncStatus&(model.SyncFlagPriceMask|model.SyncFlagNewMask) != 0 {
|
||||||
|
params["sale_price"] = storeSku.Price
|
||||||
|
params["market_price"] = storeSku.Price
|
||||||
|
}
|
||||||
|
if storeSku.StoreSkuSyncStatus&(model.SyncFlagSaleMask|model.SyncFlagNewMask) != 0 {
|
||||||
|
params["status"] = jxSkuStatus2Ebai(storeSku.StoreSkuStatus)
|
||||||
|
}
|
||||||
|
// todo 饿百如果给的UPC是空要报错,但如果我要删除UPC怎么弄?
|
||||||
|
if storeSku.Upc != "" {
|
||||||
|
params["upc"] = storeSku.Upc
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetStoreSkusInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.BareStoreSkuInfo) (outStoreSkuList []*partner.BareStoreSkuInfo, err error) {
|
||||||
|
vendorSkuIDIntList := partner.BareStoreSkuInfoList(inStoreSkuList).GetVendorSkuIDIntList()
|
||||||
|
var vendorSkuList []*ebaiapi.SkuInfo
|
||||||
|
if len(vendorSkuIDIntList) > 1 {
|
||||||
|
task := tasksch.NewParallelTask("获取饿百平台门店商品信息", nil, ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
vendorSkuID := batchItemList[0].(int64)
|
||||||
|
skuInfo, err := api.EbaiAPI.SkuList(utils.Int2Str(storeID), &ebaiapi.SkuListParams{
|
||||||
|
SkuID: vendorSkuID,
|
||||||
|
})
|
||||||
|
if err == nil {
|
||||||
|
vendorSkuList = skuInfo.List
|
||||||
|
return skuInfo.List, nil
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}, vendorSkuIDIntList)
|
||||||
|
tasksch.HandleTask(task, parentTask, false).Run()
|
||||||
|
_, err = task.GetResult(0)
|
||||||
|
} else if len(vendorSkuIDIntList) == 1 {
|
||||||
|
skuInfo, err2 := api.EbaiAPI.SkuList(utils.Int2Str(storeID), &ebaiapi.SkuListParams{
|
||||||
|
SkuID: vendorSkuIDIntList[0],
|
||||||
|
})
|
||||||
|
if err = err2; err == nil {
|
||||||
|
vendorSkuList = skuInfo.List
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
storeSkuMap := make(map[int64]*partner.BareStoreSkuInfo)
|
||||||
|
for _, v := range inStoreSkuList {
|
||||||
|
storeSkuMap[utils.Str2Int64(v.VendorSkuID)] = v
|
||||||
|
}
|
||||||
|
for _, skuInfo := range vendorSkuList {
|
||||||
|
storeSku := storeSkuMap[skuInfo.SkuID]
|
||||||
|
globals.SugarLogger.Debug(utils.Format4Output(storeSku, false))
|
||||||
|
outStoreSkuList = append(outStoreSkuList, storeSku)
|
||||||
|
storeSku.Price = skuInfo.SalePrice
|
||||||
|
storeSku.Status = ebaiSkuStatus2Jx(skuInfo.Status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return outStoreSkuList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ebaiSkuStatus2Jx(ebaiSkuStatus int) (jxSkuStatus int) {
|
||||||
|
if ebaiSkuStatus == ebaiapi.SkuStatusOnline {
|
||||||
|
jxSkuStatus = model.SkuStatusNormal
|
||||||
|
} else if ebaiSkuStatus == ebaiapi.SkuStatusOffline {
|
||||||
|
jxSkuStatus = model.SkuStatusDontSale
|
||||||
|
} else if ebaiSkuStatus == ebaiapi.SkuStatusOnline {
|
||||||
|
jxSkuStatus = model.SkuStatusDeleted
|
||||||
|
}
|
||||||
|
return jxSkuStatus
|
||||||
|
}
|
||||||
@@ -18,10 +18,10 @@ var (
|
|||||||
ebaiapi.WaybillStatusCourierPickedup: model.WaybillStatusDelivering,
|
ebaiapi.WaybillStatusCourierPickedup: model.WaybillStatusDelivering,
|
||||||
ebaiapi.WaybillStatusDeliveryCancled: model.WaybillStatusCanceled,
|
ebaiapi.WaybillStatusDeliveryCancled: model.WaybillStatusCanceled,
|
||||||
ebaiapi.WaybillStatusFinished: model.WaybillStatusDelivered,
|
ebaiapi.WaybillStatusFinished: model.WaybillStatusDelivered,
|
||||||
ebaiapi.WaybillStatusExceptional: model.WaybillStatusUnknown,
|
ebaiapi.WaybillStatusExceptional: model.WaybillStatusCanceled,
|
||||||
ebaiapi.WaybillStatusSelfDelivery: model.WaybillStatusUnknown,
|
ebaiapi.WaybillStatusSelfDelivery: model.WaybillStatusUnknown,
|
||||||
ebaiapi.WaybillStatusNotInDelivering: model.WaybillStatusUnknown,
|
ebaiapi.WaybillStatusDontDeliver: model.WaybillStatusCanceled,
|
||||||
ebaiapi.WaybillStatusDeliveryRejected: model.WaybillStatusNeverSend,
|
ebaiapi.WaybillStatusDeliveryRejected: model.WaybillStatusCanceled,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
19
business/partner/purchase/elm/act.go
Normal file
19
business/partner/purchase/elm/act.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package elm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) CancelAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
"git.rosy.net.cn/jx-callback/business/partner"
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -186,47 +187,23 @@ func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo
|
|||||||
SalePrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(product["price"])),
|
SalePrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(product["price"])),
|
||||||
Weight: int(math.Round(utils.Interface2Float64WithDefault(product["weight"], 0.0))),
|
Weight: int(math.Round(utils.Interface2Float64WithDefault(product["weight"], 0.0))),
|
||||||
}
|
}
|
||||||
if sku.VendorSkuID == "0" {
|
if dao.IsVendorThingIDEmpty(sku.VendorSkuID) {
|
||||||
sku.VendorSkuID = utils.Int64ToStr(utils.MustInterface2Int64(product["id"])) // 2018-09-28日,饿了么迁移到饿百后,这个字段发生了变化
|
sku.VendorSkuID = utils.Int64ToStr(utils.MustInterface2Int64(product["id"])) // 2018-09-28日,饿了么迁移到饿百后,这个字段发生了变化
|
||||||
}
|
}
|
||||||
order.Skus = append(order.Skus, sku)
|
order.Skus = append(order.Skus, sku)
|
||||||
order.SkuCount++
|
|
||||||
order.GoodsCount += sku.Count
|
|
||||||
order.SalePrice += sku.SalePrice * int64(sku.Count)
|
|
||||||
order.Weight += sku.Weight * sku.Count
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setOrederDetailFee(result, order)
|
jxutils.RefreshOrderSkuRelated(order)
|
||||||
return order
|
return order
|
||||||
}
|
}
|
||||||
|
|
||||||
func setOrederDetailFee(result map[string]interface{}, order *model.GoodsOrder) {
|
|
||||||
orderActivities, ok := result["orderActivities"].([]interface{})
|
|
||||||
if ok {
|
|
||||||
for _, value := range orderActivities {
|
|
||||||
activity := value.(map[string]interface{})
|
|
||||||
categoryId := utils.MustInterface2Int64(activity["categoryId"])
|
|
||||||
restaurantPart := -jxutils.StandardPrice2Int(utils.MustInterface2Float64(activity["restaurantPart"]))
|
|
||||||
elemePart := -jxutils.StandardPrice2Int(utils.MustInterface2Float64(activity["elemePart"]))
|
|
||||||
if _, ok := model.ElmSkuPromotion[int(categoryId)]; ok {
|
|
||||||
order.SkuPmFee += restaurantPart
|
|
||||||
order.SkuPmSubsidy += elemePart
|
|
||||||
} else {
|
|
||||||
order.OrderPmFee += restaurantPart
|
|
||||||
order.OrderPmSubsidy += elemePart
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
order.PlatformFeeRate = int16(utils.MustInterface2Float64(result["serviceRate"]))
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
func (c *PurchaseHandler) onOrderNew(msg map[string]interface{}) (response *elmapi.CallbackResponse) {
|
func (c *PurchaseHandler) onOrderNew(msg map[string]interface{}) (response *elmapi.CallbackResponse) {
|
||||||
// todo 这里应该可以直接用msg里的内容,而不用再次去查
|
// todo 这里应该可以直接用msg里的内容,而不用再次去查
|
||||||
order, err := c.GetOrder(msg["orderId"].(string))
|
order, err := c.GetOrder(msg["orderId"].(string))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
order.VendorStatus = c.stateAndType2Str(order.VendorStatus, elmapi.MsgTypeOrderValid)
|
order.VendorStatus = c.stateAndType2Str(order.VendorStatus, elmapi.MsgTypeOrderValid)
|
||||||
err = partner.CurOrderManager.OnOrderNew(order, c.stateAndType2Str(msg["status"].(string), elmapi.MsgTypeOrderValid))
|
err = partner.CurOrderManager.OnOrderNew(order, nil)
|
||||||
// if globals.HandleLegacyJxOrder && err == nil {
|
// if globals.HandleLegacyJxOrder && err == nil {
|
||||||
// c.legacyWriteElmOrder(order)
|
// c.legacyWriteElmOrder(order)
|
||||||
// }
|
// }
|
||||||
|
|||||||
16
business/partner/purchase/elm/order_afs.go
Normal file
16
business/partner/purchase/elm/order_afs.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package elm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 审核售后单申请
|
||||||
|
func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认收到退货
|
||||||
|
func (c *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -3,6 +3,8 @@ package elm
|
|||||||
import (
|
import (
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
"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/jxutils/tasksch"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *PurchaseHandler) SyncStoreCategory(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync bool) (hint string, err error) {
|
func (p *PurchaseHandler) SyncStoreCategory(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync bool) (hint string, err error) {
|
||||||
@@ -24,3 +26,11 @@ func (p *PurchaseHandler) FullSyncStoreSkus(ctx *jxcontext.Context, parentTask t
|
|||||||
func (p *PurchaseHandler) DeleteRemoteStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
func (p *PurchaseHandler) DeleteRemoteStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
return hint, err
|
return hint, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetStoresSku(ctx *jxcontext.Context, parentTask tasksch.ITask, storeIDs []int) (storeSkuList []*model.StoreSkuBind, err error) {
|
||||||
|
return storeSkuList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetStoreSkusInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.BareStoreSkuInfo) (outStoreSkuList []*partner.BareStoreSkuInfo, err error) {
|
||||||
|
return outStoreSkuList, err
|
||||||
|
}
|
||||||
|
|||||||
183
business/partner/purchase/jd/act.go
Normal file
183
business/partner/purchase/jd/act.go
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
package jd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"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"
|
||||||
|
)
|
||||||
|
|
||||||
|
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 api.JdAPI.CreatePromotionInfosSingle(name, beginDate, endDate, outInfoId, advertising, traceId)
|
||||||
|
} else {
|
||||||
|
return api.JdAPI.CreatePromotionInfosLimitTime(name, beginDate, endDate, outInfoId, advertising, traceId)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
infoId = jxutils.GenFakeID()
|
||||||
|
}
|
||||||
|
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 api.JdAPI.CreatePromotionRulesSingle(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily, traceId)
|
||||||
|
} else {
|
||||||
|
return api.JdAPI.CreatePromotionRulesLimitTime(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily, traceId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreatePromotionSku(promotionType int, infoId int64, outInfoId string, skus []*jdapi.PromotionSku, traceId string) (skusResult []*jdapi.PromotionSku, err error) {
|
||||||
|
if globals.EnableJdStoreWrite {
|
||||||
|
if promotionType == model.ActSkuDirectDown {
|
||||||
|
return api.JdAPI.CreatePromotionSkuSingle(infoId, outInfoId, skus, traceId)
|
||||||
|
} else {
|
||||||
|
return api.JdAPI.CreatePromotionSkuLimitTime(infoId, outInfoId, skus, traceId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return skusResult, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func CancelPromotionSku(promotionType int, infoId int64, outInfoId string, skus []*jdapi.PromotionSku, traceId string) (err error) {
|
||||||
|
if globals.EnableJdStoreWrite {
|
||||||
|
if promotionType == model.ActSkuDirectDown {
|
||||||
|
return api.JdAPI.CancelPromotionSkuSingle(infoId, outInfoId, skus, traceId)
|
||||||
|
} else {
|
||||||
|
return api.JdAPI.CancelPromotionSkuLimitTime(infoId, outInfoId, skus, traceId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConfirmPromotion(promotionType int, infoId int64, outInfoId, traceId string) (err error) {
|
||||||
|
if globals.EnableJdStoreWrite {
|
||||||
|
if promotionType == model.ActSkuDirectDown {
|
||||||
|
return api.JdAPI.ConfirmPromotionSingle(infoId, outInfoId, traceId)
|
||||||
|
} else {
|
||||||
|
return api.JdAPI.ConfirmPromotionLimitTime(infoId, outInfoId, traceId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func CancelPromotion(promotionType int, infoId int64, outInfoId, traceId string) (err error) {
|
||||||
|
if globals.EnableJdStoreWrite {
|
||||||
|
if promotionType == model.ActSkuDirectDown {
|
||||||
|
return api.JdAPI.CancelPromotionSingle(infoId, outInfoId, traceId)
|
||||||
|
} else {
|
||||||
|
return api.JdAPI.CancelPromotionLimitTime(infoId, outInfoId, traceId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func AdjustPromotionTime(promotionType int, infoId int64, outInfoId string, endDate time.Time, traceId string) (err error) {
|
||||||
|
if globals.EnableJdStoreWrite {
|
||||||
|
if promotionType == model.ActSkuDirectDown {
|
||||||
|
return api.JdAPI.AdjustPromotionTimeSingle(infoId, outInfoId, endDate, traceId)
|
||||||
|
} else {
|
||||||
|
return api.JdAPI.AdjustPromotionTimeLimitTime(infoId, outInfoId, endDate, traceId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func AdjustPromotionSku(promotionType int, infoId int64, outInfoId string, skus []*jdapi.PromotionSku, traceId string) (skusResult []*jdapi.PromotionSku, err error) {
|
||||||
|
if globals.EnableJdStoreWrite {
|
||||||
|
if promotionType == model.ActSkuDirectDown {
|
||||||
|
return api.JdAPI.AdjustPromotionSkuSingle(infoId, outInfoId, skus, traceId)
|
||||||
|
} else {
|
||||||
|
return api.JdAPI.AdjustPromotionSkuLimitTime(infoId, outInfoId, skus, traceId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return skusResult, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTraceID(ctx *jxcontext.Context) (traceID string) {
|
||||||
|
traceID = ctx.GetUserName() + utils.GetUUID()
|
||||||
|
return traceID
|
||||||
|
}
|
||||||
|
|
||||||
|
func storeSku2Jd(actStoreSku []*model.ActStoreSku2, handler func(syncStatus int) bool) (jdActStoreSku []*jdapi.PromotionSku) {
|
||||||
|
for _, v := range actStoreSku {
|
||||||
|
if handler(v.SyncStatus) {
|
||||||
|
jdActStoreSku = append(jdActStoreSku, &jdapi.PromotionSku{
|
||||||
|
StationNo: utils.Str2Int64(v.VendorStoreID),
|
||||||
|
SkuID: utils.Str2Int64(v.VendorSkuID),
|
||||||
|
PromotionPrice: v.ActPrice,
|
||||||
|
// LimitSkuCount:0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return jdActStoreSku
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
|
||||||
|
traceID := getTraceID(ctx)
|
||||||
|
if act.Type < model.ActOrderBegin {
|
||||||
|
outInfoID := utils.Int2Str(act.ID)
|
||||||
|
infoID, err2 := CreatePromotionInfos(act.Type, act.Name, act.BeginAt, act.EndAt, outInfoID, act.Advertising, traceID)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
act.VendorActID = utils.Int64ToStr(infoID)
|
||||||
|
if err = CreatePromotionRules(act.Type, infoID, "", act.LimitDevice, act.LimitPin, act.LimitCount, act.LimitDaily, traceID); err == nil {
|
||||||
|
if _, err = CreatePromotionSku(act.Type, infoID, "", storeSku2Jd(actStoreSku, model.IsSyncStatusNeedCreate), traceID); err == nil {
|
||||||
|
err = ConfirmPromotion(act.Type, infoID, "", traceID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
|
||||||
|
traceID := getTraceID(ctx)
|
||||||
|
if act.Type < model.ActOrderBegin {
|
||||||
|
outInfoID := utils.Int2Str(act.ID)
|
||||||
|
if !utils.IsTimeZero(act.EndAt) {
|
||||||
|
if err = AdjustPromotionTime(act.Type, 0, outInfoID, act.EndAt, traceID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if toBeDeleted := storeSku2Jd(actStoreSku, model.IsSyncStatusNeedDelete); len(toBeDeleted) > 0 {
|
||||||
|
if err = CancelPromotionSku(act.Type, 0, outInfoID, toBeDeleted, traceID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if toBeAdded := storeSku2Jd(actStoreSku, model.IsSyncStatusNeedDelete); len(toBeAdded) > 0 {
|
||||||
|
// if _, err = CreatePromotionSku(act.Type, 0, outInfoID, toBeAdded, traceID); err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if toBeUpdated := storeSku2Jd(actStoreSku, model.IsSyncStatusNeedDelete); len(toBeUpdated) > 0 {
|
||||||
|
// if _, err = AdjustPromotionSku(act.Type, 0, outInfoID, toBeUpdated, traceID); err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) CancelAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
|
||||||
|
traceID := getTraceID(ctx)
|
||||||
|
if act.Type < model.ActOrderBegin {
|
||||||
|
outInfoID := utils.Int2Str(act.ID)
|
||||||
|
err = CancelPromotion(act.Type, 0, outInfoID, traceID)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -1,42 +1,26 @@
|
|||||||
package jd
|
package jd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func OnOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
|
func OnOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
|
||||||
if curPurchaseHandler != nil {
|
if curPurchaseHandler != nil {
|
||||||
if retVal = curPurchaseHandler.OnOrderMsg(msg); retVal == nil {
|
retVal = curPurchaseHandler.OnOrderMsg(msg)
|
||||||
retVal = jdapi.Err2CallbackResponse(errors.New("Internal Error"), "")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return retVal
|
return retVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func OnWaybillMsg(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) {
|
func OnWaybillMsg(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) {
|
||||||
if curPurchaseHandler != nil {
|
if curPurchaseHandler != nil {
|
||||||
if retVal = curPurchaseHandler.OnWaybillMsg(msg); retVal == nil {
|
retVal = curPurchaseHandler.OnWaybillMsg(msg)
|
||||||
retVal = jdapi.Err2CallbackResponse(errors.New("Internal Error"), "")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return retVal
|
return retVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func OnStoreMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
|
func OnStoreMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
|
||||||
if curPurchaseHandler != nil {
|
if curPurchaseHandler != nil {
|
||||||
retVal = curPurchaseHandler.onStoreMsg(msg)
|
retVal = curPurchaseHandler.OnStoreMsg(msg)
|
||||||
}
|
|
||||||
return retVal
|
|
||||||
}
|
|
||||||
|
|
||||||
func OnAfterSaleMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
|
|
||||||
if curPurchaseHandler != nil {
|
|
||||||
utils.CallFuncAsync(func() {
|
|
||||||
OnFinancialMsg(msg)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return retVal
|
return retVal
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,15 @@ import (
|
|||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) OnFinancialMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
|
||||||
|
utils.CallFuncAsync(func() {
|
||||||
|
retVal = p.onFinancialMsg(msg)
|
||||||
|
})
|
||||||
|
return retVal
|
||||||
|
}
|
||||||
|
|
||||||
// 京东正向/退款订单类型处理--存储
|
// 京东正向/退款订单类型处理--存储
|
||||||
func OnFinancialMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
|
func (p *PurchaseHandler) onFinancialMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
|
||||||
var err error
|
var err error
|
||||||
// if msg.StatusID == jdapi.OrderStatusPayFinishedSettle || msg.StatusID == jdapi.OrderStatusTipChanged || msg.StatusID == jdapi.OrderStatusSwitch2SelfSettle { // 如果是正向单
|
// if msg.StatusID == jdapi.OrderStatusPayFinishedSettle || msg.StatusID == jdapi.OrderStatusTipChanged || msg.StatusID == jdapi.OrderStatusSwitch2SelfSettle { // 如果是正向单
|
||||||
if msg.StatusID == jdapi.OrderStatusPayFinishedSettle || msg.StatusID == jdapi.OrderStatusTipChanged || msg.StatusID == jdapi.OrderStatusAdjustSettle || msg.StatusID == jdapi.OrderStatusSwitch2SelfSettle { // 如果是正向单
|
if msg.StatusID == jdapi.OrderStatusPayFinishedSettle || msg.StatusID == jdapi.OrderStatusTipChanged || msg.StatusID == jdapi.OrderStatusAdjustSettle || msg.StatusID == jdapi.OrderStatusSwitch2SelfSettle { // 如果是正向单
|
||||||
@@ -30,7 +37,7 @@ func OnFinancialMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse
|
|||||||
} else {
|
} else {
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
} else if msg.StatusID == jdapi.SaleBillStatusRefundSuccess || msg.StatusID == jdapi.SaleBillStatusSaleReturnSuccess { // 如果是退款单
|
} else if msg.StatusID == jdapi.AfsServiceStateRefundSuccess || msg.StatusID == jdapi.AfsServiceStateReturnGoodsSuccess { // 如果是退款单
|
||||||
orderData, err2 := api.JdAPI.GetAfsService(msg.BillID)
|
orderData, err2 := api.JdAPI.GetAfsService(msg.BillID)
|
||||||
if err = err2; err == nil {
|
if err = err2; err == nil {
|
||||||
err = partner.CurOrderManager.SaveAfsOrderFinancialInfo(curPurchaseHandler.AfsOrderDetail2Financial(orderData))
|
err = partner.CurOrderManager.SaveAfsOrderFinancialInfo(curPurchaseHandler.AfsOrderDetail2Financial(orderData))
|
||||||
@@ -127,18 +134,20 @@ func (p *PurchaseHandler) OrderDetail2Financial(orderData map[string]interface{}
|
|||||||
orderFinancial.TotalDiscountMoney += discountPrice
|
orderFinancial.TotalDiscountMoney += discountPrice
|
||||||
if xMap["orderShareRatioData"] != nil {
|
if xMap["orderShareRatioData"] != nil {
|
||||||
orderShareRatioData, _ := utils.HTTPBody2Values([]byte(utils.Interface2String(xMap["orderShareRatioData"])), false)
|
orderShareRatioData, _ := utils.HTTPBody2Values([]byte(utils.Interface2String(xMap["orderShareRatioData"])), false)
|
||||||
activity := &model.OrderDiscountFinancial{
|
if promotionID := orderShareRatioData.Get("promotionId"); promotionID != "" {
|
||||||
VendorID: orderFinancial.VendorID,
|
activity := &model.OrderDiscountFinancial{
|
||||||
VendorOrderID: orderFinancial.VendorOrderID,
|
VendorID: orderFinancial.VendorID,
|
||||||
VendorActivityID: utils.Interface2String(orderShareRatioData["promotionId"][0]),
|
VendorOrderID: orderFinancial.VendorOrderID,
|
||||||
Type: utils.Int64ToStr(int64(discountType)),
|
VendorActivityID: promotionID, // utils.Interface2String(orderShareRatioData["promotionId"][0]),
|
||||||
// ActivityName: utils.Interface2String(xMap["discountName"]),
|
Type: utils.Int64ToStr(int64(discountType)),
|
||||||
// ActivityMoney: discountPrice,
|
// ActivityName: utils.Interface2String(xMap["discountName"]),
|
||||||
// Remark: utils.Interface2String(xMap["orderShareRatioData"]),
|
// ActivityMoney: discountPrice,
|
||||||
|
// Remark: utils.Interface2String(xMap["orderShareRatioData"]),
|
||||||
|
}
|
||||||
|
orderFinancial.Discounts = append(orderFinancial.Discounts, activity)
|
||||||
|
// 通过活动Id去取,京西活动补贴
|
||||||
|
// orderFinancial.JxSubsidyMoney +=
|
||||||
}
|
}
|
||||||
orderFinancial.Discounts = append(orderFinancial.Discounts, activity)
|
|
||||||
// 通过活动Id去取,京西活动补贴
|
|
||||||
// orderFinancial.JxSubsidyMoney +=
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
globals.SugarLogger.Debug(utils.Format4Output(orderFinancial.Discounts, false))
|
globals.SugarLogger.Debug(utils.Format4Output(orderFinancial.Discounts, false))
|
||||||
@@ -154,7 +163,7 @@ func (p *PurchaseHandler) OrderDetail2Financial(orderData map[string]interface{}
|
|||||||
orderFinancial.PmSubsidyMoney = utils.Interface2Int64WithDefault(order1["platOrderGoodsDiscountMoney"], 0) + orderFinancial.PmSkuSubsidyMoney
|
orderFinancial.PmSubsidyMoney = utils.Interface2Int64WithDefault(order1["platOrderGoodsDiscountMoney"], 0) + orderFinancial.PmSkuSubsidyMoney
|
||||||
} else {
|
} else {
|
||||||
if !isFromOrderDetail {
|
if !isFromOrderDetail {
|
||||||
globals.SugarLogger.Warnf("jd OrderDetail2Financial, orderID:%s is not found from api.JdAPI.OrderShoudSettlementService", orderFinancial.VendorOrderID)
|
globals.SugarLogger.Warnf("jd OrderDetail2Financial, orderID:%s is not found from api.JdAPI.OrderShoudSettlementService, err:%v", orderFinancial.VendorOrderID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return orderFinancial, err
|
return orderFinancial, err
|
||||||
@@ -168,7 +177,7 @@ func (p *PurchaseHandler) AfsOrderDetail2Financial(orderData map[string]interfac
|
|||||||
VendorOrderID: utils.Interface2String(orderData["orderId"]),
|
VendorOrderID: utils.Interface2String(orderData["orderId"]),
|
||||||
VendorStoreID: utils.Interface2String(orderData["stationId"]),
|
VendorStoreID: utils.Interface2String(orderData["stationId"]),
|
||||||
StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(orderData["stationNumOutSystem"]), 0)),
|
StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(orderData["stationNumOutSystem"]), 0)),
|
||||||
AfsCreateAt: utils.Timestamp2Time(utils.MustInterface2Int64(orderData["updateTime"].(map[string]interface{})["time"]) / 1000),
|
AfsCreatedAt: utils.Timestamp2Time(utils.MustInterface2Int64(orderData["updateTime"].(map[string]interface{})["time"]) / 1000),
|
||||||
FreightUserMoney: utils.MustInterface2Int64(orderData["orderFreightMoney"]),
|
FreightUserMoney: utils.MustInterface2Int64(orderData["orderFreightMoney"]),
|
||||||
AfsFreightMoney: utils.MustInterface2Int64(orderData["afsFreight"]),
|
AfsFreightMoney: utils.MustInterface2Int64(orderData["afsFreight"]),
|
||||||
BoxMoney: utils.MustInterface2Int64(orderData["packagingMoney"]),
|
BoxMoney: utils.MustInterface2Int64(orderData["packagingMoney"]),
|
||||||
|
|||||||
@@ -12,6 +12,6 @@ func TestOnFinancialMsg(t *testing.T) {
|
|||||||
BillID: "907315020000322",
|
BillID: "907315020000322",
|
||||||
StatusID: "330902",
|
StatusID: "330902",
|
||||||
}
|
}
|
||||||
res := OnFinancialMsg(msg)
|
res := curPurchaseHandler.onFinancialMsg(msg)
|
||||||
fmt.Println(res)
|
fmt.Println(res)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ func JdStoreStatus2JxStatus(yn, closeStatus interface{}) int {
|
|||||||
if yn2 == 1 {
|
if yn2 == 1 {
|
||||||
return model.StoreStatusDisabled
|
return model.StoreStatusDisabled
|
||||||
} else if closeStatus2 == 1 {
|
} else if closeStatus2 == 1 {
|
||||||
return model.StoreStatusClosed
|
return model.StoreStatusHaveRest
|
||||||
}
|
}
|
||||||
return model.StoreStatusOpened
|
return model.StoreStatusOpened
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ func JxStoreStatus2JdStatus(status int) (yn, closeStatus int) {
|
|||||||
switch status {
|
switch status {
|
||||||
case model.StoreStatusDisabled:
|
case model.StoreStatusDisabled:
|
||||||
return 1, 1
|
return 1, 1
|
||||||
case model.StoreStatusClosed:
|
case model.StoreStatusHaveRest, model.StoreStatusClosed:
|
||||||
return 0, 1
|
return 0, 1
|
||||||
default:
|
default:
|
||||||
return 0, 0
|
return 0, 0
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/autonavi"
|
"git.rosy.net.cn/baseapi/platformapi/autonavi"
|
||||||
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
@@ -19,8 +21,8 @@ import (
|
|||||||
var (
|
var (
|
||||||
VendorStatus2StatusMap = map[string]int{
|
VendorStatus2StatusMap = map[string]int{
|
||||||
jdapi.OrderStatusPurchased: model.OrderStatusNew,
|
jdapi.OrderStatusPurchased: model.OrderStatusNew,
|
||||||
jdapi.OrderStatusNew: model.OrderStatusNew,
|
|
||||||
jdapi.OrderStatusWaitOutStore: model.OrderStatusAccepted,
|
jdapi.OrderStatusWaitOutStore: model.OrderStatusAccepted,
|
||||||
|
jdapi.StatusIDWaitOutStore: model.OrderStatusAccepted,
|
||||||
jdapi.OrderStatusFinishedPickup: model.OrderStatusFinishedPickup,
|
jdapi.OrderStatusFinishedPickup: model.OrderStatusFinishedPickup,
|
||||||
jdapi.OrderStatusDelivering: model.OrderStatusDelivering,
|
jdapi.OrderStatusDelivering: model.OrderStatusDelivering,
|
||||||
jdapi.OrderStatusDelivered: model.OrderStatusFinished,
|
jdapi.OrderStatusDelivered: model.OrderStatusFinished,
|
||||||
@@ -42,38 +44,83 @@ func (c *PurchaseHandler) OnOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *PurchaseHandler) onOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
|
func (c *PurchaseHandler) onOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
|
||||||
if jdapi.OrderStatusNew == msg.StatusID {
|
status := c.callbackMsg2Status(msg)
|
||||||
retVal = c.onOrderNew(msg)
|
if jdapi.StatusIDNewOrder == msg.StatusID {
|
||||||
} else if jdapi.OrderStatusAdjust == msg.StatusID {
|
status.Status = model.OrderStatusNew // 因为京东将事件32000与状态32000混用,事件32000可能是新订单,也可能是已接单,统一当成新订单处理
|
||||||
retVal = c.onOrderAdjust(msg)
|
}
|
||||||
|
if partner.CurOrderManager.GetStatusDuplicatedCount(status) > 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if msg.MsgURL == jdapi.CallbackMsgOrderAccounting {
|
||||||
|
retVal = c.OnFinancialMsg(msg)
|
||||||
|
} else if msg.MsgURL == jdapi.CallbackMsgAfterSaleBillStatus {
|
||||||
|
retVal = c.OnAfsOrderMsg(msg)
|
||||||
} else {
|
} else {
|
||||||
status := c.callbackMsg2Status(msg)
|
// 新订单事件,与订单状态有点冲突
|
||||||
if msg.StatusID == jdapi.OrderStatusAddComment || msg.StatusID == jdapi.OrderStatusModifyComment {
|
if jdapi.StatusIDNewOrder == msg.StatusID {
|
||||||
utils.CallFuncAsync(func() {
|
retVal = c.onOrderNew(msg, status)
|
||||||
c.onOrderComment2(msg)
|
} else if jdapi.OrderStatusAdjust == msg.StatusID {
|
||||||
})
|
retVal = c.onOrderAdjust(msg, status)
|
||||||
|
} else {
|
||||||
|
if msg.StatusID == jdapi.OrderStatusAddComment || msg.StatusID == jdapi.OrderStatusModifyComment {
|
||||||
|
utils.CallFuncAsync(func() {
|
||||||
|
c.onOrderComment2(msg)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
err := partner.CurOrderManager.OnOrderStatusChanged(status)
|
||||||
|
// if globals.HandleLegacyJxOrder && err == nil {
|
||||||
|
// c.legacyJdOrderStatusChanged(status)
|
||||||
|
// }
|
||||||
|
retVal = jdapi.Err2CallbackResponse(err, status.VendorStatus)
|
||||||
}
|
}
|
||||||
err := partner.CurOrderManager.OnOrderStatusChanged(status)
|
|
||||||
// if globals.HandleLegacyJxOrder && err == nil {
|
|
||||||
// c.legacyJdOrderStatusChanged(status)
|
|
||||||
// }
|
|
||||||
retVal = jdapi.Err2CallbackResponse(err, status.VendorStatus)
|
|
||||||
}
|
}
|
||||||
return retVal
|
return retVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PurchaseHandler) getOrder(orderID string) (order *model.GoodsOrder, orderMap map[string]interface{}, err error) {
|
func (c *PurchaseHandler) getOrder(orderID string) (order *model.GoodsOrder, orderMap map[string]interface{}, err error) {
|
||||||
globals.SugarLogger.Debugf("jd GetOrder orderID:%s", orderID)
|
globals.SugarLogger.Debugf("jd getOrder orderID:%s", orderID)
|
||||||
if orderMap, err = api.JdAPI.QuerySingleOrder(orderID); err == nil {
|
var (
|
||||||
order = c.Map2Order(orderMap)
|
realMobile string
|
||||||
if jxutils.IsMobileFake(order.ConsigneeMobile) {
|
orderSettlement *jdapi.OrderSettlementInfo
|
||||||
if realMobile, err := api.JdAPI.GetRealMobile4Order(orderID, order.VendorStoreID); err == nil { // 故意强制忽略取不到真实手机号错误
|
)
|
||||||
order.ConsigneeMobile2 = jxutils.FormalizeMobile(realMobile)
|
task := tasksch.NewParallelTask("jd getOrder", tasksch.NewParallelConfig().SetIsContinueWhenError(true), jxcontext.AdminCtx,
|
||||||
} else {
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
// globals.SugarLogger.Warnf("jd GetOrder orderID:%s, GetRealMobile4Order failed with error:%v", orderID, err2)
|
taskIndex := batchItemList[0].(int)
|
||||||
|
switch taskIndex {
|
||||||
|
case 0:
|
||||||
|
orderMap, err = api.JdAPI.QuerySingleOrder(orderID)
|
||||||
|
if err == nil {
|
||||||
|
order = c.Map2Order(orderMap)
|
||||||
|
realMobile, err = api.JdAPI.GetRealMobile4Order(orderID, order.VendorStoreID)
|
||||||
|
if realMobile != "" {
|
||||||
|
order.ConsigneeMobile2 = jxutils.FormalizeMobile(realMobile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
orderSettlement, err = api.JdAPI.OrderShoudSettlementService2(orderID)
|
||||||
}
|
}
|
||||||
|
return nil, err
|
||||||
|
}, []int{0, 1})
|
||||||
|
task.Run()
|
||||||
|
task.GetResult(0)
|
||||||
|
if order != nil {
|
||||||
|
if orderSettlement != nil {
|
||||||
|
order.TotalShopMoney = orderSettlement.SettlementAmount
|
||||||
|
order.PmSubsidyMoney = orderSettlement.PlatOrderGoodsDiscountMoney + orderSettlement.PlatSkuGoodsDiscountMoney
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// if orderMap, err = api.JdAPI.QuerySingleOrder(orderID); err == nil {
|
||||||
|
// globals.SugarLogger.Debugf("jd getOrder2 orderID:%s", orderID)
|
||||||
|
// order = c.Map2Order(orderMap)
|
||||||
|
// if jxutils.IsMobileFake(order.ConsigneeMobile) {
|
||||||
|
// if realMobile, err := api.JdAPI.GetRealMobile4Order(orderID, order.VendorStoreID); err == nil { // 故意强制忽略取不到真实手机号错误
|
||||||
|
// globals.SugarLogger.Debugf("jd getOrder3 orderID:%s", orderID)
|
||||||
|
// order.ConsigneeMobile2 = jxutils.FormalizeMobile(realMobile)
|
||||||
|
// } else {
|
||||||
|
// // globals.SugarLogger.Warnf("jd GetOrder orderID:%s, GetRealMobile4Order failed with error:%v", orderID, err2)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
return order, orderMap, err
|
return order, orderMap, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,6 +132,8 @@ func (c *PurchaseHandler) GetOrder(orderID string) (order *model.GoodsOrder, err
|
|||||||
func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) {
|
func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) {
|
||||||
result := orderData
|
result := orderData
|
||||||
orderID := utils.Int64ToStr(utils.MustInterface2Int64(result["orderId"]))
|
orderID := utils.Int64ToStr(utils.MustInterface2Int64(result["orderId"]))
|
||||||
|
globals.SugarLogger.Debugf("jd Map2Order orderID:%s", orderID)
|
||||||
|
|
||||||
const defaultStatusTimeField = "orderPurchaseTime"
|
const defaultStatusTimeField = "orderPurchaseTime"
|
||||||
statusTimeField := defaultStatusTimeField
|
statusTimeField := defaultStatusTimeField
|
||||||
if result[statusTimeField] == nil { // 814560888003021 orderPurchaseTime为空
|
if result[statusTimeField] == nil { // 814560888003021 orderPurchaseTime为空
|
||||||
@@ -108,7 +157,6 @@ func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo
|
|||||||
StatusTime: utils.Str2Time(result[statusTimeField].(string)),
|
StatusTime: utils.Str2Time(result[statusTimeField].(string)),
|
||||||
OriginalData: string(utils.MustMarshal(result)),
|
OriginalData: string(utils.MustMarshal(result)),
|
||||||
ActualPayPrice: utils.MustInterface2Int64(result["orderBuyerPayableMoney"]),
|
ActualPayPrice: utils.MustInterface2Int64(result["orderBuyerPayableMoney"]),
|
||||||
Skus: []*model.OrderSku{},
|
|
||||||
}
|
}
|
||||||
order.Status = c.GetStatusFromVendorStatus(order.VendorStatus)
|
order.Status = c.GetStatusFromVendorStatus(order.VendorStatus)
|
||||||
businessTage := utils.Interface2String(result["businessTag"])
|
businessTage := utils.Interface2String(result["businessTag"])
|
||||||
@@ -143,8 +191,11 @@ func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo
|
|||||||
VendorSkuID: utils.Int64ToStr(utils.MustInterface2Int64(product["skuId"])),
|
VendorSkuID: utils.Int64ToStr(utils.MustInterface2Int64(product["skuId"])),
|
||||||
SkuName: product["skuName"].(string),
|
SkuName: product["skuName"].(string),
|
||||||
Weight: jxutils.FloatWeight2Int(float32(utils.MustInterface2Float64(product["skuWeight"]))),
|
Weight: jxutils.FloatWeight2Int(float32(utils.MustInterface2Float64(product["skuWeight"]))),
|
||||||
|
VendorPrice: utils.MustInterface2Int64(product["skuStorePrice"]),
|
||||||
SalePrice: utils.MustInterface2Int64(product["skuJdPrice"]),
|
SalePrice: utils.MustInterface2Int64(product["skuJdPrice"]),
|
||||||
PromotionType: int(utils.MustInterface2Int64(product["promotionType"])),
|
}
|
||||||
|
if jdPromotionType := int(utils.MustInterface2Int64(product["promotionType"])); jdPromotionType != jdapi.PromotionTypeNormal {
|
||||||
|
sku.StoreSubName = utils.Int2Str(jdPromotionType)
|
||||||
}
|
}
|
||||||
if skuCostumeProperty, ok := product["skuCostumeProperty"]; ok {
|
if skuCostumeProperty, ok := product["skuCostumeProperty"]; ok {
|
||||||
sku.SkuName += skuCostumeProperty.(string)
|
sku.SkuName += skuCostumeProperty.(string)
|
||||||
@@ -153,26 +204,18 @@ func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *mo
|
|||||||
sku.SkuType = 1
|
sku.SkuType = 1
|
||||||
}
|
}
|
||||||
order.Skus = append(order.Skus, sku)
|
order.Skus = append(order.Skus, sku)
|
||||||
order.SkuCount++
|
|
||||||
order.GoodsCount += sku.Count
|
|
||||||
order.SalePrice += sku.SalePrice * int64(sku.Count)
|
|
||||||
order.Weight += sku.Weight * sku.Count
|
|
||||||
}
|
}
|
||||||
setOrederDetailFee(result, order)
|
jxutils.RefreshOrderSkuRelated(order)
|
||||||
return order
|
return order
|
||||||
}
|
}
|
||||||
|
|
||||||
func setOrederDetailFee(result map[string]interface{}, order *model.GoodsOrder) {
|
|
||||||
order.BoxFee = utils.Interface2Int64WithDefault(result["packagingMoney"], 0)
|
|
||||||
order.PlatformFeeRate = model.JdPlatformFeeRate
|
|
||||||
order.BillStoreFreightFee = utils.Interface2Int64WithDefault(result["merchantPaymentDistanceFreightMoney"], 0) + utils.Interface2Int64WithDefault(result["tips"], 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
func (c *PurchaseHandler) onOrderNew(msg *jdapi.CallbackOrderMsg) (response *jdapi.CallbackResponse) {
|
func (c *PurchaseHandler) onOrderNew(msg *jdapi.CallbackOrderMsg, orderStatus *model.OrderStatus) (response *jdapi.CallbackResponse) {
|
||||||
|
globals.SugarLogger.Debugf("onOrderNew orderID:%s", msg.BillID)
|
||||||
order, orderMap, err := c.getOrder(msg.BillID)
|
order, orderMap, err := c.getOrder(msg.BillID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if err = partner.CurOrderManager.OnOrderNew(order, msg.StatusID); err == nil {
|
globals.SugarLogger.Debugf("onOrderNew2 orderID:%s", msg.BillID)
|
||||||
|
if err = partner.CurOrderManager.OnOrderNew(order, orderStatus); err == nil {
|
||||||
utils.CallFuncAsync(func() {
|
utils.CallFuncAsync(func() {
|
||||||
c.OnOrderDetail(orderMap, partner.CreatedPeration)
|
c.OnOrderDetail(orderMap, partner.CreatedPeration)
|
||||||
})
|
})
|
||||||
@@ -181,10 +224,10 @@ func (c *PurchaseHandler) onOrderNew(msg *jdapi.CallbackOrderMsg) (response *jda
|
|||||||
return jdapi.Err2CallbackResponse(err, "jd onOrderNew")
|
return jdapi.Err2CallbackResponse(err, "jd onOrderNew")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PurchaseHandler) onOrderAdjust(msg *jdapi.CallbackOrderMsg) *jdapi.CallbackResponse {
|
func (c *PurchaseHandler) onOrderAdjust(msg *jdapi.CallbackOrderMsg, orderStatus *model.OrderStatus) *jdapi.CallbackResponse {
|
||||||
order, orderMap, err := c.getOrder(msg.BillID)
|
order, orderMap, err := c.getOrder(msg.BillID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = partner.CurOrderManager.OnOrderAdjust(order, msg.StatusID)
|
err = partner.CurOrderManager.OnOrderAdjust(order, orderStatus)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
utils.CallFuncAsync(func() {
|
utils.CallFuncAsync(func() {
|
||||||
c.OnOrderDetail(orderMap, partner.UpdatedPeration)
|
c.OnOrderDetail(orderMap, partner.UpdatedPeration)
|
||||||
@@ -233,14 +276,14 @@ func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptI
|
|||||||
if globals.EnableStoreWrite {
|
if globals.EnableStoreWrite {
|
||||||
err = api.JdAPI.OrderAcceptOperate(order.VendorOrderID, isAcceptIt, userName)
|
err = api.JdAPI.OrderAcceptOperate(order.VendorOrderID, isAcceptIt, userName)
|
||||||
} else {
|
} else {
|
||||||
c.postFakeMsg(order.VendorOrderID, jdapi.OrderStatusWaitOutStore)
|
c.postFakeMsg(order.VendorOrderID, jdapi.StatusIDWaitOutStore)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) {
|
func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) {
|
||||||
globals.SugarLogger.Debugf("jd PickupGoods orderID:%s, isSelfDelivery:%t", order.VendorOrderID, isSelfDelivery)
|
globals.SugarLogger.Debugf("jd PickupGoods orderID:%s, isSelfDelivery:%t", order.VendorOrderID, isSelfDelivery)
|
||||||
if !isSelfDelivery && globals.EnableStoreWrite {
|
if !isSelfDelivery && globals.EnableJdStoreWrite {
|
||||||
_, err = api.JdAPI.OrderJDZBDelivery(order.VendorOrderID, userName)
|
_, err = api.JdAPI.OrderJDZBDelivery(order.VendorOrderID, userName)
|
||||||
} else {
|
} else {
|
||||||
c.postFakeMsg(order.VendorOrderID, jdapi.OrderStatusFinishedPickup)
|
c.postFakeMsg(order.VendorOrderID, jdapi.OrderStatusFinishedPickup)
|
||||||
@@ -249,21 +292,21 @@ func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) {
|
func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) {
|
||||||
if globals.EnableStoreWrite {
|
if globals.EnableJdStoreWrite {
|
||||||
err = api.JdAPI.ReceiveFailedAudit(order.VendorOrderID, isAcceptIt, ctx.GetUserName(), "")
|
err = api.JdAPI.ReceiveFailedAudit(order.VendorOrderID, isAcceptIt, ctx.GetUserName(), "")
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 拣货失败后再次招唤平台配送
|
func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 拣货失败后再次招唤平台配送
|
||||||
if globals.EnableStoreWrite {
|
if globals.EnableJdStoreWrite {
|
||||||
err = api.JdAPI.UrgeDispatching(order.VendorOrderID, ctx.GetUserName())
|
err = api.JdAPI.UrgeDispatching(order.VendorOrderID, ctx.GetUserName())
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 投递失败后确认收到退货
|
func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 投递失败后确认收到退货
|
||||||
if globals.EnableStoreWrite {
|
if globals.EnableJdStoreWrite {
|
||||||
err = api.JdAPI.ConfirmReceiveGoods(order.VendorOrderID)
|
err = api.JdAPI.ConfirmReceiveGoods(order.VendorOrderID)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@@ -271,7 +314,7 @@ func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *mod
|
|||||||
|
|
||||||
func (c *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) {
|
func (c *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) {
|
||||||
globals.SugarLogger.Debugf("jd Swtich2SelfDeliver orderID:%s", order.VendorOrderID)
|
globals.SugarLogger.Debugf("jd Swtich2SelfDeliver orderID:%s", order.VendorOrderID)
|
||||||
if globals.EnableStoreWrite {
|
if globals.EnableJdStoreWrite {
|
||||||
_, err = api.JdAPI.ModifySellerDelivery(order.VendorOrderID, userName)
|
_, err = api.JdAPI.ModifySellerDelivery(order.VendorOrderID, userName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errWithCode, ok := err.(*utils.ErrorWithCode); ok && errWithCode.Level() == 1 {
|
if errWithCode, ok := err.(*utils.ErrorWithCode); ok && errWithCode.Level() == 1 {
|
||||||
@@ -292,7 +335,7 @@ func (c *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName s
|
|||||||
|
|
||||||
func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) {
|
func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) {
|
||||||
globals.SugarLogger.Debugf("jd Swtich2SelfDelivered orderID:%s", order.VendorOrderID)
|
globals.SugarLogger.Debugf("jd Swtich2SelfDelivered orderID:%s", order.VendorOrderID)
|
||||||
if globals.EnableStoreWrite {
|
if globals.EnableJdStoreWrite {
|
||||||
_, err = api.JdAPI.DeliveryEndOrder(order.VendorOrderID, userName)
|
_, err = api.JdAPI.DeliveryEndOrder(order.VendorOrderID, userName)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@@ -300,7 +343,7 @@ func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName
|
|||||||
|
|
||||||
func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) {
|
func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) {
|
||||||
globals.SugarLogger.Debugf("jd SelfDeliverDelivering orderID:%s", order.VendorOrderID)
|
globals.SugarLogger.Debugf("jd SelfDeliverDelivering orderID:%s", order.VendorOrderID)
|
||||||
if globals.EnableStoreWrite {
|
if globals.EnableJdStoreWrite {
|
||||||
_, err = api.JdAPI.OrderSerllerDelivery(order.VendorOrderID, userName)
|
_, err = api.JdAPI.OrderSerllerDelivery(order.VendorOrderID, userName)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@@ -309,7 +352,7 @@ func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userNam
|
|||||||
// 京东送达接口都是一样的
|
// 京东送达接口都是一样的
|
||||||
func (c *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) {
|
func (c *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) {
|
||||||
globals.SugarLogger.Debugf("jd SelfDeliverDelivered orderID:%s", order.VendorOrderID)
|
globals.SugarLogger.Debugf("jd SelfDeliverDelivered orderID:%s", order.VendorOrderID)
|
||||||
if globals.EnableStoreWrite {
|
if globals.EnableJdStoreWrite {
|
||||||
err = c.Swtich2SelfDelivered(order, userName)
|
err = c.Swtich2SelfDelivered(order, userName)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@@ -321,7 +364,7 @@ func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *mode
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) {
|
func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) {
|
||||||
if globals.EnableStoreWrite {
|
if globals.EnableJdStoreWrite {
|
||||||
err = api.JdAPI.OrderCancelOperate(order.VendorOrderID, isAgree, ctx.GetUserName(), reason)
|
err = api.JdAPI.OrderCancelOperate(order.VendorOrderID, isAgree, ctx.GetUserName(), reason)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@@ -333,29 +376,15 @@ func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.Goods
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
|
func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
|
||||||
removedSkuMap := make(map[int]*model.OrderSku)
|
order = jxutils.RemoveSkuFromOrder(order, removedSkuList)
|
||||||
for _, sku := range removedSkuList {
|
|
||||||
removedSkuMap[jxutils.GetSkuIDFromOrderSku(sku)] = sku
|
|
||||||
}
|
|
||||||
var oaosAdjustDTOList []*jdapi.OAOSAdjustDTO
|
var oaosAdjustDTOList []*jdapi.OAOSAdjustDTO
|
||||||
for _, sku := range order.Skus {
|
for _, sku := range order.Skus {
|
||||||
skuID := jxutils.GetSkuIDFromOrderSku(sku)
|
oaosAdjustDTOList = append(oaosAdjustDTOList, &jdapi.OAOSAdjustDTO{
|
||||||
tmp := &jdapi.OAOSAdjustDTO{
|
OutSkuID: utils.Int2Str(jxutils.GetSkuIDFromOrderSku(sku)),
|
||||||
OutSkuID: utils.Int2Str(skuID),
|
|
||||||
SkuCount: sku.Count,
|
SkuCount: sku.Count,
|
||||||
}
|
})
|
||||||
if removedSkuMap[skuID] != nil {
|
|
||||||
if removedSkuMap[skuID].Count >= sku.Count {
|
|
||||||
tmp = nil
|
|
||||||
} else {
|
|
||||||
tmp.SkuCount -= removedSkuMap[skuID].Count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if tmp != nil {
|
|
||||||
oaosAdjustDTOList = append(oaosAdjustDTOList, tmp)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if globals.EnableStoreWrite {
|
if globals.EnableJdStoreWrite {
|
||||||
err = api.JdAPI.AdjustOrder(order.VendorOrderID, ctx.GetUserName(), reason, oaosAdjustDTOList)
|
err = api.JdAPI.AdjustOrder(order.VendorOrderID, ctx.GetUserName(), reason, oaosAdjustDTOList)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
|||||||
190
business/partner/purchase/jd/order_afs.go
Normal file
190
business/partner/purchase/jd/order_afs.go
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
package jd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
AfsVendorStatus2StatusMap = map[string]int{
|
||||||
|
jdapi.AfsServiceStateWaiting4Audit: model.AfsOrderStatusWait4Approve, // 需要审核
|
||||||
|
|
||||||
|
jdapi.AfsServiceStateRefundProcessing: model.AfsOrderStatusNew,
|
||||||
|
jdapi.AfsServiceStateWaiting4DirectCompensate: model.AfsOrderStatusNew,
|
||||||
|
jdapi.AfsServiceStateWaiting4ReturnGoods: model.AfsOrderStatusNew,
|
||||||
|
|
||||||
|
jdapi.AfsServiceStateWaiting4MerchantReceiveGoods: model.AfsOrderStatusWait4ReceiveGoods,
|
||||||
|
|
||||||
|
jdapi.AfsServiceStateRefundSuccess: model.AfsOrderStatusFinished,
|
||||||
|
jdapi.AfsServiceStateSolved: model.AfsOrderStatusFinished,
|
||||||
|
jdapi.AfsServiceStateDirectCompensateSuccess: model.AfsOrderStatusFinished,
|
||||||
|
jdapi.AfsServiceStateReturnGoodsSuccess: model.AfsOrderStatusFinished,
|
||||||
|
|
||||||
|
jdapi.AfsServiceStateRefundFailed: model.AfsOrderStatusFailed,
|
||||||
|
jdapi.AfsServiceStateAuditRefused: model.AfsOrderStatusFailed,
|
||||||
|
jdapi.AfsServiceStateUserCanceled: model.AfsOrderStatusFailed,
|
||||||
|
jdapi.AfsServiceStateMerchantFailedReceiveGoods: model.AfsOrderStatusFailed,
|
||||||
|
jdapi.AfsServiceStateDirectCompensateFailed: model.AfsOrderStatusFailed,
|
||||||
|
jdapi.AfsServiceStateReturnGoodsFailed: model.AfsOrderStatusFailed,
|
||||||
|
}
|
||||||
|
|
||||||
|
afsReasonTypeMap = map[int]int8{
|
||||||
|
jdapi.AfsReasonTypeGoodsQuality: model.AfsReasonTypeGoodsQuality,
|
||||||
|
jdapi.AfsReasonTypeWrongGoods: model.AfsReasonTypeWrongGoods,
|
||||||
|
jdapi.AfsReasonTypeMissingGoods: model.AfsReasonTypeMissingGoods,
|
||||||
|
jdapi.AfsReasonTypeNoGoods: model.AfsReasonTypeNoGoods,
|
||||||
|
jdapi.AfsReasonTypeDamagedGoods: model.AfsReasonTypeDamagedGoods,
|
||||||
|
jdapi.AfsReasonTypeGoodsQuantity: model.AfsReasonTypeGoodsQuantity,
|
||||||
|
jdapi.AfsReasonTypeAgreedByMerchant: model.AfsReasonTypeAgreedByMerchant,
|
||||||
|
jdapi.AfsReasonTypeGoodsSizeNoSame: model.AfsReasonTypeGoodsNoSame,
|
||||||
|
jdapi.AfsReasonTypeGoodsColorNoSame: model.AfsReasonTypeGoodsNoSame,
|
||||||
|
jdapi.AfsReasonWrongPurchase: model.AfsReasonWrongPurchase,
|
||||||
|
jdapi.AfsReasonNotReceivedIntime: model.AfsReasonNotReceivedIntime,
|
||||||
|
}
|
||||||
|
afsAppealTypeMap = map[string]int8{
|
||||||
|
jdapi.AfsDealTypeRefund: model.AfsAppealTypeRefund,
|
||||||
|
jdapi.AfsDealTypeReturnGoodsRefund: model.AfsAppealTypeReturnAndRefund,
|
||||||
|
jdapi.AfsDealTypeDirectCompensate: model.AfsAppealTypeNewGoods,
|
||||||
|
}
|
||||||
|
afsApproveTypeMap = map[int]int{
|
||||||
|
partner.AfsApproveTypeRefund: jdapi.AfsApproveTypeRefund,
|
||||||
|
partner.AfsApproveTypeReturnGoods: jdapi.AfsApproveTypeReturnGoods,
|
||||||
|
partner.AfsApproveTypeRefused: jdapi.AfsApproveTypeRefused,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) OnAfsOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
|
||||||
|
jxutils.CallMsgHandlerAsync(func() {
|
||||||
|
retVal = c.onAfsOrderMsg(msg)
|
||||||
|
}, jxutils.ComposeUniversalOrderID(msg.BillID, model.VendorIDJD))
|
||||||
|
return retVal
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) onAfsOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
|
||||||
|
afsInfo, err := api.JdAPI.GetAfsService2(msg.BillID)
|
||||||
|
if err == nil {
|
||||||
|
status := c.callbackAfsMsg2Status(msg, afsInfo)
|
||||||
|
if status.Status == model.AfsOrderStatusWait4Approve || status.Status == model.AfsOrderStatusNew {
|
||||||
|
afsOrder := c.buildAfsOrder(afsInfo)
|
||||||
|
err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, status)
|
||||||
|
} else {
|
||||||
|
err = partner.CurOrderManager.OnAfsOrderStatusChanged(status)
|
||||||
|
}
|
||||||
|
retVal = jdapi.Err2CallbackResponse(err, status.VendorStatus)
|
||||||
|
}
|
||||||
|
return retVal
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) callbackAfsMsg2Status(msg *jdapi.CallbackOrderMsg, afsInfo *jdapi.AfsServiceResponse) *model.OrderStatus {
|
||||||
|
orderStatus := &model.OrderStatus{
|
||||||
|
VendorOrderID: msg.BillID, // 是售后单ID,不是订单ID,订单ID在RefVendorOrderID中
|
||||||
|
VendorID: model.VendorIDJD,
|
||||||
|
OrderType: model.OrderTypeAfsOrder,
|
||||||
|
RefVendorOrderID: afsInfo.OrderID,
|
||||||
|
RefVendorID: model.VendorIDJD,
|
||||||
|
VendorStatus: msg.StatusID,
|
||||||
|
Status: c.GetAfsStatusFromVendorStatus(msg.StatusID),
|
||||||
|
StatusTime: utils.Str2Time(msg.Timestamp),
|
||||||
|
Remark: msg.Remark,
|
||||||
|
}
|
||||||
|
return orderStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) GetAfsStatusFromVendorStatus(vendorStatus string) int {
|
||||||
|
if status, ok := AfsVendorStatus2StatusMap[vendorStatus]; ok {
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
return model.OrderStatusUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) convertAfsReasonType(vendorReasonType int) int8 {
|
||||||
|
if status, ok := afsReasonTypeMap[vendorReasonType]; ok {
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
return model.AfsReasonNotOthers
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) convertAfsAppealType(vendorAppealType string) int8 {
|
||||||
|
if status, ok := afsAppealTypeMap[vendorAppealType]; ok {
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
globals.SugarLogger.Warnf("jd convertAfsAppealType unknown vendorAppealType:%d", vendorAppealType)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) buildAfsOrder(afsInfo *jdapi.AfsServiceResponse) (afsOrder *model.AfsOrder) {
|
||||||
|
afsOrder = &model.AfsOrder{
|
||||||
|
VendorID: model.VendorIDJD,
|
||||||
|
AfsOrderID: afsInfo.AfsServiceOrder,
|
||||||
|
VendorOrderID: afsInfo.OrderID,
|
||||||
|
VendorStoreID: afsInfo.StationID,
|
||||||
|
StoreID: int(utils.Str2Int64WithDefault(afsInfo.StationNumOutSystem, 0)),
|
||||||
|
AfsCreatedAt: afsInfo.CreateTime.GoTime(),
|
||||||
|
FreightUserMoney: afsInfo.OrderFreightMoney,
|
||||||
|
AfsFreightMoney: afsInfo.AfsFreight,
|
||||||
|
BoxMoney: afsInfo.PackagingMoney,
|
||||||
|
TongchengFreightMoney: afsInfo.TongchengFreightMoney,
|
||||||
|
SkuBoxMoney: afsInfo.MealBoxMoney,
|
||||||
|
|
||||||
|
VendorStatus: utils.Int2Str(afsInfo.AfsServiceState),
|
||||||
|
VendorReasonType: utils.Int2Str(afsInfo.QuestionTypeCid),
|
||||||
|
ReasonType: c.convertAfsReasonType(afsInfo.QuestionTypeCid),
|
||||||
|
ReasonDesc: utils.LimitUTF8StringLen(afsInfo.QuestionDesc, 1024),
|
||||||
|
ReasonImgList: utils.LimitUTF8StringLen(jdapi.ProcessQuestionPic(afsInfo.QuestionPic), 1024),
|
||||||
|
VendorAppealType: afsInfo.ApplyDeal,
|
||||||
|
AppealType: c.convertAfsAppealType(afsInfo.ApplyDeal),
|
||||||
|
}
|
||||||
|
afsOrder.Status = c.GetAfsStatusFromVendorStatus(afsOrder.VendorStatus)
|
||||||
|
|
||||||
|
for _, x := range afsInfo.AfsDetailList {
|
||||||
|
orderSku := &model.OrderSkuFinancial{
|
||||||
|
// VendorID: model.VendorIDJD,
|
||||||
|
// AfsOrderID: afsOrder.AfsOrderID,
|
||||||
|
// VendorOrderID: afsOrder.VendorOrderID,
|
||||||
|
// VendorStoreID: afsOrder.VendorStoreID,
|
||||||
|
// StoreID: afsOrder.StoreID,
|
||||||
|
// IsAfsOrder: 1,
|
||||||
|
|
||||||
|
Count: x.SkuCount,
|
||||||
|
// ConfirmTime: afsOrder.AfsCreateAt,
|
||||||
|
VendorSkuID: utils.Int64ToStr(x.WareID),
|
||||||
|
SkuID: int(utils.Str2Int64WithDefault(x.SkuIDIsv, 0)),
|
||||||
|
Name: x.WareName,
|
||||||
|
UserMoney: x.AfsMoney,
|
||||||
|
PmSkuSubsidyMoney: x.PlatPayMoney,
|
||||||
|
}
|
||||||
|
afsOrder.PmSkuSubsidyMoney += orderSku.PmSkuSubsidyMoney
|
||||||
|
orderSku.PmSubsidyMoney += orderSku.PmSkuSubsidyMoney
|
||||||
|
|
||||||
|
for _, y := range x.AfsSkuDiscountList {
|
||||||
|
orderSku.PmSubsidyMoney += y.PlatPayMoney
|
||||||
|
}
|
||||||
|
|
||||||
|
afsOrder.SkuUserMoney += orderSku.UserMoney
|
||||||
|
afsOrder.PmSubsidyMoney += orderSku.PmSubsidyMoney
|
||||||
|
afsOrder.Skus = append(afsOrder.Skus, orderSku)
|
||||||
|
}
|
||||||
|
return afsOrder
|
||||||
|
}
|
||||||
|
|
||||||
|
// 审核售后单申请
|
||||||
|
func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) {
|
||||||
|
if globals.EnableJdStoreWrite {
|
||||||
|
err = api.JdAPI.AfsOpenApprove(order.AfsOrderID, afsApproveTypeMap[approveType], reason, ctx.GetUserName())
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认收到退货
|
||||||
|
func (c *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) {
|
||||||
|
if globals.EnableJdStoreWrite {
|
||||||
|
err = api.JdAPI.ConfirmReceipt(order.AfsOrderID, ctx.GetUserName())
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package jd
|
|||||||
// 这里函数取得的信息,除了与自身实体相关的ID(比如PARENT ID),都已经转换成了本地ID了
|
// 这里函数取得的信息,除了与自身实体相关的ID(比如PARENT ID),都已经转换成了本地ID了
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
||||||
@@ -130,7 +131,7 @@ func (p *PurchaseHandler) ReorderCategories(db *dao.DaoDB, parentCatID int, user
|
|||||||
func (p *PurchaseHandler) cuSku(db *dao.DaoDB, sku *model.Sku, handler func(skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (string, error)) (err error) {
|
func (p *PurchaseHandler) cuSku(db *dao.DaoDB, sku *model.Sku, handler func(skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (string, error)) (err error) {
|
||||||
var skuInfoExt tSkuInfoExt
|
var skuInfoExt tSkuInfoExt
|
||||||
err = dao.GetRow(nil, &skuInfoExt, `
|
err = dao.GetRow(nil, &skuInfoExt, `
|
||||||
SELECT t2.*, t3.jd_id jd_cat_id, t3.jd_category_id, t4.jd_id sku_cat_id
|
SELECT t2.*, t3.jd_id jd_cat_id, IF(t2.jd_category_id > 0, t2.jd_category_id, t3.jd_category_id) jd_category_id, t4.jd_id sku_cat_id
|
||||||
FROM sku t1
|
FROM sku t1
|
||||||
JOIN sku_name t2 ON t1.name_id = t2.id
|
JOIN sku_name t2 ON t1.name_id = t2.id
|
||||||
JOIN sku_category t3 ON t2.category_id = t3.id
|
JOIN sku_category t3 ON t2.category_id = t3.id
|
||||||
@@ -164,8 +165,14 @@ func (p *PurchaseHandler) cuSku(db *dao.DaoDB, sku *model.Sku, handler func(skuE
|
|||||||
if addParams["sellCities"] == nil {
|
if addParams["sellCities"] == nil {
|
||||||
addParams["sellCities"] = []int{0}
|
addParams["sellCities"] = []int{0}
|
||||||
}
|
}
|
||||||
|
if skuInfoExt.DescImg != "" {
|
||||||
|
addParams[jdapi.KeyProductDesc] = fmt.Sprintf(`<img src="%s" alt="一张图片" />`, skuInfoExt.DescImg)
|
||||||
|
addParams[jdapi.KeyIfViewDesc] = 0
|
||||||
|
} else {
|
||||||
|
addParams[jdapi.KeyIfViewDesc] = 1
|
||||||
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
skuName := jxutils.ComposeSkuName(skuInfoExt.Prefix, skuInfoExt.Name, sku.Comment, skuInfoExt.Unit, sku.SpecQuality, sku.SpecUnit, 0)
|
skuName := jxutils.ComposeSkuName(skuInfoExt.Prefix, skuInfoExt.Name, sku.Comment, skuInfoExt.Unit, sku.SpecQuality, sku.SpecUnit, jdapi.MaxSkuNameCharCount)
|
||||||
skuPrice := jxutils.CaculateSkuPrice(skuInfoExt.Price, sku.SpecQuality, sku.SpecUnit, skuInfoExt.Unit)
|
skuPrice := jxutils.CaculateSkuPrice(skuInfoExt.Price, sku.SpecQuality, sku.SpecUnit, skuInfoExt.Unit)
|
||||||
if skuInfoExt.Upc != "" {
|
if skuInfoExt.Upc != "" {
|
||||||
addParams[jdapi.KeyUpcCode] = skuInfoExt.Upc
|
addParams[jdapi.KeyUpcCode] = skuInfoExt.Upc
|
||||||
@@ -385,7 +392,7 @@ func (p *PurchaseHandler) syncSkuNameAsSpu(db *dao.DaoDB, sku *model.Sku, skuExt
|
|||||||
skuNameJdID := skuExt.JdID
|
skuNameJdID := skuExt.JdID
|
||||||
globals.SugarLogger.Debugf("syncSkuNameAsSpu1 sku.id=%d, bareSkuName:%s, skuName:%s, skuNameJdID:%d", sku.ID, skuExt.Name, skuName, skuNameJdID)
|
globals.SugarLogger.Debugf("syncSkuNameAsSpu1 sku.id=%d, bareSkuName:%s, skuName:%s, skuNameJdID:%d", sku.ID, skuExt.Name, skuName, skuNameJdID)
|
||||||
spuAddParams, skuAddParams := splitAddParams(addParams)
|
spuAddParams, skuAddParams := splitAddParams(addParams)
|
||||||
if !jxutils.IsFakeID(skuNameJdID) && sku.JdSyncStatus&model.SyncFlagDeletedMask != 0 { // 删除SKU
|
if !jxutils.IsEmptyID(skuNameJdID) && sku.JdSyncStatus&model.SyncFlagDeletedMask != 0 { // 删除SKU
|
||||||
if globals.EnableStoreWrite {
|
if globals.EnableStoreWrite {
|
||||||
err = api.JdAPI.UpdateSkuBaseInfo(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted))
|
err = api.JdAPI.UpdateSkuBaseInfo(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted))
|
||||||
}
|
}
|
||||||
@@ -412,7 +419,7 @@ func (p *PurchaseHandler) syncSkuNameAsSpu(db *dao.DaoDB, sku *model.Sku, skuExt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if skuExt.JdSyncStatus&model.SyncFlagNewMask != 0 && jxutils.IsFakeID(skuNameJdID) {
|
} else if skuExt.JdSyncStatus&model.SyncFlagNewMask != 0 && jxutils.IsEmptyID(skuNameJdID) {
|
||||||
if globals.EnableStoreWrite {
|
if globals.EnableStoreWrite {
|
||||||
spuName := jxutils.ComposeSpuName(skuExt.Prefix, skuExt.Name, 0)
|
spuName := jxutils.ComposeSpuName(skuExt.Prefix, skuExt.Name, 0)
|
||||||
skus := []map[string]interface{}{
|
skus := []map[string]interface{}{
|
||||||
@@ -461,7 +468,7 @@ func (p *PurchaseHandler) syncSkuNameAsSpu(db *dao.DaoDB, sku *model.Sku, skuExt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err == nil && !jxutils.IsFakeID(skuNameJdID) {
|
if err == nil && !jxutils.IsEmptyID(skuNameJdID) {
|
||||||
if sku.JdSyncStatus&model.SyncFlagNewMask != 0 { // 非首次新增SKU
|
if sku.JdSyncStatus&model.SyncFlagNewMask != 0 { // 非首次新增SKU
|
||||||
if globals.EnableStoreWrite {
|
if globals.EnableStoreWrite {
|
||||||
vendorSkuID2, err2 := api.JdAPI.AppendSku(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), skuName, price, jxutils.IntWeight2Float(sku.Weight), []string{skuExt.Img}, jxStatus2jdStatus(sku.Status), true, composeSkuSpec(sku.SpecQuality, sku.SpecUnit, skuExt.Unit), skuAddParams)
|
vendorSkuID2, err2 := api.JdAPI.AppendSku(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), skuName, price, jxutils.IntWeight2Float(sku.Weight), []string{skuExt.Img}, jxStatus2jdStatus(sku.Status), true, composeSkuSpec(sku.SpecQuality, sku.SpecUnit, skuExt.Unit), skuAddParams)
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin
|
|||||||
if store.DeliveryRangeType == model.DeliveryRangeTypePolygon {
|
if store.DeliveryRangeType == model.DeliveryRangeTypePolygon {
|
||||||
params["coordinatePoints"] = store.DeliveryRange
|
params["coordinatePoints"] = store.DeliveryRange
|
||||||
} else {
|
} else {
|
||||||
params["deliveryRangeRadius"] = utils.Str2Int64(store.DeliveryRange)
|
params["deliveryRangeRadius"] = utils.Str2Int64WithDefault(store.DeliveryRange, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
openTime2 := JxOperationTime2JdOperationTime(store.OpenTime2)
|
openTime2 := JxOperationTime2JdOperationTime(store.OpenTime2)
|
||||||
@@ -147,7 +147,7 @@ func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName strin
|
|||||||
}
|
}
|
||||||
_, params["closeStatus"] = JxStoreStatus2JdStatus(jxutils.MergeStoreStatus(store.Status, store.JdStoreStatus))
|
_, params["closeStatus"] = JxStoreStatus2JdStatus(jxutils.MergeStoreStatus(store.Status, store.JdStoreStatus))
|
||||||
globals.SugarLogger.Debug(utils.Format4Output(params, false))
|
globals.SugarLogger.Debug(utils.Format4Output(params, false))
|
||||||
if globals.EnableStoreWrite {
|
if globals.EnableJdStoreWrite {
|
||||||
if err = api.JdAPI.UpdateStoreInfo4Open(store.VendorStoreID, store.RealLastOperator, params); err != nil {
|
if err = api.JdAPI.UpdateStoreInfo4Open(store.VendorStoreID, store.RealLastOperator, params); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -238,7 +238,7 @@ func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask
|
|||||||
if step != stepCount-1 {
|
if step != stepCount-1 {
|
||||||
storeParams["outSystemId"] = utils.GetUUID()
|
storeParams["outSystemId"] = utils.GetUUID()
|
||||||
}
|
}
|
||||||
if true { //globals.EnableStoreWrite {
|
if globals.EnableJdStoreWrite {
|
||||||
err = api.JdAPI.UpdateStoreInfo4Open(store.VendorStoreID, ctx.GetUserName(), storeParams)
|
err = api.JdAPI.UpdateStoreInfo4Open(store.VendorStoreID, ctx.GetUserName(), storeParams)
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -302,7 +302,7 @@ func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorStoreID s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 当前京东的storeCrud消息不会在门店状态改变时发送,所以意义不大,先放在这里
|
// 当前京东的storeCrud消息不会在门店状态改变时发送,所以意义不大,先放在这里
|
||||||
func (c *PurchaseHandler) onStoreMsg(msg *jdapi.CallbackOrderMsg) (response *jdapi.CallbackResponse) {
|
func (c *PurchaseHandler) OnStoreMsg(msg *jdapi.CallbackOrderMsg) (response *jdapi.CallbackResponse) {
|
||||||
var err error
|
var err error
|
||||||
if msg.StatusID == jdapi.StatusIDUpdateStore {
|
if msg.StatusID == jdapi.StatusIDUpdateStore {
|
||||||
var storeStatus int
|
var storeStatus int
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package jd
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
@@ -17,140 +19,137 @@ import (
|
|||||||
|
|
||||||
type tStoreSkuBindExt struct {
|
type tStoreSkuBindExt struct {
|
||||||
model.StoreSkuBind
|
model.StoreSkuBind
|
||||||
PricePercentage int
|
PricePercentage int
|
||||||
VendorStoreID string `orm:"column(vendor_store_id)"`
|
CatPricePercentage int
|
||||||
JdID int64 `orm:"column(jd_id)"`
|
VendorStoreID string `orm:"column(vendor_store_id)"`
|
||||||
|
JdID int64 `orm:"column(jd_id)"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 京东到家,以有库存表示关注(认领)
|
// 京东到家,以有库存表示关注(认领)
|
||||||
func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
func (p *PurchaseHandler) syncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, db *dao.DaoDB, storeID int, storeSkus []*dao.StoreSkuSyncInfo, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
globals.SugarLogger.Debugf("jd SyncStoresSkus, storeID:%d, skuIDs:%v", storeID, skuIDs)
|
globals.SugarLogger.Debugf("jd syncStoreSkus, storeID:%d", storeID)
|
||||||
sqlWhere0 := `
|
storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJD)
|
||||||
WHERE (t1.jd_sync_status <> 0) AND t1.store_id = ?
|
if err != nil {
|
||||||
`
|
|
||||||
sqlWhere := sqlWhere0
|
|
||||||
sqlWhereParams := []interface{}{
|
|
||||||
storeID,
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(skuIDs) > 0 {
|
|
||||||
sqlWhere += " AND t1.sku_id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ")"
|
|
||||||
sqlWhereParams = append(sqlWhereParams, skuIDs)
|
|
||||||
}
|
|
||||||
|
|
||||||
sql := `
|
|
||||||
SELECT t3.jd_id, t1.*, t2.price_percentage, t2.vendor_store_id
|
|
||||||
FROM store_sku_bind t1
|
|
||||||
JOIN store_map t2 ON t1.store_id = t2.store_id AND t2.vendor_id = ? AND t2.deleted_at = ?
|
|
||||||
JOIN sku t3 ON t1.sku_id = t3.id AND t3.deleted_at = ?
|
|
||||||
` + sqlWhere + " ORDER BY t1.updated_at"
|
|
||||||
var storeSkus []*tStoreSkuBindExt
|
|
||||||
sqlParams := []interface{}{
|
|
||||||
model.VendorIDJD,
|
|
||||||
utils.DefaultTimeValue,
|
|
||||||
utils.DefaultTimeValue,
|
|
||||||
}
|
|
||||||
db := dao.GetDB()
|
|
||||||
if err = dao.GetRows(db, &storeSkus, sql, append(sqlParams, sqlWhereParams...)...); err != nil {
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
task := tasksch.NewParallelTask("SyncStoresSkus京东", tasksch.NewParallelConfig().SetBatchSize(jdapi.MaxStoreSkuBatchSize).SetIsContinueWhenError(isContinueWhenError), ctx,
|
batchSize := jdapi.MaxStoreSkuBatchSize
|
||||||
|
// storeSkusLen := len(storeSkus)
|
||||||
|
// if storeSkusLen < jdapi.MaxStoreSkuBatchSize/2 {
|
||||||
|
// batchSize = 1
|
||||||
|
// } else if storeSkusLen < jdapi.MaxStoreSkuBatchSize {
|
||||||
|
// batchSize = (storeSkusLen + 1) / 2
|
||||||
|
// } else if storeSkusLen < jdapi.MaxStoreSkuBatchSize*2 {
|
||||||
|
// batchSize = (storeSkusLen + 2) / 3
|
||||||
|
// }
|
||||||
|
task := tasksch.NewParallelTask("syncStoreSkus京东", tasksch.NewParallelConfig().SetBatchSize(batchSize).SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
var skuPriceInfoList []*jdapi.SkuPriceInfo
|
doWork := func(batchItemList []interface{}) (isPartialFailed bool, err error) {
|
||||||
var skuVendibilityList []*jdapi.StockVendibility
|
var skuPriceInfoList []*jdapi.SkuPriceInfo
|
||||||
var skuStockList []*jdapi.SkuStock
|
var skuVendibilityList []*jdapi.StockVendibility
|
||||||
stationNo := batchItemList[0].(*tStoreSkuBindExt).VendorStoreID
|
var skuStockList []*jdapi.SkuStock
|
||||||
var batchSkuIDs []int
|
stationNo := storeDetail.VendorStoreID
|
||||||
for _, v := range batchItemList {
|
var batchBindIDs []int
|
||||||
storeSku := v.(*tStoreSkuBindExt)
|
for _, v := range batchItemList {
|
||||||
alreadyAddStock := false
|
storeSku := v.(*dao.StoreSkuSyncInfo)
|
||||||
if storeSku.JdSyncStatus&model.SyncFlagChangedMask != 0 {
|
alreadyAddStock := false
|
||||||
batchSkuIDs = append(batchSkuIDs, storeSku.SkuID)
|
if storeSku.StoreSkuSyncStatus&model.SyncFlagChangedMask != 0 || storeSku.BindID == 0 || storeSku.NameID == 0 {
|
||||||
if storeSku.JdSyncStatus&(model.SyncFlagDeletedMask|model.SyncFlagNewMask) != 0 { // 关注或取消关注
|
if storeSku.BindID > 0 {
|
||||||
stock := &jdapi.SkuStock{
|
batchBindIDs = append(batchBindIDs, storeSku.BindID)
|
||||||
OutSkuId: utils.Int2Str(storeSku.SkuID),
|
|
||||||
StockQty: model.MaxStoreSkuStockQty,
|
|
||||||
}
|
}
|
||||||
if storeSku.DeletedAt != utils.DefaultTimeValue {
|
if storeSku.StoreSkuSyncStatus&(model.SyncFlagDeletedMask|model.SyncFlagNewMask) != 0 || storeSku.BindID == 0 || storeSku.NameID == 0 { // 关注或取消关注
|
||||||
stock.StockQty = 0
|
|
||||||
} else {
|
|
||||||
alreadyAddStock = true
|
|
||||||
}
|
|
||||||
if stock.StockQty != 0 || !storeskulock.IsJdStoreSkuLocked(stationNo, storeSku.JdID) {
|
|
||||||
skuStockList = append(skuStockList, stock)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if storeSku.JdSyncStatus&(model.SyncFlagPriceMask|model.SyncFlagNewMask) != 0 {
|
|
||||||
skuPriceInfoList = append(skuPriceInfoList, &jdapi.SkuPriceInfo{
|
|
||||||
OutSkuId: utils.Int2Str(storeSku.SkuID),
|
|
||||||
Price: constrainPrice(jxutils.CaculateSkuVendorPrice(storeSku.Price, storeSku.PricePercentage)),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if storeSku.JdSyncStatus&(model.SyncFlagSaleMask|model.SyncFlagNewMask) != 0 {
|
|
||||||
vendibility := &jdapi.StockVendibility{
|
|
||||||
OutSkuId: utils.Int2Str(storeSku.SkuID),
|
|
||||||
DoSale: true,
|
|
||||||
}
|
|
||||||
if storeSku.Status != model.StoreSkuBindStatusNormal {
|
|
||||||
vendibility.DoSale = false
|
|
||||||
} else if !alreadyAddStock { // 如果是设置可售则自动将库存加满
|
|
||||||
stock := &jdapi.SkuStock{
|
stock := &jdapi.SkuStock{
|
||||||
OutSkuId: utils.Int2Str(storeSku.SkuID),
|
OutSkuId: utils.Int2Str(storeSku.SkuID),
|
||||||
StockQty: model.MaxStoreSkuStockQty,
|
StockQty: model.MaxStoreSkuStockQty,
|
||||||
}
|
}
|
||||||
skuStockList = append(skuStockList, stock)
|
if storeSku.StoreSkuSyncStatus&model.SyncFlagDeletedMask != 0 || storeSku.DeletedAt != utils.DefaultTimeValue || storeSku.BindID == 0 || storeSku.NameID == 0 {
|
||||||
|
stock.StockQty = 0
|
||||||
|
} else {
|
||||||
|
alreadyAddStock = true
|
||||||
|
}
|
||||||
|
if stock.StockQty != 0 || !storeskulock.IsJdStoreSkuLocked(stationNo, storeSku.JdID) {
|
||||||
|
skuStockList = append(skuStockList, stock)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if vendibility.DoSale || !storeskulock.IsJdStoreSkuLocked(stationNo, storeSku.JdID) {
|
if storeSku.StoreSkuSyncStatus&(model.SyncFlagPriceMask|model.SyncFlagNewMask) != 0 {
|
||||||
skuVendibilityList = append(skuVendibilityList, vendibility)
|
skuPriceInfoList = append(skuPriceInfoList, &jdapi.SkuPriceInfo{
|
||||||
|
OutSkuId: utils.Int2Str(storeSku.SkuID),
|
||||||
|
Price: constrainPrice(jxutils.CaculateSkuVendorPrice(int(storeSku.Price), int(storeDetail.PricePercentage), storeSku.CatPricePercentage)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if storeSku.StoreSkuSyncStatus&(model.SyncFlagSaleMask|model.SyncFlagNewMask) != 0 {
|
||||||
|
vendibility := &jdapi.StockVendibility{
|
||||||
|
OutSkuId: utils.Int2Str(storeSku.SkuID),
|
||||||
|
DoSale: true,
|
||||||
|
}
|
||||||
|
if storeSku.StoreSkuStatus != model.StoreSkuBindStatusNormal {
|
||||||
|
vendibility.DoSale = false
|
||||||
|
} else if !alreadyAddStock { // 如果是设置可售则自动将库存加满
|
||||||
|
stock := &jdapi.SkuStock{
|
||||||
|
OutSkuId: utils.Int2Str(storeSku.SkuID),
|
||||||
|
StockQty: model.MaxStoreSkuStockQty,
|
||||||
|
}
|
||||||
|
skuStockList = append(skuStockList, stock)
|
||||||
|
}
|
||||||
|
if vendibility.DoSale || !storeskulock.IsJdStoreSkuLocked(stationNo, storeSku.JdID) {
|
||||||
|
skuVendibilityList = append(skuVendibilityList, vendibility)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
syncMask := 0
|
||||||
syncMask := 0
|
errList := []error{}
|
||||||
errList := []error{}
|
if globals.EnableJdStoreWrite {
|
||||||
if globals.EnableStoreWrite {
|
// todo 以下可以优化为并行操作
|
||||||
// todo 以下可以优化为并行操作
|
globals.SugarLogger.Debug(utils.Format4Output(skuVendibilityList, false), utils.Format4Output(skuPriceInfoList, false), utils.Format4Output(skuStockList, false))
|
||||||
globals.SugarLogger.Debug(utils.Format4Output(skuVendibilityList, false), utils.Format4Output(skuPriceInfoList, false), utils.Format4Output(skuStockList, false))
|
if len(skuVendibilityList) > 0 {
|
||||||
if len(skuVendibilityList) > 0 {
|
if _, err = api.JdAPI.BatchUpdateVendibility("", stationNo, skuVendibilityList, ctx.GetUserName()); err == nil {
|
||||||
if _, err = api.JdAPI.BatchUpdateVendibility("", stationNo, skuVendibilityList, ctx.GetUserName()); err == nil {
|
syncMask |= model.SyncFlagSaleMask
|
||||||
syncMask |= model.SyncFlagSaleMask
|
} else {
|
||||||
} else {
|
errList = append(errList, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (err == nil || isContinueWhenError) && len(skuStockList) > 0 {
|
||||||
|
if _, err = api.JdAPI.BatchUpdateCurrentQtys("", stationNo, skuStockList, ctx.GetUserName()); err == nil {
|
||||||
|
syncMask |= model.SyncFlagNewMask | model.SyncFlagDeletedMask
|
||||||
|
} else {
|
||||||
|
errList = append(errList, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (err == nil || isContinueWhenError) && len(skuPriceInfoList) > 0 {
|
||||||
|
if _, err = api.JdAPI.UpdateVendorStationPrice("", stationNo, skuPriceInfoList); err == nil {
|
||||||
|
syncMask |= model.SyncFlagPriceMask
|
||||||
|
} else {
|
||||||
|
isPartialFailed = isErrPartialFailed(err)
|
||||||
|
errList = append(errList, partner.NewErrorCode(err.Error(), partner.ErrCodeChangePriceFailed, model.VendorIDJD))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(errList) == 0 {
|
||||||
|
syncMask = -1
|
||||||
|
}
|
||||||
|
if syncMask != 0 && len(batchBindIDs) > 0 {
|
||||||
|
// db := dao.GetDB() // 多线程问题
|
||||||
|
sql := `
|
||||||
|
UPDATE store_sku_bind t1
|
||||||
|
SET t1.jd_sync_status = t1.jd_sync_status & ?
|
||||||
|
WHERE t1.id IN (` + dao.GenQuestionMarks(len(batchBindIDs)) + ")"
|
||||||
|
if _, err = dao.ExecuteSQL(db, sql, ^syncMask, batchBindIDs); err != nil {
|
||||||
errList = append(errList, err)
|
errList = append(errList, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (err == nil || isContinueWhenError) && len(skuStockList) > 0 {
|
if len(errList) == 1 {
|
||||||
if _, err = api.JdAPI.BatchUpdateCurrentQtys("", stationNo, skuStockList, ctx.GetUserName()); err == nil {
|
err = errList[0]
|
||||||
syncMask |= model.SyncFlagNewMask | model.SyncFlagDeletedMask
|
} else if len(errList) > 1 {
|
||||||
} else {
|
err = fmt.Errorf("%v", errList)
|
||||||
errList = append(errList, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (err == nil || isContinueWhenError) && len(skuPriceInfoList) > 0 {
|
return isPartialFailed, err
|
||||||
if _, err = api.JdAPI.UpdateVendorStationPrice("", stationNo, skuPriceInfoList); err == nil {
|
}
|
||||||
syncMask |= model.SyncFlagPriceMask
|
isErrPartialFailed, err := doWork(batchItemList)
|
||||||
} else {
|
if isErrPartialFailed && len(batchItemList) > 1 {
|
||||||
errList = append(errList, err)
|
for _, v := range batchItemList {
|
||||||
}
|
doWork([]interface{}{v})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(errList) == 0 {
|
|
||||||
syncMask = -1
|
|
||||||
}
|
|
||||||
if syncMask != 0 && len(batchSkuIDs) > 0 {
|
|
||||||
db := dao.GetDB() // 多线程问题
|
|
||||||
sql := `
|
|
||||||
UPDATE store_sku_bind t1
|
|
||||||
SET t1.jd_sync_status = t1.jd_sync_status & ?
|
|
||||||
` + sqlWhere0 + " AND t1.sku_id IN (" + dao.GenQuestionMarks(len(batchSkuIDs)) + ")"
|
|
||||||
if _, err = dao.ExecuteSQL(db, sql, ^syncMask, storeID, batchSkuIDs); err != nil {
|
|
||||||
errList = append(errList, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(errList) == 1 {
|
|
||||||
err = errList[0]
|
|
||||||
} else if len(errList) > 1 {
|
|
||||||
err = fmt.Errorf("%v", errList)
|
|
||||||
}
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}, storeSkus)
|
}, storeSkus)
|
||||||
tasksch.HandleTask(task, parentTask, false).Run()
|
tasksch.HandleTask(task, parentTask, false).Run()
|
||||||
@@ -160,112 +159,35 @@ func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasks
|
|||||||
return task.ID, err
|
return task.ID, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isErrPartialFailed(err error) bool {
|
||||||
|
if errExt, ok := err.(*utils.ErrorWithCode); ok && errExt.Code() == jdapi.ResponseInnerCodePartialFailed {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
|
globals.SugarLogger.Debugf("jd SyncStoresSkus, storeID:%d, skuIDs:%v", storeID, skuIDs)
|
||||||
|
db := dao.GetDB()
|
||||||
|
storeSkus, err := dao.GetStoreSkus(db, model.VendorIDJD, storeID, skuIDs)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return p.syncStoreSkus(ctx, parentTask, db, storeID, storeSkus, isAsync, isContinueWhenError)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *PurchaseHandler) FullSyncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
func (p *PurchaseHandler) FullSyncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
globals.SugarLogger.Debugf("jd FullSyncStoreSkus, storeID:%d", storeID)
|
globals.SugarLogger.Debugf("jd FullSyncStoreSkus, storeID:%d", storeID)
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
_, err = dao.SetStoreSkuSyncStatus(db, model.VendorIDJD, storeID, nil, model.SyncFlagModifiedMask|model.SyncFlagPriceMask|model.SyncFlagSaleMask)
|
_, err = dao.SetStoreSkuSyncStatus(db, model.VendorIDJD, []int{storeID}, nil, model.SyncFlagStoreSkuOnlyMask)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
skus, err := dao.GetFullStoreSkus(db, model.VendorIDJD, storeID)
|
storeSkus, err := dao.GetFullStoreSkus(db, model.VendorIDJD, storeID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return p.syncStoreSkus(ctx, parentTask, db, storeID, skus, isAsync, isContinueWhenError)
|
return p.syncStoreSkus(ctx, parentTask, db, storeID, storeSkus, isAsync, isContinueWhenError)
|
||||||
}
|
|
||||||
|
|
||||||
// todo 之后应该与SyncStoreSkus合并
|
|
||||||
func (p *PurchaseHandler) syncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, db *dao.DaoDB, storeID int, skus []*dao.StoreSkuSyncInfo, isAsync, isContinueWhenError bool) (hint string, err error) {
|
|
||||||
globals.SugarLogger.Debugf("jd syncStoreSkus, storeID:%d, len(skus):%d", storeID, len(skus))
|
|
||||||
if len(skus) == 0 {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJD)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
stationNo := storeDetail.VendorStoreID
|
|
||||||
task := tasksch.NewParallelTask("SyncStoresSkus京东", tasksch.NewParallelConfig().SetBatchSize(jdapi.MaxStoreSkuBatchSize).SetIsContinueWhenError(isContinueWhenError), ctx,
|
|
||||||
func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
|
||||||
var skuPriceInfoList []*jdapi.SkuPriceInfo
|
|
||||||
var skuVendibilityList []*jdapi.StockVendibility
|
|
||||||
var skuStockList []*jdapi.SkuStock
|
|
||||||
var batchSkuIDs []int
|
|
||||||
for _, v := range batchItemList {
|
|
||||||
storeSku := v.(*dao.StoreSkuSyncInfo)
|
|
||||||
alreadyAddStock := false
|
|
||||||
if storeSku.SkuSyncStatus&model.SyncFlagChangedMask != 0 || storeSku.BindID == 0 {
|
|
||||||
if storeSku.BindID != 0 {
|
|
||||||
batchSkuIDs = append(batchSkuIDs, storeSku.BindID)
|
|
||||||
}
|
|
||||||
if storeSku.SkuSyncStatus&(model.SyncFlagDeletedMask|model.SyncFlagNewMask) != 0 || storeSku.BindID == 0 { // 关注或取消关注
|
|
||||||
stock := &jdapi.SkuStock{
|
|
||||||
OutSkuId: utils.Int2Str(storeSku.ID),
|
|
||||||
StockQty: model.MaxStoreSkuStockQty,
|
|
||||||
}
|
|
||||||
if storeSku.DeletedAt != utils.DefaultTimeValue || storeSku.BindID == 0 {
|
|
||||||
stock.StockQty = 0
|
|
||||||
} else {
|
|
||||||
alreadyAddStock = true
|
|
||||||
}
|
|
||||||
if stock.StockQty != 0 || !storeskulock.IsJdStoreSkuLocked(stationNo, storeSku.JdID) {
|
|
||||||
skuStockList = append(skuStockList, stock)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if storeSku.SkuSyncStatus&(model.SyncFlagPriceMask|model.SyncFlagNewMask) != 0 {
|
|
||||||
skuPriceInfoList = append(skuPriceInfoList, &jdapi.SkuPriceInfo{
|
|
||||||
OutSkuId: utils.Int2Str(storeSku.ID),
|
|
||||||
Price: constrainPrice(jxutils.CaculateSkuVendorPrice(int(storeSku.Price), int(storeDetail.PricePercentage))),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if storeSku.SkuSyncStatus&(model.SyncFlagSaleMask|model.SyncFlagNewMask) != 0 {
|
|
||||||
vendibility := &jdapi.StockVendibility{
|
|
||||||
OutSkuId: utils.Int2Str(storeSku.ID),
|
|
||||||
DoSale: true,
|
|
||||||
}
|
|
||||||
if storeSku.StoreSkuStatus != model.StoreSkuBindStatusNormal {
|
|
||||||
vendibility.DoSale = false
|
|
||||||
} else if !alreadyAddStock { // 如果是设置可售则自动将库存加满
|
|
||||||
stock := &jdapi.SkuStock{
|
|
||||||
OutSkuId: utils.Int2Str(storeSku.ID),
|
|
||||||
StockQty: model.MaxStoreSkuStockQty,
|
|
||||||
}
|
|
||||||
skuStockList = append(skuStockList, stock)
|
|
||||||
}
|
|
||||||
if vendibility.DoSale || !storeskulock.IsJdStoreSkuLocked(stationNo, storeSku.JdID) {
|
|
||||||
skuVendibilityList = append(skuVendibilityList, vendibility)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
globals.SugarLogger.Debugf("jd syncStoreSkus sync detail, storeID:%d, skuVendibilityList:%s, skuPriceInfoList:%s, skuStockList:%s", storeID, utils.Format4Output(skuVendibilityList, true), utils.Format4Output(skuPriceInfoList, true), utils.Format4Output(skuStockList, true))
|
|
||||||
if globals.EnableStoreWrite {
|
|
||||||
// todo 以下可以优化为并行操作
|
|
||||||
if len(skuVendibilityList) > 0 {
|
|
||||||
_, err = api.JdAPI.BatchUpdateVendibility("", stationNo, skuVendibilityList, ctx.GetUserName())
|
|
||||||
}
|
|
||||||
if err == nil && len(skuStockList) > 0 {
|
|
||||||
_, err = api.JdAPI.BatchUpdateCurrentQtys("", stationNo, skuStockList, ctx.GetUserName())
|
|
||||||
}
|
|
||||||
if err == nil && len(skuPriceInfoList) > 0 {
|
|
||||||
_, err = api.JdAPI.UpdateVendorStationPrice("", stationNo, skuPriceInfoList)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == nil && len(batchSkuIDs) > 0 {
|
|
||||||
db := dao.GetDB() // 多线程问题
|
|
||||||
sql := `
|
|
||||||
UPDATE store_sku_bind t1
|
|
||||||
SET t1.jd_sync_status = 0
|
|
||||||
WHERE t1.id IN (` + dao.GenQuestionMarks(len(batchSkuIDs)) + ")"
|
|
||||||
_, err = dao.ExecuteSQL(db, sql, batchSkuIDs)
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}, skus)
|
|
||||||
tasksch.HandleTask(task, parentTask, false).Run()
|
|
||||||
if !isAsync {
|
|
||||||
_, err = task.GetResult(0)
|
|
||||||
}
|
|
||||||
return task.ID, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PurchaseHandler) DeleteRemoteStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
func (p *PurchaseHandler) DeleteRemoteStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
@@ -278,3 +200,117 @@ func constrainPrice(price int) int {
|
|||||||
}
|
}
|
||||||
return price
|
return price
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetStoresSku(ctx *jxcontext.Context, parentTask tasksch.ITask, storeIDs []int) (storeSkuList []*model.StoreSkuBind, err error) {
|
||||||
|
db := dao.GetDB()
|
||||||
|
skuList, err := dao.GetSkus(db, nil, nil, []int{model.SkuStatusNormal}, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var skuInfoList []*jdapi.BaseStockCenterRequest
|
||||||
|
skuMap := make(map[int64]int)
|
||||||
|
for _, sku := range skuList {
|
||||||
|
if !jxutils.IsEmptyID(sku.JdID) {
|
||||||
|
skuInfoList = append(skuInfoList, &jdapi.BaseStockCenterRequest{
|
||||||
|
SkuId: sku.JdID,
|
||||||
|
})
|
||||||
|
skuMap[sku.JdID] = sku.ID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, storeID := range storeIDs {
|
||||||
|
storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJD)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, sku := range skuInfoList {
|
||||||
|
sku.StationNo = storeDetail.VendorStoreID
|
||||||
|
}
|
||||||
|
task := tasksch.NewParallelTask("jd 获取京东门店商品信息", tasksch.NewParallelConfig().SetBatchSize(jdapi.MaxStoreSkuBatchSize), ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
batchSkuInfoList := make([]*jdapi.BaseStockCenterRequest, len(batchItemList))
|
||||||
|
batchSkuList := make([]int64, len(batchItemList))
|
||||||
|
for k, v := range batchItemList {
|
||||||
|
batchSkuInfoList[k] = v.(*jdapi.BaseStockCenterRequest)
|
||||||
|
batchSkuList[k] = batchSkuInfoList[k].SkuId
|
||||||
|
}
|
||||||
|
stockInfo, err := api.JdAPI.QueryOpenUseable(batchSkuInfoList)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
priceInfo, err := api.JdAPI.GetStationInfoList(storeDetail.VendorStoreID, batchSkuList)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var batchStoreSkuList []*model.StoreSkuBind
|
||||||
|
batchStoreSkuMap := make(map[int64]*model.StoreSkuBind)
|
||||||
|
for _, v := range stockInfo {
|
||||||
|
if v.UsableQty > 0 {
|
||||||
|
batchSku := &model.StoreSkuBind{
|
||||||
|
StoreID: storeID,
|
||||||
|
SkuID: skuMap[v.SkuID],
|
||||||
|
}
|
||||||
|
if v.Vendibility == 0 {
|
||||||
|
batchSku.Status = model.SkuStatusNormal
|
||||||
|
} else {
|
||||||
|
batchSku.Status = model.SkuStatusDontSale
|
||||||
|
}
|
||||||
|
batchStoreSkuMap[v.SkuID] = batchSku
|
||||||
|
batchStoreSkuList = append(batchStoreSkuList, batchSku)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, v := range priceInfo {
|
||||||
|
if storeSku := batchStoreSkuMap[v.SkuID]; storeSku != nil {
|
||||||
|
storeSku.Price = int(v.Price)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return batchStoreSkuList, err
|
||||||
|
}, skuInfoList)
|
||||||
|
tasksch.AddChild(parentTask, task).Run()
|
||||||
|
result, err := task.GetResult(0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, v := range result {
|
||||||
|
storeSkuList = append(storeSkuList, v.(*model.StoreSkuBind))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return storeSkuList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) SyncStoreProducts(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
|
globals.SugarLogger.Debugf("jd SyncStoreProducts, storeID:%d", storeID)
|
||||||
|
db := dao.GetDB()
|
||||||
|
storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJD)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
storeSkuList, err := dao.GetStoreSkus2(db, model.VendorIDJD, storeID, skuIDs, false)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
task := tasksch.NewParallelTask("SyncStoreProducts京东", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
storeSku := batchItemList[0].(*dao.StoreSkuSyncInfo)
|
||||||
|
if storeSku.VendorSkuID != "" && storeSku.StoreSkuStatus == model.SkuStatusNormal {
|
||||||
|
if globals.EnableJdStoreWrite {
|
||||||
|
synchronized, err2 := api.JdAPI.SyncProduct(storeDetail.VendorStoreID, storeSku.VendorSkuID)
|
||||||
|
if err = err2; err == nil && synchronized {
|
||||||
|
retVal = []int{1}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
retVal = []int{1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retVal, err
|
||||||
|
}, storeSkuList)
|
||||||
|
tasksch.HandleTask(task, parentTask, true).Run()
|
||||||
|
if !isAsync {
|
||||||
|
result, err2 := task.GetResult(0)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
hint = utils.Int2Str(len(result))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hint = task.GetID()
|
||||||
|
}
|
||||||
|
return hint, err
|
||||||
|
}
|
||||||
|
|||||||
66
business/partner/purchase/jd/store_sku2.go
Normal file
66
business/partner/purchase/jd/store_sku2.go
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package jd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetStoreSkusInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.BareStoreSkuInfo) (outStoreSkuList []*partner.BareStoreSkuInfo, err error) {
|
||||||
|
var batchSkuInfoList []*jdapi.BaseStockCenterRequest
|
||||||
|
batchSkuList := partner.BareStoreSkuInfoList(inStoreSkuList).GetVendorSkuIDIntList()
|
||||||
|
for _, v := range inStoreSkuList {
|
||||||
|
if !dao.IsVendorThingIDEmpty(v.VendorSkuID) {
|
||||||
|
batchSkuInfoList = append(batchSkuInfoList, &jdapi.BaseStockCenterRequest{
|
||||||
|
StationNo: vendorStoreID,
|
||||||
|
SkuId: utils.Str2Int64(v.VendorSkuID),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(batchSkuInfoList) > 0 {
|
||||||
|
var stockInfo []*jdapi.QueryStockResponse
|
||||||
|
var priceInfo []*jdapi.StorePriceInfo
|
||||||
|
task := tasksch.NewParallelTask("获取京东到家平台门店商品信息", tasksch.NewParallelConfig().SetParallelCount(2), ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
subTaskID := batchItemList[0].(int)
|
||||||
|
if subTaskID == 0 {
|
||||||
|
stockInfo, err = api.JdAPI.QueryOpenUseable(batchSkuInfoList)
|
||||||
|
} else {
|
||||||
|
priceInfo, err = api.JdAPI.GetStationInfoList(vendorStoreID, batchSkuList)
|
||||||
|
globals.SugarLogger.Debug(utils.Format4Output(priceInfo, false))
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}, []int{0, 1})
|
||||||
|
tasksch.HandleTask(task, parentTask, false).Run()
|
||||||
|
_, err = task.GetResult(0)
|
||||||
|
if err == nil {
|
||||||
|
storeSkuMap := make(map[int64]*partner.BareStoreSkuInfo)
|
||||||
|
for _, v := range inStoreSkuList {
|
||||||
|
storeSkuMap[utils.Str2Int64(v.VendorSkuID)] = v
|
||||||
|
}
|
||||||
|
for _, v := range stockInfo {
|
||||||
|
outStoreSkuList = append(outStoreSkuList, storeSkuMap[v.SkuID])
|
||||||
|
storeSkuMap[v.SkuID].Status = jdStoreSkuStatus2Jx(v.Vendibility)
|
||||||
|
}
|
||||||
|
for _, v := range priceInfo {
|
||||||
|
storeSkuMap[v.SkuID].Price = v.Price
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return outStoreSkuList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func jdStoreSkuStatus2Jx(jdStoreSkuStatus int) (jxSkuStatus int) {
|
||||||
|
if jdStoreSkuStatus == 0 {
|
||||||
|
jxSkuStatus = model.SkuStatusNormal
|
||||||
|
} else {
|
||||||
|
jxSkuStatus = model.SkuStatusDontSale
|
||||||
|
}
|
||||||
|
return jxSkuStatus
|
||||||
|
}
|
||||||
169
business/partner/purchase/mtwm/act.go
Normal file
169
business/partner/purchase/mtwm/act.go
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
package mtwm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
func actOrderRules2Mtwm(actOrderRules []*model.ActOrderRule) (actDetails []*mtwmapi.FullDiscountActDetail) {
|
||||||
|
for _, v := range actOrderRules {
|
||||||
|
actDetails = append(actDetails, &mtwmapi.FullDiscountActDetail{
|
||||||
|
OriginalPrice: jxutils.IntPrice2Standard(v.SalePrice),
|
||||||
|
ActPrice: jxutils.IntPrice2Standard(v.DeductPrice),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return actDetails
|
||||||
|
}
|
||||||
|
|
||||||
|
func storeSku2ActData(act *model.Act2, actStoreSku []*model.ActStoreSku2, handler func(int) bool) (actData []*mtwmapi.RetailDiscountActData) {
|
||||||
|
for _, v := range actStoreSku {
|
||||||
|
if handler == nil || handler(v.SyncStatus) {
|
||||||
|
actData = append(actData, &mtwmapi.RetailDiscountActData{
|
||||||
|
AppFoodCode: utils.Int2Str(v.SkuID),
|
||||||
|
// UserType: 0,
|
||||||
|
StartTime: act.BeginAt.Unix(),
|
||||||
|
EndTime: act.EndAt.Unix(),
|
||||||
|
OrderLimit: act.LimitCount,
|
||||||
|
DayLimit: act.LimitDaily,
|
||||||
|
// Period: "",
|
||||||
|
// WeeksTime: "",
|
||||||
|
SettingType: mtwmapi.SettingTypeAsPrice,
|
||||||
|
ActPrice: jxutils.IntPrice2Standard(v.ActPrice),
|
||||||
|
// DiscountCoefficient: 0,
|
||||||
|
Sequence: int(v.ActPrice),
|
||||||
|
ItemID: utils.Str2Int64WithDefault(v.VendorActID, 0),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actData
|
||||||
|
}
|
||||||
|
|
||||||
|
func storeSku2ActData4Delete(actStoreSku []*model.ActStoreSku2, handler func(int) bool) (actIDList []string) {
|
||||||
|
for _, v := range actStoreSku {
|
||||||
|
if handler == nil || handler(v.SyncStatus) {
|
||||||
|
if v.VendorActID != "" {
|
||||||
|
actIDList = append(actIDList, v.VendorActID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actIDList
|
||||||
|
}
|
||||||
|
|
||||||
|
func isCreateOrUpdate(syncStatus int) bool {
|
||||||
|
return model.IsSyncStatusNeedCreate(syncStatus) || model.IsSyncStatusNeedUpdate(syncStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createOneShopAct(act *model.Act2, storeMap *model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
|
||||||
|
actData := storeSku2ActData(act, actStoreSku, isCreateOrUpdate)
|
||||||
|
if len(actData) > 0 {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
actResult, err2 := api.MtwmAPI.RetailDiscountBatchSave(storeMap.VendorStoreID, actData)
|
||||||
|
if err = err2; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
actResultMap := make(map[string]*mtwmapi.RetailDiscountActResult)
|
||||||
|
for _, v := range actResult {
|
||||||
|
actResultMap[v.AppFoodCode] = v
|
||||||
|
}
|
||||||
|
for _, v := range actStoreSku {
|
||||||
|
if result := actResultMap[utils.Int2Str(v.SkuID)]; result != nil {
|
||||||
|
v.VendorActID = utils.Int64ToStr(result.ActID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, v := range actStoreSku {
|
||||||
|
v.VendorActID = utils.Int64ToStr(jxutils.GenFakeID())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
|
||||||
|
globals.SugarLogger.Debugf("mtwm CreateAct actID:%d", act.ID)
|
||||||
|
if act.Type < model.ActOrderBegin {
|
||||||
|
actStoreSkuMap := partner.ActStoreSku2Map(actStoreSku)
|
||||||
|
task := tasksch.NewParallelTask("mtwm CreateAct", nil, ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
store := batchItemList[0].(*model.ActStore2)
|
||||||
|
err = createOneShopAct(act, store, actStoreSkuMap[store.StoreID])
|
||||||
|
return nil, err
|
||||||
|
}, actStoreMap)
|
||||||
|
tasksch.HandleTask(task, parentTask, true).Run()
|
||||||
|
_, err = task.GetResult(0)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
|
||||||
|
if act.Type < model.ActOrderBegin {
|
||||||
|
actStoreSkuMap := partner.ActStoreSku2Map(actStoreSku)
|
||||||
|
if len(actStoreMap2Remove) > 0 {
|
||||||
|
if err = c.CancelAct(ctx, parentTask, act, actStoreMap2Remove, nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, v := range actStoreMap2Remove {
|
||||||
|
delete(actStoreSkuMap, v.StoreID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(actStoreMap2Add) > 0 {
|
||||||
|
if err = c.CreateAct(ctx, parentTask, act, actOrderRules, actStoreMap2Add, actStoreSku); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, v := range actStoreMap2Add {
|
||||||
|
delete(actStoreSkuMap, v.StoreID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
task := tasksch.NewParallelTask("mtwm UpdateAct", nil, ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
v := batchItemList[0].(*model.ActStore2)
|
||||||
|
if storeSkus := actStoreSkuMap[v.StoreID]; storeSkus != nil {
|
||||||
|
if list := storeSku2ActData4Delete(storeSkus, model.IsSyncStatusNeedDelete); len(list) > 0 {
|
||||||
|
if err = api.MtwmAPI.RetailDiscountDelete(v.VendorStoreID, list); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err = createOneShopAct(act, v, actStoreSkuMap[v.StoreID]); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}, actStoreMap2Update)
|
||||||
|
tasksch.HandleTask(task, parentTask, true).Run()
|
||||||
|
_, err = task.GetResult(0)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) CancelAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
|
||||||
|
if act.Type < model.ActOrderBegin {
|
||||||
|
actStoreSkuMap := partner.ActStoreSku2Map(actStoreSku)
|
||||||
|
task := tasksch.NewParallelTask("mtwm DeleteAct", nil, ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
v := batchItemList[0].(*model.ActStore2)
|
||||||
|
actIDList := storeSku2ActData4Delete(actStoreSkuMap[v.StoreID], nil)
|
||||||
|
if len(actIDList) > 0 {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
err = api.MtwmAPI.RetailDiscountDelete(v.VendorStoreID, actIDList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}, actStoreMap)
|
||||||
|
tasksch.HandleTask(task, parentTask, true).Run()
|
||||||
|
_, err = task.GetResult(0)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@ package mtwm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
|
||||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
"git.rosy.net.cn/jx-callback/business/model"
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
)
|
)
|
||||||
@@ -19,11 +18,11 @@ func OnOrderCallbackMsg(msg *mtwmapi.CallbackMsg) (response *mtwmapi.CallbackRes
|
|||||||
}
|
}
|
||||||
}, jxutils.ComposeUniversalOrderID(orderID, model.VendorIDMTWM))
|
}, jxutils.ComposeUniversalOrderID(orderID, model.VendorIDMTWM))
|
||||||
}
|
}
|
||||||
if msg.Cmd == mtwmapi.MsgTypeOrderRefund || msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund {
|
/*if msg.Cmd == mtwmapi.MsgTypeOrderRefund || msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund {
|
||||||
utils.CallFuncAsync(func() {
|
utils.CallFuncAsync(func() {
|
||||||
OnFinancialMsg(msg)
|
OnFinancialMsg(msg)
|
||||||
})
|
})
|
||||||
} else if msg.Cmd == mtwmapi.MsgTypeStoreStatusChanged {
|
} else */if msg.Cmd == mtwmapi.MsgTypeStoreStatusChanged {
|
||||||
response = curPurchaseHandler.onStoreStatusChanged(msg)
|
response = curPurchaseHandler.onStoreStatusChanged(msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -31,5 +30,5 @@ func OnOrderCallbackMsg(msg *mtwmapi.CallbackMsg) (response *mtwmapi.CallbackRes
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetOrderIDFromMsg(msg *mtwmapi.CallbackMsg) string {
|
func GetOrderIDFromMsg(msg *mtwmapi.CallbackMsg) string {
|
||||||
return msg.Data.Get(mtwmapi.KeyOrderID)
|
return msg.FormData.Get(mtwmapi.KeyOrderID)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ const (
|
|||||||
// 存储美团退款订单结账信息
|
// 存储美团退款订单结账信息
|
||||||
func OnFinancialMsg(msg *mtwmapi.CallbackMsg) (err error) {
|
func OnFinancialMsg(msg *mtwmapi.CallbackMsg) (err error) {
|
||||||
if msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund { // 部分退款处理
|
if msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund { // 部分退款处理
|
||||||
orderData := msg.Data
|
orderData := msg.FormData
|
||||||
if orderData.Get("notify_type") == mtwmapi.NotifyTypeSuccess {
|
if orderData.Get("notify_type") == mtwmapi.NotifyTypeSuccess {
|
||||||
err = partner.CurOrderManager.SaveAfsOrderFinancialInfo(curPurchaseHandler.AfsOrderDetail2Financial(orderData))
|
err = partner.CurOrderManager.SaveAfsOrderFinancialInfo(curPurchaseHandler.AfsOrderDetail2Financial(orderData))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if msg.Cmd == mtwmapi.MsgTypeOrderRefund { // todo 全额退款处理
|
if msg.Cmd == mtwmapi.MsgTypeOrderRefund { // todo 全额退款处理
|
||||||
orderData := msg.Data
|
orderData := msg.FormData
|
||||||
if orderData.Get("notify_type") == mtwmapi.NotifyTypeSuccess {
|
if orderData.Get("notify_type") == mtwmapi.NotifyTypeSuccess {
|
||||||
globals.SugarLogger.Debug(orderData.Get("order_id")) // 获得退款订单ID,去本地数据库拿?饿百消息推送只给了订单号,也没有通过订单号查询退款信息的接口
|
globals.SugarLogger.Debug(orderData.Get("order_id")) // 获得退款订单ID,去本地数据库拿?饿百消息推送只给了订单号,也没有通过订单号查询退款信息的接口
|
||||||
afsOrderID := orderData.Get("order_id")
|
afsOrderID := orderData.Get("order_id")
|
||||||
@@ -45,7 +45,7 @@ func (p *PurchaseHandler) OrderFinancialDetail2Refund(orderFinancial *model.Orde
|
|||||||
VendorID: model.VendorIDMTWM,
|
VendorID: model.VendorIDMTWM,
|
||||||
AfsOrderID: orderData.Get("order_id"),
|
AfsOrderID: orderData.Get("order_id"),
|
||||||
VendorOrderID: orderData.Get("order_id"),
|
VendorOrderID: orderData.Get("order_id"),
|
||||||
AfsCreateAt: utils.Timestamp2Time(utils.Str2Int64(orderData.Get("timestamp"))),
|
AfsCreatedAt: utils.Timestamp2Time(utils.Str2Int64(orderData.Get("timestamp"))),
|
||||||
// BoxMoney: orderFinancial.BoxMoney,
|
// BoxMoney: orderFinancial.BoxMoney,
|
||||||
// SkuBoxMoney: orderFinancial.SkuBoxMoney, // 美团的餐盒费已经拆到单条SKU里面去了,退款时直接计算用户支付sku金额就好了
|
// SkuBoxMoney: orderFinancial.SkuBoxMoney, // 美团的餐盒费已经拆到单条SKU里面去了,退款时直接计算用户支付sku金额就好了
|
||||||
FreightUserMoney: orderFinancial.FreightMoney,
|
FreightUserMoney: orderFinancial.FreightMoney,
|
||||||
@@ -64,9 +64,8 @@ func (p *PurchaseHandler) OrderFinancialDetail2Refund(orderFinancial *model.Orde
|
|||||||
}
|
}
|
||||||
for _, sku := range orderFinancial.Skus {
|
for _, sku := range orderFinancial.Skus {
|
||||||
orderSkuFinancial := &model.OrderSkuFinancial{
|
orderSkuFinancial := &model.OrderSkuFinancial{
|
||||||
VendorID: sku.VendorID,
|
VendorID: sku.VendorID,
|
||||||
VendorOrderID: sku.VendorOrderID,
|
VendorOrderID: sku.VendorOrderID,
|
||||||
VendorOrderID2: sku.VendorOrderID2,
|
|
||||||
// OrderFinancialID: sku.VendorOrderID,
|
// OrderFinancialID: sku.VendorOrderID,
|
||||||
// ConfirmTime: afsOrder.AfsCreateAt,
|
// ConfirmTime: afsOrder.AfsCreateAt,
|
||||||
VendorStoreID: afsOrder.VendorStoreID,
|
VendorStoreID: afsOrder.VendorStoreID,
|
||||||
@@ -93,7 +92,7 @@ func (p *PurchaseHandler) AfsOrderDetail2Financial(orderData url.Values) (afsOrd
|
|||||||
VendorID: model.VendorIDMTWM,
|
VendorID: model.VendorIDMTWM,
|
||||||
AfsOrderID: orderData.Get("order_id"),
|
AfsOrderID: orderData.Get("order_id"),
|
||||||
VendorOrderID: orderData.Get("order_id"),
|
VendorOrderID: orderData.Get("order_id"),
|
||||||
AfsCreateAt: utils.Timestamp2Time(utils.Str2Int64(orderData.Get("timestamp"))),
|
AfsCreatedAt: utils.Timestamp2Time(utils.Str2Int64(orderData.Get("timestamp"))),
|
||||||
RefundMoney: jxutils.StandardPrice2Int(utils.Str2Float64(orderData.Get("money"))),
|
RefundMoney: jxutils.StandardPrice2Int(utils.Str2Float64(orderData.Get("money"))),
|
||||||
}
|
}
|
||||||
// if orderData.Get("timestamp") != "" {
|
// if orderData.Get("timestamp") != "" {
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ import (
|
|||||||
|
|
||||||
func TestOnFinancialMsg(t *testing.T) {
|
func TestOnFinancialMsg(t *testing.T) {
|
||||||
msg := &mtwmapi.CallbackMsg{
|
msg := &mtwmapi.CallbackMsg{
|
||||||
Cmd: "orderRefund",
|
Cmd: "orderRefund",
|
||||||
Data: url.Values{},
|
FormData: url.Values{},
|
||||||
}
|
}
|
||||||
msg.Data.Set("timestamp", utils.Int64ToStr(time.Now().Unix()))
|
msg.FormData.Set("timestamp", utils.Int64ToStr(time.Now().Unix()))
|
||||||
msg.Data.Set("order_id", "33762863167364867")
|
msg.FormData.Set("order_id", "33762863167364867")
|
||||||
msg.Data.Set("notify_type", "agree")
|
msg.FormData.Set("notify_type", "agree")
|
||||||
msg.Data.Set("money", "23.56")
|
msg.FormData.Set("money", "23.56")
|
||||||
food := []map[string]interface{}{
|
food := []map[string]interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"app_food_code": "123",
|
"app_food_code": "123",
|
||||||
@@ -40,8 +40,8 @@ func TestOnFinancialMsg(t *testing.T) {
|
|||||||
"box_price": 1,
|
"box_price": 1,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
msg.Data.Set("food", string(utils.MustMarshal(food)))
|
msg.FormData.Set("food", string(utils.MustMarshal(food)))
|
||||||
res := OnFinancialMsg(msg)
|
res := curPurchaseHandler.onAfsOrderMsg(msg)
|
||||||
fmt.Println(res)
|
fmt.Println(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ func bizStatusMtwm2JX(openLevel, online int) int {
|
|||||||
return model.StoreStatusDisabled
|
return model.StoreStatusDisabled
|
||||||
} else {
|
} else {
|
||||||
if openLevel == mtwmapi.PoiOpenLevelHaveRest {
|
if openLevel == mtwmapi.PoiOpenLevelHaveRest {
|
||||||
return model.StoreStatusClosed
|
return model.StoreStatusHaveRest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return model.StoreStatusOpened
|
return model.StoreStatusOpened
|
||||||
@@ -138,7 +138,7 @@ func bizStatusMtwm2JX(openLevel, online int) int {
|
|||||||
func bizStatusJX2Mtwm(status int) (openLevel, online int) {
|
func bizStatusJX2Mtwm(status int) (openLevel, online int) {
|
||||||
if status == model.StoreStatusDisabled {
|
if status == model.StoreStatusDisabled {
|
||||||
return mtwmapi.PoiOpenLevelHaveRest, mtwmapi.PoiStatusOffline
|
return mtwmapi.PoiOpenLevelHaveRest, mtwmapi.PoiStatusOffline
|
||||||
} else if status == model.StoreStatusClosed {
|
} else if status == model.StoreStatusHaveRest || status == model.StoreStatusClosed {
|
||||||
return mtwmapi.PoiOpenLevelHaveRest, mtwmapi.PoiStatusOnline
|
return mtwmapi.PoiOpenLevelHaveRest, mtwmapi.PoiStatusOnline
|
||||||
}
|
}
|
||||||
return mtwmapi.PoiOpenLevelNormal, mtwmapi.PoiStatusOnline
|
return mtwmapi.PoiOpenLevelNormal, mtwmapi.PoiStatusOnline
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user