package cms import ( "errors" "fmt" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/basesch" "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" ) type VendorSync struct { } type SyncError struct { Original error `json:"original"` Message string `json:"message"` } var ( MultiStoresVendorHandlers []partner.IMultipleStoresHandler SingleStoreVendorIDs []int ) var ( ErrHaveNotImplementedYet = errors.New("还没有实现") ErrEntityNotExist = errors.New("找不到相应实体") ) func Init() { for k, v := range basesch.FixedBaseScheduler.PurchasePlatformHandlers { if multiHandler, ok := v.(partner.IMultipleStoresHandler); ok { MultiStoresVendorHandlers = append(MultiStoresVendorHandlers, multiHandler) } else if _, ok := v.(partner.ISingleStoreHandler); ok { SingleStoreVendorIDs = append(SingleStoreVendorIDs, k) } else { panic(fmt.Sprintf("platform:%d type is wrong!", k)) } } } func (v *VendorSync) SyncCategory(db *dao.DaoDB, categoryID int, isForce bool, userName string) (err error) { err = v.LoopMultiStoresVendors(db, func(batchItemList []interface{}, params ...interface{}) (interface{}, error) { multiStoresHandler := batchItemList[0].(partner.IMultipleStoresHandler) var cats []*model.SkuCategory cond := make(map[string]interface{}) if categoryID > 0 { cond[model.FieldID] = categoryID } err := dao.GetEntitiesByKV(db, &cats, cond, true) if err == nil { task := tasksch.RunTask("", false, nil, len(cats), 1, userName, func(batchItemList []interface{}, params ...interface{}) (interface{}, error) { for _, v := range batchItemList { cat := v.(*model.SkuCategory) updateFields := []string{multiStoresHandler.GetFieldSyncStatusName()} if (cat.JdSyncStatus & model.SyncFlagDeletedMask) != 0 { //删除 err = multiStoresHandler.DeleteCategory(db, cat, userName) } else if (cat.JdSyncStatus&model.SyncFlagNewMask) != 0 || isForce { // 新增 err = multiStoresHandler.CreateCategory(db, cat, userName) updateFields = append(updateFields, multiStoresHandler.GetFieldIDName()) } else if (cat.JdSyncStatus & model.SyncFlagModifiedMask) != 0 { // 修改 err = multiStoresHandler.UpdateCategory(db, cat, userName) } if err == nil { cat.JdSyncStatus = 0 _, err = dao.UpdateEntity(db, cat, updateFields...) } else { break } } return nil, err }, cats) _, err = task.GetResult(0) } return nil, err }) return err } func (v *VendorSync) SyncReorderCategories(db *dao.DaoDB, categoryID int, isForce bool, userName string) (err error) { err = v.LoopMultiStoresVendors(db, func(batchItemList []interface{}, params ...interface{}) (interface{}, error) { multiStoresHandler := batchItemList[0].(partner.IMultipleStoresHandler) err2 := multiStoresHandler.ReorderCategories(db, categoryID, userName) if err2 == nil { cat := &model.SkuCategory{} _, err2 = dao.UpdateEntityByKV(db, cat, utils.Params2Map(multiStoresHandler.GetFieldSyncStatusName(), 0), utils.Params2Map(model.FieldParentID, categoryID)) return nil, err2 } return nil, err2 }) return err } func (v *VendorSync) SyncStore(db *dao.DaoDB, vendorID, storeID int, isForce bool, userName string) (err error) { globals.SugarLogger.Debugf("SyncStore, storeID:%d", storeID) err = v.LoopStoreMap(db, storeID, func(batchItemList []interface{}, params ...interface{}) (interface{}, error) { storeMap := batchItemList[0].(*model.StoreMap) if (vendorID == -1 || vendorID == storeMap.VendorID) && (isForce || storeMap.SyncStatus != 0) { if handler := GetPurchaseHandler(storeMap.VendorID); handler != nil { if err = handler.UpdateStore(db, storeID, userName); err == nil { storeMap.SyncStatus = 0 _, err = dao.UpdateEntity(db, storeMap, model.FieldSyncStatus) } } } return nil, err }) return err } func (v *VendorSync) SyncSku(db *dao.DaoDB, nameID, skuID int, isForce bool, userName string) (err error) { globals.SugarLogger.Debugf("SyncSku, nameID:%d, skuID:%d, isForce:%t, userName:%s", nameID, skuID, isForce, userName) err = v.LoopMultiStoresVendors(db, func(batchItemList []interface{}, params ...interface{}) (interface{}, error) { multiStoresHandler := batchItemList[0].(partner.IMultipleStoresHandler) var skuList []*model.Sku cond := make(map[string]interface{}) if nameID != -1 { cond[model.FieldNameID] = nameID } if skuID != -1 { cond[model.FieldID] = skuID } err := dao.GetEntitiesByKV(db, &skuList, cond, true) if err == nil { // globals.SugarLogger.Debug(utils.Format4Output(skuList, false)) task := tasksch.RunTask("SyncSku", false, nil, len(skuList), 1, userName, func(batchItemList []interface{}, params ...interface{}) (interface{}, error) { for _, v := range batchItemList { sku := v.(*model.Sku) if (skuID == -1 || skuID == sku.ID) && (isForce || sku.JdSyncStatus != 0) { updateFields := []string{multiStoresHandler.GetFieldSyncStatusName()} if sku.JdSyncStatus&model.SyncFlagDeletedMask != 0 { // 删除 err = multiStoresHandler.DeleteSku(db, sku, userName) } else if sku.JdSyncStatus&model.SyncFlagNewMask != 0 { // 新增 err = multiStoresHandler.CreateSku(db, sku, userName) updateFields = append(updateFields, multiStoresHandler.GetFieldIDName()) } else if sku.JdSyncStatus&model.SyncFlagModifiedMask != 0 { // 修改 err = multiStoresHandler.UpdateSku(db, sku, userName) } if err == nil { sku.JdSyncStatus = 0 dao.UpdateEntity(db, sku, updateFields...) } else { break } } } return nil, err }, skuList) _, err = task.GetResult(0) } return nil, err }) return err } // func (v *VendorSync) SyncStoreSku(db *dao.DaoDB, storeID int, skuIDs []int, isForce bool, userName string) (err error) { globals.SugarLogger.Debug("SyncStoreSku") err = v.LoopStoreMap(db, storeID, func(batchItemList []interface{}, params ...interface{}) (interface{}, error) { storeMap := batchItemList[0].(*model.StoreMap) if handler := GetPurchaseHandler(storeMap.VendorID); handler != nil { err = handler.SyncStoreSkus(db, []int{storeID}, skuIDs, isForce, userName) } return nil, err }) return err } func (v *VendorSync) LoopStoreMap(db *dao.DaoDB, storeID int, handler tasksch.WorkFunc) (err error) { storeMaps, err := GetStoreVendorMaps(db, storeID, -1) if err == nil { task := tasksch.RunTask("LoopStoreMap", false, nil, len(storeMaps), 1, "", handler, storeMaps) _, err = task.GetResult(0) } return makeSyncError(err) } func (v *VendorSync) LoopMultiStoresVendors(db *dao.DaoDB, handler tasksch.WorkFunc) (err error) { task := tasksch.RunTask("LoopMultiStoresVendors", false, nil, len(MultiStoresVendorHandlers), 1, "", handler, MultiStoresVendorHandlers) _, err = task.GetResult(0) return makeSyncError(err) } func (v *VendorSync) LoopSingleStoreVendors(db *dao.DaoDB, taskName, userName string, handler tasksch.WorkFunc) (err error) { if taskName == "" { taskName = "LoopSingleStoreVendors" } var storeMaps []*model.StoreMap if err = dao.GetRows(db, &storeMaps, ` SELECT * FROM store_map WHERE vendor_id IN (`+dao.GenQuestionMarks(len(SingleStoreVendorIDs))+")", SingleStoreVendorIDs); err == nil { parellelCount := len(storeMaps) if parellelCount > 20 { parellelCount = 20 } task := tasksch.RunManagedTask(taskName, false, nil, parellelCount, 1, userName, handler, storeMaps) _, err = task.GetResult(0) } return makeSyncError(err) } func (v *VendorSync) RefreshSkuIDs(nameID, skuID int, isForce bool, userName string) (err error) { sql := ` SELECT t1.id FROM sku t1 JOIN sku_name t2 ON t1.name_id = t2.id WHERE 1 = 1 ` sqlParams := []interface{}{} if nameID != -1 { sql += " AND t1.name_id = ?" sqlParams = append(sqlParams, nameID) } if skuID != -1 { sql += " AND t1.id = ?" sqlParams = append(sqlParams, skuID) } var ids []int db := dao.GetDB() if err = dao.GetRows(db, &ids, sql, sqlParams); err == nil { // globals.SugarLogger.Debug(utils.Format4Output(ids, false)) err = v.LoopMultiStoresVendors(db, func(batchItemList []interface{}, params ...interface{}) (interface{}, error) { multiStoresHandler := batchItemList[0].(partner.IMultipleStoresHandler) err := multiStoresHandler.SyncSkusIDMap(db, ids, userName) globals.SugarLogger.Debug(err) return nil, err }) } return err } func makeSyncError(err error) (newErr error) { if err != nil { return &SyncError{ Original: err, } } return err } func (e *SyncError) Error() string { return fmt.Sprintf("本地数据修改成功,但同步失败,请根据错误提示处理!,同步错误信息:%s", e.Original.Error()) }