From 2ca58bd5824d7ada300e4d9c4d8dcc1f3f3eea45 Mon Sep 17 00:00:00 2001 From: gazebo Date: Wed, 13 Nov 2019 10:49:55 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E7=94=9F=E6=88=90=E4=BA=AC=E8=A5=BF?= =?UTF-8?q?=E5=95=86=E5=9F=8E=E8=AE=A2=E5=8D=95=E5=88=9D=E5=A7=8B=E3=80=82?= =?UTF-8?q?=E3=80=82=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/partner/purchase/jx/localjx/order.go | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 business/partner/purchase/jx/localjx/order.go diff --git a/business/partner/purchase/jx/localjx/order.go b/business/partner/purchase/jx/localjx/order.go new file mode 100644 index 000000000..df843ee0f --- /dev/null +++ b/business/partner/purchase/jx/localjx/order.go @@ -0,0 +1,133 @@ +package localjx + +import ( + "fmt" + "time" + + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxutils" + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/business/model/dao" +) + +type JxSkuInfo struct { + SkuID int `json:"skuID"` + Count int `json:"count"` + + Price int64 `json:"price,omitempty"` // 原价 + SalePrice int64 `json:"salePrice,omitempty"` // 售卖价 +} + +type JxOrderInfo struct { + Skus []*JxSkuInfo `json:"skus"` + + ExpectedDeliveredTime *time.Time `orm:"type(datetime)" json:"expectedDeliveredTime"` // 预期送达时间 + + TotalPrice int64 `json:"totalPrice"` // 单位为分 订单总价 + FreightPrice int64 `json:"freightPrice"` // 单位为分 订单配送费 + OrderPrice int64 `json:"orderPrice"` // 单位为分 订单商品价格 + ActualPayPrice int64 `json:"actualPayPrice"` // 单位为分 顾客实际支付 +} + +func PreCreateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64, ExpectedDeliveredTime *time.Time) (outJxOrder *JxOrderInfo, err error) { + return outJxOrder, err +} + +func formalizeSkus(skus []*JxSkuInfo) (outSkus []*JxSkuInfo) { + skuMap := make(map[int]int) + for _, v := range skus { + skuMap[v.SkuID] += v.Count + } + for skuID, skuCount := range skuMap { + outSkus = append(outSkus, &JxSkuInfo{ + SkuID: skuID, + Count: skuCount, + }) + } + return outSkus +} + +func isTimeInOpTime(openTime1, closeTime1, openTime2, closeTime2 int16, time2Check time.Time) bool { + timeStrList := []string{ + jxutils.OperationTime2StrWithSecond(openTime1), + jxutils.OperationTime2StrWithSecond(closeTime1), + } + if openTime1 > 0 { + timeStrList = append(timeStrList, + jxutils.OperationTime2StrWithSecond(openTime2), + jxutils.OperationTime2StrWithSecond(closeTime2), + ) + } + checkTimeStr := utils.Time2TimeStr(time2Check) + for i := 0; i < len(timeStrList); i += 2 { + if checkTimeStr >= timeStrList[i] && checkTimeStr <= timeStrList[i+1] { + return true + } + } + return false +} + +func generateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, storeID int, addressID int64, ExpectedDeliveredTime *time.Time) (outJxOrder *JxOrderInfo, err error) { + db := dao.GetDB() + + // 配送范围检查 + storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJX) + if err != nil { + return nil, err + } + addressList, _, err := dao.QueryUserDeliveryAddress(db, addressID, []string{ctx.GetUserID()}, 0, 0) + if err != nil { + return nil, err + } + if len(addressList) == 0 { + return nil, fmt.Errorf("地址ID不正确") + } + deliveryAddress := addressList[0] + if distance := jxutils.Point2StoreDistance(deliveryAddress.Lng, deliveryAddress.Lat, storeDetail.Lng, storeDetail.Lat, storeDetail.DeliveryRangeType, storeDetail.DeliveryRange); distance == 0 { + return nil, fmt.Errorf("送货地址:%s不在门店%s的配送范围", deliveryAddress.DetailAddress, storeDetail.Name) + } + + // 营业状态及时间检查 + if storeDetail.Status == model.StoreStatusDisabled { + return nil, fmt.Errorf("门店:%s状态是:%s", storeDetail.Name, model.StoreStatusName[storeDetail.Status]) + } + checkTime := time.Now() + if ExpectedDeliveredTime == nil { + if storeDetail.Status != model.StoreStatusOpened { + return nil, fmt.Errorf("门店:%s不是营业状态,状态是:%s", storeDetail.Name, model.StoreStatusName[storeDetail.Status]) + } + } else { + checkTime = *ExpectedDeliveredTime + } + if !isTimeInOpTime(storeDetail.OpenTime1, storeDetail.CloseTime1, storeDetail.OpenTime2, storeDetail.CloseTime2, checkTime) { + return nil, fmt.Errorf("门店:%s不在营业时间范围", storeDetail.Name) + } + + skus := formalizeSkus(jxOrder.Skus) + var skuIDs []int + for _, v := range skus { + skuIDs = append(skuIDs, v.SkuID) + } + storeSkuList, err := dao.GetStoresSkusInfo(db, []int{storeID}, skuIDs) + if err != nil { + return nil, err + } + storeSkuMap := make(map[int]*model.StoreSkuBind) + for _, v := range storeSkuList { + storeSkuMap[v.SkuID] = v + } + + outJxOrder = &JxOrderInfo{} + for _, v := range skus { + outJxOrder.Skus = append(outJxOrder.Skus, &JxSkuInfo{ + SkuID: v.SkuID, + Count: v.Count, + Price: v.Price, + SalePrice: v.SalePrice, + }) + outJxOrder.TotalPrice += int64(v.Count) * v.SalePrice + } + + return outJxOrder, err +} From 7f231d1f6ae83ec9617858f51ea887bcb9b75845 Mon Sep 17 00:00:00 2001 From: gazebo Date: Wed, 13 Nov 2019 15:16:11 +0800 Subject: [PATCH 2/5] =?UTF-8?q?StoreSkuBind=E6=B7=BB=E5=8A=A0JxPrice?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/cms/cms.go | 6 ++- business/jxstore/cms/store_sku.go | 65 ++++++++++++++++++++------ business/jxstore/cms/sync_store_sku.go | 5 +- business/jxutils/jxutils_cms.go | 48 +++++++++++++------ business/jxutils/jxutils_cms_test.go | 44 +++++++++++++++++ business/model/const.go | 12 +++-- business/model/dao/store.go | 2 +- business/model/store_sku.go | 2 +- 8 files changed, 146 insertions(+), 38 deletions(-) diff --git a/business/jxstore/cms/cms.go b/business/jxstore/cms/cms.go index 1364ad65b..d5acfc8aa 100644 --- a/business/jxstore/cms/cms.go +++ b/business/jxstore/cms/cms.go @@ -354,7 +354,11 @@ func UpdateConfig(ctx *jxcontext.Context, key, configType, value string) (hint s vendorStoreMap[v.VendorID] = append(vendorStoreMap[v.VendorID], v.StoreID) } for vendorID, storeIDs := range vendorStoreMap { - dao.SetStoreSkuSyncStatus(db, vendorID, storeIDs, nil, model.SyncFlagPriceMask) + if vendorID != model.VendorIDJX { + dao.SetStoreSkuSyncStatus(db, vendorID, storeIDs, nil, model.SyncFlagPriceMask) + } else { + ReCalculateJxPrice(ctx, storeIDs) + } } // for _, v := range storeMapList { // if _, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, &model.StoreSkuBind{}, nil, ctx.GetUserName(), map[string]interface{}{ diff --git a/business/jxstore/cms/store_sku.go b/business/jxstore/cms/store_sku.go index f9e8bf733..3dc915670 100644 --- a/business/jxstore/cms/store_sku.go +++ b/business/jxstore/cms/store_sku.go @@ -66,7 +66,7 @@ type StoreSkuExt struct { JdPrice int `json:"jdPrice"` EbaiPrice int `json:"ebaiPrice"` MtwmPrice int `json:"mtwmPrice"` - // WscPrice int `json:"wscPrice"` + JxPrice int `json:"jxPrice"` AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"` @@ -198,7 +198,8 @@ func getGetStoresSkusBaseSQL(db *dao.DaoDB, storeIDs, skuIDs []int, isFocus bool sql += ` JOIN ( SELECT t2.store_id, t2.sku_id, - MIN(IF(t3.actual_act_price = 0, NULL, t3.actual_act_price)) actual_act_price, MIN(IF(t2.earning_price = 0, NULL, t2.earning_price)) earning_price /*non-zero min value*/ + 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 = ?) @@ -443,7 +444,7 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bo 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.jd_sync_status, t4.ebai_sync_status, t4.mtwm_sync_status, - t4.jd_price, t4.ebai_price, t4.mtwm_price + t4.jd_price, t4.ebai_price, t4.mtwm_price, t4.jx_price ` + sql var tmpList []*tGetStoresSkusInfo beginTime := time.Now() @@ -924,6 +925,12 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs } }() for _, storeID := range storeIDs { + // todo 可以考虑在需要更新价格再获取 + storeDetail, err := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDJX) + if err != nil { + dao.Rollback(db) + return nil, err + } for _, skuBindInfo := range skuBindInfos { // 关注且没有给价时,需要尝试从store_sku_bind中得到已有的单价 needGetExistingUnitPrice := skuBindInfo.UnitPrice == 0 && skuBindInfo.IsFocus == 1 @@ -1001,6 +1008,7 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs Price: jxutils.CaculateSkuPrice(unitPrice, v.SpecQuality, v.SpecUnit, v.SkuNameUnit), Status: model.StoreSkuBindStatusDontSale, // 缺省不可售? } + skuBind.JxPrice = jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), skuBind.Price) if tmpStatus := getSkuSaleStatus(inSkuBind, skuBindInfo); tmpStatus != model.StoreSkuBindStatusNA { skuBind.Status = tmpStatus } @@ -1048,9 +1056,11 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs if skuBindInfo.UnitPrice != 0 && isCanChangePrice { // 这里是否需要加此条件限制 skuBind.UnitPrice = unitPrice skuBind.Price = jxutils.CaculateSkuPrice(unitPrice, v.SpecQuality, v.SpecUnit, v.SkuNameUnit) + skuBind.JxPrice = jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), skuBind.Price) setStoreSkuBindStatus(skuBind, model.SyncFlagPriceMask) updateFieldMap["UnitPrice"] = 1 updateFieldMap["Price"] = 1 + updateFieldMap["JxPrice"] = 1 } // todo 这里应该是不需处理这个信息的吧? // if inSkuBind != nil && inSkuBind.EbaiID != 0 { @@ -1267,6 +1277,7 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode SET t1.last_operator = ?, t1.updated_at = ?, t1.price = t1.price * ? / 100, + t1.jx_price = t1.jx_price * ? / 100, t1.unit_price = t1.unit_price * ? / 100, t1.jd_sync_status = t1.jd_sync_status | ?, t1.mtwm_sync_status = t1.mtwm_sync_status | ?, @@ -1281,6 +1292,7 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode now, pricePercentage, pricePercentage, + pricePercentage, model.SyncFlagPriceMask, model.SyncFlagPriceMask, model.SyncFlagPriceMask, @@ -1307,13 +1319,14 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode JOIN sku t2 ON t1.sku_id = t2.id/* AND t2.deleted_at = ?*/ JOIN sku_name t3 ON t2.name_id = t3.id/* AND t2.deleted_at = ?*/ LEFT JOIN sku_category t4 ON t3.category_id = t4.id AND t2.deleted_at = ? - SET t1.deleted_at = ?, - t1.updated_at = ?, - t1.last_operator = ?, - t1.status = ?, - t1.jd_sync_status = IF((t1.jd_sync_status & ?) <> 0, 0, ?), - t1.mtwm_sync_status = IF((t1.mtwm_sync_status & ?) <> 0, 0, ?), - t1.ebai_sync_status = IF((t1.ebai_sync_status & ?) <> 0, 0, ?) + SET + t1.deleted_at = ?, + t1.updated_at = ?, + t1.last_operator = ?, + t1.status = ?, + t1.jd_sync_status = IF((t1.jd_sync_status & ?) <> 0, 0, ?), + t1.mtwm_sync_status = IF((t1.mtwm_sync_status & ?) <> 0, 0, ?), + t1.ebai_sync_status = IF((t1.ebai_sync_status & ?) <> 0, 0, ?) WHERE t1.store_id = ? AND t1.deleted_at = ? AND t0.id IS NULL ` sqlDeleteParams := []interface{}{ @@ -1356,10 +1369,12 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode JOIN sku t2 ON t1.sku_id = t2.id/* AND t2.deleted_at = ?*/ JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/ LEFT JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ? - SET t1.last_operator = ?, + SET + t1.last_operator = ?, t1.updated_at = ?, t1.sub_store_id = 0, t1.price = IF(t0.price * ? / 100 > 0, t0.price * ? / 100, 1), + t1.jx_price = IF(t0.jx_price * ? / 100 > 0, t0.jx_price * ? / 100, 1), t1.unit_price = IF(t0.unit_price * ? / 100 > 0, t0.unit_price * ? / 100, 1), t1.status = IF(? = 0, t1.status, t0.status), t1.jd_sync_status = t1.jd_sync_status | ?, @@ -1379,6 +1394,8 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode pricePercentage, pricePercentage, pricePercentage, + pricePercentage, + pricePercentage, isModifyStatus, syncStatus, syncStatus, @@ -1397,10 +1414,11 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode // 添加toStore中不存在,但fromStore存在的 sql = ` - INSERT INTO store_sku_bind(created_at, updated_at, last_operator, deleted_at, store_id, sku_id, sub_store_id, price, unit_price, status, + INSERT INTO store_sku_bind(created_at, updated_at, last_operator, deleted_at, store_id, sku_id, sub_store_id, price, jx_price, unit_price, status, jd_sync_status, ebai_sync_status, mtwm_sync_status) SELECT ?, ?, ?, ?, ?, - t1.sku_id, 0, IF(t1.price * ? / 100 > 0, t1.price * ? / 100, 1), IF(t1.unit_price * ? / 100 > 0, t1.unit_price * ? / 100, 1), + t1.sku_id, 0, + IF(t1.price * ? / 100 > 0, t1.price * ? / 100, 1), IF(t1.jx_price * ? / 100 > 0, t1.jx_price * ? / 100, 1), IF(t1.unit_price * ? / 100 > 0, t1.unit_price * ? / 100, 1), IF(? = 0, ?, t1.status), ?, ?, ? FROM store_sku_bind t1 JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ? @@ -1415,6 +1433,8 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode pricePercentage, pricePercentage, pricePercentage, + pricePercentage, + pricePercentage, isModifyStatus, model.SkuStatusDontSale, model.SyncFlagNewMask, @@ -2045,3 +2065,22 @@ func AutoSaleStoreSku(ctx *jxcontext.Context, storeIDs []int, isNeedSync bool) ( } return err } + +func ReCalculateJxPrice(ctx *jxcontext.Context, storeIDs []int) (err error) { + db := dao.GetDB() + for _, storeID := range storeIDs { + if storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJX); err == nil { + if storeSkuList, err := dao.GetStoresSkusInfo(db, []int{storeID}, nil); err == nil { + for _, skuBind := range storeSkuList { + skuBind.JxPrice = jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), skuBind.Price) + dao.UpdateEntity(db, skuBind) + } + } else { + return err + } + } else { + return err + } + } + return err +} diff --git a/business/jxstore/cms/sync_store_sku.go b/business/jxstore/cms/sync_store_sku.go index cf92145b1..d63cf40d9 100644 --- a/business/jxstore/cms/sync_store_sku.go +++ b/business/jxstore/cms/sync_store_sku.go @@ -213,8 +213,7 @@ func storeSkuSyncInfo2Bare(inSku *dao.StoreSkuSyncInfo) (outSku *partner.StoreSk func calVendorPrice4StoreSku(inSku *dao.StoreSkuSyncInfo, pricePercentagePack model.PricePercentagePack, pricePercentage int) (outSku *dao.StoreSkuSyncInfo) { if inSku.VendorPrice <= 0 { // 避免重新计算 - pricePercentage2, priceAdd2 := jxutils.GetPricePercentage(pricePercentagePack, int(inSku.Price), pricePercentage) - inSku.VendorPrice = int64(jxutils.CaculateSkuVendorPrice(int(inSku.Price), pricePercentage2, priceAdd2)) + inSku.VendorPrice = int64(jxutils.CaculatePriceByPricePack(pricePercentagePack, pricePercentage, int(inSku.Price))) if inSku.VendorPrice <= 0 { inSku.VendorPrice = 1 // 最少1分钱 } @@ -348,7 +347,7 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo calVendorPrice4StoreSku(sku, storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage)) if singleStoreHandler == nil { sku.StoreSkuSyncStatus |= model.SyncFlagSaleMask | model.SyncFlagPriceMask - bareSku = storeSkuSyncInfo2Bare(calVendorPrice4StoreSku(sku, storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage))) + bareSku = storeSkuSyncInfo2Bare(sku) stockList = append(stockList, bareSku) priceList = append(priceList, bareSku) if sku.MergedStatus == model.SkuStatusNormal { diff --git a/business/jxutils/jxutils_cms.go b/business/jxutils/jxutils_cms.go index 5c54e00e4..874682300 100644 --- a/business/jxutils/jxutils_cms.go +++ b/business/jxutils/jxutils_cms.go @@ -245,10 +245,15 @@ func CaculateUnitPrice(skuPrice int, specQuality float32, specUnit string, skuNa return unitPrice } -func CaculateSkuVendorPrice(price, percentage, priceAdd int) (vendorPrice int) { - if percentage <= 10 || percentage >= 400 { - percentage = 100 +func ConstrainPricePercentage(percentage int) int { + if percentage <= model.MinVendorPricePercentage || percentage >= model.MaxVendorPricePercentage { + percentage = model.DefVendorPricePercentage } + return percentage +} + +func CaculateSkuVendorPrice(price, percentage, priceAdd int) (vendorPrice int) { + percentage = ConstrainPricePercentage(percentage) vendorPrice = int(math.Round(float64(price*percentage)/100)) + priceAdd if vendorPrice < 1 { vendorPrice = 1 @@ -257,9 +262,7 @@ func CaculateSkuVendorPrice(price, percentage, priceAdd int) (vendorPrice int) { } func CaculateSkuPriceFromVendor(vendorPrice, percentage, priceAdd int) (price int) { - if percentage <= 10 || percentage >= 400 { - percentage = 100 - } + percentage = ConstrainPricePercentage(percentage) price = int(math.Round(float64(vendorPrice-priceAdd) * 100 / float64(percentage))) if price < 0 { price = 0 @@ -269,18 +272,28 @@ func CaculateSkuPriceFromVendor(vendorPrice, percentage, priceAdd int) (price in func GetPricePercentage(l model.PricePercentagePack, price int, defPricePercentage int) (pricePercentage, priceAdd int) { pricePercentage = defPricePercentage - if len(l) > 0 { - var lastItem *model.PricePercentageItem - for _, v := range l { - if v.BeginPrice > price { + itemLen := len(l) + if itemLen > 0 { + low := 0 + high := itemLen - 1 + mid := 0 + for low <= high { + mid = low + (high-low)/2 + if mid == 0 || mid == itemLen-1 { break } - lastItem = v - } - if lastItem != nil { - pricePercentage = lastItem.PricePercentage - priceAdd = lastItem.PriceAdd + if price >= l[mid].BeginPrice { + if price < l[mid+1].BeginPrice { + break + } else { + low = mid + 1 + } + } else { + high = mid - 1 + } } + pricePercentage = l[mid].PricePercentage + priceAdd = l[mid].PriceAdd } return pricePercentage, priceAdd } @@ -303,6 +316,11 @@ func GetPricePercentageByVendorPrice(l model.PricePercentagePack, vendorPrice in return pricePercentage, priceAdd } +func CaculatePriceByPricePack(l model.PricePercentagePack, defPricePercentage, price int) (outPrice int) { + pricePercentage, priceAdd := GetPricePercentage(l, price, defPricePercentage) + return CaculateSkuVendorPrice(price, pricePercentage, priceAdd) +} + func IsSkuSpecial(specQuality float32, specUnit string) bool { return int(specQuality) == model.SpecialSpecQuality && (specUnit == model.SpecialSpecUnit || specUnit == model.SpecialSpecUnit2) } diff --git a/business/jxutils/jxutils_cms_test.go b/business/jxutils/jxutils_cms_test.go index d447b160e..90bcd437e 100644 --- a/business/jxutils/jxutils_cms_test.go +++ b/business/jxutils/jxutils_cms_test.go @@ -164,3 +164,47 @@ func TestCaculateSkuPrice(t *testing.T) { } } } + +func TestGetPricePercentage(t *testing.T) { + type tTestInfo struct { + DesiredPrice int + UnitPrice int + SpecQuality float32 + SpecUnit string + Unit string + } + l := []*model.PricePercentageItem{ + &model.PricePercentageItem{ + BeginPrice: 0, + PricePercentage: 0, + PriceAdd: 0, + }, + &model.PricePercentageItem{ + BeginPrice: 10, + PricePercentage: 10, + PriceAdd: 1, + }, + &model.PricePercentageItem{ + BeginPrice: 20, + PricePercentage: 20, + PriceAdd: 2, + }, + &model.PricePercentageItem{ + BeginPrice: 30, + PricePercentage: 30, + PriceAdd: 3, + }, + } + for _, v := range [][]int{ + []int{0, 0, 0, 0}, + []int{30, 3, 40, 0}, + []int{20, 2, 25, 0}, + []int{10, 1, 10, 0}, + } { + pricePercentage, priceAdd := GetPricePercentage(l, v[2], v[3]) + if pricePercentage != v[0] || priceAdd != v[1] { + t.Errorf("price:%d, defPricePercentage:%d, expected pricePercentage:%d, priceAdd:%d, actual pricePercentage:%d, priceAdd:%d", + v[2], v[3], v[0], v[1], pricePercentage, priceAdd) + } + } +} diff --git a/business/model/const.go b/business/model/const.go index d055752f7..1a6030675 100644 --- a/business/model/const.go +++ b/business/model/const.go @@ -307,6 +307,14 @@ const ( AfsTypeFullRefund = 2 // 全额退款 ) +const ( + DefaultEarningPricePercentage = 70 // 门店缺省结算百分比 + + MinVendorPricePercentage = 10 + DefVendorPricePercentage = 100 // 平台缺省调价比例 + MaxVendorPricePercentage = 400 +) + func IsPurchaseVendorExist(vendorID int) bool { _, ok := VendorNames[vendorID] return ok && vendorID >= VendorIDPurchaseBegin && vendorID <= VendorIDPurchaseEnd @@ -358,7 +366,3 @@ func WaybillVendorID2Mask(vendorID int) (mask int8) { func IsAfsOrderFinalStatus(status int) bool { return status >= AfsOrderStatusFinished && status <= AfsOrderStatusFailed } - -const ( - DefaultEarningPricePercentage = 70 // 门店缺省结算百分比 -) diff --git a/business/model/dao/store.go b/business/model/dao/store.go index c9a63b540..75f0234a7 100644 --- a/business/model/dao/store.go +++ b/business/model/dao/store.go @@ -100,7 +100,7 @@ func getStoreDetail(db *DaoDB, storeID, vendorID int, vendorStoreID string) (sto storeDetail.FreightDeductionPackObj = FreightDeductionPack2Obj(storeDetail.FreightDeductionPackStr) if storeDetail.VendorStoreID == "" { storeDetail.VendorStatus = storeDetail.Status - storeDetail.PricePercentage = 100 + storeDetail.PricePercentage = model.DefVendorPricePercentage storeDetail.AutoPickup = 1 storeDetail.DeliveryType = model.StoreDeliveryTypeByStore storeDetail.DeliveryCompetition = 1 diff --git a/business/model/store_sku.go b/business/model/store_sku.go index 310697fcc..9147b3646 100644 --- a/business/model/store_sku.go +++ b/business/model/store_sku.go @@ -108,7 +108,7 @@ type StoreSkuBind struct { JdPrice int `json:"jdPrice"` EbaiPrice int `json:"ebaiPrice"` MtwmPrice int `json:"mtwmPrice"` - // JxPrice int `json:"jxPrice"` + JxPrice int `json:"jxPrice"` // WscPrice int `json:"wscPrice"` AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"` From ae5a923d3865876b89c93eb0315fc47b5a82abbe Mon Sep 17 00:00:00 2001 From: gazebo Date: Wed, 13 Nov 2019 16:22:15 +0800 Subject: [PATCH 3/5] =?UTF-8?q?GetStoreSkus=E6=B7=BB=E5=8A=A0=E5=8F=82?= =?UTF-8?q?=E6=95=B0=EF=BC=9AactVendorID=E8=A1=A8=E7=A4=BA=E8=A6=81?= =?UTF-8?q?=E5=8F=96=E5=93=AA=E4=B8=AA=E5=B9=B3=E5=8F=B0=E7=9A=84=E6=B4=BB?= =?UTF-8?q?=E5=8A=A8=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/cms/store_sku.go | 24 +++++++++++++++++++----- controllers/cms_store_sku.go | 2 ++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/business/jxstore/cms/store_sku.go b/business/jxstore/cms/store_sku.go index 3dc915670..88c6833da 100644 --- a/business/jxstore/cms/store_sku.go +++ b/business/jxstore/cms/store_sku.go @@ -70,8 +70,12 @@ type StoreSkuExt struct { AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"` - ActPrice int `json:"actPrice"` - EarningPrice int `json:"earningPrice"` + ActPrice int `json:"actPrice"` + ActID int `orm:"column(act_id)" json:"actID"` + + EarningPrice int `json:"earningPrice"` + EarningActID int `orm:"column(earning_act_id)" json:"earningActID"` + RealEarningPrice int `json:"realEarningPrice"` Count int `json:"count"` @@ -487,8 +491,12 @@ func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bo if true { //!(offset == 0 && pageSize == model.UnlimitedPageSize) { storeIDs, skuIDs = GetStoreAndSkuIDsFromInfo(skuNamesInfo) } + actVendorID := -1 + if params["actVendorID"] != nil { + actVendorID = int(utils.Interface2Int64WithDefault(params["actVendorID"], -1)) + } beginTime := time.Now() - err = updateActPrice4StoreSkuNameNew(db, storeIDs, skuIDs, skuNamesInfo) + err = updateActPrice4StoreSkuNameNew(db, storeIDs, skuIDs, skuNamesInfo, actVendorID) globals.SugarLogger.Debugf("GetStoresSkusNew updateActPrice4StoreSkuName:%v", time.Now().Sub(beginTime)) if !isFocus { err = updateUnitPrice4StoreSkuNameNew(db, skuNamesInfo) @@ -535,11 +543,15 @@ func updateUnitPrice4StoreSkuNameNew(db *dao.DaoDB, skuNamesInfo *StoreSkuNamesI } // skuIDs为空,会导致性能极低,所以要skuIDs必须有值 -func updateActPrice4StoreSkuNameNew(db *dao.DaoDB, storeIDs, skuIDs []int, skuNamesInfo *StoreSkuNamesInfo) (err error) { +func updateActPrice4StoreSkuNameNew(db *dao.DaoDB, storeIDs, skuIDs []int, skuNamesInfo *StoreSkuNamesInfo, actVendorID int) (err error) { if len(skuIDs) == 0 { return nil } - actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, nil, storeIDs, skuIDs, time.Now(), time.Now()) + var vendorIDs []int + if actVendorID >= 0 { + vendorIDs = []int{actVendorID} + } + actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, vendorIDs, storeIDs, skuIDs, time.Now(), time.Now()) if err != nil { globals.SugarLogger.Errorf("updateActPrice4StoreSkuNameNew can not get sku promotion info for error:%v", err) return err @@ -552,9 +564,11 @@ func updateActPrice4StoreSkuNameNew(db *dao.DaoDB, storeIDs, skuIDs []int, skuNa for _, v := range skuName.Skus2 { if actStoreSku := actStoreSkuMap4Act.GetActStoreSku(skuName.StoreID, v.SkuID, -1); actStoreSku != nil { v.ActPrice = int(actStoreSku.ActualActPrice) + v.ActID = actStoreSku.ActID } if actStoreSku := actStoreSkuMap4EarningPrice.GetActStoreSku(skuName.StoreID, v.SkuID, -1); actStoreSku != nil { v.EarningPrice = int(actStoreSku.EarningPrice) + v.EarningActID = actStoreSku.ActID } v.RealEarningPrice = v.EarningPrice diff --git a/controllers/cms_store_sku.go b/controllers/cms_store_sku.go index 9271ef80e..3aa15fb22 100644 --- a/controllers/cms_store_sku.go +++ b/controllers/cms_store_sku.go @@ -40,6 +40,7 @@ type StoreSkuController struct { // @Param pageSize query int false "门店列表页大小(缺省为50,-1表示全部)" // @Param isBySku query bool false "是否按SKU分拆" // @Param isAct query bool false "是否活动商品(包括正常活动与补贴)" +// @Param actVendorID query int false "要得到哪个平台的活动信息(缺省不限制,非零最小值)" // @Param jdSyncStatus query int false "京东同步标识" // @Param ebaiSyncStatus query int false "饿百同步标识" // @Param mtwmSyncStatus query int false "美团外卖同步标识" @@ -79,6 +80,7 @@ func (c *StoreSkuController) GetStoreSkus() { // @Param pageSize query int false "门店列表页大小(缺省为50,-1表示全部)" // @Param isBySku query bool false "是否按SKU分拆" // @Param isAct query bool false "是否活动商品(包括正常活动与补贴)" +// @Param actVendorID query int false "要得到哪个平台的活动信息(缺省不限制,非零最小值)" // @Param jdSyncStatus query int false "京东同步标识" // @Param ebaiSyncStatus query int false "饿百同步标识" // @Param mtwmSyncStatus query int false "美团外卖同步标识" From 5935c94aca1bb612a7721dcbb3dc2e4072fa6e74 Mon Sep 17 00:00:00 2001 From: gazebo Date: Wed, 13 Nov 2019 17:30:54 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E9=81=BF=E5=85=8D=E4=BB=B7=E6=A0=BC?= =?UTF-8?q?=E5=8C=85=E5=9B=A0=E4=B8=BA=E6=9C=89=E5=B0=8F=E6=95=B0=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/model/dao/store.go | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/business/model/dao/store.go b/business/model/dao/store.go index 75f0234a7..a603c7856 100644 --- a/business/model/dao/store.go +++ b/business/model/dao/store.go @@ -295,15 +295,31 @@ func GetRebindPrinterStoreList(db *DaoDB) (storeList []*model.Store, err error) return storeList, err } +// 容错用 +type tPricePercentageItemFloat struct { + BeginPrice float64 `json:"beginPrice"` // 起始价格区间(包括) + PricePercentage float64 `json:"pricePercentage"` // 调价比例 + PriceAdd float64 `json:"priceAdd"` // 调价额定值 +} + func PricePercentagePack2Obj(packStr string) (obj model.PricePercentagePack) { if packStr != "" { - if err := utils.UnmarshalUseNumber([]byte(packStr), &obj); err == nil { - for _, v := range obj { - if v.PricePercentage >= 500 || v.PricePercentage <= 80 { - return nil + var floatObj []*tPricePercentageItemFloat + if err := utils.UnmarshalUseNumber([]byte(packStr), &floatObj); err == nil { + if len(floatObj) > 0 { + obj = make(model.PricePercentagePack, len(floatObj)) + for k, v := range floatObj { + if v.PricePercentage >= 500 || v.PricePercentage <= 80 { + return nil + } + obj[k] = &model.PricePercentageItem{ + BeginPrice: int(v.BeginPrice), + PricePercentage: int(v.PricePercentage), + PriceAdd: int(v.PriceAdd), + } } + sort.Sort(obj) } - sort.Sort(obj) } } return obj From 7b9e77ba2a547327072c864b3970cbcbf7a8cb9f Mon Sep 17 00:00:00 2001 From: gazebo Date: Thu, 14 Nov 2019 11:22:18 +0800 Subject: [PATCH 5/5] =?UTF-8?q?mtwmapi.SkuInfo.Weight=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E4=BB=8Eint=E4=BF=AE=E6=AD=A3=E4=B8=BAstring=EF=BC=8C=E7=9B=B8?= =?UTF-8?q?=E5=BA=94=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/partner/purchase/mtwm/store_sku2.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/business/partner/purchase/mtwm/store_sku2.go b/business/partner/purchase/mtwm/store_sku2.go index 6fca62741..28468214d 100644 --- a/business/partner/purchase/mtwm/store_sku2.go +++ b/business/partner/purchase/mtwm/store_sku2.go @@ -403,7 +403,7 @@ func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTas func vendorSku2Jx(appFood *mtwmapi.AppFood) (skuName *partner.SkuNameInfo) { prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(appFood.Name) vendorSku := appFood.SkuList[0] - weight := vendorSku.Weight + weight := int(utils.Str2Int64WithDefault(vendorSku.Weight, 0)) if weight <= 0 { weight = jxutils.FormatSkuWeight(specQuality, specUnit) }