@@ -71,9 +71,9 @@ var (
}
)
func ( p * PurchaseHandler ) SyncStoreSkus ( db * dao . DaoDB , storeIDs [ ] int , skuIDs [ ] int , isForce bool , userName string ) ( err error ) {
func ( p * PurchaseHandler ) SyncStoreSkus ( db * dao . DaoDB , storeIDs [ ] int , skuIDs [ ] int , isSync bool , userName string ) ( err error ) {
for _ , storeID := range storeIDs {
err = p . syncOneStoreSkus ( db , storeID , skuIDs , isForce , userName )
err = p . syncOneStoreSkus ( db , storeID , skuIDs , isSync , userName )
if err != nil {
break
}
@@ -81,13 +81,14 @@ func (p *PurchaseHandler) SyncStoreSkus(db *dao.DaoDB, storeIDs []int, skuIDs []
return err
}
func ( p * PurchaseHandler ) syncOneStoreSkus ( db * dao . DaoDB , storeID int , skuIDs [ ] int , isForce bool , userName string ) ( err error ) {
func ( p * PurchaseHandler ) syncOneStoreSkus ( db * dao . DaoDB , storeID int , skuIDs [ ] int , isSync bool , userName string ) ( err error ) {
globals . SugarLogger . Debugf ( "syncOneStoreSkus storeID:%d, skuIDs:%v, userName:%s" , storeID , skuIDs , userName )
if err = p . syncOneStoreCategoriesFromRemote2Local ( db , storeID , userName ) ; err != nil {
return err
}
sql := `
doThing : = func ( ) ( err error ) {
if err = p . syncOneStoreCategoriesFromRemote2Local ( db , storeID , userName ) ; err != nil {
return err
}
sql := `
SELECT t1.*, t2.spec_quality, t2.spec_unit, t2.weight, t2.status sku_status,
t3.prefix, t3.name, t3.comment, t3.is_global, t3.unit, t3.img,
t4.name cat_name,
@@ -107,82 +108,86 @@ func (p *PurchaseHandler) syncOneStoreSkus(db *dao.DaoDB, storeID int, skuIDs []
WHERE t1.store_id = ? AND (t1.ebai_sync_status <> 0)
`
sqlParams := [ ] interface { } {
model . VendorIDEBAI ,
model . VendorIDEBAI ,
storeID ,
}
if skuIDs != nil && len ( skuIDs ) > 0 {
sql += " AND t1.sku_id IN (" + dao . GenQuestionMarks ( len ( skuIDs ) ) + ")"
sqlParams = append ( sqlParams , skuIDs )
}
strStoreID := utils . Int2Str ( storeID )
var storeSkuInfoList [ ] * tStoreSkuFullInfo
if err = dao . GetRows ( db , & storeSkuInfoList , sql , sqlParams ... ) ; err == nil {
// globals.SugarLogger.Debug(utils.Format4Output(storeSkuInfoList, false))
catList2Add := make ( map [ int ] int )
for _ , storeSku := range storeSkuInfoList {
if storeSku . EbaiSyncStatus & model . SyncFlagNewMask != 0 {
if storeSku . ParentCatEbaiID == 0 {
catList2Add [ storeSku . ParentCatID ] = 1
}
if storeSku . CatEbaiID == 0 {
catList2Add [ storeSku . CatID ] = 1
sqlParams := [ ] interface { } {
model . VendorIDEBAI ,
model . VendorIDEBAI ,
storeID ,
}
if skuIDs != nil && len ( skuIDs ) > 0 {
sql += " AND t1.sku_id IN (" + dao . GenQuestionMarks ( len ( skuIDs ) ) + ")"
sqlParams = append ( sqlParams , skuIDs )
}
strStoreID := utils . Int2Str ( storeID )
var storeSkuInfoList [ ] * tStoreSkuFullInfo
if err = dao . GetRows ( db , & storeSkuInfoList , sql , sqlParams ... ) ; err == nil {
// globals.SugarLogger.Debug(utils.Format4Output(storeSkuInfoList, false))
catList2Add := make ( map [ int ] int )
for _ , storeSku := range storeSkuInfoList {
if storeSku . EbaiSyncStatus & model . SyncFlagNewMask != 0 {
if storeSku . ParentCatEbaiID == 0 {
catList2Add [ storeSku . ParentCatID ] = 1
}
if storeSku . CatEbaiID == 0 {
catList2Add [ storeSku . CatID ] = 1
}
}
}
}
for k := range catList2Add {
if err = dao . AddStoreCategoryMap ( db , storeID , k , model . VendorIDEBAI , "" , model . SyncFlagNewMask , userName ) ; err != nil {
for k := range catList2Add {
if err = dao . AddStoreCategoryMap ( db , storeID , k , model . VendorIDEBAI , "" , model . SyncFlagNewMask , userName ) ; err != nil {
return err
}
}
if err = p . SyncOneStoreCategories ( db , storeID , userName ) ; err != nil {
return err
}
}
if err = p . syncOneStoreCategoriesFromLocal2Remote ( db , storeID , userNam e) ; err != nil {
return err
}
if err = dao . GetRows ( db , & storeSkuInfoList , sql , sqlParams ... ) ; err = = nil {
task : = tasksch . RunTask ( "syncOneStoreSkus skus" , false , nil , 0 , 1 , userName , func ( batchItemList [ ] interface { } , params ... interface { } ) ( retVal interface { } , err error ) {
storeSku := batchItemList [ 0 ] . ( * tStoreSkuFullInfo )
updateFields := [ ] string { model . FieldEbaiSyncStatus }
if storeSku . EbaiSyncStatus & model . SyncFlagDeletedMask ! = 0 {
err = api . EbaiAPI . SkuDelete ( strStoreID , utils . Int64ToStr ( storeSku . EbaiID ) )
} else if storeSku . EbaiSyncStatus & model . SyncFlagNewMask != 0 {
// globals.SugarLogger.Debug(utils.Format4Output(genSkuParamsFromStoreSkuInfo(storeSku), false))
if storeSku . EbaiID , err = api . EbaiAPI . SkuCreate ( strStoreID , storeSku . Sku ID, genSkuParamsFromStoreSkuInfo ( storeSku ) ) ; err == nil {
// todo 创建SKU后马上绑定分类, 会失败, 待解决
updateFields = append ( updateFields , model . FieldEbaiID )
if err = dao . GetRows ( db , & storeSkuInfoList , sql , sqlParams ... ) ; err == nil {
task : = tasksch . RunManagedTask ( "syncOneStoreSkus skus" , false , nil , 0 , 1 , userName , func ( batchItemList [ ] interface { } , params ... interface { } ) ( retVal interfac e{ } , err error ) {
storeSku := batchItemList [ 0 ] . ( * tStoreSkuFullInfo )
updateFields := [ ] string { model . FieldEbaiSyncStatus }
if storeSku . EbaiSyncStatus & model . SyncFlagDeletedMask ! = 0 {
err = api . EbaiAPI . SkuDelete ( strStoreID , utils . Int64ToStr ( storeSku . EbaiID ) )
} else if storeSku . E baiSyncStatus & model . SyncFlagNewMask != 0 {
// globals.SugarLogger.Debug(utils.Format4Output(genSkuParamsFromStoreSkuInfo(storeSku), false))
if storeSku . EbaiID , err = api . EbaiAPI . SkuCreate ( strStoreID , storeSku . SkuID , genSkuParamsFromStoreSkuInfo ( storeSku ) ) ; err = = nil {
// todo 创建SKU后马上绑定分类, 会失败, 待解决
updateFields = append ( updateFields , model . FieldEbaiID )
time . AfterFunc ( 3 * time . Second , func ( ) {
api . EbaiAPI . SkuShopCategoryMap ( strStoreID , storeSku . Ebai ID, utils . Int64ToStr ( storeSku . CatEbaiID ) )
} )
}
} else if storeSku . EbaiSyncStatus & model . SyncFlagModifiedMask != 0 {
if _ , err = api . EbaiAPI . SkuUpdate ( strStoreID , storeSku . EbaiID , genSkuParamsFromStoreSkuInfo ( storeSku ) ) ; err == nil {
err = api . EbaiAPI . SkuShopCategoryMap ( strStoreID , storeSku . EbaiID , utils . Int64ToStr ( storeSku . CatEbaiID ) )
}
}
} else if storeSku . EbaiSyncStatus & model . SyncFlagModifiedMask != 0 {
_ , err = api . EbaiAPI . SkuUpdate ( strStoreID , storeSku . EbaiID , genSkuParamsFromStoreSkuInfo ( storeSku ) )
}
if storeSku . EbaiSyncStatus & ( model . SyncFlagNewMask | model . SyncFlagModifiedMask ) != 0 {
time . AfterFunc ( 3 * time . Second , func ( ) {
api . EbaiAPI . SkuShopCategoryMap ( strStoreID , storeSku . EbaiID , utils . Int64ToStr ( storeSku . CatEbaiID ) )
} )
}
if err == nil {
storeSku . EbaiSyncStatus = 0
_ , err = dao . UpdateEntity ( nil , & storeSku . StoreSkuBind , updateFields ... )
}
return nil , err
} , storeSkuInfoList )
_ , err = task . GetResult ( 0 )
if err == nil {
storeSku . EbaiSyncStatus = 0
_ , err = dao . UpdateEntity ( nil , & storeSku . StoreSkuBind , updateFields ... )
}
return nil , err
} , storeSkuInfoList )
_ , err = task . GetResult ( 0 )
}
}
return err
}
if isSync {
err = doThing ( )
} else {
go doThing ( )
}
return err
}
func ( p * PurchaseHandler ) SyncStoreCategories ( db * dao . DaoDB , storeIDs [ ] int , catIDs [ ] int ) ( err error ) {
// sql := `
// SELECT t1.*, t2.spec_quality, t2.spec_unit, t2.weight,
// t3.prefix, t3.name, t3.comment, t3.is_global, t3.unit, t3.img,
// t4.ebai_category_id, t4.name cat_name, t5.ebai_id cat_id, t5.ebai_category_id
// FROM store_sku_bind t1
// JOIN sku t2 ON t1.sku_id = t2.skuIDs
// JOIN sku_name t3 ON t2.name_id = t3.id
// JOIN sku_category t4 ON t3.category_id = t4.id
// LEFT JOIN store_sku_category_map t5 ON t5.store_id = t1.store_id AND t5.category_id = t4.id
// WHERE t1.store_id = ? AND (t1.ebai_sync_status <> 0
// `
func ( p * PurchaseHandler ) SyncStoreCategories ( db * dao . DaoDB , storeIDs [ ] int , userName str ing ) ( err error ) {
globals . SugarLogger . Debugf ( "SyncStoreCategories storeIDs:%d, userName:%s" , storeIDs , userName )
for _ , storeID := range storeIDs {
if err = p . SyncOneStoreCategories ( db , storeID , userName ) ; err != nil {
break
}
}
return err
}
@@ -301,6 +306,10 @@ func getEbaiCat(catID int64, level int) int64 {
}
// 从饿百同步分类信息到本地
// 些函数执行后:
// 远程有与本地有的条目会关联(并置标记,下次同步会刷新远程)
// 远程没有本地有的条目会标记新增
// 远程有本地没有的条目不做处理
func ( p * PurchaseHandler ) syncOneStoreCategoriesFromRemote2Local ( db * dao . DaoDB , storeID int , userName string ) ( err error ) {
globals . SugarLogger . Debugf ( "syncOneStoreCategoriesFromRemote2Local storeID:%d, userName:%s" , storeID , userName )
@@ -316,6 +325,7 @@ func (p *PurchaseHandler) syncOneStoreCategoriesFromRemote2Local(db *dao.DaoDB,
cat1Map := map [ string ] * tStoreCatInfo { }
for _ , v := range catList {
v . Name = utils . FilterMb4 ( v . Name )
globals . SugarLogger . Debug ( v . Name )
if v . Level == 1 {
cat1 := cat1Map [ v . Name ]
if cat1 == nil {
@@ -330,27 +340,19 @@ func (p *PurchaseHandler) syncOneStoreCategoriesFromRemote2Local(db *dao.DaoDB,
}
cat1 . Children [ v . Name ] = v
}
v . EbaiSyncStatus |= model . SyncFlagNewMask
}
if result , err := api . EbaiAPI . ShopCategoryGet ( utils . Int2Str ( storeID ) ) ; err == nil {
for _ , v := range result {
jxCat := cat1Map [ v . Name ]
if jxCat == nil { // 远程有,本地没有,非法类别
} else {
if jxCat . EbaiID ! = v . CategoryID || utils . Int2Str ( jxCat . CatID ) ! = v . ShopCustomID {
if jxCat . ID == 0 { // 远程有,本门店没有
globals . SugarLogger . Debug ( jxCat . CatID )
err = dao . AddStoreCategoryMap ( db , storeID , jxCat . CatID , model . VendorIDEBAI , utils . Int64ToStr ( v . CategoryID ) , model . SyncFlagModifiedMask , userName )
} else { // 远程有, 本门店有, 但ID信息不一致
err = dao . AddStoreCategoryMap ( db , storeID , jxCat . CatID , model . VendorIDEBAI , utils . Int64ToStr ( v . CategoryID ) , model . SyncFlagModifiedMask , userName )
}
} else { // 两边都有,且信息一致
}
}
if err != nil {
return err
}
dao . Begin ( db )
defer func ( ) {
dao . Rollback ( db )
} ( )
// globals.SugarLogger.Debug(utils.Format4Output(cat1Map, false))
if err = p . processLocalCatByRemote ( db , storeID , cat1Map , result , userName ) ; err = = nil {
err = p . updateLocalCatAsNew ( db , cat1Map , userName )
}
if err == nil {
dao . Commit ( db )
}
}
}
@@ -359,8 +361,8 @@ func (p *PurchaseHandler) syncOneStoreCategoriesFromRemote2Local(db *dao.DaoDB,
// 从本地同步分类信息到饿百
// 测试过程中出现过,父分类创建成功后马上创建子分类会报没有父分类错
func ( p * PurchaseHandler ) s yncOneStoreCategoriesFromLocal2Remote ( db * dao . DaoDB , storeID int , userName string ) ( err error ) {
globals . SugarLogger . Debugf ( "s yncOneStoreCategoriesFromLocal2Remote storeID:%d, userName:%s" , storeID , userName )
func ( p * PurchaseHandler ) S yncOneStoreCategories( db * dao . DaoDB , storeID int , userName string ) ( err error ) {
globals . SugarLogger . Debugf ( "S yncOneStoreCategories storeID:%d, userName:%s" , storeID , userName )
for level := 1 ; level <= 2 ; level ++ {
sql := `
@@ -387,13 +389,13 @@ func (p *PurchaseHandler) syncOneStoreCategoriesFromLocal2Remote(db *dao.DaoDB,
if catInfo . EbaiSyncStatus & model . SyncFlagDeletedMask != 0 { // 删除
err = api . EbaiAPI . ShopCategoryDelete ( strStoreID , catInfo . EbaiID )
} else if catInfo . EbaiSyncStatus & model . SyncFlagNewMask != 0 { // 新增
ebaiID , err2 := api . EbaiAPI . ShopCategoryCreate ( strStoreID , catInfo . ParentEbaiID , utils . FilterMb4 ( catInfo . Name ) , int ( catInfo . Seq + 1 ) , utils . Int2Str ( catInfo . ID ) )
ebaiID , err2 := api . EbaiAPI . ShopCategoryCreate ( strStoreID , catInfo . ParentEbaiID , utils . FilterMb4 ( catInfo . Name ) , int ( catInfo . Seq + 1 ) , utils . Int2Str ( catInfo . Category ID) )
if err = err2 ; err == nil {
catInfo . EbaiID = ebaiID
updateFields = append ( updateFields , model . FieldEbaiID )
}
} else if catInfo . EbaiSyncStatus & model . SyncFlagModifiedMask != 0 { // 修改
err = api . EbaiAPI . ShopCategoryUpdate ( strStoreID , catInfo . EbaiID , utils . FilterMb4 ( catInfo . Name ) , int ( catInfo . Seq + 1 ) , utils . Int2Str ( catInfo . ID ) )
err = api . EbaiAPI . ShopCategoryUpdate ( strStoreID , catInfo . EbaiID , utils . FilterMb4 ( catInfo . Name ) , int ( catInfo . Seq + 1 ) , utils . Int2Str ( catInfo . Category ID) )
}
if err == nil {
catInfo . EbaiSyncStatus = 0
@@ -406,3 +408,54 @@ func (p *PurchaseHandler) syncOneStoreCategoriesFromLocal2Remote(db *dao.DaoDB,
}
return err
}
func ( p * PurchaseHandler ) processLocalCatByRemote ( db * dao . DaoDB , storeID int , localCatMap map [ string ] * tStoreCatInfo , remoteCatList [ ] * ebaiapi . CategoryInfo , userName string ) ( err error ) {
if localCatMap == nil || remoteCatList == nil {
return nil
}
for _ , v := range remoteCatList {
jxCat := localCatMap [ v . Name ]
if jxCat == nil { // 远程有,本地没有,非法类别
globals . SugarLogger . Debug ( v . Name )
globals . SugarLogger . Debug ( utils . Format4Output ( localCatMap , false ) )
} else {
if jxCat . EbaiID != v . CategoryID || utils . Int2Str ( jxCat . CatID ) != v . ShopCustomID {
if jxCat . ID == 0 { // 远程有,本门店没有
globals . SugarLogger . Debug ( jxCat . CatID )
err = dao . AddStoreCategoryMap ( db , storeID , jxCat . CatID , model . VendorIDEBAI , utils . Int64ToStr ( v . CategoryID ) , model . SyncFlagModifiedMask , userName )
} else { // 远程有, 本门店有, 但ID信息不一致
_ , err = dao . UpdateEntityLogicallyAndUpdateSyncStatus ( db , & jxCat . StoreSkuCategoryMap , map [ string ] interface { } {
model . FieldEbaiID : v . CategoryID ,
} , userName , nil , model . FieldEbaiSyncStatus )
}
} else { // 两边都有,且信息一致
}
jxCat . EbaiSyncStatus = 0
if err = p . processLocalCatByRemote ( db , storeID , jxCat . Children , v . Children , userName ) ; err != nil {
return err
}
}
if err != nil {
return err
}
}
return nil
}
func ( p * PurchaseHandler ) updateLocalCatAsNew ( db * dao . DaoDB , localCatMap map [ string ] * tStoreCatInfo , userName string ) ( err error ) {
if localCatMap == nil {
return nil
}
for _ , v := range localCatMap {
if v . EbaiSyncStatus & model . SyncFlagNewMask != 0 {
dao . WrapUpdateULEntity ( & v . StoreSkuCategoryMap , userName )
if _ , err = dao . UpdateEntity ( db , & v . StoreSkuCategoryMap ) ; err != nil {
return err
}
}
if err = p . updateLocalCatAsNew ( db , v . Children , userName ) ; err != nil {
return err
}
}
return nil
}