Merge branch 'mark' of e.coding.net:rosydev/jx-callback into mark

This commit is contained in:
gazebo
2020-01-09 18:01:07 +08:00
14 changed files with 671 additions and 213 deletions

View File

@@ -1090,21 +1090,23 @@ func refreshStoreSkuPrice(ctx *jxcontext.Context, db *dao.DaoDB, skuID int) (err
} }
} }
}() }()
for vendorID := range partner.PurchasePlatformHandlers { list, err := dao.GetStoreSkusAndSkuName(db, nil, []int{skuID}, nil)
storeSkuList, err := dao.GetStoreSkus2(db, vendorID, 0, []int{skuID}, false) for _, v := range list {
if err == nil { storeID := v.StoreID
for _, v := range storeSkuList { storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJX)
v.Price = int64(jxutils.CaculateSkuPrice(int(v.UnitPrice), v.SpecQuality, v.SpecUnit, v.Unit)) if err != nil {
storeSku := &model.StoreSkuBind{} return err
storeSku.ID = v.BindID
if _, err = dao.UpdateEntityLogically(db, storeSku, map[string]interface{}{
"Price": v.Price,
dao.GetSyncStatusStructField(model.VendorNames[vendorID]): v.SkuSyncStatus | model.SyncFlagPriceMask,
}, ctx.GetUserName(), nil); err != nil {
return err
}
}
} }
storeSku := &model.StoreSkuBind{}
storeSku.ID = v.BindID
storeSku.JdSyncStatus = v.JdSyncStatus | model.SyncFlagPriceMask
storeSku.MtwmSyncStatus = v.MtwmSyncStatus | model.SyncFlagPriceMask
storeSku.EbaiSyncStatus = v.EbaiSyncStatus | model.SyncFlagPriceMask
storeSku.Price = jxutils.CaculateSkuPrice(int(v.UnitPrice), v.SpecQuality, v.SpecUnit, v.Unit)
storeSku.JxPrice = jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), int(storeSku.Price))
storeSku.LastOperator = ctx.GetUserName()
storeSku.UpdatedAt = time.Now()
dao.UpdateEntity(db, storeSku, "Price", "JdSyncStatus", "MtwmSyncStatus", "EbaiSyncStatus", "JxPrice")
} }
dao.Commit(db) dao.Commit(db)
return err return err

View File

@@ -13,6 +13,8 @@ import (
"time" "time"
"unicode" "unicode"
"git.rosy.net.cn/jx-callback/business/jxstore/event"
"git.rosy.net.cn/baseapi" "git.rosy.net.cn/baseapi"
"git.rosy.net.cn/jx-callback/business/jxutils/excel" "git.rosy.net.cn/jx-callback/business/jxutils/excel"
@@ -1035,6 +1037,7 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs
if tmpStatus := getSkuSaleStatus(inSkuBind, skuBindInfo); tmpStatus != model.StoreSkuBindStatusNA { if tmpStatus := getSkuSaleStatus(inSkuBind, skuBindInfo); tmpStatus != model.StoreSkuBindStatusNA {
skuBind.Status = tmpStatus skuBind.Status = tmpStatus
} }
// err = AddEventDetail(model.OperateAdd, v.RealSkuID, model.ThingTypeSku, storeID, ctx.GetTrackInfo(), "", "")
setStoreSkuBindStatus(skuBind, model.SyncFlagNewMask) setStoreSkuBindStatus(skuBind, model.SyncFlagNewMask)
dao.WrapAddIDCULDEntity(skuBind, userName) dao.WrapAddIDCULDEntity(skuBind, userName)
// globals.SugarLogger.Debug(utils.Format4Output(skuBind, false)) // globals.SugarLogger.Debug(utils.Format4Output(skuBind, false))
@@ -1059,8 +1062,8 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs
} }
} else { } else {
skuBind = &v.StoreSkuBind skuBind = &v.StoreSkuBind
if skuBindInfo.IsFocus == -1 && isCanChangePrice { if skuBindInfo.IsFocus == -1 && isCanChangePrice {
// err = AddEventDetail(model.OperateDelete, skuBind.SkuID, model.ThingTypeSku, storeID, ctx.GetTrackInfo(), "", "")
if num, err = dao.DeleteEntityLogically(db, skuBind, map[string]interface{}{ if num, err = dao.DeleteEntityLogically(db, skuBind, map[string]interface{}{
model.FieldStatus: model.StoreSkuBindStatusDeleted, model.FieldStatus: model.StoreSkuBindStatusDeleted,
model.FieldJdSyncStatus: model.SyncFlagDeletedMask, model.FieldJdSyncStatus: model.SyncFlagDeletedMask,
@@ -1072,7 +1075,7 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs
} }
} else { } else {
// 用了SELECT FOR UPDATE后只更新修改字段是没有必要的暂时保留 // 用了SELECT FOR UPDATE后只更新修改字段是没有必要的暂时保留
updateFieldMap := make(map[string]int) updateFieldMap := make(map[string]interface{})
if skuBindInfo.IsFocus == 1 { // 关注之后再关注不操作 if skuBindInfo.IsFocus == 1 { // 关注之后再关注不操作
// skuBind.Status = model.StoreSkuBindStatusDontSale // 缺省不可售? // skuBind.Status = model.StoreSkuBindStatusDontSale // 缺省不可售?
// skuBind.DeletedAt = utils.DefaultTimeValue // skuBind.DeletedAt = utils.DefaultTimeValue
@@ -1114,7 +1117,12 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs
skuBind.StatusSaleEnd = skuBindInfo.StatusSaleEnd skuBind.StatusSaleEnd = skuBindInfo.StatusSaleEnd
} }
} }
// if updateFieldMap != nil {
// afterData := utils.MustMarshal(updateFieldMap)
// mapresult := refutil.FindMapAndStructMixed(updateFieldMap, skuBind)
// beforeData := utils.MustMarshal(mapresult)
// AddEventDetail(model.OperateUpdate, v.RealSkuID, model.ThingTypeSku, storeID, ctx.GetTrackInfo(), string(beforeData), string(afterData))
// }
if len(updateFieldMap) > 0 { if len(updateFieldMap) > 0 {
updateFieldMap[model.FieldJdSyncStatus] = 1 updateFieldMap[model.FieldJdSyncStatus] = 1
updateFieldMap[model.FieldEbaiSyncStatus] = 1 updateFieldMap[model.FieldEbaiSyncStatus] = 1
@@ -1166,6 +1174,20 @@ func getSkuSaleStatus(inSkuBind *StoreSkuBindSkuInfo, skuNameBindInfo *StoreSkuB
return model.StoreSkuBindStatusNA return model.StoreSkuBindStatusNA
} }
func AddEventDetail(operateType, thingID, thingType, storeID int, accessUUID, beforeData, afterData string) (err error) {
operateEventDetail := &model.OperateEventDetail{
OperateType: operateType,
ThingID: thingID,
ThingType: thingType,
StoreID: storeID,
AccessUUID: accessUUID,
BeforeData: beforeData,
AfterData: afterData,
}
err = event.AddOperateEventDetail(operateEventDetail)
return err
}
func formatAutoSaleTime(autoSaleTime time.Time) (outAutoSaleTime time.Time) { func formatAutoSaleTime(autoSaleTime time.Time) (outAutoSaleTime time.Time) {
if utils.IsTimeZero(autoSaleTime) { if utils.IsTimeZero(autoSaleTime) {
outAutoSaleTime = utils.DefaultTimeValue outAutoSaleTime = utils.DefaultTimeValue
@@ -2924,7 +2946,6 @@ func GetCellForFocusStoreSkus(db *dao.DaoDB, rowNum int, row []string, sheetPara
func FocusStoreSkusBySku(ctx *jxcontext.Context, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { func FocusStoreSkusBySku(ctx *jxcontext.Context, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
var ( var (
skuNameMap = make(map[int][]*StoreSkuBindSkuInfo) skuNameMap = make(map[int][]*StoreSkuBindSkuInfo)
storeIDs []int
result1 []interface{} result1 []interface{}
) )
db := dao.GetDB() db := dao.GetDB()
@@ -2933,9 +2954,6 @@ func FocusStoreSkusBySku(ctx *jxcontext.Context, skuIDs []int, isAsync, isContin
taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
switch step { switch step {
case 0: case 0:
for _, v := range storeList {
storeIDs = append(storeIDs, v.ID)
}
for _, v := range skuList { for _, v := range skuList {
skuNameMap[v.NameID] = append(skuNameMap[v.NameID], &StoreSkuBindSkuInfo{ skuNameMap[v.NameID] = append(skuNameMap[v.NameID], &StoreSkuBindSkuInfo{
SkuID: v.ID, SkuID: v.ID,
@@ -2997,67 +3015,94 @@ func FocusStoreSkusBySku(ctx *jxcontext.Context, skuIDs []int, isAsync, isContin
return hint, err return hint, err
} }
func AutoFocusStoreSkusWithoutFocusForTopSkus(ctx *jxcontext.Context) (err error) { func AutoFocusStoreSkusWithoutFocusForTopSkus(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) {
db := dao.GetDB() db := dao.GetDB()
var skuBindInfoList []*StoreSkuBindInfo var (
skuBindInfoList []*StoreSkuBindInfo
result1 []interface{}
)
storeList, err := dao.GetStoreList(db, nil, nil, "") storeList, err := dao.GetStoreList(db, nil, nil, "")
for _, v := range storeList { taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
var ( switch step {
skuName []*model.SkuName case 0:
skuNameMap = make(map[int]int) taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
) v := batchItemList[0].(*model.Store)
sql := ` var (
SELECT DISTINCT a.name_id id skuName []*model.SkuName
FROM sku a skuNameMap = make(map[int]int)
LEFT JOIN (SELECT DISTINCT b.name_id )
FROM store_sku_bind a sql := `
JOIN sku b ON a.sku_id = b.id SELECT DISTINCT a.name_id id
WHERE a.deleted_at = ? FROM sku a
AND store_id = ?)b ON a.name_id = b.name_id LEFT JOIN (SELECT DISTINCT b.name_id
WHERE a.status = ? FROM store_sku_bind a
AND a.deleted_at = ? JOIN sku b ON a.sku_id = b.id
AND b.name_id IS NULL WHERE a.deleted_at = ?
` AND store_id = ?)b ON a.name_id = b.name_id
sqlParams := []interface{}{ WHERE a.status = ?
utils.DefaultTimeValue, AND a.deleted_at = ?
v.ID, AND b.name_id IS NULL
model.SkuStatusNormal, `
utils.DefaultTimeValue, sqlParams := []interface{}{
} utils.DefaultTimeValue,
err = dao.GetRows(db, &skuName, sql, sqlParams...) v.ID,
for _, v := range skuName { model.SkuStatusNormal,
skuNameMap[v.ID] = v.ID utils.DefaultTimeValue,
} }
skuNameAndPlaceList, err2 := GetTopSkusByCityCode(ctx, v.CityCode, v.ID) err = dao.GetRows(db, &skuName, sql, sqlParams...)
if err2 != nil { for _, v := range skuName {
return err2 skuNameMap[v.ID] = v.ID
} }
var payPercentage int skuNameAndPlaceList, err2 := GetTopSkusByCityCode(ctx, v.CityCode, v.ID)
if v.PayPercentage < 50 { if err2 != nil {
payPercentage = 70 return retVal, err2
} else { }
payPercentage = v.PayPercentage var payPercentage int
} if v.PayPercentage < 50 {
if len(skuNameAndPlaceList) > 0 { payPercentage = 70
for _, vv := range skuNameAndPlaceList { } else {
if skuNameMap[vv.ID] != 0 { payPercentage = v.PayPercentage
priceReferList, err := dao.GetPriceReferSnapshotNoPage(db, []int{vv.CityCode}, nil, []int{vv.ID}, utils.Time2Date(time.Now().AddDate(0, 0, -1))) }
if err == nil && len(priceReferList) > 0 { if len(skuNameAndPlaceList) > 0 {
storeSkuBindInfo := &StoreSkuBindInfo{ for _, vv := range skuNameAndPlaceList {
StoreID: v.ID, if skuNameMap[vv.ID] != 0 {
NameID: vv.ID, priceReferList, err := dao.GetPriceReferSnapshotNoPage(db, []int{vv.CityCode}, nil, []int{vv.ID}, utils.Time2Date(time.Now().AddDate(0, 0, -1)))
UnitPrice: priceReferList[0].MidUnitPrice * payPercentage / 100, if err == nil && len(priceReferList) > 0 {
IsFocus: 1, storeSkuBindInfo := &StoreSkuBindInfo{
IsSale: 0, StoreID: v.ID,
NameID: vv.ID,
UnitPrice: priceReferList[0].MidUnitPrice * payPercentage / 100,
IsFocus: 1,
IsSale: 0,
}
skuBindInfoList = append(skuBindInfoList, storeSkuBindInfo)
}
} }
skuBindInfoList = append(skuBindInfoList, storeSkuBindInfo)
} }
} }
return retVal, err
} }
taskParallel := tasksch.NewParallelTask("自动关注畅销品", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, taskFunc, storeList)
tasksch.HandleTask(taskParallel, task, true).Run()
result1, _ = taskParallel.GetResult(0)
case 2:
var skuBindInfos []*StoreSkuBindInfo
for _, v := range result1 {
skuBindInfos = append(skuBindInfos, v.(*StoreSkuBindInfo))
}
UpdateStoresSkusByBind(ctx, skuBindInfos, isAsync, isContinueWhenError)
} }
return result, err
} }
UpdateStoresSkusByBind(ctx, skuBindInfoList, true, true) taskSeq := tasksch.NewSeqTask2("自动关注畅销品", ctx, isContinueWhenError, taskSeqFunc, 3)
return err tasksch.HandleTask(taskSeq, nil, true).Run()
if !isAsync {
_, err = taskSeq.GetResult(0)
hint = "1"
} else {
hint = taskSeq.GetID()
}
return hint, err
} }
func AutoFocusStoreSkusWithoutFocus(ctx *jxcontext.Context, skuIDs []int, isSync bool) (err error) { func AutoFocusStoreSkusWithoutFocus(ctx *jxcontext.Context, skuIDs []int, isSync bool) (err error) {
@@ -3075,8 +3120,8 @@ func AutoFocusStoreSkusWithoutFocus(ctx *jxcontext.Context, skuIDs []int, isSync
}) })
} else { } else {
skuBindInfo := &StoreSkuBindInfo{ skuBindInfo := &StoreSkuBindInfo{
UnitPrice: vv.UnitPrice, UnitPrice: int(vv.UnitPrice),
NameID: vv.ID, NameID: vv.NameID,
StoreID: v.ID, StoreID: v.ID,
Skus: []*StoreSkuBindSkuInfo{}, Skus: []*StoreSkuBindSkuInfo{},
} }

View File

@@ -548,6 +548,7 @@ func CheckSkuDiffBetweenJxAndVendor(ctx *jxcontext.Context, vendorIDList []int,
} else { } else {
filterStoreList := GetFilterStoreList(jxStoreInfoList.Stores, vendorMap, storeIDMap) filterStoreList := GetFilterStoreList(jxStoreInfoList.Stores, vendorMap, storeIDMap)
diffData.InitData() diffData.InitData()
//循环门店store
taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
jxStoreInfoListValue := batchItemList[0].(*StoreExt) jxStoreInfoListValue := batchItemList[0].(*StoreExt)
storeID := jxStoreInfoListValue.ID storeID := jxStoreInfoListValue.ID
@@ -556,22 +557,23 @@ func CheckSkuDiffBetweenJxAndVendor(ctx *jxcontext.Context, vendorIDList []int,
jxSkuInfoDataSingle := &dao.StoreSkuNamesInfo{} jxSkuInfoDataSingle := &dao.StoreSkuNamesInfo{}
jxSkuInfoDataMulti := &dao.StoreSkuNamesInfo{} jxSkuInfoDataMulti := &dao.StoreSkuNamesInfo{}
if jxStoreInfoListValue.StoreMaps != nil { if jxStoreInfoListValue.StoreMaps != nil {
var multiFlag = false
var singleFlag = false
var filterJxSkuInfoMapSingle map[int]*dao.StoreSkuNameExt var filterJxSkuInfoMapSingle map[int]*dao.StoreSkuNameExt
var filterJxSkuInfoMapMulti map[int]*dao.StoreSkuNameExt var filterJxSkuInfoMapMulti map[int]*dao.StoreSkuNameExt
for _, vendorListValue := range jxStoreInfoListValue.StoreMaps { for _, vendorListValue := range jxStoreInfoListValue.StoreMaps {
vendorID := vendorListValue.VendorID vendorID := vendorListValue.VendorID
var flag = false
if partner.IsMultiStore(vendorID) { if partner.IsMultiStore(vendorID) {
if flag == false { if multiFlag == false {
jxSkuInfoDataMulti, _ = GetStoreSkus(ctx, storeID, filterJxDepotUnSaleSkuIds, true, "", true, false, map[string]interface{}{}, 0, -1) jxSkuInfoDataMulti, _ = GetStoreSkus(ctx, storeID, filterJxDepotUnSaleSkuIds, true, "", true, false, map[string]interface{}{}, 0, -1)
filterJxSkuInfoMapMulti = GetFilterJxSkuInfoMap(jxSkuInfoDataMulti.SkuNames) //map[京西商品ID:StoreSkuNameExt] filterJxSkuInfoMapMulti = GetFilterJxSkuInfoMap(jxSkuInfoDataMulti.SkuNames) //map[京西商品ID:StoreSkuNameExt]
flag = true multiFlag = true
} }
} else { } else {
if flag == false { if singleFlag == false {
jxSkuInfoDataSingle, _ = GetStoreSkus(ctx, storeID, []int{}, true, "", true, false, map[string]interface{}{}, 0, -1) jxSkuInfoDataSingle, _ = GetStoreSkus(ctx, storeID, []int{}, true, "", true, false, map[string]interface{}{}, 0, -1)
filterJxSkuInfoMapSingle = GetFilterJxSkuInfoMap(jxSkuInfoDataSingle.SkuNames) //map[京西商品ID:StoreSkuNameExt] filterJxSkuInfoMapSingle = GetFilterJxSkuInfoMap(jxSkuInfoDataSingle.SkuNames) //map[京西商品ID:StoreSkuNameExt]
flag = true singleFlag = true
} }
} }

View File

@@ -3,9 +3,15 @@ package cms
import ( import (
"errors" "errors"
"fmt" "fmt"
"sync"
"time"
"git.rosy.net.cn/baseapi"
"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
"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/ddmsg"
"git.rosy.net.cn/jx-callback/business/jxutils/excel"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/jxutils/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/model"
@@ -14,6 +20,23 @@ import (
"git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals"
) )
type SyncErrResult struct {
SkuID int `json:"商品ID"`
CategoryName string `json:"分类名"`
StoreID int `json:"门店ID"`
VendorID int `json:"平台ID"`
VendorSkuID string `json:"平台商品ID"`
NameID int `json:"商品nameID"`
VendorPrice int64 `json:"平台价"`
SyncType string `json:"同步类型"`
ErrMsg string `json:"错误信息"`
}
type SyncErrResultLock struct {
syncErrResult []SyncErrResult
locker sync.RWMutex
}
type LoopStoreMapInfo struct { type LoopStoreMapInfo struct {
VendorID int VendorID int
StoreMapList []*model.StoreMap StoreMapList []*model.StoreMap
@@ -44,6 +67,18 @@ var (
var ( var (
ErrHaveNotImplementedYet = errors.New("还没有实现") ErrHaveNotImplementedYet = errors.New("还没有实现")
ErrEntityNotExist = errors.New("找不到相应实体") ErrEntityNotExist = errors.New("找不到相应实体")
SyncErrResultTitle = []string{
"商品ID",
"分类名",
"门店ID",
"平台ID",
"平台商品ID",
"商品nameID",
"平台价",
"同步类型",
"错误信息",
}
syncErrResultLock SyncErrResultLock
) )
// 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) {
@@ -592,9 +627,28 @@ func (v *VendorSync) LoopStoresMap2(ctx *jxcontext.Context, db *dao.DaoDB, taskN
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)
if isAsync {
task.SetFinishHook(func(task tasksch.ITask) {
var noticeMsg string
if len(task.GetFailedList()) > 10 {
downloadURL, _, _ := WirteToExcelBySyncFailed(task)
noticeMsg = fmt.Sprintf("[详情点我]path1=%s\n", downloadURL)
} else {
if err != nil {
noticeMsg = utils.Format4Output(buildErrMsgJson(task), true)
}
}
if authInfo, err := ctx.GetV2AuthInfo(); err == nil {
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, authInfo.UserID, "同步错误返回", noticeMsg)
}
})
}
tasksch.HandleTask(task, nil, isManageIt).Run() tasksch.HandleTask(task, nil, isManageIt).Run()
if !isAsync { if !isAsync {
resultList, err2 := task.GetResult(0) resultList, err2 := task.GetResult(0)
if err2 != nil {
err2 = buildErrMsg(task)
}
if err = err2; err == nil { if err = err2; err == nil {
if len(resultList) == 0 { if len(resultList) == 0 {
hint = "1" // todo 暂时这样 hint = "1" // todo 暂时这样
@@ -608,6 +662,38 @@ func (v *VendorSync) LoopStoresMap2(ctx *jxcontext.Context, db *dao.DaoDB, taskN
return task, hint, err return task, hint, err
} }
func buildErrMsg(task tasksch.ITask) (err error) {
err = fmt.Errorf(utils.Format4Output(buildErrMsgJson(task), true))
return makeSyncError(err)
}
func buildErrMsgJson(task tasksch.ITask) (resultL []*SyncErrResult) {
failedList := task.GetFailedList()
for _, v := range failedList {
for _, vv := range v.([]*partner.StoreSkuInfoWithErr) {
result := &SyncErrResult{
SkuID: 0,
StoreID: vv.StoreID,
CategoryName: vv.CategoryName,
VendorID: vv.VendoreID,
VendorSkuID: "",
NameID: 0,
VendorPrice: 0,
SyncType: vv.SyncType,
ErrMsg: vv.ErrMsg,
}
if vv.StoreSkuInfo != nil {
result.SkuID = vv.StoreSkuInfo.SkuID
result.VendorSkuID = vv.StoreSkuInfo.VendorSkuID
result.NameID = vv.StoreSkuInfo.NameID
result.VendorPrice = vv.StoreSkuInfo.VendorPrice
}
resultL = append(resultL, result)
}
}
return resultL
}
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) { 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, false, handler, isContinueWhenError) _, hint, err = v.LoopStoresMap2(ctx, db, taskName, isAsync, isManageIt, vendorIDs, storeIDs, false, handler, isContinueWhenError)
return hint, err return hint, err
@@ -739,3 +825,36 @@ func GetTimeMixByInt(begin1, end1, begin2, end2 int16) (beginAt, endAt int16) {
} }
return beginAt, endAt return beginAt, endAt
} }
func WirteToExcelBySyncFailed(task tasksch.ITask) (downloadURL, fileName string, err error) {
var (
sheetList1 []*excel.Obj2ExcelSheetConfig
)
syncErrResultLock.syncErrResult = syncErrResultLock.syncErrResult[0:0]
list := buildErrMsgJson(task)
for _, v := range list {
syncErrResultLock.AppendData(*v)
}
excelConf1 := &excel.Obj2ExcelSheetConfig{
Title: "同步错误",
Data: syncErrResultLock.syncErrResult,
CaptionList: SyncErrResultTitle,
}
sheetList1 = append(sheetList1, excelConf1)
if excelConf1 != nil {
downloadURL, fileName, err = jxutils.UploadExeclAndPushMsg(sheetList1, time.Now().Format("200601021504")+"同步错误返回")
baseapi.SugarLogger.Debug("WriteToExcel: download is [%v]", downloadURL)
} else {
baseapi.SugarLogger.Debug("WriteToExcel: dataSuccess is nil!")
}
if err != nil {
baseapi.SugarLogger.Errorf("WriteToExcel:upload %s , %s failed error:%v", fileName, err)
}
return downloadURL, fileName, err
}
func (d *SyncErrResultLock) AppendData(syncErrResult SyncErrResult) {
d.locker.Lock()
defer d.locker.Unlock()
d.syncErrResult = append(d.syncErrResult, syncErrResult)
}

View File

@@ -69,7 +69,7 @@ func SyncStoreCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendo
rootTask := tasksch.NewSeqTask(fmt.Sprintf("%s SyncStoreCategory step1", model.VendorChineseNames[vendorID]), ctx, rootTask := tasksch.NewSeqTask(fmt.Sprintf("%s SyncStoreCategory step1", model.VendorChineseNames[vendorID]), ctx,
func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
level := step + 1 level := step + 1
catList, err := dao.GetDirtyStoreCategories(db, vendorID, storeID, level) catList, err := dao.GetDirtyStoreCategories(db, vendorID, storeID, level, skuIDs)
if len(catList) > 0 { if len(catList) > 0 {
num += len(catList) num += len(catList)
task := tasksch.NewParallelTask(fmt.Sprintf("%s SyncStoreCategory step2, level=%d", model.VendorChineseNames[vendorID], level), task := tasksch.NewParallelTask(fmt.Sprintf("%s SyncStoreCategory step2, level=%d", model.VendorChineseNames[vendorID], level),
@@ -80,11 +80,14 @@ func SyncStoreCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendo
catInfo := batchItemList[0].(*dao.SkuStoreCatInfo) catInfo := batchItemList[0].(*dao.SkuStoreCatInfo)
storeCatMap := &model.StoreSkuCategoryMap{} storeCatMap := &model.StoreSkuCategoryMap{}
storeCatMap.ID = catInfo.MapID storeCatMap.ID = catInfo.MapID
var failedList []*partner.StoreSkuInfoWithErr
if model.IsSyncStatusDelete(catInfo.CatSyncStatus) { // 删除 if model.IsSyncStatusDelete(catInfo.CatSyncStatus) { // 删除
if model.IsSyncStatusDelete(catInfo.CatSyncStatus) && !dao.IsVendorThingIDEmpty(catInfo.VendorCatID) { if model.IsSyncStatusDelete(catInfo.CatSyncStatus) && !dao.IsVendorThingIDEmpty(catInfo.VendorCatID) {
err = handler.DeleteStoreCategory(ctx, storeID, vendorStoreID, catInfo.VendorCatID, level) err = handler.DeleteStoreCategory(ctx, storeID, vendorStoreID, catInfo.VendorCatID, level)
if err != nil && handler.IsErrCategoryNotExist(err) { if err != nil && handler.IsErrCategoryNotExist(err) {
err = nil err = nil
} else if err != nil && !handler.IsErrCategoryNotExist(err) {
failedList = putils.GetErrMsg2FailedSingleList(nil, err, storeID, vendorID, "删除分类")
} }
} }
} else if model.IsSyncStatusNew(catInfo.CatSyncStatus) { // 新增 } else if model.IsSyncStatusNew(catInfo.CatSyncStatus) { // 新增
@@ -93,6 +96,8 @@ func SyncStoreCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendo
if cat, err2 := handler.GetStoreCategory(ctx, storeID, vendorStoreID, catInfo.Name); err2 == nil { if cat, err2 := handler.GetStoreCategory(ctx, storeID, vendorStoreID, catInfo.Name); err2 == nil {
catInfo.VendorCatID = cat.VendorCatID catInfo.VendorCatID = cat.VendorCatID
err = nil err = nil
} else if err != nil && !handler.IsErrCategoryExist(err) {
failedList = putils.GetErrMsg2FailedSingleList(nil, err, storeID, vendorID, "新增分类")
} }
} }
if err == nil { if err == nil {
@@ -103,10 +108,19 @@ func SyncStoreCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendo
} }
} }
} else if model.IsSyncStatusUpdate(catInfo.CatSyncStatus) { // 修改 } else if model.IsSyncStatusUpdate(catInfo.CatSyncStatus) { // 修改
if err = handler.UpdateStoreCategory(ctx, storeID, vendorStoreID, catInfo); err == nil { err = handler.UpdateStoreCategory(ctx, storeID, vendorStoreID, catInfo)
if err == nil {
updateFields = append(updateFields, idFieldName) updateFields = append(updateFields, idFieldName)
} else {
failedList = putils.GetErrMsg2FailedSingleList(nil, err, storeID, vendorID, "修改分类")
} }
} }
if len(failedList) > 0 {
for _, v := range failedList {
v.CategoryName = catInfo.Name
}
task.AddFailedList(failedList)
}
if err == nil { if err == nil {
if vendorID == model.VendorIDMTWM { if vendorID == model.VendorIDMTWM {
refutil.SetObjFieldByName(storeCatMap, idFieldName, catInfo.VendorCatID) refutil.SetObjFieldByName(storeCatMap, idFieldName, catInfo.VendorCatID)
@@ -318,7 +332,6 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
return err return err
} }
vendorStoreID := storeDetail.VendorStoreID vendorStoreID := storeDetail.VendorStoreID
var skus []*dao.StoreSkuSyncInfo var skus []*dao.StoreSkuSyncInfo
if isFull { if isFull {
skus, err = dao.GetFullStoreSkus(db, vendorID, storeID) skus, err = dao.GetFullStoreSkus(db, vendorID, storeID)
@@ -477,15 +490,18 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
case 0: case 0:
if len(deleteList) > 0 { if len(deleteList) > 0 {
_, err = putils.FreeBatchStoreSkuInfo("删除门店商品", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { _, err = putils.FreeBatchStoreSkuInfo("删除门店商品", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) {
var successList []*partner.StoreSkuInfo var failedList []*partner.StoreSkuInfoWithErr
if successList, err = singleStoreHandler.DeleteStoreSkus(ctx, storeID, vendorStoreID, batchedStoreSkuList); singleStoreHandler.IsErrSkuNotExist(err) { failedList, err = singleStoreHandler.DeleteStoreSkus(ctx, storeID, vendorStoreID, batchedStoreSkuList)
if len(failedList) > 0 {
task.AddFailedList(failedList)
}
if singleStoreHandler.IsErrSkuNotExist(err) {
err = nil err = nil
} }
if err == nil { if err != nil {
successList = batchedStoreSkuList
} else {
offlineList = append(offlineList, batchedStoreSkuList...) offlineList = append(offlineList, batchedStoreSkuList...)
} }
successList := putils.UnselectStoreSkuListByVendorSkuIDs(batchedStoreSkuList, GetVendorSkuIDList(failedList))
if len(successList) > 0 { if len(successList) > 0 {
updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagDeletedMask) updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagDeletedMask)
} }
@@ -495,29 +511,33 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
case 1: case 1:
if len(createList) > 0 { if len(createList) > 0 {
_, err = putils.FreeBatchStoreSkuSyncInfo("创建门店商品", func(task tasksch.ITask, batchedStoreSkuList []*dao.StoreSkuSyncInfo) (result interface{}, successCount int, err error) { _, err = putils.FreeBatchStoreSkuSyncInfo("创建门店商品", func(task tasksch.ITask, batchedStoreSkuList []*dao.StoreSkuSyncInfo) (result interface{}, successCount int, err error) {
var successList []*dao.StoreSkuSyncInfo var failedList []*partner.StoreSkuInfoWithErr
if successList, err = singleStoreHandler.CreateStoreSkus(ctx, storeID, vendorStoreID, batchedStoreSkuList); singleStoreHandler.IsErrSkuExist(err) { failedList, err = singleStoreHandler.CreateStoreSkus(ctx, storeID, vendorStoreID, batchedStoreSkuList)
if skuNameList, err2 := singleStoreHandler.GetStoreSkusFullInfo(ctx, task, storeID, vendorStoreID, []*partner.StoreSkuInfo{ singleStoreHandler.IsErrSkuExist(err)
&partner.StoreSkuInfo{ if skuNameList, err2 := singleStoreHandler.GetStoreSkusFullInfo(ctx, task, storeID, vendorStoreID, []*partner.StoreSkuInfo{
SkuID: batchedStoreSkuList[0].SkuID, &partner.StoreSkuInfo{
}, SkuID: batchedStoreSkuList[0].SkuID,
}); err2 == nil && len(skuNameList) > 0 { },
batchedStoreSkuList[0].VendorNameID = skuNameList[0].VendorNameID }); err2 == nil && len(skuNameList) > 0 {
batchedStoreSkuList[0].VendorSkuID = skuNameList[0].SkuList[0].VendorSkuID batchedStoreSkuList[0].VendorNameID = skuNameList[0].VendorNameID
batchedStoreSkuList[0].VendorSkuID = skuNameList[0].SkuList[0].VendorSkuID
// 如果创建商品时已经存在,需要更新 // 如果创建商品时已经存在,需要更新
updateList = append(updateList, calVendorPrice4StoreSku(batchedStoreSkuList[0], storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage))) updateList = append(updateList, calVendorPrice4StoreSku(batchedStoreSkuList[0], storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage)))
err = nil err = nil
}
}
if err == nil {
successList = batchedStoreSkuList
} else { } else {
failedList = append(failedList, putils.GetErrMsg2FailedSingleList(batchedStoreSkuList, err2, storeID, vendorID, "查询是否有该商品")...)
}
if len(failedList) > 0 {
task.AddFailedList(failedList)
}
if err != nil {
//handle error for sensitive words, if find, then insert to table sensitive_words //handle error for sensitive words, if find, then insert to table sensitive_words
if sensitiveWord := GetSensitiveWord(singleStoreHandler, err.Error()); sensitiveWord != "" { if sensitiveWord := GetSensitiveWord(singleStoreHandler, err.Error()); sensitiveWord != "" {
dao.InsertSensitiveWord(sensitiveWord, vendorID, ctx.GetUserName()) dao.InsertSensitiveWord(sensitiveWord, vendorID, ctx.GetUserName())
} }
} }
successList := putils.UnselectStoreSkuSyncListByVendorSkuIDs(batchedStoreSkuList, GetVendorSkuIDList(failedList))
if len(successList) > 0 { if len(successList) > 0 {
updateStoreSku(dao.GetDB(), vendorID, successList, model.SyncFlagNewMask) updateStoreSku(dao.GetDB(), vendorID, successList, model.SyncFlagNewMask)
} }
@@ -527,10 +547,12 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
case 2: case 2:
if len(updateList) > 0 { if len(updateList) > 0 {
_, err = putils.FreeBatchStoreSkuSyncInfo("更新门店商品基础信息", func(task tasksch.ITask, batchedStoreSkuList []*dao.StoreSkuSyncInfo) (result interface{}, successCount int, err error) { _, err = putils.FreeBatchStoreSkuSyncInfo("更新门店商品基础信息", func(task tasksch.ITask, batchedStoreSkuList []*dao.StoreSkuSyncInfo) (result interface{}, successCount int, err error) {
var successList []*dao.StoreSkuSyncInfo var failedList []*partner.StoreSkuInfoWithErr
if successList, err = singleStoreHandler.UpdateStoreSkus(ctx, storeID, vendorStoreID, batchedStoreSkuList); err == nil { failedList, err = singleStoreHandler.UpdateStoreSkus(ctx, storeID, vendorStoreID, batchedStoreSkuList)
successList = batchedStoreSkuList if len(failedList) > 0 {
task.AddFailedList(failedList)
} }
successList := putils.UnselectStoreSkuSyncListByVendorSkuIDs(batchedStoreSkuList, GetVendorSkuIDList(failedList))
if len(successList) > 0 { if len(successList) > 0 {
updateStoreSku(dao.GetDB(), vendorID, successList, model.SyncFlagModifiedMask) updateStoreSku(dao.GetDB(), vendorID, successList, model.SyncFlagModifiedMask)
} }
@@ -541,10 +563,12 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
for k, list := range [][]*partner.StoreSkuInfo{stockList /*, onlineList*/} { for k, list := range [][]*partner.StoreSkuInfo{stockList /*, onlineList*/} {
if len(list) > 0 { if len(list) > 0 {
_, err = putils.FreeBatchStoreSkuInfo("更新门店商品库存", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { _, err = putils.FreeBatchStoreSkuInfo("更新门店商品库存", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) {
var successList []*partner.StoreSkuInfo var failedList []*partner.StoreSkuInfoWithErr
if successList, err = storeSkuHandler.UpdateStoreSkusStock(ctx, storeDetail.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList); err == nil { failedList, err = storeSkuHandler.UpdateStoreSkusStock(ctx, storeDetail.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList)
successList = batchedStoreSkuList if len(failedList) > 0 {
task.AddFailedList(failedList)
} }
successList := putils.UnselectStoreSkuListByVendorSkuIDs(batchedStoreSkuList, GetVendorSkuIDList(failedList))
if k == 0 && len(successList) > 0 { if k == 0 && len(successList) > 0 {
updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagStockMask) updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagStockMask)
} }
@@ -563,10 +587,12 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
} }
if len(statusList) > 0 { if len(statusList) > 0 {
_, err = putils.FreeBatchStoreSkuInfo(name, func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { _, err = putils.FreeBatchStoreSkuInfo(name, func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) {
var successList []*partner.StoreSkuInfo var failedList []*partner.StoreSkuInfoWithErr
if successList, err = storeSkuHandler.UpdateStoreSkusStatus(ctx, storeDetail.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList, status); err == nil { failedList, err = storeSkuHandler.UpdateStoreSkusStatus(ctx, storeDetail.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList, status)
successList = batchedStoreSkuList if len(failedList) > 0 {
task.AddFailedList(failedList)
} }
successList := putils.UnselectStoreSkuListByVendorSkuIDs(batchedStoreSkuList, GetVendorSkuIDList(failedList))
if len(successList) > 0 { if len(successList) > 0 {
updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagSaleMask) updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagSaleMask)
} }
@@ -576,10 +602,12 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
case 6: case 6:
if len(priceList) > 0 { if len(priceList) > 0 {
_, err = putils.FreeBatchStoreSkuInfo("更新门店商品价格", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { _, err = putils.FreeBatchStoreSkuInfo("更新门店商品价格", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) {
var successList []*partner.StoreSkuInfo var failedList []*partner.StoreSkuInfoWithErr
if successList, err = storeSkuHandler.UpdateStoreSkusPrice(ctx, storeDetail.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList); err == nil { failedList, err = storeSkuHandler.UpdateStoreSkusPrice(ctx, storeDetail.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList)
successList = batchedStoreSkuList if len(failedList) > 0 {
task.AddFailedList(failedList)
} }
successList := putils.UnselectStoreSkuListByVendorSkuIDs(batchedStoreSkuList, GetVendorSkuIDList(failedList))
if len(successList) > 0 { if len(successList) > 0 {
updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagPriceMask) updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagPriceMask)
} }
@@ -726,7 +754,7 @@ func amendAndPruneStoreStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, v
} }
sku2Delete = nil sku2Delete = nil
case 2: case 2:
localCatList, err := dao.GetStoreCategories(db, vendorID, storeID, 0, false) localCatList, err := dao.GetStoreCategories(db, vendorID, storeID, nil, 0, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -889,3 +917,13 @@ func MergeSkuSaleStatusWithStoreOpTime(sku *dao.StoreSkuSyncInfo, storeDetail *d
} }
return sku.MergedStatus return sku.MergedStatus
} }
func GetVendorSkuIDList(l []*partner.StoreSkuInfoWithErr) (vendorSkuIDs []string) {
vendorSkuIDs2 := make([]string, len(l))
if len(l) > 0 {
for k, v := range l {
vendorSkuIDs2[k] = v.StoreSkuInfo.VendorSkuID
}
}
return vendorSkuIDs2
}

View File

@@ -63,7 +63,9 @@ type ITask interface {
// GetDetailErrList() []error // GetDetailErrList() []error
GetLeafResult() (finishedItemCount, failedItemCount int) GetLeafResult() (finishedItemCount, failedItemCount int)
AddBatchErr(err error) AddBatchErr(err error)
AddFailedList(failedList ...interface{})
GetFailedList() (failedList []interface{})
SetFinishHook(func(task ITask))
json.Marshaler json.Marshaler
} }
@@ -128,6 +130,8 @@ type BaseTask struct {
ctx *jxcontext.Context ctx *jxcontext.Context
isGetResultCalled bool isGetResultCalled bool
FailedList []interface{}
finishHook func(task ITask)
} }
func (s TaskList) Len() int { func (s TaskList) Len() int {
@@ -169,6 +173,9 @@ func (t *BaseTask) GetID() string {
return t.ID return t.ID
} }
func (t *BaseTask) Run() {
}
// 此函数成功返回结果后结果在任务中会被删除以免被管理的任务不必要的HOLD住对象 // 此函数成功返回结果后结果在任务中会被删除以免被管理的任务不必要的HOLD住对象
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 {
@@ -355,6 +362,29 @@ func (t *BaseTask) Error() (errMsg string) {
return errMsg return errMsg
} }
func (t *BaseTask) SetFinishHook(hook func(task ITask)) {
t.locker.RLock()
defer t.locker.RUnlock()
t.finishHook = hook
}
func (t *BaseTask) GetFailedList() (failedList []interface{}) {
t.locker.RLock()
failedList = append(failedList, t.FailedList...)
t.locker.RUnlock()
for _, v := range t.Children {
failedList = append(failedList, v.GetFailedList()...)
}
return failedList
}
func (t *BaseTask) AddFailedList(failedList ...interface{}) {
t.locker.Lock()
defer t.locker.Unlock()
t.FailedList = append(t.FailedList, failedList...)
}
// func (t *BaseTask) GetDetailErrList() []error { // func (t *BaseTask) GetDetailErrList() []error {
// t.locker.RLock() // t.locker.RLock()
// defer t.locker.RUnlock() // defer t.locker.RUnlock()
@@ -405,7 +435,6 @@ func (t *BaseTask) run(taskHandler func()) {
task.TerminatedAt = time.Now() task.TerminatedAt = time.Now()
task.locker.Unlock() task.locker.Unlock()
task.Error() task.Error()
globals.SugarLogger.Debugf("Task:%s, mainErr:%v, batchErrList:%v", task.Name, task.mainErr, task.batchErrList) globals.SugarLogger.Debugf("Task:%s, mainErr:%v, batchErrList:%v", task.Name, task.mainErr, task.batchErrList)
select { select {
@@ -419,30 +448,37 @@ func (t *BaseTask) run(taskHandler func()) {
globals.SugarLogger.Infof("BaseTask run, failed with error:%v", err) globals.SugarLogger.Infof("BaseTask run, failed with error:%v", err)
} }
} }
close(t.finishChan) close(t.finishChan)
time.Sleep(10 * time.Millisecond) // 等待GetResult中的isGetResultCalled赋值 if t.finishHook != nil {
globals.SugarLogger.Debugf("BaseTask task ID:%s, name:%s finished, isGetResultCalled:%t", t.ID, t.Name, t.isGetResultCalled) t.finishHook(t)
if !t.isGetResultCalled && t.parent == nil && len(GetTasks(t.ID, TaskStatusBegin, TaskStatusEnd, 24, "")) > 0 { } else {
if authInfo, err := t.ctx.GetV2AuthInfo(); err == nil { // 这里应该是不管登录类型,直接以可能的方式发消息 SendMessage(t)
var content string
taskDesc := fmt.Sprintf("你的异步任务[%s],ID[%s],开始于:%s,结束于:%s,", t.Name, t.ID, utils.Time2Str(t.CreatedAt), utils.Time2Str(t.TerminatedAt))
content = fmt.Sprintf("%s执行%s", taskDesc, TaskStatusName[t.Status])
if t.Error() == "" {
noticeMsg := t.GetNoticeMsg()
if noticeMsg != "" {
content += ",通知消息:" + noticeMsg
}
} else {
content += ",\n" + t.Error()
}
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, authInfo.UserID, "异步任务完成", content)
}
} }
}) })
} }
} }
func SendMessage(t *BaseTask) {
time.Sleep(10 * time.Millisecond) // 等待GetResult中的isGetResultCalled赋值
globals.SugarLogger.Debugf("BaseTask task ID:%s, name:%s finished, isGetResultCalled:%t", t.ID, t.Name, t.isGetResultCalled)
if !t.isGetResultCalled && t.parent == nil && len(GetTasks(t.ID, TaskStatusBegin, TaskStatusEnd, 24, "")) > 0 {
if authInfo, err := t.ctx.GetV2AuthInfo(); err == nil { // 这里应该是不管登录类型,直接以可能的方式发消息
var content string
taskDesc := fmt.Sprintf("你的异步任务[%s],ID[%s],开始于:%s,结束于:%s,", t.Name, t.ID, utils.Time2Str(t.CreatedAt), utils.Time2Str(t.TerminatedAt))
content = fmt.Sprintf("%s执行%s", taskDesc, TaskStatusName[t.Status])
if t.Error() == "" {
noticeMsg := t.GetNoticeMsg()
if noticeMsg != "" {
content += ",通知消息:" + noticeMsg
}
} else {
content += ",\n" + t.Error()
}
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, authInfo.UserID, "异步任务完成", content)
}
}
}
// successCount表示在返回错误的情况下部分成功的个数如果没有返回错误则successCount无意义 // successCount表示在返回错误的情况下部分成功的个数如果没有返回错误则successCount无意义
func (t *BaseTask) finishedOneJob(itemCount, successCount int, err error) { func (t *BaseTask) finishedOneJob(itemCount, successCount int, err error) {
t.locker.Lock() t.locker.Lock()

View File

@@ -99,6 +99,9 @@ type StoreSkuSyncInfo struct {
SkuName string SkuName string
StatusSaleBegin int16 `json:"statusSaleBegin"` //商品可售时间范围 StatusSaleBegin int16 `json:"statusSaleBegin"` //商品可售时间范围
StatusSaleEnd int16 `json:"statusSaleEnd"` StatusSaleEnd int16 `json:"statusSaleEnd"`
JdSyncStatus int8 `orm:"default(2)"`
MtwmSyncStatus int8 `orm:"default(2)"`
EbaiSyncStatus int8 `orm:"default(2)"`
} }
type MissingStoreSkuInfo struct { type MissingStoreSkuInfo struct {
@@ -279,7 +282,7 @@ func GetSkusCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level int
// 单门店模式厂商适用 // 单门店模式厂商适用
// 单纯的从已经创建的store_sku_category_map中得到相关的同步信息 // 单纯的从已经创建的store_sku_category_map中得到相关的同步信息
func GetStoreCategories(db *DaoDB, vendorID, storeID int, level int, mustDirty bool) (cats []*SkuStoreCatInfo, err error) { func GetStoreCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level int, mustDirty bool) (cats []*SkuStoreCatInfo, err error) {
fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID])
sql := ` sql := `
SELECT t4.*, SELECT t4.*,
@@ -288,16 +291,28 @@ func GetStoreCategories(db *DaoDB, vendorID, storeID int, level int, mustDirty b
t5p.id parent_map_id, t5p.%s_id parent_vendor_cat_id, t5p.%s_sync_status parent_cat_sync_status 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 = ?
`
sqlParams := []interface{}{
utils.DefaultTimeValue,
}
fieldPrefixParams := []interface{}{fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix}
if len(skuIDs) > 0 {
sql += `
JOIN (
SELECT DISTINCT b.category_id
FROM sku a
JOIN sku_name b ON a.name_id = b.id AND b.deleted_at = ?
WHERE a.id IN (` + GenQuestionMarks(len(skuIDs)) + `)
AND a.deleted_at = ?
) t6 ON t6.category_id = t4.id
`
sqlParams = append(sqlParams, utils.DefaultTimeValue, skuIDs, utils.DefaultTimeValue)
}
sql += `
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 t5.deleted_at = ?` WHERE t5.store_id = ? AND t5.deleted_at = ?`
fieldPrefixParams := []interface{}{fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix} sqlParams = append(sqlParams, utils.DefaultTimeValue, storeID, utils.DefaultTimeValue)
sqlParams := []interface{}{
utils.DefaultTimeValue,
utils.DefaultTimeValue,
storeID,
utils.DefaultTimeValue,
}
if mustDirty { if mustDirty {
sql += " AND t5.%s_sync_status <> 0" sql += " AND t5.%s_sync_status <> 0"
fieldPrefixParams = append(fieldPrefixParams, fieldPrefix) fieldPrefixParams = append(fieldPrefixParams, fieldPrefix)
@@ -312,8 +327,8 @@ func GetStoreCategories(db *DaoDB, vendorID, storeID int, level int, mustDirty b
return cats, err return cats, err
} }
func GetDirtyStoreCategories(db *DaoDB, vendorID, storeID int, level int) (cats []*SkuStoreCatInfo, err error) { func GetDirtyStoreCategories(db *DaoDB, vendorID, storeID int, level int, skuIDs []int) (cats []*SkuStoreCatInfo, err error) {
return GetStoreCategories(db, vendorID, storeID, level, true) return GetStoreCategories(db, vendorID, storeID, skuIDs, level, true)
} }
// 以store_sku_bind为基础来做同步正常情况下使用 // 以store_sku_bind为基础来做同步正常情况下使用
@@ -1173,7 +1188,7 @@ func GetTopSkusByStoreIDs(db *DaoDB, storeIDs []int) (storeSkuNameExt []*StoreSk
t4.sub_store_id, t4.price bind_price, IF(t4.unit_price IS NOT NULL, t4.unit_price, t1.price) unit_price, t4.status store_sku_status, t4.auto_sale_at, t4.sub_store_id, t4.price bind_price, IF(t4.unit_price IS NOT NULL, t4.unit_price, t1.price) unit_price, t4.status store_sku_status, t4.auto_sale_at,
t4.ebai_id, t4.mtwm_id, t4.ebai_id, t4.mtwm_id,
t4.ebai_sync_status, t4.mtwm_sync_status, t4.ebai_sync_status, t4.mtwm_sync_status,
t4.jd_price, t4.ebai_price, t4.mtwm_price, t4.jx_price t4.jd_price, t4.ebai_price, t4.mtwm_price, t4.jx_price, a.spec_quality sku_spec_quality, a.spec_unit sku_spec_unit
FROM sku a FROM sku a
JOIN sku_name t1 ON a.name_id = t1.id AND t1.deleted_at = ? JOIN sku_name t1 ON a.name_id = t1.id AND t1.deleted_at = ?
JOIN store_sku_bind t4 ON t4.sku_id = a.id AND t4.deleted_at = ? JOIN store_sku_bind t4 ON t4.sku_id = a.id AND t4.deleted_at = ?
@@ -1517,9 +1532,10 @@ func GetPriceReferPrice(db *DaoDB, cityCode int, skuID int, snapDate time.Time)
return priceRefer, err return priceRefer, err
} }
func GetStoreSkusAndSkuName(db *DaoDB, storeIDs, skuIDs, nameIDs []int) (storeSkuNameExt []*StoreSkuNameExt, err error) { func GetStoreSkusAndSkuName(db *DaoDB, storeIDs, skuIDs, nameIDs []int) (storeSkuSyncInfo []*StoreSkuSyncInfo, err error) {
sql := ` sql := `
SELECT a.*,c.id SELECT a.id bind_id, a.store_id, a.jd_sync_status, a.mtwm_sync_status, a.ebai_sync_status, a.unit_price,
c.id name_id, c.unit, b.*
FROM store_sku_bind a FROM store_sku_bind a
JOIN sku b ON b.id = a.sku_id AND b.deleted_at = ? JOIN sku b ON b.id = a.sku_id AND b.deleted_at = ?
JOIN sku_name c ON c.id = b.name_id AND c.deleted_at = ? JOIN sku_name c ON c.id = b.name_id AND c.deleted_at = ?
@@ -1542,6 +1558,6 @@ func GetStoreSkusAndSkuName(db *DaoDB, storeIDs, skuIDs, nameIDs []int) (storeSk
sql += " AND b.name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")" sql += " AND b.name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")"
sqlParams = append(sqlParams, nameIDs) sqlParams = append(sqlParams, nameIDs)
} }
err = GetRows(db, &storeSkuNameExt, sql, sqlParams...) err = GetRows(db, &storeSkuSyncInfo, sql, sqlParams...)
return storeSkuNameExt, err return storeSkuSyncInfo, err
} }

View File

@@ -24,8 +24,8 @@ type OperateEventDetail struct {
ThingType int `json:"thingType"` //各字段类型 ThingType int `json:"thingType"` //各字段类型
StoreID int `orm:"column(store_id)" json:"storeID"` StoreID int `orm:"column(store_id)" json:"storeID"`
AccessUUID string `orm:"column(access_uuid)" json:"accessUUID"` AccessUUID string `orm:"column(access_uuid)" json:"accessUUID"`
BeforeData string `orm:"size(32)" json:"beforeData"` BeforeData string `orm:"size(255)" json:"beforeData"`
AfterData string `orm:"size(32)" json:"afterData"` AfterData string `orm:"size(255)" json:"afterData"`
} }
func (v *OperateEventDetail) TableIndex() [][]string { func (v *OperateEventDetail) TableIndex() [][]string {

View File

@@ -43,6 +43,15 @@ type StoreSkuInfo struct {
Seq int `json:"seq,omitempty"` Seq int `json:"seq,omitempty"`
} }
type StoreSkuInfoWithErr struct {
StoreSkuInfo *StoreSkuInfo
CategoryName string
VendoreID int
StoreID int
SyncType string
ErrMsg string
}
type SkuInfo struct { type SkuInfo struct {
StoreSkuInfo StoreSkuInfo
SkuName string SkuName string
@@ -129,18 +138,18 @@ type IPurchasePlatformStoreSkuHandler interface {
// 此接口要求实现为不限制批处理大小的 // 此接口要求实现为不限制批处理大小的
GetStoreSkusBareInfo(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*StoreSkuInfo) (outStoreSkuList []*StoreSkuInfo, err error) GetStoreSkusBareInfo(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*StoreSkuInfo) (outStoreSkuList []*StoreSkuInfo, err error)
UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (successList []*StoreSkuInfo, err error) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (failedList []*StoreSkuInfoWithErr, err error)
UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo, status int) (successList []*StoreSkuInfo, err error) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo, status int) (failedList []*StoreSkuInfoWithErr, err error)
UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (successList []*StoreSkuInfo, err error) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (failedList []*StoreSkuInfoWithErr, err error)
} }
type ISingleStoreStoreSkuHandler interface { type ISingleStoreStoreSkuHandler interface {
IPurchasePlatformStoreSkuHandler IPurchasePlatformStoreSkuHandler
GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (outSkuNameList []*SkuNameInfo, err error) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (outSkuNameList []*SkuNameInfo, err error)
CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (successList []*dao.StoreSkuSyncInfo, err error) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*StoreSkuInfoWithErr, err error)
UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (successList []*dao.StoreSkuSyncInfo, err error) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*StoreSkuInfoWithErr, err error)
DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (successList []*StoreSkuInfo, err error) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (failedList []*StoreSkuInfoWithErr, err error)
DeleteStoreAllSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, isContinueWhenError bool) (err error) DeleteStoreAllSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, isContinueWhenError bool) (err error)
IsErrSkuExist(err error) (isExist bool) IsErrSkuExist(err error) (isExist bool)
IsErrSkuNotExist(err error) (isNotExist bool) IsErrSkuNotExist(err error) (isNotExist bool)

View File

@@ -113,27 +113,30 @@ func (p *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) {
return ebaiapi.IsErrSkuNotExist(err) return ebaiapi.IsErrSkuNotExist(err)
} }
func (p *PurchaseHandler) updateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo, isNeedMapCat bool) (successList []*dao.StoreSkuSyncInfo, err error) { func (p *PurchaseHandler) updateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo, isNeedMapCat bool) (failedList []*partner.StoreSkuInfoWithErr, err error) {
storeSku := storeSkuList[0] storeSku := storeSkuList[0]
strStoreID := utils.Int2Str(storeID) strStoreID := utils.Int2Str(storeID)
params := genSkuParamsFromStoreSkuInfo2(storeSku, false) params := genSkuParamsFromStoreSkuInfo2(storeSku, false)
if globals.EnableEbaiStoreWrite { if globals.EnableEbaiStoreWrite {
_, err = api.EbaiAPI.SkuUpdate(ctx.GetTrackInfo(), strStoreID, utils.Str2Int64(storeSku.VendorSkuID), params) _, err = api.EbaiAPI.SkuUpdate(ctx.GetTrackInfo(), strStoreID, utils.Str2Int64(storeSku.VendorSkuID), params)
if err != nil {
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorIDEBAI, "更新商品基础信息")
}
if isNeedMapCat { if isNeedMapCat {
utils.CallFuncAsync(func() { utils.CallFuncAsync(func() {
api.EbaiAPI.SkuShopCategoryMap(strStoreID, utils.Str2Int64(storeSku.VendorSkuID), "", utils.Str2Int64(storeSku.VendorCatID), genSkuCatRank(storeSku)) api.EbaiAPI.SkuShopCategoryMap(strStoreID, utils.Str2Int64(storeSku.VendorSkuID), "", utils.Str2Int64(storeSku.VendorCatID), genSkuCatRank(storeSku))
}) })
} }
} }
return nil, err return failedList, err
} }
func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (successList []*dao.StoreSkuSyncInfo, err error) { func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
return p.updateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, true) return p.updateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, true)
} }
// 对于多门店平台来说storeSkuList中只有SkuID与VendorSkuID有意义 // 对于多门店平台来说storeSkuList中只有SkuID与VendorSkuID有意义
func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (successList []*dao.StoreSkuSyncInfo, err error) { func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
storeSku := storeSkuList[0] storeSku := storeSkuList[0]
var vendorSkuID int64 var vendorSkuID int64
params := genSkuParamsFromStoreSkuInfo2(storeSku, true) params := genSkuParamsFromStoreSkuInfo2(storeSku, true)
@@ -146,12 +149,14 @@ func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, v
// 比如门店100887, skuID33805订单1577176719141226065 // 比如门店100887, skuID33805订单1577176719141226065
p.updateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, false) p.updateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, false)
}) })
} else {
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorIDEBAI, "创建商品")
} }
} else { } else {
vendorSkuID = jxutils.GenFakeID() vendorSkuID = jxutils.GenFakeID()
} }
storeSku.VendorSkuID = utils.Int64ToStr(vendorSkuID) storeSku.VendorSkuID = utils.Int64ToStr(vendorSkuID)
return nil, err return failedList, err
} }
func getFailedVendorSkuIDsFromOpResult(opResult *ebaiapi.BatchOpResult) (skuIDs []string) { func getFailedVendorSkuIDsFromOpResult(opResult *ebaiapi.BatchOpResult) (skuIDs []string) {
@@ -163,19 +168,20 @@ func getFailedVendorSkuIDsFromOpResult(opResult *ebaiapi.BatchOpResult) (skuIDs
return skuIDs return skuIDs
} }
func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
if globals.EnableEbaiStoreWrite { if globals.EnableEbaiStoreWrite {
opResult, err2 := api.EbaiAPI.SkuDelete(ctx.GetTrackInfo(), utils.Int2Str(storeID), partner.BareStoreSkuInfoList(storeSkuList).GetVendorSkuIDIntList(), nil) opResult, err2 := api.EbaiAPI.SkuDelete(ctx.GetTrackInfo(), utils.Int2Str(storeID), partner.BareStoreSkuInfoList(storeSkuList).GetVendorSkuIDIntList(), nil)
if err = err2; err2 != nil && opResult != nil { if err = err2; err2 != nil && opResult != nil {
if len(storeSkuList) > len(opResult.FailedList) { // if len(storeSkuList) > len(opResult.FailedList) {
successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getFailedVendorSkuIDsFromOpResult(opResult)) failedList = SelectStoreSkuListByOpResult(storeSkuList, opResult, storeID, model.VendorIDEBAI, "删除商品")
} // successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getFailedVendorSkuIDsFromOpResult(opResult))
// }
} }
} }
return successList, err return failedList, err
} }
func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (successList []*partner.StoreSkuInfo, err error) { func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) {
vendorSkuIDs := partner.BareStoreSkuInfoList(storeSkuList).GetVendorSkuIDIntList() vendorSkuIDs := partner.BareStoreSkuInfoList(storeSkuList).GetVendorSkuIDIntList()
if globals.EnableEbaiStoreWrite { if globals.EnableEbaiStoreWrite {
var opResult *ebaiapi.BatchOpResult var opResult *ebaiapi.BatchOpResult
@@ -184,19 +190,24 @@ func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOr
opResult, err = api.EbaiAPI.SkuOnline(ctx.GetTrackInfo(), utils.Int2Str(storeID), vendorSkuIDs, nil, nil) opResult, err = api.EbaiAPI.SkuOnline(ctx.GetTrackInfo(), utils.Int2Str(storeID), vendorSkuIDs, nil, nil)
} else if len(vendorSkuIDs) == 1 { } else if len(vendorSkuIDs) == 1 {
err = api.EbaiAPI.SkuOnlineOne(ctx.GetTrackInfo(), utils.Int2Str(storeID), vendorSkuIDs[0], "", "") err = api.EbaiAPI.SkuOnlineOne(ctx.GetTrackInfo(), utils.Int2Str(storeID), vendorSkuIDs[0], "", "")
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorIDEBAI, "更新商品状态")
return failedList, err
} }
} else { } else {
if len(vendorSkuIDs) > 1 { if len(vendorSkuIDs) > 1 {
opResult, err = api.EbaiAPI.SkuOffline(ctx.GetTrackInfo(), utils.Int2Str(storeID), vendorSkuIDs, nil, nil) opResult, err = api.EbaiAPI.SkuOffline(ctx.GetTrackInfo(), utils.Int2Str(storeID), vendorSkuIDs, nil, nil)
} else if len(vendorSkuIDs) == 1 { } else if len(vendorSkuIDs) == 1 {
err = api.EbaiAPI.SkuOfflineOne(ctx.GetTrackInfo(), utils.Int2Str(storeID), vendorSkuIDs[0], "", "") err = api.EbaiAPI.SkuOfflineOne(ctx.GetTrackInfo(), utils.Int2Str(storeID), vendorSkuIDs[0], "", "")
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorIDEBAI, "更新商品状态")
return failedList, err
} }
} }
if err != nil && opResult != nil { if err != nil && opResult != nil {
successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getFailedVendorSkuIDsFromOpResult(opResult)) failedList = SelectStoreSkuListByOpResult(storeSkuList, opResult, storeID, model.VendorIDEBAI, "更新商品状态")
// failedList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getFailedVendorSkuIDsFromOpResult(opResult))
} }
} }
return successList, err return failedList, err
} }
func StoreSkuInfoList2Ebai(storeSkuList []*partner.StoreSkuInfo) (outList ebaiapi.ShopSkuInfoList) { func StoreSkuInfoList2Ebai(storeSkuList []*partner.StoreSkuInfo) (outList ebaiapi.ShopSkuInfoList) {
@@ -212,32 +223,37 @@ func StoreSkuInfoList2Ebai(storeSkuList []*partner.StoreSkuInfo) (outList ebaiap
return outList return outList
} }
func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
if globals.EnableEbaiStoreWrite { if globals.EnableEbaiStoreWrite {
if len(storeSkuList) > 1 { if len(storeSkuList) > 1 {
opResult, err2 := api.EbaiAPI.SkuPriceUpdateBatch(ctx.GetTrackInfo(), utils.Int2Str(storeID), StoreSkuInfoList2Ebai(storeSkuList), ebaiapi.SkuIDTypeSkuID) opResult, err2 := api.EbaiAPI.SkuPriceUpdateBatch(ctx.GetTrackInfo(), utils.Int2Str(storeID), StoreSkuInfoList2Ebai(storeSkuList), ebaiapi.SkuIDTypeSkuID)
if err = err2; err != nil && opResult != nil { if err = err2; err != nil && opResult != nil {
successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getFailedVendorSkuIDsFromOpResult(opResult)) failedList = SelectStoreSkuListByOpResult(storeSkuList, opResult, storeID, model.VendorIDEBAI, "更新商品价格")
} }
} else if len(storeSkuList) == 1 { } else if len(storeSkuList) == 1 {
_, err = api.EbaiAPI.SkuPriceUpdateOne(ctx.GetTrackInfo(), utils.Int2Str(storeID), StoreSkuInfoList2Ebai(storeSkuList)[0]) opResult2, err := api.EbaiAPI.SkuPriceUpdateOne(ctx.GetTrackInfo(), utils.Int2Str(storeID), StoreSkuInfoList2Ebai(storeSkuList)[0])
if err != nil && opResult2 != nil {
failedList = SelectStoreSkuListByOpResult(storeSkuList, opResult2, storeID, model.VendorIDEBAI, "更新商品价格")
}
} }
} }
return successList, err return failedList, err
} }
func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
if globals.EnableEbaiStoreWrite { if globals.EnableEbaiStoreWrite {
if len(storeSkuList) > 1 { if len(storeSkuList) > 1 {
opResult, err2 := api.EbaiAPI.SkuStockUpdateBatch(ctx.GetTrackInfo(), utils.Int2Str(storeID), StoreSkuInfoList2Ebai(storeSkuList), ebaiapi.SkuIDTypeSkuID) opResult, err2 := api.EbaiAPI.SkuStockUpdateBatch(ctx.GetTrackInfo(), utils.Int2Str(storeID), StoreSkuInfoList2Ebai(storeSkuList), ebaiapi.SkuIDTypeSkuID)
if err = err2; err != nil && opResult != nil { if err = err2; err != nil && opResult != nil {
successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getFailedVendorSkuIDsFromOpResult(opResult)) failedList = SelectStoreSkuListByOpResult(storeSkuList, opResult, storeID, model.VendorIDEBAI, "更新商品库存")
// successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getFailedVendorSkuIDsFromOpResult(opResult))
} }
} else if len(storeSkuList) == 1 { } else if len(storeSkuList) == 1 {
err = api.EbaiAPI.SkuStockUpdateOne(ctx.GetTrackInfo(), utils.Int2Str(storeID), StoreSkuInfoList2Ebai(storeSkuList)[0]) err = api.EbaiAPI.SkuStockUpdateOne(ctx.GetTrackInfo(), utils.Int2Str(storeID), StoreSkuInfoList2Ebai(storeSkuList)[0])
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorIDEBAI, "更新商品库存")
} }
} }
return successList, err return failedList, err
} }
func genSkuParamsFromStoreSkuInfo2(storeSku *dao.StoreSkuSyncInfo, isCreate bool) (params map[string]interface{}) { func genSkuParamsFromStoreSkuInfo2(storeSku *dao.StoreSkuSyncInfo, isCreate bool) (params map[string]interface{}) {
@@ -414,3 +430,26 @@ func vendorSkuList2Jx(vendorSkuList []*ebaiapi.SkuInfo) (skuNameList []*partner.
func (p *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp { func (p *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp {
return sensitiveWordRegexp return sensitiveWordRegexp
} }
//饿百api返回
func SelectStoreSkuListByOpResult(storeSkuList []*partner.StoreSkuInfo, opResult *ebaiapi.BatchOpResult, storeID, vendorID int, syncType string) (selectedStoreSkuList []*partner.StoreSkuInfoWithErr) {
opResultMap := make(map[int64]string)
if len(opResult.FailedList) > 0 {
for _, v := range opResult.FailedList {
opResultMap[v.SkuID] = v.ErrorMsg
}
for _, v := range storeSkuList {
if opResultMap[utils.Str2Int64(v.VendorSkuID)] != "" {
opFailed := &partner.StoreSkuInfoWithErr{
StoreSkuInfo: v,
ErrMsg: opResultMap[utils.Str2Int64(v.VendorSkuID)],
StoreID: storeID,
VendoreID: vendorID,
SyncType: syncType,
}
selectedStoreSkuList = append(selectedStoreSkuList, opFailed)
}
}
}
return selectedStoreSkuList
}

View File

@@ -110,7 +110,7 @@ func getStrOutSkuIDs(l []*jdapi.StoreSkuBatchUpdateResponse, isSuccess bool) (ou
return outSkuIDs return outSkuIDs
} }
func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (successList []*partner.StoreSkuInfo, err error) { func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) {
var skuVendibilityList []*jdapi.StockVendibility var skuVendibilityList []*jdapi.StockVendibility
jdStatus := jxStoreSkuStatus2Jd(status) jdStatus := jxStoreSkuStatus2Jd(status)
for _, v := range storeSkuList { for _, v := range storeSkuList {
@@ -122,16 +122,18 @@ func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOr
if globals.EnableJdStoreWrite { if globals.EnableJdStoreWrite {
responseList, err2 := getAPI(vendorOrgCode).BatchUpdateVendibility(ctx.GetTrackInfo(), "", vendorStoreID, skuVendibilityList, ctx.GetUserName()) responseList, err2 := getAPI(vendorOrgCode).BatchUpdateVendibility(ctx.GetTrackInfo(), "", vendorStoreID, skuVendibilityList, ctx.GetUserName())
if err = err2; isErrPartialFailed(err) { if err = err2; isErrPartialFailed(err) {
successList = putils.UnselectStoreSkuListBySkuIDs(storeSkuList, utils.StringSlice2Int(getStrOutSkuIDs(responseList, false))) failedList = SelectStoreSkuListByResponseList(storeSkuList, responseList, storeID, model.VendorIDJD, "更新商品状态")
// successList = putils.UnselectStoreSkuListBySkuIDs(storeSkuList, utils.StringSlice2Int(getStrOutSkuIDs(responseList, false)))
} }
} }
return successList, err return failedList, err
} }
func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
if len(storeSkuList) == 1 { if len(storeSkuList) == 1 {
if globals.EnableJdStoreWrite { if globals.EnableJdStoreWrite {
_, err = getAPI(vendorOrgCode).UpdateStationPrice(ctx.GetTrackInfo(), utils.Str2Int64WithDefault(storeSkuList[0].VendorSkuID, 0), vendorStoreID, int(storeSkuList[0].VendorPrice)) _, err = getAPI(vendorOrgCode).UpdateStationPrice(ctx.GetTrackInfo(), utils.Str2Int64WithDefault(storeSkuList[0].VendorSkuID, 0), vendorStoreID, int(storeSkuList[0].VendorPrice))
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorIDJD, "更新商品价格")
} }
} else { } else {
var skuPriceInfoList []*jdapi.SkuPriceInfo var skuPriceInfoList []*jdapi.SkuPriceInfo
@@ -144,17 +146,18 @@ func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrg
if globals.EnableJdStoreWrite { if globals.EnableJdStoreWrite {
responseList, err2 := getAPI(vendorOrgCode).UpdateVendorStationPrice(ctx.GetTrackInfo(), "", vendorStoreID, skuPriceInfoList) responseList, err2 := getAPI(vendorOrgCode).UpdateVendorStationPrice(ctx.GetTrackInfo(), "", vendorStoreID, skuPriceInfoList)
if err = err2; isErrPartialFailed(err) { if err = err2; isErrPartialFailed(err) {
successList = putils.UnselectStoreSkuListBySkuIDs(storeSkuList, utils.StringSlice2Int(getStrOutSkuIDs(responseList, false))) failedList = SelectStoreSkuListByResponseList(storeSkuList, responseList, storeID, model.VendorIDJD, "更新商品价格")
} }
} }
} }
return successList, err return failedList, err
} }
func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
if len(storeSkuList) == 1 { if len(storeSkuList) == 1 {
if globals.EnableJdStoreWrite { if globals.EnableJdStoreWrite {
err = getAPI(vendorOrgCode).UpdateCurrentQty(ctx.GetTrackInfo(), vendorStoreID, utils.Str2Int64WithDefault(storeSkuList[0].VendorSkuID, 0), storeSkuList[0].Stock) err = getAPI(vendorOrgCode).UpdateCurrentQty(ctx.GetTrackInfo(), vendorStoreID, utils.Str2Int64WithDefault(storeSkuList[0].VendorSkuID, 0), storeSkuList[0].Stock)
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorIDJD, "更新商品库存")
} }
} else { } else {
var skuStockList []*jdapi.SkuStock var skuStockList []*jdapi.SkuStock
@@ -167,11 +170,12 @@ func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrg
if globals.EnableJdStoreWrite { if globals.EnableJdStoreWrite {
responseList, err2 := getAPI(vendorOrgCode).BatchUpdateCurrentQtys(ctx.GetTrackInfo(), "", vendorStoreID, skuStockList, ctx.GetUserName()) responseList, err2 := getAPI(vendorOrgCode).BatchUpdateCurrentQtys(ctx.GetTrackInfo(), "", vendorStoreID, skuStockList, ctx.GetUserName())
if err = err2; isErrPartialFailed(err) { if err = err2; isErrPartialFailed(err) {
successList = putils.UnselectStoreSkuListBySkuIDs(storeSkuList, utils.StringSlice2Int(getStrOutSkuIDs(responseList, false))) failedList = SelectStoreSkuListByResponseList(storeSkuList, responseList, storeID, model.VendorIDJD, "更新商品库存")
// successList = putils.UnselectStoreSkuListBySkuIDs(storeSkuList, utils.StringSlice2Int(getStrOutSkuIDs(responseList, false)))
} }
} }
} }
return successList, err return failedList, err
} }
func (p *PurchaseHandler) SyncStoreProducts(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { func (p *PurchaseHandler) SyncStoreProducts(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) {
@@ -211,3 +215,28 @@ func (p *PurchaseHandler) SyncStoreProducts(ctx *jxcontext.Context, vendorOrgCod
} }
return hint, err return hint, err
} }
//京东api返回
func SelectStoreSkuListByResponseList(storeSkuList []*partner.StoreSkuInfo, responseList []*jdapi.StoreSkuBatchUpdateResponse, storeID, vendorID int, syncType string) (selectedStoreSkuList []*partner.StoreSkuInfoWithErr) {
responseMap := make(map[string]string)
if len(responseList) > 0 {
for _, v := range responseList {
if v.Code != "0" {
responseMap[v.OutSkuID] = v.Msg
}
}
for _, v := range storeSkuList {
if responseMap[utils.Int2Str(v.SkuID)] != "" {
respFailed := &partner.StoreSkuInfoWithErr{
StoreSkuInfo: v,
ErrMsg: responseMap[utils.Int2Str(v.SkuID)],
StoreID: storeID,
VendoreID: vendorID,
SyncType: syncType,
}
selectedStoreSkuList = append(selectedStoreSkuList, respFailed)
}
}
}
return selectedStoreSkuList
}

View File

@@ -1,6 +1,7 @@
package mtwm package mtwm
import ( import (
"encoding/json"
"regexp" "regexp"
"strings" "strings"
@@ -211,29 +212,35 @@ func (p *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) {
// return newStoreSkuList // return newStoreSkuList
// } // }
func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (successList []*dao.StoreSkuSyncInfo, err error) { func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
successList, err = p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, false) failedList, err = p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, false)
// if err == nil && vendorStoreID == specialStoreID { // if err == nil && vendorStoreID == specialStoreID {
// for i := 0; i < 2; i++ { // for i := 0; i < 2; i++ {
// p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, duplicateStoreSkuList(storeSkuList, i+1), true) // p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, duplicateStoreSkuList(storeSkuList, i+1), true)
// } // }
// } // }
return successList, err return failedList, err
} }
func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (successList []*dao.StoreSkuSyncInfo, err error) { func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
successList, err = p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, true) failedList, err = p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, true)
// if err == nil && vendorStoreID == specialStoreID { // if err == nil && vendorStoreID == specialStoreID {
// for i := 0; i < 2; i++ { // for i := 0; i < 2; i++ {
// p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, duplicateStoreSkuList(storeSkuList, i+1), true) // p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, duplicateStoreSkuList(storeSkuList, i+1), true)
// } // }
// } // }
return successList, err return failedList, err
} }
// 对于多门店平台来说storeSkuList中只有SkuID与VendorSkuID有意义 // 对于多门店平台来说storeSkuList中只有SkuID与VendorSkuID有意义
func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo, isCreate bool) (successList []*dao.StoreSkuSyncInfo, err error) { func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo, isCreate bool) (failedList []*partner.StoreSkuInfoWithErr, err error) {
var syncType string
foodDataList := make([]map[string]interface{}, len(storeSkuList)) foodDataList := make([]map[string]interface{}, len(storeSkuList))
if isCreate {
syncType = "创建商品"
} else {
syncType = "更新商品"
}
for i, storeSku := range storeSkuList { for i, storeSku := range storeSkuList {
isNeedUpdatePrice := isCreate //storeSku.SkuSyncStatus&( model.SyncFlagPriceMask| model.SyncFlagNewMask) != 0 isNeedUpdatePrice := isCreate //storeSku.SkuSyncStatus&( model.SyncFlagPriceMask| model.SyncFlagNewMask) != 0
foodData := make(map[string]interface{}) foodData := make(map[string]interface{})
@@ -295,11 +302,13 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI
if len(foodDataList) == 1 { if len(foodDataList) == 1 {
foodDataList[0]["skus"] = string(utils.MustMarshal(foodDataList[0]["skus"])) foodDataList[0]["skus"] = string(utils.MustMarshal(foodDataList[0]["skus"]))
err = api.MtwmAPI.RetailInitData(ctx.GetTrackInfo(), vendorStoreID, utils.Int2Str(storeSkuList[0].SkuID), foodDataList[0]) err = api.MtwmAPI.RetailInitData(ctx.GetTrackInfo(), vendorStoreID, utils.Int2Str(storeSkuList[0].SkuID), foodDataList[0])
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorIDMTWM, syncType)
} else if len(foodDataList) > 0 { } else if len(foodDataList) > 0 {
failedFoodList, err2 := api.MtwmAPI.RetailBatchInitData(ctx.GetTrackInfo(), vendorStoreID, foodDataList) failedFoodList, err2 := api.MtwmAPI.RetailBatchInitData(ctx.GetTrackInfo(), vendorStoreID, foodDataList)
if err = err2; err == nil { if err = err2; err == nil {
if err = putils.GenPartialFailedErr(failedFoodList, len(failedFoodList)); err != nil { if err = putils.GenPartialFailedErr(failedFoodList, len(failedFoodList)); err != nil {
successList = putils.UnselectStoreSkuSyncListByVendorSkuIDs(storeSkuList, getAppFoodCodeList(failedFoodList)) failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorIDMTWM, syncType)
// successList = putils.UnselectStoreSkuSyncListByVendorSkuIDs(storeSkuList, getAppFoodCodeList(failedFoodList))
} }
} }
} }
@@ -307,7 +316,7 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI
for _, storeSku := range storeSkuList { for _, storeSku := range storeSkuList {
storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID) storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID)
} }
return successList, err return failedList, err
} }
func getAppFoodCodeList(l []*mtwmapi.AppFoodResult) (vendorSkuIDs []string) { func getAppFoodCodeList(l []*mtwmapi.AppFoodResult) (vendorSkuIDs []string) {
@@ -320,16 +329,24 @@ func getAppFoodCodeList(l []*mtwmapi.AppFoodResult) (vendorSkuIDs []string) {
return vendorSkuIDs return vendorSkuIDs
} }
func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
if globals.EnableMtwmStoreWrite { if globals.EnableMtwmStoreWrite {
if len(storeSkuList) == 1 { if len(storeSkuList) == 1 {
err = api.MtwmAPI.RetailDelete(ctx.GetTrackInfo(), vendorStoreID, storeSkuList[0].VendorSkuID) err = api.MtwmAPI.RetailDelete(ctx.GetTrackInfo(), vendorStoreID, storeSkuList[0].VendorSkuID)
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorIDMTWM, "删除商品")
} else { } else {
// todo 部分失败 // todo 部分失败
err = api.MtwmAPI.RetailCatSkuBatchDelete2(ctx.GetTrackInfo(), vendorStoreID, nil, nil, nil, nil, partner.BareStoreSkuInfoList(storeSkuList).GetVendorSkuIDList()) err = api.MtwmAPI.RetailCatSkuBatchDelete2(ctx.GetTrackInfo(), vendorStoreID, nil, nil, nil, nil, partner.BareStoreSkuInfoList(storeSkuList).GetVendorSkuIDList())
if err != nil {
if errExt, ok := err.(*utils.ErrorWithCode); ok {
myMap := make(map[string][]*mtwmapi.AppFoodResult)
json.Unmarshal([]byte(errExt.ErrMsg()), &myMap)
failedList = SelectStoreSkuListByFoodList(storeSkuList, myMap["retail_error_list"], storeID, model.VendorIDMTWM, "批量删除商品")
}
}
} }
} }
return nil, err return failedList, err
} }
func stockCount2Mtwm(stock int) (mtwmStock string) { func stockCount2Mtwm(stock int) (mtwmStock string) {
@@ -358,44 +375,48 @@ func storeSku2Mtwm(storeSkuList []*partner.StoreSkuInfo, updateType int) (skuLis
return skuList return skuList
} }
func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (successList []*partner.StoreSkuInfo, err error) { func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) {
skuList := storeSku2Mtwm(storeSkuList, updateTypeStatus) skuList := storeSku2Mtwm(storeSkuList, updateTypeStatus)
mtwmStatus := skuStatusJX2Mtwm(status) mtwmStatus := skuStatusJX2Mtwm(status)
if globals.EnableMtwmStoreWrite { if globals.EnableMtwmStoreWrite {
failedFoodList, err2 := api.MtwmAPI.RetailSellStatus(ctx.GetTrackInfo(), vendorStoreID, skuList, mtwmStatus) failedFoodList, err2 := api.MtwmAPI.RetailSellStatus(ctx.GetTrackInfo(), vendorStoreID, skuList, mtwmStatus)
if err = err2; err == nil { if err = err2; err == nil {
if len(failedFoodList) > 0 { if len(failedFoodList) > 0 {
successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getAppFoodCodeList(failedFoodList)) failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorIDMTWM, "更新商品状态")
// successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getAppFoodCodeList(failedFoodList))
} }
} }
} }
return successList, err return failedList, err
} }
func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
priceList := storeSku2Mtwm(storeSkuList, updateTypePrice) priceList := storeSku2Mtwm(storeSkuList, updateTypePrice)
if globals.EnableMtwmStoreWrite { if globals.EnableMtwmStoreWrite {
failedFoodList, err2 := api.MtwmAPI.RetailSkuPrice(ctx.GetTrackInfo(), vendorStoreID, priceList) failedFoodList, err2 := api.MtwmAPI.RetailSkuPrice(ctx.GetTrackInfo(), vendorStoreID, priceList)
if err = err2; err == nil { if err = err2; err == nil {
if err = putils.GenPartialFailedErr(failedFoodList, len(failedFoodList)); err != nil { if len(failedFoodList) > 0 {
successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getAppFoodCodeList(failedFoodList)) failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorIDMTWM, "更新商品价格")
} }
} }
} }
return successList, err return failedList, err
} }
func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
stockList := storeSku2Mtwm(storeSkuList, updateTypeStock) stockList := storeSku2Mtwm(storeSkuList, updateTypeStock)
if globals.EnableMtwmStoreWrite { if globals.EnableMtwmStoreWrite {
failedFoodList, err2 := api.MtwmAPI.RetailSkuStock(ctx.GetTrackInfo(), vendorStoreID, stockList) failedFoodList, err2 := api.MtwmAPI.RetailSkuStock(ctx.GetTrackInfo(), vendorStoreID, stockList)
if err = err2; err == nil { if err = err2; err == nil {
if err = putils.GenPartialFailedErr(failedFoodList, len(failedFoodList)); err != nil { if len(failedFoodList) > 0 {
successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getAppFoodCodeList(failedFoodList)) failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorIDMTWM, "更新商品库存")
} }
//if err = putils.GenPartialFailedErr(failedFoodList, len(failedFoodList)); err != nil {
// successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getAppFoodCodeList(failedFoodList))
// }
} }
} }
return successList, err return failedList, err
} }
func mtwmSkuStatus2Jx(mtwmSkuStatus int) (jxSkuStatus int) { func mtwmSkuStatus2Jx(mtwmSkuStatus int) (jxSkuStatus int) {
@@ -506,3 +527,50 @@ func vendorSkuList2Jx(appFoodList []*mtwmapi.AppFood) (skuNameList []*partner.Sk
func (p *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp { func (p *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp {
return sensitiveWordRegexp return sensitiveWordRegexp
} }
//美团api返回
func SelectStoreSkuListByFoodList(storeSkuList interface{}, foodList []*mtwmapi.AppFoodResult, storeID, vendorID int, syncType string) (selectedStoreSkuList []*partner.StoreSkuInfoWithErr) {
foodMap := make(map[string]string)
if len(foodList) > 0 {
for _, v := range foodList {
foodMap[v.AppFoodCode] = v.ErrorMsg
}
if storeSkuLists, ok := storeSkuList.([]*partner.StoreSkuInfo); ok {
for _, v := range storeSkuLists {
if foodMap[v.VendorSkuID] != "" {
foodFailed := &partner.StoreSkuInfoWithErr{
StoreSkuInfo: v,
ErrMsg: foodMap[v.VendorSkuID],
StoreID: storeID,
VendoreID: vendorID,
SyncType: syncType,
}
selectedStoreSkuList = append(selectedStoreSkuList, foodFailed)
}
}
}
if storeSkuLists, ok := storeSkuList.([]*dao.StoreSkuSyncInfo); ok {
for _, v := range storeSkuLists {
if foodMap[v.VendorSkuID] != "" {
storeSkuInfo := &partner.StoreSkuInfo{
SkuID: v.SkuID,
VendorSkuID: v.VendorSkuID,
NameID: v.NameID,
VendorNameID: v.VendorNameID,
VendorPrice: v.VendorPrice,
Status: v.Status,
}
foodFailed := &partner.StoreSkuInfoWithErr{
StoreSkuInfo: storeSkuInfo,
ErrMsg: foodMap[v.VendorSkuID],
StoreID: storeID,
VendoreID: vendorID,
SyncType: syncType,
}
selectedStoreSkuList = append(selectedStoreSkuList, foodFailed)
}
}
}
}
return selectedStoreSkuList
}

View File

@@ -58,7 +58,8 @@ func (p *DefSingleStorePlatform) DeleteStoreAllCategories(ctx *jxcontext.Context
vendorCatIDs[k] = v.VendorCatID vendorCatIDs[k] = v.VendorCatID
} }
err = FreeBatchCategoryIDOp(func(vendorCatID string) (err error) { err = FreeBatchCategoryIDOp(func(vendorCatID string) (err error) {
return p.DeleteStoreCategory(ctx, storeID, vendorStoreID, vendorCatID, step) err2 := p.DeleteStoreCategory(ctx, storeID, vendorStoreID, vendorCatID, step)
return err2
}, ctx, task, vendorCatIDs, isContinueWhenError) }, ctx, task, vendorCatIDs, isContinueWhenError)
return nil, err return nil, err
}, len(levelList)) }, len(levelList))
@@ -230,6 +231,49 @@ func UnselectStoreSkuListByVendorSkuIDs(storeSkuList []*partner.StoreSkuInfo, ve
return selectedStoreSkuList return selectedStoreSkuList
} }
func GetErrMsg2FailedSingleList(storeSkuList interface{}, err error, storeID, vendorID int, syncType string) (failedList []*partner.StoreSkuInfoWithErr) {
if err != nil {
if errExt, ok := err.(*utils.ErrorWithCode); ok {
if storeSkuLists, ok := storeSkuList.([]*partner.StoreSkuInfo); ok {
storeSkuInfoWithErr := &partner.StoreSkuInfoWithErr{
StoreSkuInfo: storeSkuLists[0],
ErrMsg: errExt.ErrMsg(),
StoreID: storeID,
VendoreID: vendorID,
SyncType: syncType,
}
failedList = append(failedList, storeSkuInfoWithErr)
} else if storeSkuLists, ok := storeSkuList.([]*dao.StoreSkuSyncInfo); ok {
storeSkuInfo := &partner.StoreSkuInfo{
SkuID: storeSkuLists[0].SkuID,
VendorSkuID: storeSkuLists[0].VendorSkuID,
NameID: storeSkuLists[0].NameID,
VendorNameID: storeSkuLists[0].VendorNameID,
VendorPrice: storeSkuLists[0].VendorPrice,
Status: storeSkuLists[0].Status,
}
storeSkuInfoWithErr := &partner.StoreSkuInfoWithErr{
StoreSkuInfo: storeSkuInfo,
ErrMsg: errExt.ErrMsg(),
StoreID: storeID,
VendoreID: vendorID,
SyncType: syncType,
}
failedList = append(failedList, storeSkuInfoWithErr)
} else {
storeSkuInfoWithErr := &partner.StoreSkuInfoWithErr{
ErrMsg: errExt.ErrMsg(),
StoreID: storeID,
VendoreID: vendorID,
SyncType: syncType,
}
failedList = append(failedList, storeSkuInfoWithErr)
}
}
}
return failedList
}
func UnselectStoreSkuSyncListByVendorSkuIDs(storeSkuList []*dao.StoreSkuSyncInfo, vendorSkuIDs []string) (selectedStoreSkuList []*dao.StoreSkuSyncInfo) { func UnselectStoreSkuSyncListByVendorSkuIDs(storeSkuList []*dao.StoreSkuSyncInfo, vendorSkuIDs []string) (selectedStoreSkuList []*dao.StoreSkuSyncInfo) {
if len(vendorSkuIDs) > 0 { if len(vendorSkuIDs) > 0 {
vendorSkuIDMap := jxutils.StringList2Map(vendorSkuIDs) vendorSkuIDMap := jxutils.StringList2Map(vendorSkuIDs)

View File

@@ -91,6 +91,17 @@ func FilterMapByFieldList(mapData map[string]interface{}, fields []string) (vali
return valid, invalid return valid, invalid
} }
func FindMapAndStructMixed(mapData map[string]interface{}, obj interface{}) (valid map[string]interface{}) {
valid = make(map[string]interface{})
map2 := utils.Struct2FlatMap(obj)
for k, v := range map2 {
if mapData[k] != nil {
valid[k] = v
}
}
return valid
}
func IsValueEqual(value1, value2 interface{}) bool { func IsValueEqual(value1, value2 interface{}) bool {
if value1 == nil || value2 == nil { if value1 == nil || value2 == nil {
return value1 == value2 return value1 == value2