- jd.FullSyncStoreSkus
- refactor mtwm.SyncLocalStoreCategory
This commit is contained in:
@@ -320,7 +320,7 @@ func (v *VendorSync) FullSyncStoresSkus(ctx *jxcontext.Context, db *dao.DaoDB, v
|
|||||||
globals.SugarLogger.Debug("FullSyncStoresSkus")
|
globals.SugarLogger.Debug("FullSyncStoresSkus")
|
||||||
return v.LoopStoresMap(ctx, db, "FullSyncStoresSkus顶层", isAsync, vendorIDs, storeIDs, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) {
|
return v.LoopStoresMap(ctx, db, "FullSyncStoresSkus顶层", isAsync, vendorIDs, storeIDs, 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.GetStoreHandler(loopMapInfo.VendorID); handler != nil {
|
||||||
if len(loopMapInfo.StoreMapList) > 1 {
|
if len(loopMapInfo.StoreMapList) > 1 {
|
||||||
loopStoreTask := tasksch.NewSeqTask("FullSyncStoresSkus相同平台循环门店", ctx.GetUserName(), func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
loopStoreTask := tasksch.NewSeqTask("FullSyncStoresSkus相同平台循环门店", ctx.GetUserName(), func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
|
||||||
storeID := loopMapInfo.StoreMapList[step].StoreID
|
storeID := loopMapInfo.StoreMapList[step].StoreID
|
||||||
|
|||||||
@@ -7,16 +7,27 @@ import (
|
|||||||
|
|
||||||
type StoreDetail struct {
|
type StoreDetail struct {
|
||||||
model.Store
|
model.Store
|
||||||
|
|
||||||
VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"`
|
VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"`
|
||||||
VendorStatus int `json:"vendor_status"` // 取值同Store.Status
|
VendorStatus int `json:"vendor_status"` // 取值同Store.Status
|
||||||
DeliveryFee int `json:"deliveryFee"`
|
DeliveryFee int `json:"deliveryFee"`
|
||||||
SyncStatus int8 `orm:"default(2)" json:"syncStatus"`
|
SyncStatus int8 `orm:"default(2)" json:"syncStatus"`
|
||||||
model.Place // district info
|
|
||||||
|
PricePercentage int16 `orm:"default(100)" json:"pricePercentage"` // todo 厂商价格相对于本地价格的百分比,这个字段的修改会比较特殊,因为可能需要刷新厂商价格
|
||||||
|
AutoPickup int8 `orm:"default(1)" json:"autoPickup"` // 是否自动拣货
|
||||||
|
DeliveryType int8 `orm:"default(0)" json:"deliveryType"` // 配送类型
|
||||||
|
DeliveryCompetition int8 `orm:"default(1)" json:"deliveryCompetition"` // 是否支持配送竞争
|
||||||
|
IsSync int8 `orm:"default(1)" json:"isSync"` // 是否同步
|
||||||
|
|
||||||
|
model.Place // district info
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetStoreDetail(db *DaoDB, storeID, vendorID int) (storeDetail *StoreDetail, err error) {
|
func GetStoreDetail(db *DaoDB, storeID, vendorID int) (storeDetail *StoreDetail, err error) {
|
||||||
sql := `
|
sql := `
|
||||||
SELECT t2.status vendor_status, t2.vendor_store_id, t2.sync_status, district.*, t1.*
|
SELECT t1.*,
|
||||||
|
t2.vendor_store_id, t2.status vendor_status, t2.delivery_fee, t2.sync_status,
|
||||||
|
t2.price_percentage, t2.auto_pickup, t2.delivery_type, t2.delivery_competition, t2.is_sync,
|
||||||
|
district.*
|
||||||
FROM store t1
|
FROM store t1
|
||||||
JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? AND t2.deleted_at = ?
|
JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? AND t2.deleted_at = ?
|
||||||
LEFT JOIN place district ON t1.district_code = district.code
|
LEFT JOIN place district ON t1.district_code = district.code
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"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/globals"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SkuStoreCatInfo struct {
|
type SkuStoreCatInfo struct {
|
||||||
@@ -31,6 +32,29 @@ type StoreCatSyncInfo struct {
|
|||||||
ParentCatSyncStatus int8
|
ParentCatSyncStatus int8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StoreSkuSyncInfo struct {
|
||||||
|
BindID int `orm:"column(bind_id)"`
|
||||||
|
Price int64
|
||||||
|
UnitPrice int64
|
||||||
|
StoreSkuStatus int
|
||||||
|
SkuSyncStatus int8
|
||||||
|
model.Sku
|
||||||
|
VendorSkuID int64 `orm:"column(vendor_sku_id)"`
|
||||||
|
Prefix string
|
||||||
|
Name string
|
||||||
|
Unit string
|
||||||
|
Img string
|
||||||
|
|
||||||
|
VendorVendorCatID int64 `orm:"column(vendor_vendor_cat_id)"`
|
||||||
|
|
||||||
|
CatSyncStatus int8
|
||||||
|
VendorCatID string `orm:"column(vendor_cat_id)"`
|
||||||
|
|
||||||
|
SkuCatSyncStatus int8
|
||||||
|
SkuVendorCatID string `orm:"column(sku_vendor_cat_id)"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单门店模式厂商适用
|
||||||
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 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
|
||||||
@@ -72,6 +96,7 @@ func GetSkusCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level int
|
|||||||
return cats, err
|
return cats, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 单门店模式厂商适用
|
||||||
func GetStoreCategories(db *DaoDB, vendorID, storeID int, level int) (cats []*StoreCatSyncInfo, err error) {
|
func GetStoreCategories(db *DaoDB, vendorID, storeID int, level int) (cats []*StoreCatSyncInfo, err error) {
|
||||||
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
||||||
sql := fmt.Sprintf(`
|
sql := fmt.Sprintf(`
|
||||||
@@ -88,34 +113,14 @@ func GetStoreCategories(db *DaoDB, vendorID, storeID int, level int) (cats []*St
|
|||||||
return cats, err
|
return cats, err
|
||||||
}
|
}
|
||||||
|
|
||||||
type StoreSkuSyncInfo struct {
|
// 单门店模式厂商适用
|
||||||
BindID int `orm:"column(bind_id)"`
|
|
||||||
Price int64
|
|
||||||
UnitPrice int64
|
|
||||||
StoreSkuStatus int
|
|
||||||
SkuSyncStatus int8
|
|
||||||
model.Sku
|
|
||||||
Prefix string
|
|
||||||
Name string
|
|
||||||
Unit string
|
|
||||||
Img string
|
|
||||||
|
|
||||||
VendorVendorCatID int64 `orm:"column(vendor_vendor_cat_id)"`
|
|
||||||
|
|
||||||
CatSyncStatus int8
|
|
||||||
VendorCatID string `orm:"column(vendor_cat_id)"`
|
|
||||||
|
|
||||||
SkuCatSyncStatus int8
|
|
||||||
SkuVendorCatID string `orm:"column(sku_vendor_cat_id)"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetStoreSkus(db *DaoDB, vendorID, storeID int, skuIDs []int) (skus []*StoreSkuSyncInfo, err error) {
|
func GetStoreSkus(db *DaoDB, vendorID, storeID int, skuIDs []int) (skus []*StoreSkuSyncInfo, err error) {
|
||||||
tableName := "t1"
|
tableName := "t1"
|
||||||
if model.MultiStoresVendorMap[vendorID] == 1 { // 多店模式平台
|
if model.MultiStoresVendorMap[vendorID] == 1 { // 多店模式平台
|
||||||
tableName = "t2"
|
tableName = "t2"
|
||||||
}
|
}
|
||||||
sql := `
|
sql := `
|
||||||
SELECT t1.id bind_id, t1.price, t1.unit_price, t1.status store_sku_status, %s.%s_id, t1.%s_sync_status sku_sync_status,
|
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,
|
||||||
t2.*,
|
t2.*,
|
||||||
t3.prefix, t3.name, t3.unit, t3.img,
|
t3.prefix, t3.name, t3.unit, t3.img,
|
||||||
t4.%s_category_id vendor_vendor_cat_id,
|
t4.%s_category_id vendor_vendor_cat_id,
|
||||||
@@ -147,7 +152,42 @@ func GetStoreSkus(db *DaoDB, vendorID, storeID int, skuIDs []int) (skus []*Store
|
|||||||
return skus, err
|
return skus, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 多门店模式厂商适用
|
||||||
|
func GetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSyncInfo, err error) {
|
||||||
|
globals.SugarLogger.Debugf("GetFullStoreSkus, storeID:%d, vendorID:%d", storeID, vendorID)
|
||||||
|
|
||||||
|
sql := `
|
||||||
|
SELECT t1.id bind_id, t1.price, t1.unit_price, t1.status store_sku_status, t2.%s_id vendor_sku_id, t1.%s_sync_status sku_sync_status,
|
||||||
|
t2.*,
|
||||||
|
t3.prefix, t3.name, t3.unit, t3.img,
|
||||||
|
t4.%s_category_id vendor_vendor_cat_id,
|
||||||
|
t4.%s_sync_status cat_sync_status, t4.%s_id vendor_cat_id,
|
||||||
|
t5sku.%s_sync_status sku_cat_sync_status, t5sku.%s_id sku_vendor_cat_id
|
||||||
|
FROM sku t2
|
||||||
|
LEFT JOIN store_sku_bind t1 ON t1.sku_id = t2.id AND t1.store_id = ? AND t1.deleted_at = ?
|
||||||
|
JOIN sku_name t3 ON t2.name_id = t3.id
|
||||||
|
JOIN sku_category t4 ON t3.category_id = t4.id
|
||||||
|
LEFT JOIN sku_category t5sku ON t2.category_id = t5sku.id
|
||||||
|
WHERE t2.deleted_at = ?
|
||||||
|
`
|
||||||
|
sqlParams := []interface{}{
|
||||||
|
storeID,
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
utils.DefaultTimeValue,
|
||||||
|
}
|
||||||
|
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
||||||
|
sql = fmt.Sprintf(sql, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix)
|
||||||
|
// globals.SugarLogger.Debug(sql)
|
||||||
|
// globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false))
|
||||||
|
if err = GetRows(db, &skus, sql, sqlParams...); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return skus, err
|
||||||
|
}
|
||||||
|
|
||||||
func SetStoreSkuSyncStatus(ctx *jxcontext.Context, db *DaoDB, vendorID, storeID int, skuIDs []int, syncStatus int) (num int64, err error) {
|
func SetStoreSkuSyncStatus(ctx *jxcontext.Context, db *DaoDB, vendorID, storeID int, skuIDs []int, syncStatus int) (num int64, err error) {
|
||||||
|
globals.SugarLogger.Debugf("SetStoreSkuSyncStatus, storeID:%d, vendorID:%d", storeID, vendorID)
|
||||||
|
|
||||||
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
|
||||||
sql := fmt.Sprintf(`
|
sql := fmt.Sprintf(`
|
||||||
UPDATE store_sku_bind
|
UPDATE store_sku_bind
|
||||||
|
|||||||
@@ -89,6 +89,9 @@ type IPurchasePlatformHandler interface {
|
|||||||
SyncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error)
|
SyncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error)
|
||||||
RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error)
|
RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error)
|
||||||
|
|
||||||
|
// !!!注意,此操作会先清除门店已有的商品,一般用于初始化,小心使用
|
||||||
|
FullSyncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync, isContinueWhenError bool) (hint string, err error)
|
||||||
|
|
||||||
GetVendorID() int
|
GetVendorID() int
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,13 +117,8 @@ type IMultipleStoresHandler interface {
|
|||||||
type ISingleStoreHandler interface {
|
type ISingleStoreHandler interface {
|
||||||
IPurchasePlatformHandler
|
IPurchasePlatformHandler
|
||||||
SyncStoreCategory(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync bool) (hint string, err error)
|
SyncStoreCategory(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync bool) (hint string, err error)
|
||||||
ReadStoreCategories(storeID int) (cats []*model.SkuCategory, err error)
|
|
||||||
|
|
||||||
ReadStoreSku(storeID, skuID int) (skuNameExt *model.SkuNameExt, err error)
|
|
||||||
RefreshStoresAllSkusID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool, storeIDs []int) (hint string, err error)
|
RefreshStoresAllSkusID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool, storeIDs []int) (hint string, err error)
|
||||||
|
|
||||||
// !!!注意,此操作会先清除门店已有的商品,一般用于初始化,小心使用
|
|
||||||
FullSyncStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync, isContinueWhenError bool) (hint string, err error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type IDeliveryPlatformHandler interface {
|
type IDeliveryPlatformHandler interface {
|
||||||
|
|||||||
@@ -243,14 +243,6 @@ func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasks
|
|||||||
return rootTask.ID, err
|
return rootTask.ID, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PurchaseHandler) ReadStoreCategories(storeID int) (cats []*model.SkuCategory, err error) {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PurchaseHandler) ReadStoreSku(storeID, skuID int) (skuNameExt *model.SkuNameExt, err error) {
|
|
||||||
return skuNameExt, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PurchaseHandler) GetAllRemoteSkus(storeID int) (skus []map[string]interface{}, err error) {
|
func (p *PurchaseHandler) GetAllRemoteSkus(storeID int) (skus []map[string]interface{}, err error) {
|
||||||
page1, err := api.EbaiAPI.SkuList(utils.Int2Str(storeID), utils.Params2Map("pagesize", MaxPageSize))
|
page1, err := api.EbaiAPI.SkuList(utils.Int2Str(storeID), utils.Params2Map("pagesize", MaxPageSize))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|||||||
@@ -3,19 +3,11 @@ 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"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
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) {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
func (p *PurchaseHandler) ReadStoreCategories(storeID int) (cats []*model.SkuCategory, err error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PurchaseHandler) ReadStoreSku(storeID, skuID int) (skuNameExt *model.SkuNameExt, err error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
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, storeID int, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
return hint, err
|
return hint, err
|
||||||
|
|||||||
@@ -132,3 +132,111 @@ func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasks
|
|||||||
}
|
}
|
||||||
return task.ID, err
|
return task.ID, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
db := dao.GetDB()
|
||||||
|
_, err = dao.SetStoreSkuSyncStatus(ctx, db, model.VendorIDJD, storeID, nil, model.SyncFlagModifiedMask|model.SyncFlagPriceMask|model.SyncFlagSaleMask)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
skus, err := dao.GetFullStoreSkus(db, model.VendorIDJD, storeID)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return p.syncStoreSkus(ctx, parentTask, db, storeID, skus, 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.GetUserName(), 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: 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.Status != 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.Debug(utils.Format4Output(skuVendibilityList, false), utils.Format4Output(skuPriceInfoList, false), utils.Format4Output(skuStockList, false))
|
||||||
|
if globals.EnableStoreWrite {
|
||||||
|
// todo 以下可以优化为并行操作
|
||||||
|
if len(skuVendibilityList) > 0 {
|
||||||
|
_, err = api.JdAPI.BatchUpdateVendibility("", stationNo, skuVendibilityList, ctx.GetUserName())
|
||||||
|
}
|
||||||
|
if err == nil && len(skuPriceInfoList) > 0 {
|
||||||
|
_, err = api.JdAPI.UpdateVendorStationPrice("", stationNo, skuPriceInfoList)
|
||||||
|
}
|
||||||
|
if err == nil && len(skuStockList) > 0 {
|
||||||
|
_, err = api.JdAPI.BatchUpdateCurrentQtys("", stationNo, skuStockList, ctx.GetUserName())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
ctx.SetTaskOrAddChild(task, parentTask)
|
||||||
|
task.Run()
|
||||||
|
if !isAsync {
|
||||||
|
_, err = task.GetResult(0)
|
||||||
|
}
|
||||||
|
return task.ID, err
|
||||||
|
}
|
||||||
|
|||||||
@@ -86,10 +86,6 @@ func (p *PurchaseHandler) SyncStoreCategory(ctx *jxcontext.Context, parentTask t
|
|||||||
return hint, err
|
return hint, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PurchaseHandler) ReadStoreCategories(storeID int) (cats []*model.SkuCategory, err error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 此函数根据门店商品信息重建分类信息
|
// 此函数根据门店商品信息重建分类信息
|
||||||
// 远程有,本地无, --> 删除远程
|
// 远程有,本地无, --> 删除远程
|
||||||
// 远程有,本地有,映射无, --> 添加关联
|
// 远程有,本地有,映射无, --> 添加关联
|
||||||
@@ -110,17 +106,10 @@ func (p *PurchaseHandler) SyncLocalStoreCategory(ctx *jxcontext.Context, db *dao
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
for _, cat := range localCats {
|
for _, cat := range localCats {
|
||||||
catID := cat.VendorCatID
|
catMap[i][cat.ParentCatName+"/"+cat.Name] = cat
|
||||||
if catID == "" {
|
|
||||||
catID = cat.Name
|
|
||||||
}
|
|
||||||
parentCatID := cat.ParentVendorCatID
|
|
||||||
if parentCatID == "" {
|
|
||||||
parentCatID = cat.ParentCatName
|
|
||||||
}
|
|
||||||
catMap[i][parentCatID+"/"+catID] = cat
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
identityCatMap := make(map[int]int) // 这里面表示远程有,本地有,且完全相同,可擦掉本地的修改标记
|
||||||
if isCheckRemote {
|
if isCheckRemote {
|
||||||
strStoreID := utils.Int2Str(storeID)
|
strStoreID := utils.Int2Str(storeID)
|
||||||
remoteCats, err := api.MtwmAPI.RetailCatList(utils.Int2Str(storeID))
|
remoteCats, err := api.MtwmAPI.RetailCatList(utils.Int2Str(storeID))
|
||||||
@@ -141,7 +130,7 @@ func (p *PurchaseHandler) SyncLocalStoreCategory(ctx *jxcontext.Context, db *dao
|
|||||||
if localCat.MapID == 0 { // 本地映射没有
|
if localCat.MapID == 0 { // 本地映射没有
|
||||||
localCat.MapID = -1 // 表示远程有同名的
|
localCat.MapID = -1 // 表示远程有同名的
|
||||||
} else { // 本地映射有
|
} else { // 本地映射有
|
||||||
localCat.MapID = -2 // 表示不处理
|
identityCatMap[localCat.MapID] = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -174,13 +163,24 @@ func (p *PurchaseHandler) SyncLocalStoreCategory(ctx *jxcontext.Context, db *dao
|
|||||||
if err = dao.CreateEntity(db, catMap); err != nil {
|
if err = dao.CreateEntity(db, catMap); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
} else if v.MapID != -2 {
|
} else if isCheckRemote {
|
||||||
catMap := &model.StoreSkuCategoryMap{
|
catMap := &model.StoreSkuCategoryMap{
|
||||||
MtwmSyncStatus: model.SyncFlagNewMask,
|
MtwmSyncStatus: model.SyncFlagNewMask,
|
||||||
}
|
}
|
||||||
|
updateFields := []string{
|
||||||
|
model.FieldUpdatedAt,
|
||||||
|
model.FieldLastOperator,
|
||||||
|
model.FieldMtwmSyncStatus,
|
||||||
|
}
|
||||||
|
if identityCatMap[v.MapID] == 1 { // 如果一样,则要刷新ID(对于MTWM其实就是名字)
|
||||||
|
catMap.MtwmID = v.Name
|
||||||
|
catMap.MtwmSyncStatus = 0
|
||||||
|
updateFields = append(updateFields, model.FieldMtwmID)
|
||||||
|
}
|
||||||
catMap.ID = v.MapID
|
catMap.ID = v.MapID
|
||||||
num++
|
num++
|
||||||
if _, err = dao.UpdateEntity(db, catMap, "MtwmSyncStatus"); err != nil {
|
dao.WrapUpdateULEntity(catMap, ctx.GetUserName())
|
||||||
|
if _, err = dao.UpdateEntity(db, catMap, updateFields...); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -201,10 +201,6 @@ func TranverseRemoteCatList(parentCatName string, remoteCats []*mtwmapi.RetailCa
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PurchaseHandler) ReadStoreSku(storeID, skuID int) (skuNameExt *model.SkuNameExt, err error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// hint,如果是异步,返回的是任务ID,如果是同步,返回是本次需要同步的目录数
|
// hint,如果是异步,返回的是任务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, storeID int, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
@@ -224,8 +220,14 @@ func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasks
|
|||||||
if hint != "0" {
|
if hint != "0" {
|
||||||
return "", errors.New("同步门店商品所需目录失败")
|
return "", errors.New("同步门店商品所需目录失败")
|
||||||
}
|
}
|
||||||
|
storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDMTWM)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
skus, err := dao.GetStoreSkus(db, model.VendorIDMTWM, storeID, skuIDs)
|
skus, err := dao.GetStoreSkus(db, model.VendorIDMTWM, storeID, skuIDs)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
// globals.SugarLogger.Debug(utils.Format4Output(skus, false))
|
// globals.SugarLogger.Debug(utils.Format4Output(skus, false))
|
||||||
strStoreID := utils.Int2Str(storeID)
|
strStoreID := utils.Int2Str(storeID)
|
||||||
rootTask := tasksch.NewParallelTask("美团外卖SyncStoreSkus", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx.GetUserName(), func(rootTask *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
rootTask := tasksch.NewParallelTask("美团外卖SyncStoreSkus", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx.GetUserName(), func(rootTask *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
@@ -241,7 +243,7 @@ func (p *PurchaseHandler) SyncStoreSkus(ctx *jxcontext.Context, parentTask tasks
|
|||||||
foodData[mtwmapi.KeyAppFoodCode] = utils.Int2Str(skuItem.ID)
|
foodData[mtwmapi.KeyAppFoodCode] = utils.Int2Str(skuItem.ID)
|
||||||
foodData["name"] = jxutils.ComposeSkuName(skuItem.Prefix, skuItem.Name, skuItem.Comment, skuItem.Unit, skuItem.SpecQuality, skuItem.SpecUnit, 30)
|
foodData["name"] = jxutils.ComposeSkuName(skuItem.Prefix, skuItem.Name, skuItem.Comment, skuItem.Unit, skuItem.SpecQuality, skuItem.SpecUnit, 30)
|
||||||
foodData["description"] = skuItem.Comment
|
foodData["description"] = skuItem.Comment
|
||||||
foodData["price"] = jxutils.IntPrice2Standard(skuItem.Price)
|
foodData["price"] = jxutils.CaculateSkuVendorPrice(int(skuItem.Price), int(storeDetail.PricePercentage))
|
||||||
foodData["min_order_count"] = 1
|
foodData["min_order_count"] = 1
|
||||||
foodData["unit"] = skuItem.Unit
|
foodData["unit"] = skuItem.Unit
|
||||||
foodData["box_num"] = 0
|
foodData["box_num"] = 0
|
||||||
@@ -307,7 +309,7 @@ func (p *PurchaseHandler) FullSyncStoreSkus(ctx *jxcontext.Context, parentTask t
|
|||||||
case 3:
|
case 3:
|
||||||
_, err = p.SyncStoreCategory(ctx, rootTask, storeID, false)
|
_, err = p.SyncStoreCategory(ctx, rootTask, storeID, false)
|
||||||
case 4:
|
case 4:
|
||||||
_, err = p.SyncStoreSkus(ctx, rootTask, storeID, nil, true, isContinueWhenError)
|
// _, err = p.SyncStoreSkus(ctx, rootTask, storeID, nil, true, isContinueWhenError)
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}, 5)
|
}, 5)
|
||||||
|
|||||||
@@ -286,7 +286,7 @@ func (c *SkuController) DeleteSkuNamePlace() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Title 远程查询厂商SKU信息
|
// @Title 远程查询厂商SKU信息
|
||||||
// @Description 远程查询厂商SKU信息,这个是实时调用API远程查询
|
// @Description 远程查询厂商SKU信息,这个是实时调用API远程查询(不推荐使用)
|
||||||
// @Param token header string true "认证token"
|
// @Param token header string true "认证token"
|
||||||
// @Param vendorSkuID query string true "sku ID"
|
// @Param vendorSkuID query string true "sku ID"
|
||||||
// @Param vendorID query int true "门店所属的厂商ID"
|
// @Param vendorID query int true "门店所属的厂商ID"
|
||||||
|
|||||||
Reference in New Issue
Block a user