From 7a312eb7e453221558b6d7a81fc1a5e168e75b78 Mon Sep 17 00:00:00 2001 From: gazebo Date: Sun, 19 Jan 2020 15:50:10 +0800 Subject: [PATCH] =?UTF-8?q?StoreSkuExt=E4=B8=AD=E6=B7=BB=E5=8A=A0VendorInf?= =?UTF-8?q?oMap=EF=BC=8C=E5=B0=86=E6=89=80=E6=9C=89=E5=B9=B3=E5=8F=B0?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84=E4=BF=A1=E6=81=AF=E7=A7=BB=E5=85=A5?= =?UTF-8?q?=E5=88=B0=E8=BF=99=E9=87=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/cms/store.go | 10 +-- business/jxstore/cms/store_sku.go | 112 +++++++++++++++------------- business/model/dao/store.go | 16 ++++ business/model/dao/store_sku.go | 117 +++++++++++++++++++++++++----- 4 files changed, 177 insertions(+), 78 deletions(-) diff --git a/business/jxstore/cms/store.go b/business/jxstore/cms/store.go index d96e212a7..b7c8340f1 100644 --- a/business/jxstore/cms/store.go +++ b/business/jxstore/cms/store.go @@ -407,14 +407,8 @@ func setStoreMapInfo(ctx *jxcontext.Context, db *dao.DaoDB, storesInfo *StoresIn return err } - storeMapMap := make(map[int][]*model.StoreMap) - for _, v := range storeMapList { - storeMapMap[v.StoreID] = append(storeMapMap[v.StoreID], v) - } - storeCourierMap := make(map[int][]*model.StoreCourierMap) - for _, v := range storeCourierList { - storeCourierMap[v.StoreID] = append(storeCourierMap[v.StoreID], v) - } + storeMapMap := dao.StoreMapList2Map(storeMapList) + storeCourierMap := dao.StoreCourierList2Map(storeCourierList) for _, v := range storesInfo.Stores { if briefLevel > 0 { diff --git a/business/jxstore/cms/store_sku.go b/business/jxstore/cms/store_sku.go index 923f48859..344641103 100644 --- a/business/jxstore/cms/store_sku.go +++ b/business/jxstore/cms/store_sku.go @@ -219,46 +219,47 @@ func getGetStoresSkusBaseSQL(db *dao.DaoDB, storeIDs, skuIDs []int, isFocus bool model.VendorIDJD, utils.DefaultTimeValue, // TODO 这里直接用JD有问题 model.ThingTypeSku, utils.DefaultTimeValue, } - if isAct { - sql += ` - JOIN ( - SELECT t2.store_id, t2.sku_id, - MIN(IF(t3.actual_act_price <= 0, NULL, t3.actual_act_price)) actual_act_price, /*non-zero min value*/ - MIN(IF(t2.earning_price <= 0, NULL, t2.earning_price)) earning_price /*non-zero min value*/ - FROM act t1 - JOIN act_store_sku t2 ON t2.act_id = t1.id AND t2.deleted_at = ? - JOIN act_store_sku_map t3 ON t3.bind_id = t2.id AND t3.act_id = t1.id AND (t3.sync_status & ? = 0 OR t1.type = ?) - JOIN act_map t4 ON t4.act_id = t1.id AND t4.vendor_id = t3.vendor_id AND t4.deleted_at = ? AND (t4.sync_status & ? = 0 OR t1.type = ?) - WHERE t1.deleted_at = ? AND t1.status = ? AND NOT (t1.begin_at > ? OR t1.end_at < ?)` - sqlParams = append(sqlParams, []interface{}{ - utils.DefaultTimeValue, - model.SyncFlagNewMask, - model.ActSkuFake, - utils.DefaultTimeValue, - model.SyncFlagNewMask, - model.ActSkuFake, - utils.DefaultTimeValue, - model.ActStatusCreated, - time.Now(), - time.Now(), - }) - if actVendorID >= 0 { - sql += " AND t1.vendor_mask & ? <> 0" - sqlParams = append(sqlParams, model.GetVendorMask(actVendorID)) + if isFocus { + if isAct { + sql += ` + JOIN ( + SELECT t2.store_id, t2.sku_id, + MIN(IF(t3.actual_act_price <= 0, NULL, t3.actual_act_price)) actual_act_price, /*non-zero min value*/ + MIN(IF(t2.earning_price <= 0, NULL, t2.earning_price)) earning_price /*non-zero min value*/ + FROM act t1 + JOIN act_store_sku t2 ON t2.act_id = t1.id AND t2.deleted_at = ? + JOIN act_store_sku_map t3 ON t3.bind_id = t2.id AND t3.act_id = t1.id AND (t3.sync_status & ? = 0 OR t1.type = ?) + JOIN act_map t4 ON t4.act_id = t1.id AND t4.vendor_id = t3.vendor_id AND t4.deleted_at = ? AND (t4.sync_status & ? = 0 OR t1.type = ?) + WHERE t1.deleted_at = ? AND t1.status = ? AND NOT (t1.begin_at > ? OR t1.end_at < ?)` + sqlParams = append(sqlParams, []interface{}{ + utils.DefaultTimeValue, + model.SyncFlagNewMask, + model.ActSkuFake, + utils.DefaultTimeValue, + model.SyncFlagNewMask, + model.ActSkuFake, + utils.DefaultTimeValue, + model.ActStatusCreated, + time.Now(), + time.Now(), + }) + if actVendorID >= 0 { + sql += " AND t1.vendor_mask & ? <> 0" + sqlParams = append(sqlParams, model.GetVendorMask(actVendorID)) + } + if len(storeIDs) > 0 { + sql += " AND t2.store_id IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")" + sqlParams = append(sqlParams, storeIDs) + } + if len(skuIDs) > 0 { + sql += " AND t2.sku_id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ")" + sqlParams = append(sqlParams, skuIDs) + } + sql += ` + GROUP BY 1,2 + ) ta ON ta.store_id = t3.id AND ta.sku_id = t2.id` } - if len(storeIDs) > 0 { - sql += " AND t2.store_id IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if len(skuIDs) > 0 { - sql += " AND t2.sku_id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - sql += ` - GROUP BY 1,2 - ) ta ON ta.store_id = t3.id AND ta.sku_id = t2.id` - } - if !isFocus { + } else { sql += " LEFT" } sql += ` @@ -526,21 +527,22 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bo storeName.Skus = append(storeName.Skus, &v.StoreSkuExt) } if err == nil { - if isSaleInfo { - beginTime := time.Now() - err = updateSaleInfo4StoreSkuName(ctx, db, storeIDs, skuIDs, params, skuNamesInfo, offset, pageSize) - globals.SugarLogger.Debugf("GetStoresSkusNew updateSaleInfo4StoreSkuName:%v", time.Now().Sub(beginTime)) - } - if err == nil { - if true { //!(offset == 0 && pageSize == model.UnlimitedPageSize) { - storeIDs, skuIDs = GetStoreAndSkuIDsFromInfo(skuNamesInfo) + if isFocus { + if isSaleInfo { + beginTime := time.Now() + err = updateSaleInfo4StoreSkuName(ctx, db, storeIDs, skuIDs, params, skuNamesInfo, offset, pageSize) + globals.SugarLogger.Debugf("GetStoresSkusNew updateSaleInfo4StoreSkuName:%v", time.Now().Sub(beginTime)) } - beginTime := time.Now() - err = dao.UpdateActPrice4StoreSkuNameNew(db, storeIDs, skuIDs, skuNamesInfo, actVendorID) - globals.SugarLogger.Debugf("GetStoresSkusNew updateActPrice4StoreSkuName:%v", time.Now().Sub(beginTime)) - if !isFocus { - err = updateUnitPrice4StoreSkuNameNew(db, skuNamesInfo) + if err == nil { + if true { //!(offset == 0 && pageSize == model.UnlimitedPageSize) { + storeIDs, skuIDs = GetStoreAndSkuIDsFromInfo(skuNamesInfo) + } + beginTime := time.Now() + err = dao.UpdateActPrice4StoreSkuNameNew(db, storeIDs, skuIDs, skuNamesInfo, actVendorID) + globals.SugarLogger.Debugf("GetStoresSkusNew updateActPrice4StoreSkuName:%v", time.Now().Sub(beginTime)) } + } else { + err = updateUnitPrice4StoreSkuNameNew(db, skuNamesInfo) } } // globals.SugarLogger.Debug(utils.Format4Output(skuNamesInfo, false)) @@ -1060,6 +1062,12 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs if globals.IsAddEvent { err = AddEventDetail(db, ctx, model.OperateDelete, skuBind.SkuID, model.ThingTypeSku, storeID, "", "") } + if globals.IsStoreSkuAct { + dao.DeleteEntity(db, &model.StoreSkuAct{ + StoreID: skuBind.StoreID, + SkuID: skuBind.SkuID, + }, "StoreID", "SkuID") + } if num, err = dao.DeleteEntityLogically(db, skuBind, map[string]interface{}{ model.FieldStatus: model.StoreSkuBindStatusDeleted, model.FieldJdSyncStatus: model.SyncFlagDeletedMask, diff --git a/business/model/dao/store.go b/business/model/dao/store.go index a22c5e767..97ee58b11 100644 --- a/business/model/dao/store.go +++ b/business/model/dao/store.go @@ -256,6 +256,22 @@ func GetStoresMapList(db *DaoDB, vendorIDs, storeIDs []int, status, isSync int, return GetStoresMapList2(db, vendorIDs, storeIDs, status, isSync, pricePack, false) } +func StoreMapList2Map(storeMapList []*model.StoreMap) (storeMapMap map[int][]*model.StoreMap) { + storeMapMap = make(map[int][]*model.StoreMap) + for _, v := range storeMapList { + storeMapMap[v.StoreID] = append(storeMapMap[v.StoreID], v) + } + return storeMapMap +} + +func StoreCourierList2Map(storeCourierList []*model.StoreCourierMap) (storeCourierMap map[int][]*model.StoreCourierMap) { + storeCourierMap = make(map[int][]*model.StoreCourierMap) + for _, v := range storeCourierList { + storeCourierMap[v.StoreID] = append(storeCourierMap[v.StoreID], v) + } + return storeCourierMap +} + // 此函数在检测到一个门店的所有平台状态一样,且不为StoreStatusOpened时, // 将平台门店状态全部改为StoreStatusOpened,则把京西门店状态改为之前那个统一的平台门店状态 func FormalizeStoreStatus(db *DaoDB, storeID, storeStatus int) (err error) { diff --git a/business/model/dao/store_sku.go b/business/model/dao/store_sku.go index f5f321b27..e64af667b 100644 --- a/business/model/dao/store_sku.go +++ b/business/model/dao/store_sku.go @@ -8,6 +8,7 @@ import ( "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/globals/refutil" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/globals" @@ -150,6 +151,28 @@ type StoreSkuNamesInfo struct { SkuNames []*StoreSkuNameExt `json:"skuNames"` } +type StoreSkuVendorInfo struct { + VendorID int `orm:"column(vendor_id)" json:"vendorID"` + + VendorSkuID string `orm:"column(vendor_sku_id)" json:"vendorSkuID"` + SyncStatus int8 `json:"syncStatus"` + VendorPrice int `json:"vendorPrice"` + LockTime *time.Time `json:"lockTime,omitempty"` + + ActPrice int `json:"actPrice"` + ActID int `orm:"column(act_id)" json:"actID"` + ActType int `orm:"column(act_type)" json:"actType"` + + EarningPrice int `json:"earningPrice"` + EarningActID int `orm:"column(earning_act_id)" json:"earningActID"` + + // 新活动信息 + VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"` + ActPercentage int `json:"actPercentage"` // 直降活动百分比 + ActSyncStatus int8 `orm:"default(2)" json:"actSyncStatus"` + VendorActPrice int64 `json:"vendorActPrice"` // 保存数据用,实际的活动价 +} + type StoreSkuExt struct { NameID int `orm:"column(name_id)" json:"nameID"` SkuID int `orm:"column(sku_id)" json:"id"` @@ -158,7 +181,6 @@ type StoreSkuExt struct { SkuSpecQuality float32 `json:"specQuality"` SkuSpecUnit string `orm:"size(8)" json:"specUnit"` // 质量或容量 Weight int `json:"weight"` // 重量/质量,单位为克,当相应的SkuName的SpecUnit为g或kg时,必须等于SpecQuality - JdID string `orm:"column(sku_jd_id);null;index" json:"jdID"` SkuStatus int `json:"status"` BindCreatedAt time.Time `orm:"auto_now_add;type(datetime)" json:"createdAt"` @@ -169,16 +191,24 @@ type StoreSkuExt struct { BindPrice int `json:"price"` // 单位为分,不用int64的原因是这里不需要累加 UnitPrice int `json:"unitPrice"` // 这个是一斤的门店商品价,放在这里的原因是避免额外增加一张store sku_name表,逻辑上要保证同一SKU NAME中的所有SKU这个字段的数据一致 StoreSkuStatus int `json:"storeSkuStatus"` + AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"` + StatusSaleBegin int16 `json:"statusSaleBegin"` //商品可售时间范围 + StatusSaleEnd int16 `json:"statusSaleEnd"` + + Count int `json:"count"` + Times int `json:"times"` + + // VendorInfoMap用于替换其之下的所有信息 + VendorInfoMap map[int]*StoreSkuVendorInfo `json:"vendorInfoMap,omitempty"` + + JdID string `orm:"column(sku_jd_id);null;index" json:"jdID"` EbaiID string `orm:"column(ebai_id);index" json:"ebaiID"` MtwmID string `orm:"column(mtwm_id)" json:"mtwmID"` // 这个也不是必须的,只是为了DAO取数据语句一致 - // WscID string `orm:"column(wsc_id);index" json:"wscID"` // 表示微盟skuId - // WscID2 string `orm:"column(wsc_id2);index" json:"wscID2"` // 表示微盟goodsId JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"` EbaiSyncStatus int8 `orm:"default(2)" json:"ebaiSyncStatus"` MtwmSyncStatus int8 `orm:"default(2)" json:"mtwmSyncStatus"` - // WscSyncStatus int8 `orm:"default(2)" json:"wscSyncStatus"` JdPrice int `json:"jdPrice"` EbaiPrice int `json:"ebaiPrice"` @@ -190,22 +220,12 @@ type StoreSkuExt struct { MtwmLockTime *time.Time `orm:"null" json:"mtwmLockTime,omitempty"` JxLockTime *time.Time `orm:"null" json:"jxLockTime,omitempty"` - AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"` - ActPrice int `json:"actPrice"` ActID int `orm:"column(act_id)" json:"actID"` ActType int `orm:"column(act_type)" json:"actType"` EarningPrice int `json:"earningPrice"` EarningActID int `orm:"column(earning_act_id)" json:"earningActID"` - - // RealEarningPrice int `json:"realEarningPrice"` - - StatusSaleBegin int16 `json:"statusSaleBegin"` //商品可售时间范围 - StatusSaleEnd int16 `json:"statusSaleEnd"` - - Count int `json:"count"` - Times int `json:"times"` } type SkuNameAndPlace struct { @@ -1199,13 +1219,33 @@ func SetStoreCatMapSyncStatus(storeCatMap *model.StoreSkuCategoryMap, vendorID i // skuIDs为空,会导致性能极低,所以要skuIDs必须有值 func UpdateActPrice4StoreSkuNameNew(db *DaoDB, storeIDs, skuIDs []int, skuNamesInfo *StoreSkuNamesInfo, actVendorID int) (err error) { - if len(skuIDs) == 0 { + if len(storeIDs) == 0 || len(skuIDs) == 0 { return nil } + var vendorIDs []int - if actVendorID >= 0 { - vendorIDs = []int{actVendorID} + var storeMapMap map[int][]*model.StoreMap + var storeSkuActMap map[int64]*model.StoreSkuAct + if !globals.IsStoreSkuAct { + if actVendorID >= 0 { + vendorIDs = []int{actVendorID} + } + } else { + storeMapList, err := GetStoresMapList(db, nil, storeIDs, model.StoreStatusAll, model.StoreIsSyncAll, "") + if err != nil { + return err + } + storeMapMap = StoreMapList2Map(storeMapList) + storeSkuActList, err2 := GetStoresSkusAct(db, storeIDs, skuIDs, nil, 0, 0) + if err = err2; err != nil { + return err + } + storeSkuActMap = make(map[int64]*model.StoreSkuAct) + for _, v := range storeSkuActList { + storeSkuActMap[jxutils.Combine2Int(int(jxutils.Combine2Int(v.StoreID, v.SkuID)), v.VendorID)] = v + } } + actStoreSkuList, err := GetEffectiveActStoreSkuInfo(db, 0, vendorIDs, model.ActTypeAll, storeIDs, skuIDs, time.Now(), time.Now()) if err != nil { globals.SugarLogger.Errorf("updateActPrice4StoreSkuNameNew can not get sku promotion info for error:%v", err) @@ -1221,7 +1261,7 @@ func UpdateActPrice4StoreSkuNameNew(db *DaoDB, storeIDs, skuIDs []int, skuNamesI v.ActPrice = int(actStoreSku.ActualActPrice) v.ActID = actStoreSku.ActID v.ActType = actStoreSku.Type - v.EarningPrice = int(jxutils.CaculateSkuEarningPrice(int64(v.ActPrice), int64(v.ActPrice), skuName.PayPercentage)) + v.EarningPrice = int(jxutils.CaculateSkuEarningPrice(int64(v.BindPrice), int64(v.ActPrice), skuName.PayPercentage)) } if actStoreSku := actStoreSkuMap4EarningPrice.GetActStoreSku(skuName.StoreID, v.SkuID, -1); actStoreSku != nil { v.EarningPrice = int(actStoreSku.EarningPrice) @@ -1232,6 +1272,47 @@ func UpdateActPrice4StoreSkuNameNew(db *DaoDB, storeIDs, skuIDs []int, skuNamesI v.EarningPrice = earningPrice } } + + if globals.IsStoreSkuAct { + v.VendorInfoMap = make(map[int]*StoreSkuVendorInfo) + for _, storeMap := range storeMapMap[skuName.StoreID] { + vendorID := storeMap.VendorID + vendorInfo := &StoreSkuVendorInfo{ + VendorID: vendorID, + } + vendorInfo.VendorPrice = refutil.GetObjFieldByName(v, GetVendorPriceStructField(model.VendorNames[vendorID])).(int) + lockTime, _ := refutil.GetObjFieldByName(v, GetVendorLockTimeStructField(model.VendorNames[vendorID])).(*time.Time) + vendorInfo.LockTime = lockTime + if vendorID != model.VendorIDJX { + vendorInfo.VendorSkuID = refutil.GetObjFieldByName(v, GetVendorThingIDStructField(model.VendorNames[vendorID])).(string) + vendorInfo.SyncStatus = refutil.GetObjFieldByName(v, GetSyncStatusStructField(model.VendorNames[vendorID])).(int8) + } + if storeSkuAct := storeSkuActMap[jxutils.Combine2Int(int(jxutils.Combine2Int(skuName.StoreID, v.SkuID)), vendorID)]; storeSkuAct != nil { + vendorInfo.VendorActID = storeSkuAct.VendorActID + vendorInfo.ActPercentage = storeSkuAct.ActPercentage + vendorInfo.ActSyncStatus = storeSkuAct.SyncStatus + vendorInfo.VendorActPrice = storeSkuAct.VendorActPrice + } + + if actStoreSku := actStoreSkuMap4Act.GetActStoreSku(skuName.StoreID, v.SkuID, vendorID); actStoreSku != nil { + vendorInfo.ActPrice = int(actStoreSku.ActualActPrice) + vendorInfo.ActID = actStoreSku.ActID + vendorInfo.VendorActID = actStoreSku.VendorActID + vendorInfo.ActType = actStoreSku.Type + vendorInfo.EarningPrice = int(jxutils.CaculateSkuEarningPrice(int64(v.BindPrice), int64(v.ActPrice), skuName.PayPercentage)) + } + if actStoreSku := actStoreSkuMap4EarningPrice.GetActStoreSku(skuName.StoreID, v.SkuID, vendorID); actStoreSku != nil { + vendorInfo.EarningPrice = int(actStoreSku.EarningPrice) + vendorInfo.EarningActID = actStoreSku.ActID + } else { + earningPrice := int(jxutils.CaculateSkuEarningPrice(int64(v.BindPrice), int64(v.BindPrice), skuName.PayPercentage)) + if v.EarningPrice == 0 || earningPrice < v.EarningPrice { + vendorInfo.EarningPrice = earningPrice + } + } + v.VendorInfoMap[vendorID] = vendorInfo + } + } } } else { skuName.UnitPrice = skuName.Price