diff --git a/business/jxstore/act/act.go b/business/jxstore/act/act.go index 1b4032e17..b8c96d08b 100644 --- a/business/jxstore/act/act.go +++ b/business/jxstore/act/act.go @@ -952,7 +952,7 @@ func DeleteSkusFromAct(ctx *jxcontext.Context, vendorID int, actTypes, skuIDs [] return hint, err } -func ForceUpdateVendorPrice(ctx *jxcontext.Context, vendorID int, actType int, storeSkuList []*ActStoreSkuParam, isAsync bool) (hint string, err error) { +func ForceUpdateVendorPrice(ctx *jxcontext.Context, vendorID int, actType int, storeSkuList []*ActStoreSkuParam, lockTime time.Time, isAsync bool) (hint string, err error) { var wrongSkuList []*ActStoreSkuParam var storeSkuBindList []*model.StoreSkuBind @@ -986,7 +986,7 @@ func ForceUpdateVendorPrice(ctx *jxcontext.Context, vendorID int, actType int, s } } if storeSkuBind != nil { - dao.SetStoreSkuBindVendorPrice(storeSkuBind, vendorID, vendorPrice) + dao.SetStoreSkuBindVendorPrice(storeSkuBind, vendorID, vendorPrice, lockTime) if vendorID != model.VendorIDJX { dao.SetStoreSkuBindSyncStatus(storeSkuBind, vendorID, dao.GetStoreSkuBindSyncStatus(storeSkuBind, vendorID)|model.SyncFlagPriceMask) } diff --git a/business/jxstore/cms/store_sku.go b/business/jxstore/cms/store_sku.go index 0fcb3ba69..b8c193368 100644 --- a/business/jxstore/cms/store_sku.go +++ b/business/jxstore/cms/store_sku.go @@ -319,6 +319,12 @@ func getGetStoresSkusBaseSQL(db *dao.DaoDB, storeIDs, skuIDs []int, isFocus bool sqlParams = append(sqlParams, skuID) } } + if lockTimeStr, ok := params["lockTime"].(string); ok && lockTimeStr != "" { + if timeList, err2 := jxutils.BatchStr2Time(lockTimeStr); err2 == nil { + sql += " AND (t4.jd_lock_time > ? OR t4.mtwm_lock_time > ? OR t4.ebai_lock_time > ? OR t4.jx_lock_time > ?)" + sqlParams = append(sqlParams, timeList[0], timeList[0], timeList[0], timeList[0]) + } + } if isFocus { if params["fromStatus"] != nil { fromStatus := params["fromStatus"].(int) @@ -451,6 +457,7 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bo t4.ebai_id, t4.mtwm_id, t4.jd_sync_status, t4.ebai_sync_status, t4.mtwm_sync_status, t4.jd_price, t4.ebai_price, t4.mtwm_price, t4.jx_price, + t4.jd_lock_time, t4.ebai_lock_time, t4.mtwm_lock_time, t4.jx_lock_time, t4.status_sale_begin, t4.status_sale_end `, jdVendorIDField) + sql var tmpList []*tGetStoresSkusInfo diff --git a/business/jxstore/cms/sync_store_sku.go b/business/jxstore/cms/sync_store_sku.go index 4fb5e88f6..e23583131 100644 --- a/business/jxstore/cms/sync_store_sku.go +++ b/business/jxstore/cms/sync_store_sku.go @@ -235,6 +235,9 @@ func formalizeStoreSkuList(inSkuList []*dao.StoreSkuSyncInfo) []*dao.StoreSkuSyn func sku2Update(vendorID int, sku *dao.StoreSkuSyncInfo, syncStatus int8) (item *dao.KVUpdateItem) { kvs := map[string]interface{}{} + if !isSkuLockTimeValid(sku) { + kvs[dao.GetVendorLockTimeStructField(model.VendorNames[vendorID])] = nil + } if syncStatus&(model.SyncFlagDeletedMask|model.SyncFlagNewMask|model.SyncFlagModifiedMask) != 0 { if model.IsSyncStatusNew(syncStatus) { sku.SkuSyncStatus = 0 @@ -289,6 +292,10 @@ func updateStoreSku(db *dao.DaoDB, vendorID int, storeSkuList []*dao.StoreSkuSyn return num, err } +func isSkuLockTimeValid(sku *dao.StoreSkuSyncInfo) bool { + return sku.LockTime != nil && time.Now().Sub(*sku.LockTime) < 0 +} + func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bool, vendorID, storeID int, nameIDs, skuIDs, excludeSkuIDs []int, useVendorPriceDirectly, isContinueWhenError bool) (err error) { db := dao.GetDB() storeDetail, err := dao.GetStoreDetail(db, storeID, vendorID) @@ -335,7 +342,8 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo } now := jxutils.OperationTime2HourMinuteFormat(time.Now()) for _, sku := range skus { - if !useVendorPriceDirectly { + if !useVendorPriceDirectly && + !isSkuLockTimeValid(sku) { sku.VendorPrice = 0 } sku.MergedStatus = MergeSkuSaleStatusWithStoreOpTime(sku, storeDetail, now) diff --git a/business/model/dao/dao_utils.go b/business/model/dao/dao_utils.go index 8a36c2adc..eaca61326 100644 --- a/business/model/dao/dao_utils.go +++ b/business/model/dao/dao_utils.go @@ -160,6 +160,10 @@ func GetCategoryIDDBField(prefix string) string { return ConvertDBFieldPrefix(prefix) + "_category_id" } +func GetVendorLockTimeStructField(prefix string) string { + return ConvertStructFieldPrefix(prefix) + "LockTime" +} + func value2Value(srcValue, dstValue reflect.Value, copyType int) { srcType := srcValue.Type() for i := 0; i < srcType.NumField(); i++ { diff --git a/business/model/dao/store_sku.go b/business/model/dao/store_sku.go index 86b4bac83..cd3012df7 100644 --- a/business/model/dao/store_sku.go +++ b/business/model/dao/store_sku.go @@ -84,7 +84,9 @@ type StoreSkuSyncInfo struct { CatSyncStatus int8 VendorCatID string `orm:"column(vendor_cat_id)"` - VendorPrice int64 + VendorPrice int64 + LockTime *time.Time + MergedStatus int SkuName string StatusSaleBegin int16 `json:"statusSaleBegin"` //商品可售时间范围 @@ -170,6 +172,11 @@ type StoreSkuExt struct { MtwmPrice int `json:"mtwmPrice"` JxPrice int `json:"jxPrice"` + JdLockTime *time.Time `orm:"null" json:"jdLockTime,omitempty"` + EbaiLockTime *time.Time `orm:"null" json:"ebaiLockTime,omitempty"` + 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"` @@ -305,7 +312,7 @@ func newGetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty SELECT t14.vendor_id, t14.vendor_org_code, t1.id bind_id, t1.sku_id, t1.price, t1.unit_price, t1.status store_sku_status, - %s vendor_sku_id, t1.%s_sync_status sku_sync_status, t1.%s_price vendor_price, + %s vendor_sku_id, t1.%s_sync_status sku_sync_status, t1.%s_price vendor_price, t1.%s_lock_time lock_time, t1.store_id, t1.deleted_at bind_deleted_at,t1.status_sale_begin,t1.status_sale_end, t2.*, t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc, t3.ex_prefix, t3.ex_prefix_begin, t3.ex_prefix_end, @@ -314,7 +321,7 @@ func newGetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty t13.%s desc_img, t4.%s_category_id vendor_vendor_cat_id` fmtParams := []interface{}{ - skuVendorIDField, fieldPrefix, fieldPrefix, + skuVendorIDField, fieldPrefix, fieldPrefix, fieldPrefix, GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), @@ -512,7 +519,8 @@ func newGetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSync SELECT sm.vendor_id, sm.vendor_org_code, t1.id bind_id, t1.price, t1.unit_price, t1.status store_sku_status, - t1.%s_sync_status sku_sync_status, t1.store_id, t1.deleted_at bind_deleted_at, + t1.%s_sync_status sku_sync_status, t1.%s_price vendor_price, t1.%s_lock_time lock_time, + t1.store_id, t1.deleted_at bind_deleted_at, t2.*, t2.id sku_id, t2m.vendor_thing_id vendor_sku_id, t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc, t3.ex_prefix, t3.ex_prefix_begin, t3.ex_prefix_end, IF(t11.%s <> '', t11.%s, t3.img) img, @@ -547,7 +555,7 @@ func newGetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSync } fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) sql = fmt.Sprintf(sql, - fieldPrefix, + fieldPrefix, fieldPrefix, fieldPrefix, GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), @@ -1111,16 +1119,21 @@ func GetStoreSkuNamePrice(db *DaoDB) (storeSkuNamePriceList []*model.StoreSkuNam return storeSkuNamePriceList, err } -func SetStoreSkuBindVendorPrice(storeSkuBind *model.StoreSkuBind, vendorID int, vendorPrice int) { +func SetStoreSkuBindVendorPrice(storeSkuBind *model.StoreSkuBind, vendorID int, vendorPrice int, lockTime time.Time) { + pLockTime := utils.Time2Pointer(lockTime) switch vendorID { case model.VendorIDJD: storeSkuBind.JdPrice = vendorPrice + storeSkuBind.JdLockTime = pLockTime case model.VendorIDMTWM: storeSkuBind.MtwmPrice = vendorPrice + storeSkuBind.MtwmLockTime = pLockTime case model.VendorIDEBAI: storeSkuBind.EbaiPrice = vendorPrice + storeSkuBind.EbaiLockTime = pLockTime case model.VendorIDJX: storeSkuBind.JxPrice = vendorPrice + storeSkuBind.JxLockTime = pLockTime } } diff --git a/business/model/dao/store_sku_test.go b/business/model/dao/store_sku_test.go new file mode 100644 index 000000000..d787bb8c6 --- /dev/null +++ b/business/model/dao/store_sku_test.go @@ -0,0 +1,17 @@ +package dao + +import ( + "testing" + + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/globals" +) + +func TestGetFullStoreSkus(t *testing.T) { + skuList, err := GetFullStoreSkus(GetDB(), model.VendorIDJD, 100118) + if err != nil { + t.Fatal(err) + } + globals.SugarLogger.Debug(utils.Format4Output(skuList, false)) +} diff --git a/business/model/store_sku.go b/business/model/store_sku.go index 382a97b61..8a81ec9cb 100644 --- a/business/model/store_sku.go +++ b/business/model/store_sku.go @@ -94,22 +94,26 @@ type StoreSkuBind struct { Status int // ElmID int64 `orm:"column(elm_id);index"` - EbaiID int64 `orm:"column(ebai_id);index"` MtwmID int64 `orm:"column(mtwm_id)"` + EbaiID int64 `orm:"column(ebai_id);index"` // WscID int64 `orm:"column(wsc_id);index"` // 表示微盟skuId // WscID2 int64 `orm:"column(wsc_id2);index"` // 表示微盟goodsId // ElmSyncStatus int8 `orm:"default(2)"` JdSyncStatus int8 `orm:"default(2)"` - EbaiSyncStatus int8 `orm:"default(2)"` MtwmSyncStatus int8 `orm:"default(2)"` + EbaiSyncStatus int8 `orm:"default(2)"` // WscSyncStatus int8 `orm:"default(2)"` JdPrice int `json:"jdPrice"` - EbaiPrice int `json:"ebaiPrice"` MtwmPrice int `json:"mtwmPrice"` + EbaiPrice int `json:"ebaiPrice"` JxPrice int `json:"jxPrice"` - // WscPrice int `json:"wscPrice"` + + JdLockTime *time.Time `orm:"null" json:"jdLockTime"` + MtwmLockTime *time.Time `orm:"null" json:"mtwmLockTime"` + EbaiLockTime *time.Time `orm:"null" json:"ebaiLockTime"` + JxLockTime *time.Time `orm:"null" json:"jxLockTime"` AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"` diff --git a/business/partner/purchase/ebai/callback.go b/business/partner/purchase/ebai/callback.go index b041d5165..fd7c41714 100644 --- a/business/partner/purchase/ebai/callback.go +++ b/business/partner/purchase/ebai/callback.go @@ -5,9 +5,11 @@ import ( "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/globals" ) func OnCallbackMsg(msg *ebaiapi.CallbackMsg) (response *ebaiapi.CallbackResponse) { + globals.SugarLogger.Debugf("ebai OnCallbackMsg msg:%s", utils.Format4Output(msg, true)) if CurPurchaseHandler != nil { if orderID := GetOrderIDFromMsg(msg); orderID != "" { jxutils.CallMsgHandler(func() { diff --git a/business/partner/purchase/ebai/order.go b/business/partner/purchase/ebai/order.go index 3c1804856..a0bb3244d 100644 --- a/business/partner/purchase/ebai/order.go +++ b/business/partner/purchase/ebai/order.go @@ -400,7 +400,7 @@ func (p *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName // func (c *PurchaseHandler) onOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaiapi.CallbackResponse) { if c.isAfsMsg(msg) { - retVal = c.OnAfsOrderMsg(msg) + retVal = c.onAfsOrderMsg(msg) } else { status := c.callbackMsg2Status(msg) if partner.CurOrderManager.GetStatusDuplicatedCount(status) > 0 { diff --git a/controllers/act.go b/controllers/act.go index 21cc12fdd..8d05ff4de 100644 --- a/controllers/act.go +++ b/controllers/act.go @@ -295,8 +295,7 @@ func (c *ActController) RefreshPageActs() { // @router /DeleteSkusFromAct [delete] func (c *ActController) DeleteSkusFromAct() { c.callDeleteSkusFromAct(func(params *tActDeleteSkusFromActParams) (retVal interface{}, errCode string, err error) { - var skuIDs []int - var types []int + var skuIDs, types []int if err = jxutils.Strings2Objs(params.SkuIDs, &skuIDs, params.Types, &types); err == nil { retVal, err = act.DeleteSkusFromAct(params.Ctx, params.VendorID, types, skuIDs, params.IsAsync, params.IsContinueWhenError) } @@ -310,6 +309,7 @@ func (c *ActController) DeleteSkusFromAct() { // @Param type formData int true "活动类型,3:直降,4:秒杀(美团当前不支持秒杀)" // @Param vendorID formData int true "厂商ID,当前只支持,京东:0,京西(用于记录活动信息):9" // @Param actStoreSkuList formData string true "活动门店商品信息" +// @Param lockTime formData string false "平台价格锁定截止时间" // @Param isAsync formData bool false "是否异步,缺省否(暂时只支持同步)" // @Success 200 {object} controllers.CallResult // @Failure 200 {object} controllers.CallResult @@ -318,7 +318,10 @@ func (c *ActController) ForceUpdateVendorPrice() { c.callForceUpdateVendorPrice(func(params *tActForceUpdateVendorPriceParams) (retVal interface{}, errCode string, err error) { var actStoreSkuList []*act.ActStoreSkuParam if err = jxutils.Strings2Objs(params.ActStoreSkuList, &actStoreSkuList); err == nil { - retVal, err = act.ForceUpdateVendorPrice(params.Ctx, params.VendorID, params.Type, actStoreSkuList, params.IsAsync) + timeList, err2 := jxutils.BatchStr2Time(params.LockTime) + if err = err2; err == nil { + retVal, err = act.ForceUpdateVendorPrice(params.Ctx, params.VendorID, params.Type, actStoreSkuList, timeList[0], params.IsAsync) + } } return retVal, "", err }) diff --git a/controllers/cms_store_sku.go b/controllers/cms_store_sku.go index aeb1de9c0..71fe04087 100644 --- a/controllers/cms_store_sku.go +++ b/controllers/cms_store_sku.go @@ -43,6 +43,7 @@ type StoreSkuController struct { // @Param jdSyncStatus query int false "京东同步标识" // @Param ebaiSyncStatus query int false "饿百同步标识" // @Param mtwmSyncStatus query int false "美团外卖同步标识" +// @Param lockTime query string false "价格锁定时间" // @Success 200 {object} controllers.CallResult // @Failure 200 {object} controllers.CallResult // @router /GetStoreSkus [get] @@ -83,6 +84,7 @@ func (c *StoreSkuController) GetStoreSkus() { // @Param jdSyncStatus query int false "京东同步标识" // @Param ebaiSyncStatus query int false "饿百同步标识" // @Param mtwmSyncStatus query int false "美团外卖同步标识" +// @Param lockTime query string false "价格锁定时间" // @Success 200 {object} controllers.CallResult // @Failure 200 {object} controllers.CallResult // @router /GetStoresSkus [get,post]