From ad1bcd36ff372a1f3adb20935dc708056c0abf35 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Tue, 3 Sep 2019 14:48:37 +0800 Subject: [PATCH 01/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E8=AF=84=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 268 +++++++++++++++++++++++++++ business/model/dao/store_score.go | 23 +++ business/model/store_score.go | 20 ++ business/partner/partner.go | 8 + globals/beegodb/beegodb.go | 1 + 5 files changed, 320 insertions(+) create mode 100644 business/jxstore/misc/store_score.go create mode 100644 business/model/dao/store_score.go create mode 100644 business/model/store_score.go diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go new file mode 100644 index 000000000..3f614ad8f --- /dev/null +++ b/business/jxstore/misc/store_score.go @@ -0,0 +1,268 @@ +package misc + +import ( + "math" + "sync" + "time" + + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxstore/cms" + "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" +) + +const ( + ItemScore = 10 + TotalScore = 100 + + StoreOpenTimeNormalScore = 12.0 + SaleSkuNormalCount = 1000 + SaleSkuScorePerUnit = float64(ItemScore) / SaleSkuNormalCount + PromotionSkuNormalCount = 20 +) + +var ( + storeScoreDataWrapper StoreScoreDataWrapper + fullVendorList = map[int]bool{ + model.VendorIDJD: true, + model.VendorIDMTWM: true, + model.VendorIDEBAI: true, + } +) + +type StoreScoreDataWrapper struct { + storeScoreData map[int]*model.StoreScore + locker sync.RWMutex +} + +func (s *StoreScoreDataWrapper) AppendData(data *model.StoreScore) { + s.locker.Lock() + defer s.locker.Unlock() + s.storeScoreData[data.StoreID] = data +} + +func (s *StoreScoreDataWrapper) GetData(storeID int) *model.StoreScore { + s.locker.RLock() + defer s.locker.RUnlock() + return s.storeScoreData[storeID] +} + +func (s *StoreScoreDataWrapper) InitData() { + s.storeScoreData = make(map[int]*model.StoreScore) +} + +/* 分日评分和周评分两种,周评分为最近一周的平均值 +1 营业时间12小时及以上满分,总分10分,每少一个小时扣1分 +2 可售商品数量大于1000,总分10分,按比例扣 +3 平均捡货时间10分钟内为满分10分,每超1分钟扣1分 +4 差评订单和完成订单比例小于0.2%,得满分10分,每增加0.1,%减1分 +5 未完成订单和完成订单比小于1%,得满分10分,比例每增加5%,分数减1 +6 缺货订单和完成订单比小于1%得10分,比例每增加0.1%减1分 +7 促销品数量20个以上为满分10分,每少2个扣1分 +8 经营全平台满分10分,每少一个平台扣2分(???一个都没有,是否为0) +9 经营范围面积大于半径2km的圆得满分10分,低于1km得分0 +10 可售商品价格在附近5km内门店比较,价格低于等于平均值的商品数占90%以上满分10分,比例每降低10%减1分,100%超标得0分 +*/ + +func GetOpenTime(opTimeList []int16) (opTime float64) { + opTime = 0 + for index, _ := range opTimeList { + if index%2 == 1 { + diff := opTimeList[index] - opTimeList[index-1] + opTime += float64(diff) / 100 + } + } + return opTime +} + +func ScoreStoreOpenTime(storeList []*cms.StoreExt) { + for _, storeInfo := range storeList { + storeID := storeInfo.ID + storeStatus := storeInfo.Status + isStoreOpen := storeStatus == model.StoreStatusOpened + storeScoreData := storeScoreDataWrapper.GetData(storeID) + if storeScoreData == nil { + storeScoreData = &model.StoreScore{} + storeScoreData.StoreID = storeID + storeScoreDataWrapper.AppendData(storeScoreData) + } + for _, storeMap := range storeInfo.StoreMaps { + vendorStoreStatus := int(utils.MustInterface2Int64(storeMap["status"])) + isVendorStoreOpen := vendorStoreStatus == model.StoreStatusOpened + opTimeList := storeInfo.GetOpTimeList() + if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen { + opTime := GetOpenTime(opTimeList) + if opTime >= StoreOpenTimeNormalScore { + storeScoreData.StoreOpenTime = ItemScore + } else { + decScore := int(math.Round(StoreOpenTimeNormalScore - opTime)) + storeScoreData.StoreOpenTime = ItemScore - decScore + if storeScoreData.StoreOpenTime < 0 { + storeScoreData.StoreOpenTime = 0 + } + } + } + } + } +} + +func ScoreSaleSkuCount(ctx *jxcontext.Context, storeList []*cms.StoreExt) { + for _, storeInfo := range storeList { + storeID := storeInfo.ID + storeScoreData := storeScoreDataWrapper.GetData(storeID) + if storeScoreData == nil { + storeScoreData = &model.StoreScore{} + storeScoreData.StoreID = storeID + storeScoreDataWrapper.AppendData(storeScoreData) + } + jxSkuInfoData, _ := cms.GetStoreSkus(ctx, storeID, []int{}, true, "", true, map[string]interface{}{}, 0, -1) + saleSkuCount := 0 + for _, value := range jxSkuInfoData.SkuNames { + for _, skuInfo := range value.Skus2 { + saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus) + if saleStatus == model.SkuStatusNormal { + saleSkuCount++ + } + } + } + storeScoreData.SaleSkuCount = int(math.Round(float64(saleSkuCount) * SaleSkuScorePerUnit)) + } +} + +func ScoreAveragePickupTime() { + +} + +func ScoreBadReviewOrder() { + +} + +func ScoreUnfinishOrder() { + +} + +func ScoreLackStockOrder() { + +} + +func ScorePromotionSku(storeList []*cms.StoreExt) { + for _, storeInfo := range storeList { + storeID := storeInfo.ID + storeScoreData := storeScoreDataWrapper.GetData(storeID) + if storeScoreData == nil { + storeScoreData = &model.StoreScore{} + storeScoreData.StoreID = storeID + storeScoreDataWrapper.AppendData(storeScoreData) + } + db := dao.GetDB() + beginTime := time.Now() + endTime := time.Now() + actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, -1, []int{}, []int{storeID}, []int{}, beginTime, endTime) + if err == nil { + actStoreSkuMap := make(map[int]int) + for _, value := range actStoreSkuList { + actStoreSkuMap[value.SkuID] = 1 + } + promotionSkuCount := len(actStoreSkuMap) + if promotionSkuCount >= PromotionSkuNormalCount { + storeScoreData.PromotionSku = ItemScore + } else { + decScore := (PromotionSkuNormalCount - promotionSkuCount) / 2 + storeScoreData.PromotionSku = ItemScore - decScore + if storeScoreData.PromotionSku < 0 { + storeScoreData.PromotionSku = 0 + } + } + } + } +} + +func ScoreFullVendor(storeList []*cms.StoreExt) { + fullVendorCount := len(fullVendorList) + for _, storeInfo := range storeList { + storeID := storeInfo.ID + storeStatus := storeInfo.Status + isStoreOpen := storeStatus == model.StoreStatusOpened + storeScoreData := storeScoreDataWrapper.GetData(storeID) + if storeScoreData == nil { + storeScoreData = &model.StoreScore{} + storeScoreData.StoreID = storeID + storeScoreDataWrapper.AppendData(storeScoreData) + } + count := 0 + for _, storeMap := range storeInfo.StoreMaps { + vendorStoreStatus := int(utils.MustInterface2Int64(storeMap["status"])) + isVendorStoreOpen := vendorStoreStatus == model.StoreStatusOpened + opTimeList := storeInfo.GetOpTimeList() + if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen { + count++ + } + } + if count == fullVendorCount { + storeScoreData.FullVendor = ItemScore + } else { + decScore := (fullVendorCount - count) * 2 + storeScoreData.FullVendor = ItemScore - decScore + } + } +} + +func ScoreStoreRange() { + +} + +func ScoreSaleSkuPrice() { + +} + +func GetFilterStoreListEx(storeList []*cms.StoreExt, storeIDMap map[int]int) (outStoreList []*cms.StoreExt) { + for _, storeInfo := range storeList { + storeID := storeInfo.ID + if len(storeIDMap) > 0 { + if _, ok := storeIDMap[storeID]; !ok { + continue + } + } + for _, vendorStoreInfo := range storeInfo.StoreMaps { + vendorID := int(utils.MustInterface2Int64(vendorStoreInfo["vendorID"])) + if _, ok := fullVendorList[vendorID]; !ok { + continue + } + outStoreList = append(outStoreList, storeInfo) + } + } + + return outStoreList +} + +func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, err error) { + storeScoreDataWrapper.InitData() + storeList, err := GetStoreList(ctx) + storeIDMap := jxutils.IntList2Map(storeIDList) + storeList = GetFilterStoreListEx(storeList, storeIDMap) + + ScoreStoreOpenTime(storeList) + ScoreSaleSkuCount(ctx, storeList) + InsertStoreScore() + + return retVal, err +} + +func InsertStoreScore() { + for _, value := range storeScoreDataWrapper.storeScoreData { + scores := make(map[string]int) + scores["storeOpenTime"] = value.StoreOpenTime + scores["saleSkuCount"] = value.SaleSkuCount + scores["averagePickupTime"] = value.AveragePickupTime + scores["badReviewOrder"] = value.BadReviewOrder + scores["unfinishOrder"] = value.UnfinishOrder + scores["lackStockOrder"] = value.LackStockOrder + scores["promotionSku"] = value.PromotionSku + scores["fullVendor"] = value.FullVendor + scores["storeRange"] = value.StoreRange + scores["saleSkuPrice"] = value.SaleSkuPrice + dao.InsertStoreScore(value.StoreID, scores) + } +} diff --git a/business/model/dao/store_score.go b/business/model/dao/store_score.go new file mode 100644 index 000000000..71aea890e --- /dev/null +++ b/business/model/dao/store_score.go @@ -0,0 +1,23 @@ +package dao + +import ( + "time" + + "git.rosy.net.cn/jx-callback/business/model" +) + +func InsertStoreScore(storeID int, scores map[string]int) error { + storeScore := &model.StoreScore{CreatedAt: time.Now(), StoreID: storeID} + storeScore.StoreOpenTime = scores["storeOpenTime"] + storeScore.SaleSkuCount = scores["saleSkuCount"] + storeScore.AveragePickupTime = scores["averagePickupTime"] + storeScore.BadReviewOrder = scores["badReviewOrder"] + storeScore.UnfinishOrder = scores["unfinishOrder"] + storeScore.LackStockOrder = scores["lackStockOrder"] + storeScore.PromotionSku = scores["promotionSku"] + storeScore.FullVendor = scores["fullVendor"] + storeScore.StoreRange = scores["storeRange"] + storeScore.SaleSkuPrice = scores["saleSkuPrice"] + + return CreateEntity(nil, storeScore) +} diff --git a/business/model/store_score.go b/business/model/store_score.go new file mode 100644 index 000000000..0277557d7 --- /dev/null +++ b/business/model/store_score.go @@ -0,0 +1,20 @@ +package model + +import "time" + +type StoreScore struct { + ID int `orm:"column(id)" json:"id"` + CreatedAt time.Time `orm:"auto_now_add;type(datetime)" json:"createdAt"` + StoreID int `orm:"column(store_id)" json:"storeID"` + + StoreOpenTime int `orm:"column(store_open_time)" json:"storeOpenTime"` + SaleSkuCount int `orm:"column(sale_sku_count)" json:"saleSkuCount"` + AveragePickupTime int `orm:"column(average_pickup_time)" json:"averagePickupTime"` + BadReviewOrder int `orm:"column(bad_review_order)" json:"badReviewOrder"` + UnfinishOrder int `orm:"column(unfinish_order)" json:"unfinishOrder"` + LackStockOrder int `orm:"column(lack_stock_order)" json:"lackStockOrder"` + PromotionSku int `orm:"column(promotion_sku)" json:"promotionSku"` + FullVendor int `orm:"column(full_vendor)" json:"fullVendor"` + StoreRange int `orm:"column(store_range)" json:"storeRange"` + SaleSkuPrice int `orm:"column(sale_sku_price)" json:"saleSkuPrice"` +} diff --git a/business/partner/partner.go b/business/partner/partner.go index 803ceb747..6e106b42b 100644 --- a/business/partner/partner.go +++ b/business/partner/partner.go @@ -242,3 +242,11 @@ func GetSingleStoreVendorIDs() (vendorIDs []int) { } return vendorIDs } + +func IsMultiStore(vendorID int) bool { + if _, ok := GetPurchasePlatformFromVendorID(vendorID).(IMultipleStoresHandler); ok { + return true + } + + return false +} diff --git a/globals/beegodb/beegodb.go b/globals/beegodb/beegodb.go index 5b0b17614..fde70fb6a 100644 --- a/globals/beegodb/beegodb.go +++ b/globals/beegodb/beegodb.go @@ -54,6 +54,7 @@ func Init() { orm.RegisterModel(&model.CasbinRule{}) orm.RegisterModel(&model.SensitiveWord{}) + orm.RegisterModel(&model.StoreScore{}) // create table orm.RunSyncdb("default", false, true) } From 4eaccdc917f0ea1bd1962e1eab17521734cff552 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Thu, 5 Sep 2019 08:37:23 +0800 Subject: [PATCH 02/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E8=AF=84=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/misc2_test.go | 3 +- business/jxstore/misc/store_score.go | 272 ++++++++++++++++++---- business/jxstore/misc/store_score_test.go | 17 ++ business/model/api.go | 5 + business/model/dao/dao_order.go | 43 ++++ business/model/dao/store_score.go | 16 +- business/model/store_score.go | 4 +- 7 files changed, 297 insertions(+), 63 deletions(-) create mode 100644 business/jxstore/misc/store_score_test.go diff --git a/business/jxstore/misc/misc2_test.go b/business/jxstore/misc/misc2_test.go index 38d1a9be5..f4eee87f1 100644 --- a/business/jxstore/misc/misc2_test.go +++ b/business/jxstore/misc/misc2_test.go @@ -2,8 +2,9 @@ package misc import ( "testing" + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" ) func TestStartOrEndOpStore(t *testing.T) { - StartOrEndOpStore(1, true, 0, 0, false, true) + StartOrEndOpStore(jxcontext.AdminCtx, true, []int{}, []int{}, 0, 0, false, true) } diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index 3f614ad8f..bc34910b4 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -17,19 +17,28 @@ const ( ItemScore = 10 TotalScore = 100 - StoreOpenTimeNormalScore = 12.0 - SaleSkuNormalCount = 1000 - SaleSkuScorePerUnit = float64(ItemScore) / SaleSkuNormalCount - PromotionSkuNormalCount = 20 + StoreOpenTimeNormalTime = 12.0 //小时 + SaleSkuNormalCount = 1000 + SaleSkuScorePerUnit = float64(ItemScore) / SaleSkuNormalCount + PromotionSkuNormalCount = 20 + AveragePickupTimeNormalTime = 10.0 //分钟 + BadCommentOrderNormalRatio = 0.2 + UnfinishOrderNormalRatio = 1.0 + StoreRangeGoodRadius = 2000 //米 + StoreRangeBadRadius = 1000 //米 ) var ( + scoreStoreTimeList = []string{ + "23:30:00", + } storeScoreDataWrapper StoreScoreDataWrapper fullVendorList = map[int]bool{ model.VendorIDJD: true, model.VendorIDMTWM: true, model.VendorIDEBAI: true, } + allStoreSkus map[int]map[int]*cms.StoreSkuNameExt ) type StoreScoreDataWrapper struct { @@ -53,19 +62,6 @@ func (s *StoreScoreDataWrapper) InitData() { s.storeScoreData = make(map[int]*model.StoreScore) } -/* 分日评分和周评分两种,周评分为最近一周的平均值 -1 营业时间12小时及以上满分,总分10分,每少一个小时扣1分 -2 可售商品数量大于1000,总分10分,按比例扣 -3 平均捡货时间10分钟内为满分10分,每超1分钟扣1分 -4 差评订单和完成订单比例小于0.2%,得满分10分,每增加0.1,%减1分 -5 未完成订单和完成订单比小于1%,得满分10分,比例每增加5%,分数减1 -6 缺货订单和完成订单比小于1%得10分,比例每增加0.1%减1分 -7 促销品数量20个以上为满分10分,每少2个扣1分 -8 经营全平台满分10分,每少一个平台扣2分(???一个都没有,是否为0) -9 经营范围面积大于半径2km的圆得满分10分,低于1km得分0 -10 可售商品价格在附近5km内门店比较,价格低于等于平均值的商品数占90%以上满分10分,比例每降低10%减1分,100%超标得0分 -*/ - func GetOpenTime(opTimeList []int16) (opTime float64) { opTime = 0 for index, _ := range opTimeList { @@ -77,6 +73,7 @@ func GetOpenTime(opTimeList []int16) (opTime float64) { return opTime } +//营业时间12小时及以上满分,总分10分,每少一个小时扣1分 func ScoreStoreOpenTime(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID @@ -94,10 +91,10 @@ func ScoreStoreOpenTime(storeList []*cms.StoreExt) { opTimeList := storeInfo.GetOpTimeList() if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen { opTime := GetOpenTime(opTimeList) - if opTime >= StoreOpenTimeNormalScore { + if opTime >= StoreOpenTimeNormalTime { storeScoreData.StoreOpenTime = ItemScore } else { - decScore := int(math.Round(StoreOpenTimeNormalScore - opTime)) + decScore := int(math.Round(StoreOpenTimeNormalTime - opTime)) storeScoreData.StoreOpenTime = ItemScore - decScore if storeScoreData.StoreOpenTime < 0 { storeScoreData.StoreOpenTime = 0 @@ -108,6 +105,7 @@ func ScoreStoreOpenTime(storeList []*cms.StoreExt) { } } +//可售商品数量大于1000,总分10分,按比例扣 func ScoreSaleSkuCount(ctx *jxcontext.Context, storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID @@ -128,25 +126,103 @@ func ScoreSaleSkuCount(ctx *jxcontext.Context, storeList []*cms.StoreExt) { } } storeScoreData.SaleSkuCount = int(math.Round(float64(saleSkuCount) * SaleSkuScorePerUnit)) + if storeScoreData.SaleSkuCount > ItemScore { + storeScoreData.SaleSkuCount = ItemScore + } } } -func ScoreAveragePickupTime() { - -} - -func ScoreBadReviewOrder() { - -} - -func ScoreUnfinishOrder() { - -} - -func ScoreLackStockOrder() { +//平均捡货时间小于等于拣货截止时间为10分满分,每超出1分钟,减1分 +func ScoreAveragePickupTime(storeList []*cms.StoreExt) { + for _, storeInfo := range storeList { + storeID := storeInfo.ID + storeScoreData := storeScoreDataWrapper.GetData(storeID) + if storeScoreData == nil { + storeScoreData = &model.StoreScore{} + storeScoreData.StoreID = storeID + storeScoreDataWrapper.AppendData(storeScoreData) + } + db := dao.GetDB() + orderList, err := dao.GetDailyFinishOrderList(db, storeID) + if err == nil { + totalScore := 0 + for _, value := range orderList { + statusTime := value.StatusTime.Unix() + pickDeadline := value.PickDeadline.Unix() + if statusTime <= pickDeadline { + totalScore += ItemScore + } else { + decScore := int(math.Round(float64(statusTime-pickDeadline) / 60)) + tempScore := ItemScore - decScore + if tempScore < 0 { + tempScore = 0 + } + totalScore += tempScore + } + } + storeScoreData.AveragePickupTime = totalScore / len(orderList) + } + } +} + +//差评订单和完成订单比例小于0.2%,得满分10分,每增加0.1%减1分 +func ScoreBadCommentOrder(storeList []*cms.StoreExt) { + for _, storeInfo := range storeList { + storeID := storeInfo.ID + storeScoreData := storeScoreDataWrapper.GetData(storeID) + if storeScoreData == nil { + storeScoreData = &model.StoreScore{} + storeScoreData.StoreID = storeID + storeScoreDataWrapper.AppendData(storeScoreData) + } + db := dao.GetDB() + badCommentOrderCount, _ := dao.GetDailyBadCommentOrderCount(db, storeID) + finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) + badCommentOrderRatio := float64(badCommentOrderCount) * 100 / float64(finishOrderCount) + if badCommentOrderRatio <= BadCommentOrderNormalRatio { + storeScoreData.BadCommentOrder = ItemScore + } else { + decScore := int(math.Round((badCommentOrderRatio - BadCommentOrderNormalRatio) / 0.1)) + storeScoreData.BadCommentOrder = ItemScore - decScore + if storeScoreData.BadCommentOrder < 0 { + storeScoreData.BadCommentOrder = 0 + } + } + } +} + +//未完成订单和完成订单比小于1%,得满分10分,比例每增加5%,分数减1 +func ScoreUnfinishOrder(storeList []*cms.StoreExt) { + for _, storeInfo := range storeList { + storeID := storeInfo.ID + storeScoreData := storeScoreDataWrapper.GetData(storeID) + if storeScoreData == nil { + storeScoreData = &model.StoreScore{} + storeScoreData.StoreID = storeID + storeScoreDataWrapper.AppendData(storeScoreData) + } + db := dao.GetDB() + unFinishOrderCount, _ := dao.GetDailyUnFinishOrderCount(db, storeID) + finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) + unfinishOrderRatio := float64(unFinishOrderCount) * 100 / float64(finishOrderCount) + if unfinishOrderRatio <= UnfinishOrderNormalRatio { + storeScoreData.UnfinishOrder = ItemScore + } else { + decScore := int(math.Round((unfinishOrderRatio - UnfinishOrderNormalRatio) / 5)) + storeScoreData.UnfinishOrder = ItemScore - decScore + if storeScoreData.UnfinishOrder < 0 { + storeScoreData.UnfinishOrder = 0 + } + } + } +} + +//缺货订单和完成订单比小于1%得10分,比例每增加0.1%减1分 +func ScoreAbsentGoodsOrder(storeList []*cms.StoreExt) { } +//促销品数量20个以上为满分10分,每少2个扣1分 func ScorePromotionSku(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID @@ -163,7 +239,9 @@ func ScorePromotionSku(storeList []*cms.StoreExt) { if err == nil { actStoreSkuMap := make(map[int]int) for _, value := range actStoreSkuList { - actStoreSkuMap[value.SkuID] = 1 + if value.Type != model.ActSkuFake { + actStoreSkuMap[value.SkuID] = 1 + } } promotionSkuCount := len(actStoreSkuMap) if promotionSkuCount >= PromotionSkuNormalCount { @@ -179,6 +257,7 @@ func ScorePromotionSku(storeList []*cms.StoreExt) { } } +//经营全平台满分10分,每少一个平台扣2分(???一个都没有,是否为0) func ScoreFullVendor(storeList []*cms.StoreExt) { fullVendorCount := len(fullVendorList) for _, storeInfo := range storeList { @@ -209,12 +288,108 @@ func ScoreFullVendor(storeList []*cms.StoreExt) { } } -func ScoreStoreRange() { +func CalcPolygonArea(points [][2]float64) (area float64) { + count := len(points) + for i := 0; i < count-1; i++ { + area += (points[i][0] - points[i+1][0]) * (points[i][1] + points[i+1][1]) + } + area += (points[count-1][0] - points[0][0]) * (points[count-1][1] + points[0][1]) + area = math.Abs(area) / 2 + return area } -func ScoreSaleSkuPrice() { +//经营范围面积大于半径2km的圆得满分10分,低于1km得分0 +func ScoreStoreRange(storeList []*cms.StoreExt) { + for _, storeInfo := range storeList { + storeID := storeInfo.ID + storeScoreData := storeScoreDataWrapper.GetData(storeID) + if storeScoreData == nil { + storeScoreData = &model.StoreScore{} + storeScoreData.StoreID = storeID + storeScoreDataWrapper.AppendData(storeScoreData) + } + if storeInfo.DeliveryRangeType == model.DeliveryRangeTypePolygon { + points := jxutils.CoordinateStr2Points(storeInfo.DeliveryRange) + area := CalcPolygonArea(points) + goodArea := math.Pi * StoreRangeGoodRadius * StoreRangeGoodRadius + badArea := math.Pi * StoreRangeBadRadius * StoreRangeBadRadius + if area >= goodArea { + storeScoreData.StoreRange = ItemScore + } else if area <= badArea { + storeScoreData.StoreRange = 0 + } else { + diff := float64(goodArea - area) + ratio := float64(ItemScore) / (goodArea - badArea) + storeScoreData.StoreRange = ItemScore - int(math.Round(diff*ratio)) + } + } else if storeInfo.DeliveryRangeType == model.DeliveryRangeTypeRadius { + deliveryRadius := utils.Str2Int64WithDefault(storeInfo.DeliveryRange, 0) + if deliveryRadius >= StoreRangeGoodRadius { + storeScoreData.StoreRange = ItemScore + } else if deliveryRadius <= StoreRangeBadRadius { + storeScoreData.StoreRange = 0 + } else { + diff := float64(StoreRangeGoodRadius - deliveryRadius) + ratio := float64(ItemScore) / (StoreRangeGoodRadius - StoreRangeBadRadius) + storeScoreData.StoreRange = ItemScore - int(math.Round(diff*ratio)) + } + } + } +} +func GetRangeStoreList(storeID int, lng, lat, checkDist float64, storeList []*cms.StoreExt) (outStoreList []*cms.StoreExt) { + for _, storeInfo := range storeList { + if storeInfo.ID == storeID { + outStoreList = append(outStoreList, storeInfo) + } else { + distance := jxutils.EarthDistance(lng, lat, storeInfo.FloatLng, storeInfo.FloatLat) + if distance <= checkDist { + outStoreList = append(outStoreList, storeInfo) + } + } + } + + return outStoreList +} + +func GetAllStoreSkus(ctx *jxcontext.Context, storeList []*cms.StoreExt) { + allStoreSkus = make(map[int]map[int]*cms.StoreSkuNameExt) + for _, storeInfo := range storeList { + storeID := storeInfo.ID + jxSkuInfoData, _ := cms.GetStoreSkus(ctx, storeID, []int{}, true, "", true, map[string]interface{}{}, 0, -1) + jxSkuMapData := make(map[int]*cms.StoreSkuNameExt) + for _, value := range jxSkuInfoData.SkuNames { + for _, skuInfo := range value.Skus2 { + saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus) + if saleStatus == model.SkuStatusNormal { + jxSkuMapData[skuInfo.SkuID] = value + } + } + } + allStoreSkus[storeID] = jxSkuMapData + } +} + +func ClearAllStoreSkus() { + allStoreSkus = nil +} + +//得到所有门店的商品,map[int]*cms.StoreSkuNamesInfo +//得到距离某个门店5KM内的所有门店信息 +//可售商品价格在附近5km内门店比较,价格低于等于平均值的商品数占90%以上满分10分,比例每降低10%减1分,100%超标得0分 +func ScoreSaleSkuPrice(ctx *jxcontext.Context, storeList []*cms.StoreExt) { + GetAllStoreSkus(ctx, storeList) + for _, storeInfo := range storeList { + storeID := storeInfo.ID + storeScoreData := storeScoreDataWrapper.GetData(storeID) + if storeScoreData == nil { + storeScoreData = &model.StoreScore{} + storeScoreData.StoreID = storeID + storeScoreDataWrapper.AppendData(storeScoreData) + } + //rangeStoreList := GetRangeStoreList(storeID, storeInfo.FloatLng, storeInfo.FloatLat, 5, storeList) + } } func GetFilterStoreListEx(storeList []*cms.StoreExt, storeIDMap map[int]int) (outStoreList []*cms.StoreExt) { @@ -245,6 +420,14 @@ func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, ScoreStoreOpenTime(storeList) ScoreSaleSkuCount(ctx, storeList) + ScoreAveragePickupTime(storeList) + ScoreBadCommentOrder(storeList) + ScoreUnfinishOrder(storeList) + ScoreAbsentGoodsOrder(storeList) + ScorePromotionSku(storeList) + ScoreFullVendor(storeList) + ScoreStoreRange(storeList) + ScoreSaleSkuPrice(ctx, storeList) InsertStoreScore() return retVal, err @@ -252,17 +435,12 @@ func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, func InsertStoreScore() { for _, value := range storeScoreDataWrapper.storeScoreData { - scores := make(map[string]int) - scores["storeOpenTime"] = value.StoreOpenTime - scores["saleSkuCount"] = value.SaleSkuCount - scores["averagePickupTime"] = value.AveragePickupTime - scores["badReviewOrder"] = value.BadReviewOrder - scores["unfinishOrder"] = value.UnfinishOrder - scores["lackStockOrder"] = value.LackStockOrder - scores["promotionSku"] = value.PromotionSku - scores["fullVendor"] = value.FullVendor - scores["storeRange"] = value.StoreRange - scores["saleSkuPrice"] = value.SaleSkuPrice - dao.InsertStoreScore(value.StoreID, scores) + dao.InsertStoreScore(value) } } + +func ScheduleScoreStore() { + ScheduleTimerFunc("ScheduleScoreStore", func() { + ScoreStore(jxcontext.AdminCtx, []int{}) + }, scoreStoreTimeList) +} diff --git a/business/jxstore/misc/store_score_test.go b/business/jxstore/misc/store_score_test.go new file mode 100644 index 000000000..7d4798157 --- /dev/null +++ b/business/jxstore/misc/store_score_test.go @@ -0,0 +1,17 @@ +package misc + +import ( + "testing" + "git.rosy.net.cn/jx-callback/globals/api2" + "git.rosy.net.cn/jx-callback/globals/testinit" + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" +) + +func init() { + testinit.Init() + api2.Init() +} + +func TestScoreStore(t *testing.T) { + ScoreStore(jxcontext.AdminCtx, []int{}) +} diff --git a/business/model/api.go b/business/model/api.go index 1a3396774..79dddef04 100644 --- a/business/model/api.go +++ b/business/model/api.go @@ -73,3 +73,8 @@ type OrderFinancialSkuExt struct { OrderSkuFinancial Image string `json:"image"` } + +type OrderPickupTime struct { + StatusTime time.Time `orm:"type(datetime)" json:"statusTime"` + PickDeadline time.Time `orm:"type(datetime)" json:"pickDeadline"` +} diff --git a/business/model/dao/dao_order.go b/business/model/dao/dao_order.go index 1438e7c7d..2d7f7220b 100644 --- a/business/model/dao/dao_order.go +++ b/business/model/dao/dao_order.go @@ -290,3 +290,46 @@ func GetStoreAfsOrderSkuList(db *DaoDB, storeIDs []int, finishedAtBegin, finishe err = GetRows(db, &afsSkuList, sql, sqlParams...) return afsSkuList, err } + +func GetDailyFinishOrderList(db *DaoDB, storeID int) (orderList []*model.OrderPickupTime, err error) { + sql := ` + select t2.status_time, t1.pick_deadline + from goods_order t1 + left join order_status t2 on t1.vendor_order_id = t2.vendor_order_id + where t1.jx_store_id = ? and t2.order_type = ? and t2.status = ? and DATE_FORMAT(t1.order_finished_at, '%Y-%m-%d') = DATE_FORMAT(NOW(), '%Y-%m-%d') + ` + sqlParams := []interface{}{ + storeID, + 1, + model.OrderStatusFinishedPickup, + } + return orderList, GetRows(db, &orderList, sql, sqlParams...) +} + +func GetDailyBadCommentOrderCount(db *DaoDB, storeID int) (num int64, err error) { + sql := `select count(*) from jx_bad_comments where DATE_FORMAT(createtime, '%Y-%m-%d') = DATE_FORMAT(NOW(), '%Y-%m-%d') and jxstoreid = ?` + sqlParams := []interface{}{ + storeID, + } + return ExecuteSQL(db, sql, sqlParams) +} + +func GetDailyUnFinishOrderCount(db *DaoDB, storeID int) (num int64, err error) { + return GetDailyEndOrderCount(db, storeID, []int{model.OrderStatusCanceled}) +} + +func GetDailyFinishOrderCount(db *DaoDB, storeID int) (num int64, err error) { + return GetDailyEndOrderCount(db, storeID, []int{model.OrderStatusFinished}) +} + +func GetDailyEndOrderCount(db *DaoDB, storeID int, statusList []int) (num int64, err error) { + sql := `select count(*) from goods_order + where DATE_FORMAT(order_finished_at, '%Y-%m-%d') = DATE_FORMAT(NOW(), '%Y-%m-%d') + and jx_store_id = ? + and status in (` + GenQuestionMarks(len(statusList)) + `)` + sqlParams := []interface{}{ + storeID, + } + sqlParams = append(sqlParams, statusList) + return ExecuteSQL(db, sql, sqlParams) +} diff --git a/business/model/dao/store_score.go b/business/model/dao/store_score.go index 71aea890e..4f4f5735f 100644 --- a/business/model/dao/store_score.go +++ b/business/model/dao/store_score.go @@ -6,18 +6,8 @@ import ( "git.rosy.net.cn/jx-callback/business/model" ) -func InsertStoreScore(storeID int, scores map[string]int) error { - storeScore := &model.StoreScore{CreatedAt: time.Now(), StoreID: storeID} - storeScore.StoreOpenTime = scores["storeOpenTime"] - storeScore.SaleSkuCount = scores["saleSkuCount"] - storeScore.AveragePickupTime = scores["averagePickupTime"] - storeScore.BadReviewOrder = scores["badReviewOrder"] - storeScore.UnfinishOrder = scores["unfinishOrder"] - storeScore.LackStockOrder = scores["lackStockOrder"] - storeScore.PromotionSku = scores["promotionSku"] - storeScore.FullVendor = scores["fullVendor"] - storeScore.StoreRange = scores["storeRange"] - storeScore.SaleSkuPrice = scores["saleSkuPrice"] - +// func InsertStoreScore(storeID int, scores map[string]int) error { +func InsertStoreScore(storeScore *model.StoreScore) error { + storeScore.CreatedAt = time.Now() return CreateEntity(nil, storeScore) } diff --git a/business/model/store_score.go b/business/model/store_score.go index 0277557d7..a32c21fcf 100644 --- a/business/model/store_score.go +++ b/business/model/store_score.go @@ -10,9 +10,9 @@ type StoreScore struct { StoreOpenTime int `orm:"column(store_open_time)" json:"storeOpenTime"` SaleSkuCount int `orm:"column(sale_sku_count)" json:"saleSkuCount"` AveragePickupTime int `orm:"column(average_pickup_time)" json:"averagePickupTime"` - BadReviewOrder int `orm:"column(bad_review_order)" json:"badReviewOrder"` + BadCommentOrder int `orm:"column(bad_comment_order)" json:"badCommentOrder"` UnfinishOrder int `orm:"column(unfinish_order)" json:"unfinishOrder"` - LackStockOrder int `orm:"column(lack_stock_order)" json:"lackStockOrder"` + AbsentGoodsOrder int `orm:"column(absent_Goods_order)" json:"absentGoodsOrder"` PromotionSku int `orm:"column(promotion_sku)" json:"promotionSku"` FullVendor int `orm:"column(full_vendor)" json:"fullVendor"` StoreRange int `orm:"column(store_range)" json:"storeRange"` From c7d883b51c2e675bbae3d34e0b47c0c189073362 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Thu, 5 Sep 2019 17:24:52 +0800 Subject: [PATCH 03/32] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=97=A8=E5=BA=97?= =?UTF-8?q?=E8=AF=84=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 267 ++++++++++++---------- business/jxstore/misc/store_score_test.go | 9 +- controllers/temp_op.go | 18 ++ routers/commentsRouter_controllers.go | 9 + 4 files changed, 181 insertions(+), 122 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index bc34910b4..9d016ed65 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -2,6 +2,7 @@ package misc import ( "math" + "reflect" "sync" "time" @@ -24,8 +25,9 @@ const ( AveragePickupTimeNormalTime = 10.0 //分钟 BadCommentOrderNormalRatio = 0.2 UnfinishOrderNormalRatio = 1.0 - StoreRangeGoodRadius = 2000 //米 - StoreRangeBadRadius = 1000 //米 + StoreRangeGoodRadius = 2.0 //千米 + StoreRangeBadRadius = 1.0 //千米 + SaleSkuPriceRatio = 90 //百分比 ) var ( @@ -46,28 +48,32 @@ type StoreScoreDataWrapper struct { locker sync.RWMutex } -func (s *StoreScoreDataWrapper) AppendData(data *model.StoreScore) { - s.locker.Lock() - defer s.locker.Unlock() - s.storeScoreData[data.StoreID] = data -} - -func (s *StoreScoreDataWrapper) GetData(storeID int) *model.StoreScore { - s.locker.RLock() - defer s.locker.RUnlock() - return s.storeScoreData[storeID] -} - func (s *StoreScoreDataWrapper) InitData() { s.storeScoreData = make(map[int]*model.StoreScore) } +func (s *StoreScoreDataWrapper) SetData(storeID int, valueName string, value int) { + s.locker.Lock() + defer s.locker.Unlock() + data := s.storeScoreData[storeID] + if data == nil { + data = &model.StoreScore{} + data.StoreID = storeID + s.storeScoreData[storeID] = data + } + valueInfo := reflect.ValueOf(data).Elem() + valueInfo.FieldByName(valueName).SetInt(int64(value)) +} + func GetOpenTime(opTimeList []int16) (opTime float64) { opTime = 0 for index, _ := range opTimeList { if index%2 == 1 { - diff := opTimeList[index] - opTimeList[index-1] - opTime += float64(diff) / 100 + endTime := opTimeList[index] + startTime := opTimeList[index-1] + diffHour := float64(endTime/100 - startTime/100) + diffMin := float64(endTime%100-startTime%100) / 60 + opTime += diffHour + diffMin } } return opTime @@ -79,27 +85,23 @@ func ScoreStoreOpenTime(storeList []*cms.StoreExt) { storeID := storeInfo.ID storeStatus := storeInfo.Status isStoreOpen := storeStatus == model.StoreStatusOpened - storeScoreData := storeScoreDataWrapper.GetData(storeID) - if storeScoreData == nil { - storeScoreData = &model.StoreScore{} - storeScoreData.StoreID = storeID - storeScoreDataWrapper.AppendData(storeScoreData) - } for _, storeMap := range storeInfo.StoreMaps { vendorStoreStatus := int(utils.MustInterface2Int64(storeMap["status"])) isVendorStoreOpen := vendorStoreStatus == model.StoreStatusOpened opTimeList := storeInfo.GetOpTimeList() if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen { + finalScore := 0 opTime := GetOpenTime(opTimeList) if opTime >= StoreOpenTimeNormalTime { - storeScoreData.StoreOpenTime = ItemScore + finalScore = ItemScore } else { decScore := int(math.Round(StoreOpenTimeNormalTime - opTime)) - storeScoreData.StoreOpenTime = ItemScore - decScore - if storeScoreData.StoreOpenTime < 0 { - storeScoreData.StoreOpenTime = 0 + finalScore = ItemScore - decScore + if finalScore < 0 { + finalScore = 0 } } + storeScoreDataWrapper.SetData(storeID, "StoreOpenTime", finalScore) } } } @@ -109,25 +111,23 @@ func ScoreStoreOpenTime(storeList []*cms.StoreExt) { func ScoreSaleSkuCount(ctx *jxcontext.Context, storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID - storeScoreData := storeScoreDataWrapper.GetData(storeID) - if storeScoreData == nil { - storeScoreData = &model.StoreScore{} - storeScoreData.StoreID = storeID - storeScoreDataWrapper.AppendData(storeScoreData) - } - jxSkuInfoData, _ := cms.GetStoreSkus(ctx, storeID, []int{}, true, "", true, map[string]interface{}{}, 0, -1) - saleSkuCount := 0 - for _, value := range jxSkuInfoData.SkuNames { - for _, skuInfo := range value.Skus2 { - saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus) - if saleStatus == model.SkuStatusNormal { - saleSkuCount++ + jxSkuInfoData, err := cms.GetStoreSkus(ctx, storeID, []int{}, true, "", true, map[string]interface{}{}, 0, -1) + if err == nil && len(jxSkuInfoData.SkuNames) > 0 { + finalScore := 0 + saleSkuCount := 0 + for _, value := range jxSkuInfoData.SkuNames { + for _, skuInfo := range value.Skus2 { + saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus) + if saleStatus == model.SkuStatusNormal { + saleSkuCount++ + } } } - } - storeScoreData.SaleSkuCount = int(math.Round(float64(saleSkuCount) * SaleSkuScorePerUnit)) - if storeScoreData.SaleSkuCount > ItemScore { - storeScoreData.SaleSkuCount = ItemScore + finalScore = int(math.Round(float64(saleSkuCount) * SaleSkuScorePerUnit)) + if finalScore > ItemScore { + finalScore = ItemScore + } + storeScoreDataWrapper.SetData(storeID, "SaleSkuCount", finalScore) } } } @@ -136,15 +136,10 @@ func ScoreSaleSkuCount(ctx *jxcontext.Context, storeList []*cms.StoreExt) { func ScoreAveragePickupTime(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID - storeScoreData := storeScoreDataWrapper.GetData(storeID) - if storeScoreData == nil { - storeScoreData = &model.StoreScore{} - storeScoreData.StoreID = storeID - storeScoreDataWrapper.AppendData(storeScoreData) - } db := dao.GetDB() orderList, err := dao.GetDailyFinishOrderList(db, storeID) - if err == nil { + orderListCount := len(orderList) + if err == nil && orderListCount > 0 { totalScore := 0 for _, value := range orderList { statusTime := value.StatusTime.Unix() @@ -160,7 +155,8 @@ func ScoreAveragePickupTime(storeList []*cms.StoreExt) { totalScore += tempScore } } - storeScoreData.AveragePickupTime = totalScore / len(orderList) + finalScore := totalScore / orderListCount + storeScoreDataWrapper.SetData(storeID, "AveragePickupTime", finalScore) } } } @@ -169,24 +165,22 @@ func ScoreAveragePickupTime(storeList []*cms.StoreExt) { func ScoreBadCommentOrder(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID - storeScoreData := storeScoreDataWrapper.GetData(storeID) - if storeScoreData == nil { - storeScoreData = &model.StoreScore{} - storeScoreData.StoreID = storeID - storeScoreDataWrapper.AppendData(storeScoreData) - } db := dao.GetDB() badCommentOrderCount, _ := dao.GetDailyBadCommentOrderCount(db, storeID) finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) - badCommentOrderRatio := float64(badCommentOrderCount) * 100 / float64(finishOrderCount) - if badCommentOrderRatio <= BadCommentOrderNormalRatio { - storeScoreData.BadCommentOrder = ItemScore - } else { - decScore := int(math.Round((badCommentOrderRatio - BadCommentOrderNormalRatio) / 0.1)) - storeScoreData.BadCommentOrder = ItemScore - decScore - if storeScoreData.BadCommentOrder < 0 { - storeScoreData.BadCommentOrder = 0 + if finishOrderCount > 0 { + finalScore := 0 + badCommentOrderRatio := float64(badCommentOrderCount) * 100 / float64(finishOrderCount) + if badCommentOrderRatio <= BadCommentOrderNormalRatio { + finalScore = ItemScore + } else { + decScore := int(math.Round((badCommentOrderRatio - BadCommentOrderNormalRatio) / 0.1)) + finalScore = ItemScore - decScore + if finalScore < 0 { + finalScore = 0 + } } + storeScoreDataWrapper.SetData(storeID, "BadCommentOrder", finalScore) } } } @@ -195,24 +189,22 @@ func ScoreBadCommentOrder(storeList []*cms.StoreExt) { func ScoreUnfinishOrder(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID - storeScoreData := storeScoreDataWrapper.GetData(storeID) - if storeScoreData == nil { - storeScoreData = &model.StoreScore{} - storeScoreData.StoreID = storeID - storeScoreDataWrapper.AppendData(storeScoreData) - } db := dao.GetDB() unFinishOrderCount, _ := dao.GetDailyUnFinishOrderCount(db, storeID) finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) - unfinishOrderRatio := float64(unFinishOrderCount) * 100 / float64(finishOrderCount) - if unfinishOrderRatio <= UnfinishOrderNormalRatio { - storeScoreData.UnfinishOrder = ItemScore - } else { - decScore := int(math.Round((unfinishOrderRatio - UnfinishOrderNormalRatio) / 5)) - storeScoreData.UnfinishOrder = ItemScore - decScore - if storeScoreData.UnfinishOrder < 0 { - storeScoreData.UnfinishOrder = 0 + if finishOrderCount > 0 { + finalScore := 0 + unfinishOrderRatio := float64(unFinishOrderCount) * 100 / float64(finishOrderCount) + if unfinishOrderRatio <= UnfinishOrderNormalRatio { + finalScore = ItemScore + } else { + decScore := int(math.Round((unfinishOrderRatio - UnfinishOrderNormalRatio) / 5)) + finalScore = ItemScore - decScore + if finalScore < 0 { + finalScore = 0 + } } + storeScoreDataWrapper.SetData(storeID, "UnfinishOrder", finalScore) } } } @@ -226,17 +218,12 @@ func ScoreAbsentGoodsOrder(storeList []*cms.StoreExt) { func ScorePromotionSku(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID - storeScoreData := storeScoreDataWrapper.GetData(storeID) - if storeScoreData == nil { - storeScoreData = &model.StoreScore{} - storeScoreData.StoreID = storeID - storeScoreDataWrapper.AppendData(storeScoreData) - } db := dao.GetDB() beginTime := time.Now() endTime := time.Now() actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, -1, []int{}, []int{storeID}, []int{}, beginTime, endTime) - if err == nil { + if err == nil && len(actStoreSkuList) > 0 { + finalScore := 0 actStoreSkuMap := make(map[int]int) for _, value := range actStoreSkuList { if value.Type != model.ActSkuFake { @@ -245,14 +232,15 @@ func ScorePromotionSku(storeList []*cms.StoreExt) { } promotionSkuCount := len(actStoreSkuMap) if promotionSkuCount >= PromotionSkuNormalCount { - storeScoreData.PromotionSku = ItemScore + finalScore = ItemScore } else { decScore := (PromotionSkuNormalCount - promotionSkuCount) / 2 - storeScoreData.PromotionSku = ItemScore - decScore - if storeScoreData.PromotionSku < 0 { - storeScoreData.PromotionSku = 0 + finalScore = ItemScore - decScore + if finalScore < 0 { + finalScore = 0 } } + storeScoreDataWrapper.SetData(storeID, "PromotionSku", finalScore) } } } @@ -261,15 +249,10 @@ func ScorePromotionSku(storeList []*cms.StoreExt) { func ScoreFullVendor(storeList []*cms.StoreExt) { fullVendorCount := len(fullVendorList) for _, storeInfo := range storeList { + finalScore := 0 storeID := storeInfo.ID storeStatus := storeInfo.Status isStoreOpen := storeStatus == model.StoreStatusOpened - storeScoreData := storeScoreDataWrapper.GetData(storeID) - if storeScoreData == nil { - storeScoreData = &model.StoreScore{} - storeScoreData.StoreID = storeID - storeScoreDataWrapper.AppendData(storeScoreData) - } count := 0 for _, storeMap := range storeInfo.StoreMaps { vendorStoreStatus := int(utils.MustInterface2Int64(storeMap["status"])) @@ -280,11 +263,12 @@ func ScoreFullVendor(storeList []*cms.StoreExt) { } } if count == fullVendorCount { - storeScoreData.FullVendor = ItemScore + finalScore = ItemScore } else { decScore := (fullVendorCount - count) * 2 - storeScoreData.FullVendor = ItemScore - decScore + finalScore = ItemScore - decScore } + storeScoreDataWrapper.SetData(storeID, "FullVendor", finalScore) } } @@ -302,42 +286,39 @@ func CalcPolygonArea(points [][2]float64) (area float64) { //经营范围面积大于半径2km的圆得满分10分,低于1km得分0 func ScoreStoreRange(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { + finalScore := 0 storeID := storeInfo.ID - storeScoreData := storeScoreDataWrapper.GetData(storeID) - if storeScoreData == nil { - storeScoreData = &model.StoreScore{} - storeScoreData.StoreID = storeID - storeScoreDataWrapper.AppendData(storeScoreData) - } if storeInfo.DeliveryRangeType == model.DeliveryRangeTypePolygon { points := jxutils.CoordinateStr2Points(storeInfo.DeliveryRange) area := CalcPolygonArea(points) goodArea := math.Pi * StoreRangeGoodRadius * StoreRangeGoodRadius badArea := math.Pi * StoreRangeBadRadius * StoreRangeBadRadius if area >= goodArea { - storeScoreData.StoreRange = ItemScore + finalScore = ItemScore } else if area <= badArea { - storeScoreData.StoreRange = 0 + finalScore = 0 } else { - diff := float64(goodArea - area) + diff := goodArea - area ratio := float64(ItemScore) / (goodArea - badArea) - storeScoreData.StoreRange = ItemScore - int(math.Round(diff*ratio)) + finalScore = ItemScore - int(math.Round(diff*ratio)) } } else if storeInfo.DeliveryRangeType == model.DeliveryRangeTypeRadius { - deliveryRadius := utils.Str2Int64WithDefault(storeInfo.DeliveryRange, 0) + deliveryRadius := utils.Str2Float64WithDefault(storeInfo.DeliveryRange, 0) if deliveryRadius >= StoreRangeGoodRadius { - storeScoreData.StoreRange = ItemScore + finalScore = ItemScore } else if deliveryRadius <= StoreRangeBadRadius { - storeScoreData.StoreRange = 0 + finalScore = 0 } else { - diff := float64(StoreRangeGoodRadius - deliveryRadius) + diff := StoreRangeGoodRadius - deliveryRadius ratio := float64(ItemScore) / (StoreRangeGoodRadius - StoreRangeBadRadius) - storeScoreData.StoreRange = ItemScore - int(math.Round(diff*ratio)) + finalScore = ItemScore - int(math.Round(diff*ratio)) } } + storeScoreDataWrapper.SetData(storeID, "StoreRange", finalScore) } } +//得到距离某个门店多少KM内的所有门店信息 func GetRangeStoreList(storeID int, lng, lat, checkDist float64, storeList []*cms.StoreExt) (outStoreList []*cms.StoreExt) { for _, storeInfo := range storeList { if storeInfo.ID == storeID { @@ -353,6 +334,7 @@ func GetRangeStoreList(storeID int, lng, lat, checkDist float64, storeList []*cm return outStoreList } +//得到所有门店的商品 func GetAllStoreSkus(ctx *jxcontext.Context, storeList []*cms.StoreExt) { allStoreSkus = make(map[int]map[int]*cms.StoreSkuNameExt) for _, storeInfo := range storeList { @@ -375,21 +357,64 @@ func ClearAllStoreSkus() { allStoreSkus = nil } -//得到所有门店的商品,map[int]*cms.StoreSkuNamesInfo -//得到距离某个门店5KM内的所有门店信息 +//得到给定门店列表里的同一SkuID商品的平均价格 +func GetStoreSkusAveragePrice(storeList []*cms.StoreExt) map[int]int { + skusTotalPrice := make(map[int]int) + skusCount := make(map[int]int) + skusAveragePrice := make(map[int]int) + for _, storeInfo := range storeList { + storeID := storeInfo.ID + for _, value := range allStoreSkus[storeID] { + skuID := value.Skus2[0].SkuID + skuPrice := value.Skus2[0].BindPrice + skusTotalPrice[skuID] += skuPrice + skusCount[skuID]++ + } + } + for id, totalPrice := range skusTotalPrice { + skusAveragePrice[id] = int(math.Round(float64(totalPrice) / float64(skusCount[id]))) + } + return skusAveragePrice +} + +func GetSkusCountLessEqualAvgPrice(storeID int, skusAveragePrice map[int]int) (count int) { + for _, value := range allStoreSkus[storeID] { + skuID := value.Skus2[0].SkuID + skuPrice := value.Skus2[0].BindPrice + skuAvgPrice := skusAveragePrice[skuID] + if skuPrice <= skuAvgPrice { + count++ + } + } + + return count +} + //可售商品价格在附近5km内门店比较,价格低于等于平均值的商品数占90%以上满分10分,比例每降低10%减1分,100%超标得0分 func ScoreSaleSkuPrice(ctx *jxcontext.Context, storeList []*cms.StoreExt) { GetAllStoreSkus(ctx, storeList) for _, storeInfo := range storeList { + finalScore := 0 storeID := storeInfo.ID - storeScoreData := storeScoreDataWrapper.GetData(storeID) - if storeScoreData == nil { - storeScoreData = &model.StoreScore{} - storeScoreData.StoreID = storeID - storeScoreDataWrapper.AppendData(storeScoreData) + totalCount := len(allStoreSkus[storeID]) + if totalCount > 0 { + rangeStoreList := GetRangeStoreList(storeID, storeInfo.FloatLng, storeInfo.FloatLat, 5, storeList) + skusAveragePrice := GetStoreSkusAveragePrice(rangeStoreList) + count := GetSkusCountLessEqualAvgPrice(storeID, skusAveragePrice) + ratio := int(math.Round(float64(count) * 100 / float64(totalCount))) + if ratio >= SaleSkuPriceRatio { + finalScore = ItemScore + } else { + decScore := (SaleSkuPriceRatio - ratio) / 10 + finalScore = ItemScore - decScore + if finalScore < 0 { + finalScore = 0 + } + } + storeScoreDataWrapper.SetData(storeID, "SaleSkuPrice", finalScore) } - //rangeStoreList := GetRangeStoreList(storeID, storeInfo.FloatLng, storeInfo.FloatLat, 5, storeList) } + ClearAllStoreSkus() } func GetFilterStoreListEx(storeList []*cms.StoreExt, storeIDMap map[int]int) (outStoreList []*cms.StoreExt) { diff --git a/business/jxstore/misc/store_score_test.go b/business/jxstore/misc/store_score_test.go index 7d4798157..01e0a42bb 100644 --- a/business/jxstore/misc/store_score_test.go +++ b/business/jxstore/misc/store_score_test.go @@ -2,9 +2,16 @@ package misc import ( "testing" + + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/globals/api2" "git.rosy.net.cn/jx-callback/globals/testinit" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" + + _ "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai" + _ "git.rosy.net.cn/jx-callback/business/partner/purchase/elm" + _ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd" + _ "git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm" + _ "git.rosy.net.cn/jx-callback/business/partner/purchase/weimob/wsc" ) func init() { diff --git a/controllers/temp_op.go b/controllers/temp_op.go index ca73868e1..dc3603980 100644 --- a/controllers/temp_op.go +++ b/controllers/temp_op.go @@ -316,3 +316,21 @@ func (c *TempOpController) CheckSkuDiffBetweenJxAndVendor() { return retVal, "", err }) } + +// @Title 门店评分 +// @Description 门店评分 +// @Param token header string true "认证token" +// @Param storeIDs formData string false "京西门店ID列表" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /ScoreStore [post] +func (c *TempOpController) ScoreStore() { + c.callScoreStore(func(params *tTempopScoreStoreParams) (retVal interface{}, errCode string, err error) { + var storeIDList []int + if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDList); err == nil { + misc.ScoreStore(params.Ctx, storeIDList) + } + + return retVal, "", err + }) +} diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index c6cd714d0..b5564a00e 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -1674,6 +1674,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"], + beego.ControllerComments{ + Method: "ScoreStore", + Router: `/ScoreStore`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"], beego.ControllerComments{ Method: "TestIt", From b0022eb26ecc0f173cb5680b9f82a464ee9d10f8 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Fri, 6 Sep 2019 11:28:29 +0800 Subject: [PATCH 04/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E8=AF=84=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 64 ++++++++++++++-------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index 9d016ed65..7935c6314 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -65,6 +65,29 @@ func (s *StoreScoreDataWrapper) SetData(storeID int, valueName string, value int valueInfo.FieldByName(valueName).SetInt(int64(value)) } +//得到所有门店的商品 +func GetAllStoreSkus(ctx *jxcontext.Context, storeList []*cms.StoreExt) { + allStoreSkus = make(map[int]map[int]*cms.StoreSkuNameExt) + for _, storeInfo := range storeList { + storeID := storeInfo.ID + jxSkuInfoData, _ := cms.GetStoreSkus(ctx, storeID, []int{}, true, "", true, map[string]interface{}{}, 0, -1) + jxSkuMapData := make(map[int]*cms.StoreSkuNameExt) + for _, value := range jxSkuInfoData.SkuNames { + for _, skuInfo := range value.Skus2 { + saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus) + if saleStatus == model.SkuStatusNormal { + jxSkuMapData[skuInfo.SkuID] = value + } + } + } + allStoreSkus[storeID] = jxSkuMapData + } +} + +func ClearAllStoreSkus() { + allStoreSkus = nil +} + func GetOpenTime(opTimeList []int16) (opTime float64) { opTime = 0 for index, _ := range opTimeList { @@ -111,11 +134,11 @@ func ScoreStoreOpenTime(storeList []*cms.StoreExt) { func ScoreSaleSkuCount(ctx *jxcontext.Context, storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID - jxSkuInfoData, err := cms.GetStoreSkus(ctx, storeID, []int{}, true, "", true, map[string]interface{}{}, 0, -1) - if err == nil && len(jxSkuInfoData.SkuNames) > 0 { + skusMapData := allStoreSkus[storeID] + if len(skusMapData) > 0 { finalScore := 0 saleSkuCount := 0 - for _, value := range jxSkuInfoData.SkuNames { + for _, value := range skusMapData { for _, skuInfo := range value.Skus2 { saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus) if saleStatus == model.SkuStatusNormal { @@ -334,29 +357,6 @@ func GetRangeStoreList(storeID int, lng, lat, checkDist float64, storeList []*cm return outStoreList } -//得到所有门店的商品 -func GetAllStoreSkus(ctx *jxcontext.Context, storeList []*cms.StoreExt) { - allStoreSkus = make(map[int]map[int]*cms.StoreSkuNameExt) - for _, storeInfo := range storeList { - storeID := storeInfo.ID - jxSkuInfoData, _ := cms.GetStoreSkus(ctx, storeID, []int{}, true, "", true, map[string]interface{}{}, 0, -1) - jxSkuMapData := make(map[int]*cms.StoreSkuNameExt) - for _, value := range jxSkuInfoData.SkuNames { - for _, skuInfo := range value.Skus2 { - saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus) - if saleStatus == model.SkuStatusNormal { - jxSkuMapData[skuInfo.SkuID] = value - } - } - } - allStoreSkus[storeID] = jxSkuMapData - } -} - -func ClearAllStoreSkus() { - allStoreSkus = nil -} - //得到给定门店列表里的同一SkuID商品的平均价格 func GetStoreSkusAveragePrice(storeList []*cms.StoreExt) map[int]int { skusTotalPrice := make(map[int]int) @@ -392,7 +392,6 @@ func GetSkusCountLessEqualAvgPrice(storeID int, skusAveragePrice map[int]int) (c //可售商品价格在附近5km内门店比较,价格低于等于平均值的商品数占90%以上满分10分,比例每降低10%减1分,100%超标得0分 func ScoreSaleSkuPrice(ctx *jxcontext.Context, storeList []*cms.StoreExt) { - GetAllStoreSkus(ctx, storeList) for _, storeInfo := range storeList { finalScore := 0 storeID := storeInfo.ID @@ -414,7 +413,6 @@ func ScoreSaleSkuPrice(ctx *jxcontext.Context, storeList []*cms.StoreExt) { storeScoreDataWrapper.SetData(storeID, "SaleSkuPrice", finalScore) } } - ClearAllStoreSkus() } func GetFilterStoreListEx(storeList []*cms.StoreExt, storeIDMap map[int]int) (outStoreList []*cms.StoreExt) { @@ -443,17 +441,19 @@ func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, storeIDMap := jxutils.IntList2Map(storeIDList) storeList = GetFilterStoreListEx(storeList, storeIDMap) + // GetAllStoreSkus(ctx, storeList) ScoreStoreOpenTime(storeList) - ScoreSaleSkuCount(ctx, storeList) + // ScoreSaleSkuCount(ctx, storeList) ScoreAveragePickupTime(storeList) ScoreBadCommentOrder(storeList) ScoreUnfinishOrder(storeList) - ScoreAbsentGoodsOrder(storeList) + // ScoreAbsentGoodsOrder(storeList) ScorePromotionSku(storeList) ScoreFullVendor(storeList) ScoreStoreRange(storeList) - ScoreSaleSkuPrice(ctx, storeList) - InsertStoreScore() + // ScoreSaleSkuPrice(ctx, storeList) + // InsertStoreScore() + // ClearAllStoreSkus() return retVal, err } From 3c3be47085ea370fc5ec565afd867cf0cc786d82 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Fri, 6 Sep 2019 17:29:09 +0800 Subject: [PATCH 05/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E8=AF=84=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 174 +++++++++++++++++++------- business/model/dao/dao_order.go | 6 +- business/model/dao/store_score.go | 45 +++++++ controllers/temp_op.go | 16 +++ routers/commentsRouter_controllers.go | 9 ++ 5 files changed, 203 insertions(+), 47 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index 7935c6314..ce185ee44 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -6,6 +6,8 @@ import ( "sync" "time" + "git.rosy.net.cn/jx-callback/globals/refutil" + "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxstore/cms" "git.rosy.net.cn/jx-callback/business/jxutils" @@ -15,12 +17,12 @@ import ( ) const ( - ItemScore = 10 - TotalScore = 100 + ItemTotalScore = 10 + ItemCount = 10 StoreOpenTimeNormalTime = 12.0 //小时 SaleSkuNormalCount = 1000 - SaleSkuScorePerUnit = float64(ItemScore) / SaleSkuNormalCount + SaleSkuScorePerUnit = float64(ItemTotalScore) / SaleSkuNormalCount PromotionSkuNormalCount = 20 AveragePickupTimeNormalTime = 10.0 //分钟 BadCommentOrderNormalRatio = 0.2 @@ -28,19 +30,34 @@ const ( StoreRangeGoodRadius = 2.0 //千米 StoreRangeBadRadius = 1.0 //千米 SaleSkuPriceRatio = 90 //百分比 + + WeekDayCount = 7 ) var ( scoreStoreTimeList = []string{ "23:30:00", } - storeScoreDataWrapper StoreScoreDataWrapper - fullVendorList = map[int]bool{ + fullVendorList = map[int]bool{ model.VendorIDJD: true, model.VendorIDMTWM: true, model.VendorIDEBAI: true, } - allStoreSkus map[int]map[int]*cms.StoreSkuNameExt + storeScoreFieldName = []string{ + "StoreOpenTime", + "SaleSkuCount", + "AveragePickupTime", + "BadCommentOrder", + "UnfinishOrder", + "AbsentGoodsOrder", + "PromotionSku", + "FullVendor", + "StoreRange", + "SaleSkuPrice", + } + + storeScoreDataWrapper StoreScoreDataWrapper + allStoreSkus map[int]map[int]*cms.StoreSkuNameExt ) type StoreScoreDataWrapper struct { @@ -52,13 +69,14 @@ func (s *StoreScoreDataWrapper) InitData() { s.storeScoreData = make(map[int]*model.StoreScore) } -func (s *StoreScoreDataWrapper) SetData(storeID int, valueName string, value int) { +func (s *StoreScoreDataWrapper) SetData(storeID int, storeName, valueName string, value int) { s.locker.Lock() defer s.locker.Unlock() data := s.storeScoreData[storeID] if data == nil { data = &model.StoreScore{} data.StoreID = storeID + data.StoreName = storeName s.storeScoreData[storeID] = data } valueInfo := reflect.ValueOf(data).Elem() @@ -106,6 +124,7 @@ func GetOpenTime(opTimeList []int16) (opTime float64) { func ScoreStoreOpenTime(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID + storeName := storeInfo.Name storeStatus := storeInfo.Status isStoreOpen := storeStatus == model.StoreStatusOpened for _, storeMap := range storeInfo.StoreMaps { @@ -116,15 +135,15 @@ func ScoreStoreOpenTime(storeList []*cms.StoreExt) { finalScore := 0 opTime := GetOpenTime(opTimeList) if opTime >= StoreOpenTimeNormalTime { - finalScore = ItemScore + finalScore = ItemTotalScore } else { decScore := int(math.Round(StoreOpenTimeNormalTime - opTime)) - finalScore = ItemScore - decScore + finalScore = ItemTotalScore - decScore if finalScore < 0 { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, "StoreOpenTime", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "StoreOpenTime", finalScore) } } } @@ -134,6 +153,7 @@ func ScoreStoreOpenTime(storeList []*cms.StoreExt) { func ScoreSaleSkuCount(ctx *jxcontext.Context, storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID + storeName := storeInfo.Name skusMapData := allStoreSkus[storeID] if len(skusMapData) > 0 { finalScore := 0 @@ -147,10 +167,10 @@ func ScoreSaleSkuCount(ctx *jxcontext.Context, storeList []*cms.StoreExt) { } } finalScore = int(math.Round(float64(saleSkuCount) * SaleSkuScorePerUnit)) - if finalScore > ItemScore { - finalScore = ItemScore + if finalScore > ItemTotalScore { + finalScore = ItemTotalScore } - storeScoreDataWrapper.SetData(storeID, "SaleSkuCount", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "SaleSkuCount", finalScore) } } } @@ -159,6 +179,7 @@ func ScoreSaleSkuCount(ctx *jxcontext.Context, storeList []*cms.StoreExt) { func ScoreAveragePickupTime(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID + storeName := storeInfo.Name db := dao.GetDB() orderList, err := dao.GetDailyFinishOrderList(db, storeID) orderListCount := len(orderList) @@ -168,10 +189,10 @@ func ScoreAveragePickupTime(storeList []*cms.StoreExt) { statusTime := value.StatusTime.Unix() pickDeadline := value.PickDeadline.Unix() if statusTime <= pickDeadline { - totalScore += ItemScore + totalScore += ItemTotalScore } else { decScore := int(math.Round(float64(statusTime-pickDeadline) / 60)) - tempScore := ItemScore - decScore + tempScore := ItemTotalScore - decScore if tempScore < 0 { tempScore = 0 } @@ -179,7 +200,7 @@ func ScoreAveragePickupTime(storeList []*cms.StoreExt) { } } finalScore := totalScore / orderListCount - storeScoreDataWrapper.SetData(storeID, "AveragePickupTime", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "AveragePickupTime", finalScore) } } } @@ -188,6 +209,7 @@ func ScoreAveragePickupTime(storeList []*cms.StoreExt) { func ScoreBadCommentOrder(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID + storeName := storeInfo.Name db := dao.GetDB() badCommentOrderCount, _ := dao.GetDailyBadCommentOrderCount(db, storeID) finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) @@ -195,15 +217,15 @@ func ScoreBadCommentOrder(storeList []*cms.StoreExt) { finalScore := 0 badCommentOrderRatio := float64(badCommentOrderCount) * 100 / float64(finishOrderCount) if badCommentOrderRatio <= BadCommentOrderNormalRatio { - finalScore = ItemScore + finalScore = ItemTotalScore } else { decScore := int(math.Round((badCommentOrderRatio - BadCommentOrderNormalRatio) / 0.1)) - finalScore = ItemScore - decScore + finalScore = ItemTotalScore - decScore if finalScore < 0 { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, "BadCommentOrder", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "BadCommentOrder", finalScore) } } } @@ -212,6 +234,7 @@ func ScoreBadCommentOrder(storeList []*cms.StoreExt) { func ScoreUnfinishOrder(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID + storeName := storeInfo.Name db := dao.GetDB() unFinishOrderCount, _ := dao.GetDailyUnFinishOrderCount(db, storeID) finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) @@ -219,15 +242,15 @@ func ScoreUnfinishOrder(storeList []*cms.StoreExt) { finalScore := 0 unfinishOrderRatio := float64(unFinishOrderCount) * 100 / float64(finishOrderCount) if unfinishOrderRatio <= UnfinishOrderNormalRatio { - finalScore = ItemScore + finalScore = ItemTotalScore } else { decScore := int(math.Round((unfinishOrderRatio - UnfinishOrderNormalRatio) / 5)) - finalScore = ItemScore - decScore + finalScore = ItemTotalScore - decScore if finalScore < 0 { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, "UnfinishOrder", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "UnfinishOrder", finalScore) } } } @@ -241,6 +264,7 @@ func ScoreAbsentGoodsOrder(storeList []*cms.StoreExt) { func ScorePromotionSku(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID + storeName := storeInfo.Name db := dao.GetDB() beginTime := time.Now() endTime := time.Now() @@ -255,15 +279,15 @@ func ScorePromotionSku(storeList []*cms.StoreExt) { } promotionSkuCount := len(actStoreSkuMap) if promotionSkuCount >= PromotionSkuNormalCount { - finalScore = ItemScore + finalScore = ItemTotalScore } else { decScore := (PromotionSkuNormalCount - promotionSkuCount) / 2 - finalScore = ItemScore - decScore + finalScore = ItemTotalScore - decScore if finalScore < 0 { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, "PromotionSku", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "PromotionSku", finalScore) } } } @@ -274,6 +298,7 @@ func ScoreFullVendor(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { finalScore := 0 storeID := storeInfo.ID + storeName := storeInfo.Name storeStatus := storeInfo.Status isStoreOpen := storeStatus == model.StoreStatusOpened count := 0 @@ -286,12 +311,12 @@ func ScoreFullVendor(storeList []*cms.StoreExt) { } } if count == fullVendorCount { - finalScore = ItemScore + finalScore = ItemTotalScore } else { decScore := (fullVendorCount - count) * 2 - finalScore = ItemScore - decScore + finalScore = ItemTotalScore - decScore } - storeScoreDataWrapper.SetData(storeID, "FullVendor", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "FullVendor", finalScore) } } @@ -311,33 +336,34 @@ func ScoreStoreRange(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { finalScore := 0 storeID := storeInfo.ID + storeName := storeInfo.Name if storeInfo.DeliveryRangeType == model.DeliveryRangeTypePolygon { points := jxutils.CoordinateStr2Points(storeInfo.DeliveryRange) area := CalcPolygonArea(points) goodArea := math.Pi * StoreRangeGoodRadius * StoreRangeGoodRadius badArea := math.Pi * StoreRangeBadRadius * StoreRangeBadRadius if area >= goodArea { - finalScore = ItemScore + finalScore = ItemTotalScore } else if area <= badArea { finalScore = 0 } else { diff := goodArea - area - ratio := float64(ItemScore) / (goodArea - badArea) - finalScore = ItemScore - int(math.Round(diff*ratio)) + ratio := float64(ItemTotalScore) / (goodArea - badArea) + finalScore = ItemTotalScore - int(math.Round(diff*ratio)) } } else if storeInfo.DeliveryRangeType == model.DeliveryRangeTypeRadius { deliveryRadius := utils.Str2Float64WithDefault(storeInfo.DeliveryRange, 0) if deliveryRadius >= StoreRangeGoodRadius { - finalScore = ItemScore + finalScore = ItemTotalScore } else if deliveryRadius <= StoreRangeBadRadius { finalScore = 0 } else { diff := StoreRangeGoodRadius - deliveryRadius - ratio := float64(ItemScore) / (StoreRangeGoodRadius - StoreRangeBadRadius) - finalScore = ItemScore - int(math.Round(diff*ratio)) + ratio := float64(ItemTotalScore) / (StoreRangeGoodRadius - StoreRangeBadRadius) + finalScore = ItemTotalScore - int(math.Round(diff*ratio)) } } - storeScoreDataWrapper.SetData(storeID, "StoreRange", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "StoreRange", finalScore) } } @@ -395,6 +421,7 @@ func ScoreSaleSkuPrice(ctx *jxcontext.Context, storeList []*cms.StoreExt) { for _, storeInfo := range storeList { finalScore := 0 storeID := storeInfo.ID + storeName := storeInfo.Name totalCount := len(allStoreSkus[storeID]) if totalCount > 0 { rangeStoreList := GetRangeStoreList(storeID, storeInfo.FloatLng, storeInfo.FloatLat, 5, storeList) @@ -402,15 +429,15 @@ func ScoreSaleSkuPrice(ctx *jxcontext.Context, storeList []*cms.StoreExt) { count := GetSkusCountLessEqualAvgPrice(storeID, skusAveragePrice) ratio := int(math.Round(float64(count) * 100 / float64(totalCount))) if ratio >= SaleSkuPriceRatio { - finalScore = ItemScore + finalScore = ItemTotalScore } else { decScore := (SaleSkuPriceRatio - ratio) / 10 - finalScore = ItemScore - decScore + finalScore = ItemTotalScore - decScore if finalScore < 0 { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, "SaleSkuPrice", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "SaleSkuPrice", finalScore) } } } @@ -441,19 +468,19 @@ func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, storeIDMap := jxutils.IntList2Map(storeIDList) storeList = GetFilterStoreListEx(storeList, storeIDMap) - // GetAllStoreSkus(ctx, storeList) + GetAllStoreSkus(ctx, storeList) ScoreStoreOpenTime(storeList) - // ScoreSaleSkuCount(ctx, storeList) + ScoreSaleSkuCount(ctx, storeList) ScoreAveragePickupTime(storeList) ScoreBadCommentOrder(storeList) ScoreUnfinishOrder(storeList) - // ScoreAbsentGoodsOrder(storeList) + ScoreAbsentGoodsOrder(storeList) ScorePromotionSku(storeList) ScoreFullVendor(storeList) ScoreStoreRange(storeList) - // ScoreSaleSkuPrice(ctx, storeList) - // InsertStoreScore() - // ClearAllStoreSkus() + ScoreSaleSkuPrice(ctx, storeList) + InsertStoreScore() + ClearAllStoreSkus() return retVal, err } @@ -469,3 +496,62 @@ func ScheduleScoreStore() { ScoreStore(jxcontext.AdminCtx, []int{}) }, scoreStoreTimeList) } + +func SplitToSingelWeekDataList(storeScoreList []*model.StoreScore) (weekDataList [][]*model.StoreScore) { + singelWeekData := []*model.StoreScore{} + count := 0 + for _, value := range storeScoreList { + singelWeekData = append(singelWeekData, value) + count++ + if count == WeekDayCount { + weekDataList = append(weekDataList, singelWeekData) + singelWeekData = []*model.StoreScore{} + count = 0 + } + } + + return weekDataList +} + +func GetWeeklyStoreScore(storeID, weekIndex int) (outWeeklyStoreScoreDataList []*model.WeeklyStoreScore, err error) { + db := dao.GetDB() + storeScoreList, err := dao.GetLatestWeeklyStoreScoreList(db, storeID, 5) + if err == nil && len(storeScoreList) > 0 { + weeklyStoreScoreDataList := []*model.WeeklyStoreScore{} + weekDataList := SplitToSingelWeekDataList(storeScoreList) + for weekIndex, weekDataList := range weekDataList { + weeklyData := &model.WeeklyStoreScore{} + weeklyData.ID = weekIndex + weeklyData.ItemTotalScore = ItemTotalScore + weeklyStoreScoreDataList = append(weeklyStoreScoreDataList, weeklyData) + for dayIndex, dayData := range weekDataList { + for _, fieldName := range storeScoreFieldName { + srcFieldValue := refutil.GetObjFieldByName(dayData, fieldName).(int) + destFieldValueR := refutil.GetObjFieldByName(weeklyData, fieldName).(int) + refutil.SetObjFieldByName(weeklyData, fieldName, destFieldValueR+srcFieldValue) + } + if dayIndex == 0 { + weeklyData.BeginTime = dayData.CreatedAt + } else if dayIndex == WeekDayCount-1 { + weeklyData.EndTime = dayData.CreatedAt + } + } + for _, fieldName := range storeScoreFieldName { + destFieldValueR := refutil.GetObjFieldByName(weeklyData, fieldName).(int) + refutil.SetObjFieldByName(weeklyData, fieldName, int(math.Round(float64(destFieldValueR)/WeekDayCount))) + } + for _, fieldName := range storeScoreFieldName { + srcFieldValue := refutil.GetObjFieldByName(weeklyData, fieldName).(int) + destFieldValueR := refutil.GetObjFieldByName(weeklyData, "TotalScore").(int) + refutil.SetObjFieldByName(weeklyData, "TotalScore", destFieldValueR+srcFieldValue) + } + } + if weekIndex == -1 { + outWeeklyStoreScoreDataList = weeklyStoreScoreDataList + } else { + outWeeklyStoreScoreDataList = []*model.WeeklyStoreScore{weeklyStoreScoreDataList[weekIndex]} + } + } + + return outWeeklyStoreScoreDataList, err +} diff --git a/business/model/dao/dao_order.go b/business/model/dao/dao_order.go index 2d7f7220b..c5297e687 100644 --- a/business/model/dao/dao_order.go +++ b/business/model/dao/dao_order.go @@ -296,7 +296,7 @@ func GetDailyFinishOrderList(db *DaoDB, storeID int) (orderList []*model.OrderPi select t2.status_time, t1.pick_deadline from goods_order t1 left join order_status t2 on t1.vendor_order_id = t2.vendor_order_id - where t1.jx_store_id = ? and t2.order_type = ? and t2.status = ? and DATE_FORMAT(t1.order_finished_at, '%Y-%m-%d') = DATE_FORMAT(NOW(), '%Y-%m-%d') + where t1.jx_store_id = ? and t2.order_type = ? and t2.status = ? and DATE(t1.order_finished_at) = CURDATE() ` sqlParams := []interface{}{ storeID, @@ -307,7 +307,7 @@ func GetDailyFinishOrderList(db *DaoDB, storeID int) (orderList []*model.OrderPi } func GetDailyBadCommentOrderCount(db *DaoDB, storeID int) (num int64, err error) { - sql := `select count(*) from jx_bad_comments where DATE_FORMAT(createtime, '%Y-%m-%d') = DATE_FORMAT(NOW(), '%Y-%m-%d') and jxstoreid = ?` + sql := `select count(*) from jx_bad_comments where DATE(createtime) = CURDATE() and jxstoreid = ?` sqlParams := []interface{}{ storeID, } @@ -324,7 +324,7 @@ func GetDailyFinishOrderCount(db *DaoDB, storeID int) (num int64, err error) { func GetDailyEndOrderCount(db *DaoDB, storeID int, statusList []int) (num int64, err error) { sql := `select count(*) from goods_order - where DATE_FORMAT(order_finished_at, '%Y-%m-%d') = DATE_FORMAT(NOW(), '%Y-%m-%d') + where DATE(order_finished_at) = CURDATE() and jx_store_id = ? and status in (` + GenQuestionMarks(len(statusList)) + `)` sqlParams := []interface{}{ diff --git a/business/model/dao/store_score.go b/business/model/dao/store_score.go index 4f4f5735f..dfc19fc30 100644 --- a/business/model/dao/store_score.go +++ b/business/model/dao/store_score.go @@ -11,3 +11,48 @@ func InsertStoreScore(storeScore *model.StoreScore) error { storeScore.CreatedAt = time.Now() return CreateEntity(nil, storeScore) } + +func GetLatestWeeklyStoreScoreList(db *DaoDB, storeID, weekNum int) (storeScoreList []*model.StoreScore, err error) { + // sql := ` + // SET @dayInWeek = IF(DAYOFWEEK(CURDATE()) - 1 = 0, 7, DAYOFWEEK(CURDATE()) - 1); + // SET @endDate = DATE_SUB(CURDATE(), INTERVAL @dayInWeek DAY); + // SET @beginData = DATE_SUB(@endDate, INTERVAL ? DAY); + // SELECT * FROM store_score + // WHERE store_id = ? AND DATE(created_at) >= @beginData AND DATE(created_at) <= @endDate ORDER BY created_at DESC + // ` + sql := ` + SELECT * FROM store_score WHERE store_id = ? + AND DATE(created_at) >= DATE_SUB( + DATE_SUB( + CURDATE(), + INTERVAL + IF ( + DAYOFWEEK(CURDATE()) - 1 = 0, + 7, + DAYOFWEEK(CURDATE()) - 1 + ) DAY + ), + INTERVAL ? DAY + ) + AND DATE(created_at) <= DATE_SUB( + CURDATE(), + INTERVAL + IF ( + DAYOFWEEK(CURDATE()) - 1 = 0, + 7, + DAYOFWEEK(CURDATE()) - 1 + ) DAY + ) + ORDER BY created_at DESC + ` + if weekNum <= 0 { + weekNum = 1 + } + diffDays := weekNum*7 - 1 + sqlParams := []interface{}{ + storeID, + diffDays, + } + err = GetRows(db, &storeScoreList, sql, sqlParams) + return storeScoreList, err +} diff --git a/controllers/temp_op.go b/controllers/temp_op.go index dc3603980..b1249758f 100644 --- a/controllers/temp_op.go +++ b/controllers/temp_op.go @@ -334,3 +334,19 @@ func (c *TempOpController) ScoreStore() { return retVal, "", err }) } + +// @Title 得到门店周平均分数数据 +// @Description 得到门店周平均分数数据 +// @Param token header string true "认证token" +// @Param storeID query int true "京西门店ID" +// @Param weekIndex query int true "周索引(起始索引为0, -1为所有周数据)" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /GetWeeklyStoreScore [get] +func (c *TempOpController) GetWeeklyStoreScore() { + c.callGetWeeklyStoreScore(func(params *tTempopGetWeeklyStoreScoreParams) (retVal interface{}, errCode string, err error) { + retVal, err = misc.GetWeeklyStoreScore(params.StoreID, params.WeekIndex) + + return retVal, "", err + }) +} diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index b5564a00e..c4b114faf 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -1647,6 +1647,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"], + beego.ControllerComments{ + Method: "GetWeeklyStoreScore", + Router: `/GetWeeklyStoreScore`, + AllowHTTPMethods: []string{"get"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"], beego.ControllerComments{ Method: "PrintMsg", From 52bdbdb4ffe4fcc9616c33c46b28f896b3049d4b Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Fri, 6 Sep 2019 17:29:09 +0800 Subject: [PATCH 06/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E8=AF=84=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 174 +++++++++++++++++++------- business/model/dao/dao_order.go | 6 +- business/model/dao/store_score.go | 45 +++++++ business/model/store_score.go | 9 ++ controllers/temp_op.go | 16 +++ routers/commentsRouter_controllers.go | 9 ++ 6 files changed, 212 insertions(+), 47 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index 7935c6314..ce185ee44 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -6,6 +6,8 @@ import ( "sync" "time" + "git.rosy.net.cn/jx-callback/globals/refutil" + "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxstore/cms" "git.rosy.net.cn/jx-callback/business/jxutils" @@ -15,12 +17,12 @@ import ( ) const ( - ItemScore = 10 - TotalScore = 100 + ItemTotalScore = 10 + ItemCount = 10 StoreOpenTimeNormalTime = 12.0 //小时 SaleSkuNormalCount = 1000 - SaleSkuScorePerUnit = float64(ItemScore) / SaleSkuNormalCount + SaleSkuScorePerUnit = float64(ItemTotalScore) / SaleSkuNormalCount PromotionSkuNormalCount = 20 AveragePickupTimeNormalTime = 10.0 //分钟 BadCommentOrderNormalRatio = 0.2 @@ -28,19 +30,34 @@ const ( StoreRangeGoodRadius = 2.0 //千米 StoreRangeBadRadius = 1.0 //千米 SaleSkuPriceRatio = 90 //百分比 + + WeekDayCount = 7 ) var ( scoreStoreTimeList = []string{ "23:30:00", } - storeScoreDataWrapper StoreScoreDataWrapper - fullVendorList = map[int]bool{ + fullVendorList = map[int]bool{ model.VendorIDJD: true, model.VendorIDMTWM: true, model.VendorIDEBAI: true, } - allStoreSkus map[int]map[int]*cms.StoreSkuNameExt + storeScoreFieldName = []string{ + "StoreOpenTime", + "SaleSkuCount", + "AveragePickupTime", + "BadCommentOrder", + "UnfinishOrder", + "AbsentGoodsOrder", + "PromotionSku", + "FullVendor", + "StoreRange", + "SaleSkuPrice", + } + + storeScoreDataWrapper StoreScoreDataWrapper + allStoreSkus map[int]map[int]*cms.StoreSkuNameExt ) type StoreScoreDataWrapper struct { @@ -52,13 +69,14 @@ func (s *StoreScoreDataWrapper) InitData() { s.storeScoreData = make(map[int]*model.StoreScore) } -func (s *StoreScoreDataWrapper) SetData(storeID int, valueName string, value int) { +func (s *StoreScoreDataWrapper) SetData(storeID int, storeName, valueName string, value int) { s.locker.Lock() defer s.locker.Unlock() data := s.storeScoreData[storeID] if data == nil { data = &model.StoreScore{} data.StoreID = storeID + data.StoreName = storeName s.storeScoreData[storeID] = data } valueInfo := reflect.ValueOf(data).Elem() @@ -106,6 +124,7 @@ func GetOpenTime(opTimeList []int16) (opTime float64) { func ScoreStoreOpenTime(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID + storeName := storeInfo.Name storeStatus := storeInfo.Status isStoreOpen := storeStatus == model.StoreStatusOpened for _, storeMap := range storeInfo.StoreMaps { @@ -116,15 +135,15 @@ func ScoreStoreOpenTime(storeList []*cms.StoreExt) { finalScore := 0 opTime := GetOpenTime(opTimeList) if opTime >= StoreOpenTimeNormalTime { - finalScore = ItemScore + finalScore = ItemTotalScore } else { decScore := int(math.Round(StoreOpenTimeNormalTime - opTime)) - finalScore = ItemScore - decScore + finalScore = ItemTotalScore - decScore if finalScore < 0 { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, "StoreOpenTime", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "StoreOpenTime", finalScore) } } } @@ -134,6 +153,7 @@ func ScoreStoreOpenTime(storeList []*cms.StoreExt) { func ScoreSaleSkuCount(ctx *jxcontext.Context, storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID + storeName := storeInfo.Name skusMapData := allStoreSkus[storeID] if len(skusMapData) > 0 { finalScore := 0 @@ -147,10 +167,10 @@ func ScoreSaleSkuCount(ctx *jxcontext.Context, storeList []*cms.StoreExt) { } } finalScore = int(math.Round(float64(saleSkuCount) * SaleSkuScorePerUnit)) - if finalScore > ItemScore { - finalScore = ItemScore + if finalScore > ItemTotalScore { + finalScore = ItemTotalScore } - storeScoreDataWrapper.SetData(storeID, "SaleSkuCount", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "SaleSkuCount", finalScore) } } } @@ -159,6 +179,7 @@ func ScoreSaleSkuCount(ctx *jxcontext.Context, storeList []*cms.StoreExt) { func ScoreAveragePickupTime(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID + storeName := storeInfo.Name db := dao.GetDB() orderList, err := dao.GetDailyFinishOrderList(db, storeID) orderListCount := len(orderList) @@ -168,10 +189,10 @@ func ScoreAveragePickupTime(storeList []*cms.StoreExt) { statusTime := value.StatusTime.Unix() pickDeadline := value.PickDeadline.Unix() if statusTime <= pickDeadline { - totalScore += ItemScore + totalScore += ItemTotalScore } else { decScore := int(math.Round(float64(statusTime-pickDeadline) / 60)) - tempScore := ItemScore - decScore + tempScore := ItemTotalScore - decScore if tempScore < 0 { tempScore = 0 } @@ -179,7 +200,7 @@ func ScoreAveragePickupTime(storeList []*cms.StoreExt) { } } finalScore := totalScore / orderListCount - storeScoreDataWrapper.SetData(storeID, "AveragePickupTime", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "AveragePickupTime", finalScore) } } } @@ -188,6 +209,7 @@ func ScoreAveragePickupTime(storeList []*cms.StoreExt) { func ScoreBadCommentOrder(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID + storeName := storeInfo.Name db := dao.GetDB() badCommentOrderCount, _ := dao.GetDailyBadCommentOrderCount(db, storeID) finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) @@ -195,15 +217,15 @@ func ScoreBadCommentOrder(storeList []*cms.StoreExt) { finalScore := 0 badCommentOrderRatio := float64(badCommentOrderCount) * 100 / float64(finishOrderCount) if badCommentOrderRatio <= BadCommentOrderNormalRatio { - finalScore = ItemScore + finalScore = ItemTotalScore } else { decScore := int(math.Round((badCommentOrderRatio - BadCommentOrderNormalRatio) / 0.1)) - finalScore = ItemScore - decScore + finalScore = ItemTotalScore - decScore if finalScore < 0 { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, "BadCommentOrder", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "BadCommentOrder", finalScore) } } } @@ -212,6 +234,7 @@ func ScoreBadCommentOrder(storeList []*cms.StoreExt) { func ScoreUnfinishOrder(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID + storeName := storeInfo.Name db := dao.GetDB() unFinishOrderCount, _ := dao.GetDailyUnFinishOrderCount(db, storeID) finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) @@ -219,15 +242,15 @@ func ScoreUnfinishOrder(storeList []*cms.StoreExt) { finalScore := 0 unfinishOrderRatio := float64(unFinishOrderCount) * 100 / float64(finishOrderCount) if unfinishOrderRatio <= UnfinishOrderNormalRatio { - finalScore = ItemScore + finalScore = ItemTotalScore } else { decScore := int(math.Round((unfinishOrderRatio - UnfinishOrderNormalRatio) / 5)) - finalScore = ItemScore - decScore + finalScore = ItemTotalScore - decScore if finalScore < 0 { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, "UnfinishOrder", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "UnfinishOrder", finalScore) } } } @@ -241,6 +264,7 @@ func ScoreAbsentGoodsOrder(storeList []*cms.StoreExt) { func ScorePromotionSku(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID + storeName := storeInfo.Name db := dao.GetDB() beginTime := time.Now() endTime := time.Now() @@ -255,15 +279,15 @@ func ScorePromotionSku(storeList []*cms.StoreExt) { } promotionSkuCount := len(actStoreSkuMap) if promotionSkuCount >= PromotionSkuNormalCount { - finalScore = ItemScore + finalScore = ItemTotalScore } else { decScore := (PromotionSkuNormalCount - promotionSkuCount) / 2 - finalScore = ItemScore - decScore + finalScore = ItemTotalScore - decScore if finalScore < 0 { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, "PromotionSku", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "PromotionSku", finalScore) } } } @@ -274,6 +298,7 @@ func ScoreFullVendor(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { finalScore := 0 storeID := storeInfo.ID + storeName := storeInfo.Name storeStatus := storeInfo.Status isStoreOpen := storeStatus == model.StoreStatusOpened count := 0 @@ -286,12 +311,12 @@ func ScoreFullVendor(storeList []*cms.StoreExt) { } } if count == fullVendorCount { - finalScore = ItemScore + finalScore = ItemTotalScore } else { decScore := (fullVendorCount - count) * 2 - finalScore = ItemScore - decScore + finalScore = ItemTotalScore - decScore } - storeScoreDataWrapper.SetData(storeID, "FullVendor", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "FullVendor", finalScore) } } @@ -311,33 +336,34 @@ func ScoreStoreRange(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { finalScore := 0 storeID := storeInfo.ID + storeName := storeInfo.Name if storeInfo.DeliveryRangeType == model.DeliveryRangeTypePolygon { points := jxutils.CoordinateStr2Points(storeInfo.DeliveryRange) area := CalcPolygonArea(points) goodArea := math.Pi * StoreRangeGoodRadius * StoreRangeGoodRadius badArea := math.Pi * StoreRangeBadRadius * StoreRangeBadRadius if area >= goodArea { - finalScore = ItemScore + finalScore = ItemTotalScore } else if area <= badArea { finalScore = 0 } else { diff := goodArea - area - ratio := float64(ItemScore) / (goodArea - badArea) - finalScore = ItemScore - int(math.Round(diff*ratio)) + ratio := float64(ItemTotalScore) / (goodArea - badArea) + finalScore = ItemTotalScore - int(math.Round(diff*ratio)) } } else if storeInfo.DeliveryRangeType == model.DeliveryRangeTypeRadius { deliveryRadius := utils.Str2Float64WithDefault(storeInfo.DeliveryRange, 0) if deliveryRadius >= StoreRangeGoodRadius { - finalScore = ItemScore + finalScore = ItemTotalScore } else if deliveryRadius <= StoreRangeBadRadius { finalScore = 0 } else { diff := StoreRangeGoodRadius - deliveryRadius - ratio := float64(ItemScore) / (StoreRangeGoodRadius - StoreRangeBadRadius) - finalScore = ItemScore - int(math.Round(diff*ratio)) + ratio := float64(ItemTotalScore) / (StoreRangeGoodRadius - StoreRangeBadRadius) + finalScore = ItemTotalScore - int(math.Round(diff*ratio)) } } - storeScoreDataWrapper.SetData(storeID, "StoreRange", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "StoreRange", finalScore) } } @@ -395,6 +421,7 @@ func ScoreSaleSkuPrice(ctx *jxcontext.Context, storeList []*cms.StoreExt) { for _, storeInfo := range storeList { finalScore := 0 storeID := storeInfo.ID + storeName := storeInfo.Name totalCount := len(allStoreSkus[storeID]) if totalCount > 0 { rangeStoreList := GetRangeStoreList(storeID, storeInfo.FloatLng, storeInfo.FloatLat, 5, storeList) @@ -402,15 +429,15 @@ func ScoreSaleSkuPrice(ctx *jxcontext.Context, storeList []*cms.StoreExt) { count := GetSkusCountLessEqualAvgPrice(storeID, skusAveragePrice) ratio := int(math.Round(float64(count) * 100 / float64(totalCount))) if ratio >= SaleSkuPriceRatio { - finalScore = ItemScore + finalScore = ItemTotalScore } else { decScore := (SaleSkuPriceRatio - ratio) / 10 - finalScore = ItemScore - decScore + finalScore = ItemTotalScore - decScore if finalScore < 0 { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, "SaleSkuPrice", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, "SaleSkuPrice", finalScore) } } } @@ -441,19 +468,19 @@ func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, storeIDMap := jxutils.IntList2Map(storeIDList) storeList = GetFilterStoreListEx(storeList, storeIDMap) - // GetAllStoreSkus(ctx, storeList) + GetAllStoreSkus(ctx, storeList) ScoreStoreOpenTime(storeList) - // ScoreSaleSkuCount(ctx, storeList) + ScoreSaleSkuCount(ctx, storeList) ScoreAveragePickupTime(storeList) ScoreBadCommentOrder(storeList) ScoreUnfinishOrder(storeList) - // ScoreAbsentGoodsOrder(storeList) + ScoreAbsentGoodsOrder(storeList) ScorePromotionSku(storeList) ScoreFullVendor(storeList) ScoreStoreRange(storeList) - // ScoreSaleSkuPrice(ctx, storeList) - // InsertStoreScore() - // ClearAllStoreSkus() + ScoreSaleSkuPrice(ctx, storeList) + InsertStoreScore() + ClearAllStoreSkus() return retVal, err } @@ -469,3 +496,62 @@ func ScheduleScoreStore() { ScoreStore(jxcontext.AdminCtx, []int{}) }, scoreStoreTimeList) } + +func SplitToSingelWeekDataList(storeScoreList []*model.StoreScore) (weekDataList [][]*model.StoreScore) { + singelWeekData := []*model.StoreScore{} + count := 0 + for _, value := range storeScoreList { + singelWeekData = append(singelWeekData, value) + count++ + if count == WeekDayCount { + weekDataList = append(weekDataList, singelWeekData) + singelWeekData = []*model.StoreScore{} + count = 0 + } + } + + return weekDataList +} + +func GetWeeklyStoreScore(storeID, weekIndex int) (outWeeklyStoreScoreDataList []*model.WeeklyStoreScore, err error) { + db := dao.GetDB() + storeScoreList, err := dao.GetLatestWeeklyStoreScoreList(db, storeID, 5) + if err == nil && len(storeScoreList) > 0 { + weeklyStoreScoreDataList := []*model.WeeklyStoreScore{} + weekDataList := SplitToSingelWeekDataList(storeScoreList) + for weekIndex, weekDataList := range weekDataList { + weeklyData := &model.WeeklyStoreScore{} + weeklyData.ID = weekIndex + weeklyData.ItemTotalScore = ItemTotalScore + weeklyStoreScoreDataList = append(weeklyStoreScoreDataList, weeklyData) + for dayIndex, dayData := range weekDataList { + for _, fieldName := range storeScoreFieldName { + srcFieldValue := refutil.GetObjFieldByName(dayData, fieldName).(int) + destFieldValueR := refutil.GetObjFieldByName(weeklyData, fieldName).(int) + refutil.SetObjFieldByName(weeklyData, fieldName, destFieldValueR+srcFieldValue) + } + if dayIndex == 0 { + weeklyData.BeginTime = dayData.CreatedAt + } else if dayIndex == WeekDayCount-1 { + weeklyData.EndTime = dayData.CreatedAt + } + } + for _, fieldName := range storeScoreFieldName { + destFieldValueR := refutil.GetObjFieldByName(weeklyData, fieldName).(int) + refutil.SetObjFieldByName(weeklyData, fieldName, int(math.Round(float64(destFieldValueR)/WeekDayCount))) + } + for _, fieldName := range storeScoreFieldName { + srcFieldValue := refutil.GetObjFieldByName(weeklyData, fieldName).(int) + destFieldValueR := refutil.GetObjFieldByName(weeklyData, "TotalScore").(int) + refutil.SetObjFieldByName(weeklyData, "TotalScore", destFieldValueR+srcFieldValue) + } + } + if weekIndex == -1 { + outWeeklyStoreScoreDataList = weeklyStoreScoreDataList + } else { + outWeeklyStoreScoreDataList = []*model.WeeklyStoreScore{weeklyStoreScoreDataList[weekIndex]} + } + } + + return outWeeklyStoreScoreDataList, err +} diff --git a/business/model/dao/dao_order.go b/business/model/dao/dao_order.go index 2d7f7220b..c5297e687 100644 --- a/business/model/dao/dao_order.go +++ b/business/model/dao/dao_order.go @@ -296,7 +296,7 @@ func GetDailyFinishOrderList(db *DaoDB, storeID int) (orderList []*model.OrderPi select t2.status_time, t1.pick_deadline from goods_order t1 left join order_status t2 on t1.vendor_order_id = t2.vendor_order_id - where t1.jx_store_id = ? and t2.order_type = ? and t2.status = ? and DATE_FORMAT(t1.order_finished_at, '%Y-%m-%d') = DATE_FORMAT(NOW(), '%Y-%m-%d') + where t1.jx_store_id = ? and t2.order_type = ? and t2.status = ? and DATE(t1.order_finished_at) = CURDATE() ` sqlParams := []interface{}{ storeID, @@ -307,7 +307,7 @@ func GetDailyFinishOrderList(db *DaoDB, storeID int) (orderList []*model.OrderPi } func GetDailyBadCommentOrderCount(db *DaoDB, storeID int) (num int64, err error) { - sql := `select count(*) from jx_bad_comments where DATE_FORMAT(createtime, '%Y-%m-%d') = DATE_FORMAT(NOW(), '%Y-%m-%d') and jxstoreid = ?` + sql := `select count(*) from jx_bad_comments where DATE(createtime) = CURDATE() and jxstoreid = ?` sqlParams := []interface{}{ storeID, } @@ -324,7 +324,7 @@ func GetDailyFinishOrderCount(db *DaoDB, storeID int) (num int64, err error) { func GetDailyEndOrderCount(db *DaoDB, storeID int, statusList []int) (num int64, err error) { sql := `select count(*) from goods_order - where DATE_FORMAT(order_finished_at, '%Y-%m-%d') = DATE_FORMAT(NOW(), '%Y-%m-%d') + where DATE(order_finished_at) = CURDATE() and jx_store_id = ? and status in (` + GenQuestionMarks(len(statusList)) + `)` sqlParams := []interface{}{ diff --git a/business/model/dao/store_score.go b/business/model/dao/store_score.go index 4f4f5735f..dfc19fc30 100644 --- a/business/model/dao/store_score.go +++ b/business/model/dao/store_score.go @@ -11,3 +11,48 @@ func InsertStoreScore(storeScore *model.StoreScore) error { storeScore.CreatedAt = time.Now() return CreateEntity(nil, storeScore) } + +func GetLatestWeeklyStoreScoreList(db *DaoDB, storeID, weekNum int) (storeScoreList []*model.StoreScore, err error) { + // sql := ` + // SET @dayInWeek = IF(DAYOFWEEK(CURDATE()) - 1 = 0, 7, DAYOFWEEK(CURDATE()) - 1); + // SET @endDate = DATE_SUB(CURDATE(), INTERVAL @dayInWeek DAY); + // SET @beginData = DATE_SUB(@endDate, INTERVAL ? DAY); + // SELECT * FROM store_score + // WHERE store_id = ? AND DATE(created_at) >= @beginData AND DATE(created_at) <= @endDate ORDER BY created_at DESC + // ` + sql := ` + SELECT * FROM store_score WHERE store_id = ? + AND DATE(created_at) >= DATE_SUB( + DATE_SUB( + CURDATE(), + INTERVAL + IF ( + DAYOFWEEK(CURDATE()) - 1 = 0, + 7, + DAYOFWEEK(CURDATE()) - 1 + ) DAY + ), + INTERVAL ? DAY + ) + AND DATE(created_at) <= DATE_SUB( + CURDATE(), + INTERVAL + IF ( + DAYOFWEEK(CURDATE()) - 1 = 0, + 7, + DAYOFWEEK(CURDATE()) - 1 + ) DAY + ) + ORDER BY created_at DESC + ` + if weekNum <= 0 { + weekNum = 1 + } + diffDays := weekNum*7 - 1 + sqlParams := []interface{}{ + storeID, + diffDays, + } + err = GetRows(db, &storeScoreList, sql, sqlParams) + return storeScoreList, err +} diff --git a/business/model/store_score.go b/business/model/store_score.go index a32c21fcf..a88852ca4 100644 --- a/business/model/store_score.go +++ b/business/model/store_score.go @@ -6,6 +6,7 @@ type StoreScore struct { ID int `orm:"column(id)" json:"id"` CreatedAt time.Time `orm:"auto_now_add;type(datetime)" json:"createdAt"` StoreID int `orm:"column(store_id)" json:"storeID"` + StoreName string `orm:"column(store_name)" json:"storeName"` StoreOpenTime int `orm:"column(store_open_time)" json:"storeOpenTime"` SaleSkuCount int `orm:"column(sale_sku_count)" json:"saleSkuCount"` @@ -18,3 +19,11 @@ type StoreScore struct { StoreRange int `orm:"column(store_range)" json:"storeRange"` SaleSkuPrice int `orm:"column(sale_sku_price)" json:"saleSkuPrice"` } + +type WeeklyStoreScore struct { + StoreScore + BeginTime time.Time `json:"beginTime"` + EndTime time.Time `json:"endTime"` + TotalScore int `json:"totalScore"` + ItemTotalScore int `json:"itemTotalScore"` +} diff --git a/controllers/temp_op.go b/controllers/temp_op.go index dc3603980..b1249758f 100644 --- a/controllers/temp_op.go +++ b/controllers/temp_op.go @@ -334,3 +334,19 @@ func (c *TempOpController) ScoreStore() { return retVal, "", err }) } + +// @Title 得到门店周平均分数数据 +// @Description 得到门店周平均分数数据 +// @Param token header string true "认证token" +// @Param storeID query int true "京西门店ID" +// @Param weekIndex query int true "周索引(起始索引为0, -1为所有周数据)" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /GetWeeklyStoreScore [get] +func (c *TempOpController) GetWeeklyStoreScore() { + c.callGetWeeklyStoreScore(func(params *tTempopGetWeeklyStoreScoreParams) (retVal interface{}, errCode string, err error) { + retVal, err = misc.GetWeeklyStoreScore(params.StoreID, params.WeekIndex) + + return retVal, "", err + }) +} diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index b5564a00e..c4b114faf 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -1647,6 +1647,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"], + beego.ControllerComments{ + Method: "GetWeeklyStoreScore", + Router: `/GetWeeklyStoreScore`, + AllowHTTPMethods: []string{"get"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"], beego.ControllerComments{ Method: "PrintMsg", From b82327cefa2348e5be1244f0d1c2d088d5162222 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Fri, 6 Sep 2019 18:08:20 +0800 Subject: [PATCH 07/32] =?UTF-8?q?=E4=BF=AE=E6=94=B9BUG=EF=BC=88=E9=97=A8?= =?UTF-8?q?=E5=BA=97=E8=AF=84=E5=88=86=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index ce185ee44..0ee5d0e9d 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -523,6 +523,7 @@ func GetWeeklyStoreScore(storeID, weekIndex int) (outWeeklyStoreScoreDataList [] weeklyData := &model.WeeklyStoreScore{} weeklyData.ID = weekIndex weeklyData.ItemTotalScore = ItemTotalScore + weeklyData.StoreID = storeID weeklyStoreScoreDataList = append(weeklyStoreScoreDataList, weeklyData) for dayIndex, dayData := range weekDataList { for _, fieldName := range storeScoreFieldName { @@ -531,10 +532,11 @@ func GetWeeklyStoreScore(storeID, weekIndex int) (outWeeklyStoreScoreDataList [] refutil.SetObjFieldByName(weeklyData, fieldName, destFieldValueR+srcFieldValue) } if dayIndex == 0 { - weeklyData.BeginTime = dayData.CreatedAt - } else if dayIndex == WeekDayCount-1 { weeklyData.EndTime = dayData.CreatedAt + } else if dayIndex == WeekDayCount-1 { + weeklyData.BeginTime = dayData.CreatedAt } + weeklyData.StoreName = dayData.StoreName } for _, fieldName := range storeScoreFieldName { destFieldValueR := refutil.GetObjFieldByName(weeklyData, fieldName).(int) From 4822f7741f9a392335b02e1298b5427672c26cbe Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Mon, 9 Sep 2019 10:55:27 +0800 Subject: [PATCH 08/32] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=97=A8=E5=BA=97?= =?UTF-8?q?=E8=AF=84=E5=88=86=E7=9B=B8=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 24 ++++++++++++++++-- business/model/store_score.go | 1 + controllers/cms_store.go | 34 +++++++++++++++++++++++++ controllers/temp_op.go | 34 ------------------------- routers/commentsRouter_controllers.go | 36 +++++++++++++-------------- 5 files changed, 75 insertions(+), 54 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index 0ee5d0e9d..f16909a2f 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -497,6 +497,24 @@ func ScheduleScoreStore() { }, scoreStoreTimeList) } +func Time2Week(t time.Time) int { + yearDay := t.YearDay() + yearFirstDay := t.AddDate(0, 0, -yearDay+1) + firstDayInWeek := int(yearFirstDay.Weekday()) + + firstWeekDays := 1 + if firstDayInWeek != 0 { + firstWeekDays = 7 - firstDayInWeek + 1 + } + var week int + if yearDay <= firstWeekDays { + week = 1 + } else { + week = (yearDay-firstWeekDays)/7 + 2 + } + return week +} + func SplitToSingelWeekDataList(storeScoreList []*model.StoreScore) (weekDataList [][]*model.StoreScore) { singelWeekData := []*model.StoreScore{} count := 0 @@ -525,6 +543,7 @@ func GetWeeklyStoreScore(storeID, weekIndex int) (outWeeklyStoreScoreDataList [] weeklyData.ItemTotalScore = ItemTotalScore weeklyData.StoreID = storeID weeklyStoreScoreDataList = append(weeklyStoreScoreDataList, weeklyData) + weekDataListCount := len(weekDataList) for dayIndex, dayData := range weekDataList { for _, fieldName := range storeScoreFieldName { srcFieldValue := refutil.GetObjFieldByName(dayData, fieldName).(int) @@ -533,20 +552,21 @@ func GetWeeklyStoreScore(storeID, weekIndex int) (outWeeklyStoreScoreDataList [] } if dayIndex == 0 { weeklyData.EndTime = dayData.CreatedAt - } else if dayIndex == WeekDayCount-1 { + } else if dayIndex == weekDataListCount-1 { weeklyData.BeginTime = dayData.CreatedAt } weeklyData.StoreName = dayData.StoreName } for _, fieldName := range storeScoreFieldName { destFieldValueR := refutil.GetObjFieldByName(weeklyData, fieldName).(int) - refutil.SetObjFieldByName(weeklyData, fieldName, int(math.Round(float64(destFieldValueR)/WeekDayCount))) + refutil.SetObjFieldByName(weeklyData, fieldName, int(math.Round(float64(destFieldValueR)/float64(weekDataListCount)))) } for _, fieldName := range storeScoreFieldName { srcFieldValue := refutil.GetObjFieldByName(weeklyData, fieldName).(int) destFieldValueR := refutil.GetObjFieldByName(weeklyData, "TotalScore").(int) refutil.SetObjFieldByName(weeklyData, "TotalScore", destFieldValueR+srcFieldValue) } + weeklyData.Level = 0 } if weekIndex == -1 { outWeeklyStoreScoreDataList = weeklyStoreScoreDataList diff --git a/business/model/store_score.go b/business/model/store_score.go index a88852ca4..845c19d24 100644 --- a/business/model/store_score.go +++ b/business/model/store_score.go @@ -26,4 +26,5 @@ type WeeklyStoreScore struct { EndTime time.Time `json:"endTime"` TotalScore int `json:"totalScore"` ItemTotalScore int `json:"itemTotalScore"` + Level int `json:"level"` } diff --git a/controllers/cms_store.go b/controllers/cms_store.go index f7fe8d61d..ca293dda1 100644 --- a/controllers/cms_store.go +++ b/controllers/cms_store.go @@ -3,6 +3,7 @@ package controllers import ( "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxstore/cms" + "git.rosy.net.cn/jx-callback/business/jxstore/misc" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/jxutils/netprinter" "git.rosy.net.cn/jx-callback/business/model" @@ -422,3 +423,36 @@ func (c *StoreController) SyncStoresQualify() { return retVal, "", err }) } + +// @Title 门店评分 +// @Description 门店评分 +// @Param token header string true "认证token" +// @Param storeIDs formData string false "京西门店ID列表" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /ScoreStore [post] +func (c *StoreController) ScoreStore() { + c.callScoreStore(func(params *tStoreScoreStoreParams) (retVal interface{}, errCode string, err error) { + var storeIDList []int + if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDList); err == nil { + misc.ScoreStore(params.Ctx, storeIDList) + } + + return retVal, "", err + }) +} + +// @Title 得到门店周平均分数数据 +// @Description 得到门店周平均分数数据 +// @Param token header string true "认证token" +// @Param storeID query int true "京西门店ID" +// @Param weekIndex query int true "周索引(起始索引为0, -1为所有周数据)" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /GetWeeklyStoreScore [get] +func (c *StoreController) GetWeeklyStoreScore() { + c.callGetWeeklyStoreScore(func(params *tStoreGetWeeklyStoreScoreParams) (retVal interface{}, errCode string, err error) { + retVal, err = misc.GetWeeklyStoreScore(params.StoreID, params.WeekIndex) + return retVal, "", err + }) +} diff --git a/controllers/temp_op.go b/controllers/temp_op.go index b1249758f..ca73868e1 100644 --- a/controllers/temp_op.go +++ b/controllers/temp_op.go @@ -316,37 +316,3 @@ func (c *TempOpController) CheckSkuDiffBetweenJxAndVendor() { return retVal, "", err }) } - -// @Title 门店评分 -// @Description 门店评分 -// @Param token header string true "认证token" -// @Param storeIDs formData string false "京西门店ID列表" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /ScoreStore [post] -func (c *TempOpController) ScoreStore() { - c.callScoreStore(func(params *tTempopScoreStoreParams) (retVal interface{}, errCode string, err error) { - var storeIDList []int - if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDList); err == nil { - misc.ScoreStore(params.Ctx, storeIDList) - } - - return retVal, "", err - }) -} - -// @Title 得到门店周平均分数数据 -// @Description 得到门店周平均分数数据 -// @Param token header string true "认证token" -// @Param storeID query int true "京西门店ID" -// @Param weekIndex query int true "周索引(起始索引为0, -1为所有周数据)" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /GetWeeklyStoreScore [get] -func (c *TempOpController) GetWeeklyStoreScore() { - c.callGetWeeklyStoreScore(func(params *tTempopGetWeeklyStoreScoreParams) (retVal interface{}, errCode string, err error) { - retVal, err = misc.GetWeeklyStoreScore(params.StoreID, params.WeekIndex) - - return retVal, "", err - }) -} diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index c4b114faf..cca5b44b8 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -1305,6 +1305,24 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"], + beego.ControllerComments{ + Method: "GetWeeklyStoreScore", + Router: `/GetWeeklyStoreScore`, + AllowHTTPMethods: []string{"get"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"], + beego.ControllerComments{ + Method: "ScoreStore", + Router: `/ScoreStore`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:StoreController"], beego.ControllerComments{ Method: "SyncStoresQualify", @@ -1647,15 +1665,6 @@ func init() { Filters: nil, Params: nil}) - beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"], - beego.ControllerComments{ - Method: "GetWeeklyStoreScore", - Router: `/GetWeeklyStoreScore`, - AllowHTTPMethods: []string{"get"}, - MethodParams: param.Make(), - Filters: nil, - Params: nil}) - beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"], beego.ControllerComments{ Method: "PrintMsg", @@ -1683,15 +1692,6 @@ func init() { Filters: nil, Params: nil}) - beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"], - beego.ControllerComments{ - Method: "ScoreStore", - Router: `/ScoreStore`, - AllowHTTPMethods: []string{"post"}, - MethodParams: param.Make(), - Filters: nil, - Params: nil}) - beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:TempOpController"], beego.ControllerComments{ Method: "TestIt", From bb74874b12f2402dcaa5e685b7265f6164ddbbf7 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Mon, 9 Sep 2019 14:42:01 +0800 Subject: [PATCH 09/32] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=97=A8=E5=BA=97?= =?UTF-8?q?=E8=AF=84=E5=88=86BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 99 ++++++++++++++++++---------- business/model/store_score.go | 15 +++++ 2 files changed, 80 insertions(+), 34 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index f16909a2f..857201b5a 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -17,8 +17,14 @@ import ( ) const ( + GoldMedalScore = 90 + SilverMedalScore = 80 + BronzeMedalScore = 70 + GoldMedalLevel = 1 + SilverMedalLevel = 2 + BronzeMedalLevel = 3 + ItemTotalScore = 10 - ItemCount = 10 StoreOpenTimeNormalTime = 12.0 //小时 SaleSkuNormalCount = 1000 @@ -30,8 +36,6 @@ const ( StoreRangeGoodRadius = 2.0 //千米 StoreRangeBadRadius = 1.0 //千米 SaleSkuPriceRatio = 90 //百分比 - - WeekDayCount = 7 ) var ( @@ -44,16 +48,16 @@ var ( model.VendorIDEBAI: true, } storeScoreFieldName = []string{ - "StoreOpenTime", - "SaleSkuCount", - "AveragePickupTime", - "BadCommentOrder", - "UnfinishOrder", - "AbsentGoodsOrder", - "PromotionSku", - "FullVendor", - "StoreRange", - "SaleSkuPrice", + model.FieldStoreOpenTime, + model.FieldSaleSkuCount, + model.FieldAveragePickupTime, + model.FieldBadCommentOrder, + model.FieldUnfinishOrder, + model.FieldAbsentGoodsOrder, + model.FieldPromotionSku, + model.FieldFullVendor, + model.FieldStoreRange, + model.FieldSaleSkuPrice, } storeScoreDataWrapper StoreScoreDataWrapper @@ -510,63 +514,90 @@ func Time2Week(t time.Time) int { if yearDay <= firstWeekDays { week = 1 } else { - week = (yearDay-firstWeekDays)/7 + 2 + tempWeek := (float64(yearDay) - float64(firstWeekDays)) / float64(7) + week = int(math.Ceil(tempWeek)) + 1 } + return week } -func SplitToSingelWeekDataList(storeScoreList []*model.StoreScore) (weekDataList [][]*model.StoreScore) { +func SplitToSingleWeekDataList(storeScoreList []*model.StoreScore) (weekDataList [][]*model.StoreScore) { singelWeekData := []*model.StoreScore{} - count := 0 + weekIndex := 0 for _, value := range storeScoreList { - singelWeekData = append(singelWeekData, value) - count++ - if count == WeekDayCount { + if weekIndex == 0 { + weekIndex = Time2Week(value.CreatedAt) + } + if weekIndex == Time2Week(value.CreatedAt) { + singelWeekData = append(singelWeekData, value) + } else { weekDataList = append(weekDataList, singelWeekData) singelWeekData = []*model.StoreScore{} - count = 0 + weekIndex = 0 + singelWeekData = append(singelWeekData, value) } } + if len(singelWeekData) > 0 { + weekDataList = append(weekDataList, singelWeekData) + } return weekDataList } +func GetStoreScoreLevel(score int) int { + level := 0 + if score >= GoldMedalScore { + level = GoldMedalLevel + } else if score >= SilverMedalScore { + level = SilverMedalLevel + } else if score >= BronzeMedalScore { + level = BronzeMedalLevel + } + + return level +} + func GetWeeklyStoreScore(storeID, weekIndex int) (outWeeklyStoreScoreDataList []*model.WeeklyStoreScore, err error) { db := dao.GetDB() storeScoreList, err := dao.GetLatestWeeklyStoreScoreList(db, storeID, 5) if err == nil && len(storeScoreList) > 0 { weeklyStoreScoreDataList := []*model.WeeklyStoreScore{} - weekDataList := SplitToSingelWeekDataList(storeScoreList) - for weekIndex, weekDataList := range weekDataList { + weekDataList := SplitToSingleWeekDataList(storeScoreList) + for weekIndex, weekData := range weekDataList { weeklyData := &model.WeeklyStoreScore{} weeklyData.ID = weekIndex weeklyData.ItemTotalScore = ItemTotalScore weeklyData.StoreID = storeID weeklyStoreScoreDataList = append(weeklyStoreScoreDataList, weeklyData) - weekDataListCount := len(weekDataList) - for dayIndex, dayData := range weekDataList { + weekDataCount := len(weekData) + for dayIndex, dayData := range weekData { for _, fieldName := range storeScoreFieldName { srcFieldValue := refutil.GetObjFieldByName(dayData, fieldName).(int) - destFieldValueR := refutil.GetObjFieldByName(weeklyData, fieldName).(int) - refutil.SetObjFieldByName(weeklyData, fieldName, destFieldValueR+srcFieldValue) + destFieldValue := refutil.GetObjFieldByName(weeklyData, fieldName).(int) + refutil.SetObjFieldByName(weeklyData, fieldName, destFieldValue+srcFieldValue) } - if dayIndex == 0 { - weeklyData.EndTime = dayData.CreatedAt - } else if dayIndex == weekDataListCount-1 { + if weekDataCount == 1 { weeklyData.BeginTime = dayData.CreatedAt + weeklyData.EndTime = dayData.CreatedAt + } else { + if dayIndex == 0 { + weeklyData.EndTime = dayData.CreatedAt + } else if dayIndex == weekDataCount-1 { + weeklyData.BeginTime = dayData.CreatedAt + } } weeklyData.StoreName = dayData.StoreName } for _, fieldName := range storeScoreFieldName { - destFieldValueR := refutil.GetObjFieldByName(weeklyData, fieldName).(int) - refutil.SetObjFieldByName(weeklyData, fieldName, int(math.Round(float64(destFieldValueR)/float64(weekDataListCount)))) + destFieldValue := refutil.GetObjFieldByName(weeklyData, fieldName).(int) + refutil.SetObjFieldByName(weeklyData, fieldName, int(math.Round(float64(destFieldValue)/float64(weekDataCount)))) } for _, fieldName := range storeScoreFieldName { srcFieldValue := refutil.GetObjFieldByName(weeklyData, fieldName).(int) - destFieldValueR := refutil.GetObjFieldByName(weeklyData, "TotalScore").(int) - refutil.SetObjFieldByName(weeklyData, "TotalScore", destFieldValueR+srcFieldValue) + destFieldValue := refutil.GetObjFieldByName(weeklyData, model.FieldTotalScore).(int) + refutil.SetObjFieldByName(weeklyData, model.FieldTotalScore, destFieldValue+srcFieldValue) } - weeklyData.Level = 0 + weeklyData.Level = GetStoreScoreLevel(weeklyData.TotalScore) } if weekIndex == -1 { outWeeklyStoreScoreDataList = weeklyStoreScoreDataList diff --git a/business/model/store_score.go b/business/model/store_score.go index 845c19d24..13e121088 100644 --- a/business/model/store_score.go +++ b/business/model/store_score.go @@ -2,6 +2,21 @@ package model import "time" +const ( + FieldStoreOpenTime = "StoreOpenTime" + FieldSaleSkuCount = "SaleSkuCount" + FieldAveragePickupTime = "AveragePickupTime" + FieldBadCommentOrder = "BadCommentOrder" + FieldUnfinishOrder = "UnfinishOrder" + FieldAbsentGoodsOrder = "AbsentGoodsOrder" + FieldPromotionSku = "PromotionSku" + FieldFullVendor = "FullVendor" + FieldStoreRange = "StoreRange" + FieldSaleSkuPrice = "SaleSkuPrice" + + FieldTotalScore = "TotalScore" +) + type StoreScore struct { ID int `orm:"column(id)" json:"id"` CreatedAt time.Time `orm:"auto_now_add;type(datetime)" json:"createdAt"` From c3873c76145c72af033e02105341597c69da9fed Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Mon, 9 Sep 2019 15:37:55 +0800 Subject: [PATCH 10/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E8=AF=84=E5=88=86?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/misc.go | 1 + business/jxstore/misc/store_score.go | 61 ++++++++++++++++------------ 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/business/jxstore/misc/misc.go b/business/jxstore/misc/misc.go index 44dbd2029..42f353b51 100644 --- a/business/jxstore/misc/misc.go +++ b/business/jxstore/misc/misc.go @@ -102,6 +102,7 @@ func Init() { ScheduleTimerFunc("UpdateActStatusByTime", func() { dao.UpdateActStatusByTime(dao.GetDB(), time.Now().Add(-48*time.Hour)) }, updateActStatusTimeList) + ScheduleScoreStore() } ScheduleTimerFunc("AutoSaleStoreSku", func() { cms.AutoSaleStoreSku(jxcontext.AdminCtx, nil, false) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index 857201b5a..a52d71aa3 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -17,6 +17,8 @@ import ( ) const ( + EnableScheduleScoreStore = !true + GoldMedalScore = 90 SilverMedalScore = 80 BronzeMedalScore = 70 @@ -147,7 +149,7 @@ func ScoreStoreOpenTime(storeList []*cms.StoreExt) { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, storeName, "StoreOpenTime", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, model.FieldStoreOpenTime, finalScore) } } } @@ -174,7 +176,7 @@ func ScoreSaleSkuCount(ctx *jxcontext.Context, storeList []*cms.StoreExt) { if finalScore > ItemTotalScore { finalScore = ItemTotalScore } - storeScoreDataWrapper.SetData(storeID, storeName, "SaleSkuCount", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, model.FieldSaleSkuCount, finalScore) } } } @@ -204,7 +206,7 @@ func ScoreAveragePickupTime(storeList []*cms.StoreExt) { } } finalScore := totalScore / orderListCount - storeScoreDataWrapper.SetData(storeID, storeName, "AveragePickupTime", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, model.FieldAveragePickupTime, finalScore) } } } @@ -229,7 +231,7 @@ func ScoreBadCommentOrder(storeList []*cms.StoreExt) { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, storeName, "BadCommentOrder", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, model.FieldBadCommentOrder, finalScore) } } } @@ -254,7 +256,7 @@ func ScoreUnfinishOrder(storeList []*cms.StoreExt) { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, storeName, "UnfinishOrder", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, model.FieldUnfinishOrder, finalScore) } } } @@ -291,12 +293,12 @@ func ScorePromotionSku(storeList []*cms.StoreExt) { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, storeName, "PromotionSku", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, model.FieldPromotionSku, finalScore) } } } -//经营全平台满分10分,每少一个平台扣2分(???一个都没有,是否为0) +//经营全平台满分10分,每少一个平台扣2分(一个平台没有得0分) func ScoreFullVendor(storeList []*cms.StoreExt) { fullVendorCount := len(fullVendorList) for _, storeInfo := range storeList { @@ -314,13 +316,16 @@ func ScoreFullVendor(storeList []*cms.StoreExt) { count++ } } - if count == fullVendorCount { - finalScore = ItemTotalScore - } else { - decScore := (fullVendorCount - count) * 2 - finalScore = ItemTotalScore - decScore + + if count > 0 { + if count == fullVendorCount { + finalScore = ItemTotalScore + } else { + decScore := (fullVendorCount - count) * 2 + finalScore = ItemTotalScore - decScore + } } - storeScoreDataWrapper.SetData(storeID, storeName, "FullVendor", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, model.FieldFullVendor, finalScore) } } @@ -367,7 +372,7 @@ func ScoreStoreRange(storeList []*cms.StoreExt) { finalScore = ItemTotalScore - int(math.Round(diff*ratio)) } } - storeScoreDataWrapper.SetData(storeID, storeName, "StoreRange", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, model.FieldStoreRange, finalScore) } } @@ -431,17 +436,19 @@ func ScoreSaleSkuPrice(ctx *jxcontext.Context, storeList []*cms.StoreExt) { rangeStoreList := GetRangeStoreList(storeID, storeInfo.FloatLng, storeInfo.FloatLat, 5, storeList) skusAveragePrice := GetStoreSkusAveragePrice(rangeStoreList) count := GetSkusCountLessEqualAvgPrice(storeID, skusAveragePrice) - ratio := int(math.Round(float64(count) * 100 / float64(totalCount))) - if ratio >= SaleSkuPriceRatio { - finalScore = ItemTotalScore - } else { - decScore := (SaleSkuPriceRatio - ratio) / 10 - finalScore = ItemTotalScore - decScore - if finalScore < 0 { - finalScore = 0 + if count > 0 { + ratio := int(math.Round(float64(count) * 100 / float64(totalCount))) + if ratio >= SaleSkuPriceRatio { + finalScore = ItemTotalScore + } else { + decScore := (SaleSkuPriceRatio - ratio) / 10 + finalScore = ItemTotalScore - decScore + if finalScore < 0 { + finalScore = 0 + } } } - storeScoreDataWrapper.SetData(storeID, storeName, "SaleSkuPrice", finalScore) + storeScoreDataWrapper.SetData(storeID, storeName, model.FieldSaleSkuPrice, finalScore) } } } @@ -496,9 +503,11 @@ func InsertStoreScore() { } func ScheduleScoreStore() { - ScheduleTimerFunc("ScheduleScoreStore", func() { - ScoreStore(jxcontext.AdminCtx, []int{}) - }, scoreStoreTimeList) + if EnableScheduleScoreStore { + ScheduleTimerFunc("ScheduleScoreStore", func() { + ScoreStore(jxcontext.AdminCtx, []int{}) + }, scoreStoreTimeList) + } } func Time2Week(t time.Time) int { From 46f31a7136349f3fb53e1b0c8a5e24f3a5fecc8a Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Tue, 10 Sep 2019 08:48:58 +0800 Subject: [PATCH 11/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E8=AF=84=E5=88=86?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 51 +++++++++++++++++++++------- business/model/dao/dao_order.go | 32 +++++++++++------ 2 files changed, 60 insertions(+), 23 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index a52d71aa3..6300a2066 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -6,14 +6,13 @@ import ( "sync" "time" - "git.rosy.net.cn/jx-callback/globals/refutil" - "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxstore/cms" "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" + "git.rosy.net.cn/jx-callback/globals/refutil" ) const ( @@ -28,16 +27,17 @@ const ( ItemTotalScore = 10 - StoreOpenTimeNormalTime = 12.0 //小时 - SaleSkuNormalCount = 1000 - SaleSkuScorePerUnit = float64(ItemTotalScore) / SaleSkuNormalCount - PromotionSkuNormalCount = 20 - AveragePickupTimeNormalTime = 10.0 //分钟 - BadCommentOrderNormalRatio = 0.2 - UnfinishOrderNormalRatio = 1.0 - StoreRangeGoodRadius = 2.0 //千米 - StoreRangeBadRadius = 1.0 //千米 - SaleSkuPriceRatio = 90 //百分比 + StoreOpenTimeNormalTime = 12.0 //小时 + SaleSkuNormalCount = 1000 //数量 + SaleSkuScorePerUnit = float64(ItemTotalScore) / SaleSkuNormalCount //分数 + PromotionSkuNormalCount = 20 //数量 + AveragePickupTimeNormalTime = 10.0 //分钟 + BadCommentOrderNormalRatio = 0.2 //百分比 + UnfinishOrderNormalRatio = 1.0 //百分比 + AbsentGoodsOrderNormalRatio = 1.0 //百分比 + StoreRangeGoodRadius = 2.0 //千米 + StoreRangeBadRadius = 1.0 //千米 + SaleSkuPriceRatio = 90 //百分比 ) var ( @@ -263,7 +263,27 @@ func ScoreUnfinishOrder(storeList []*cms.StoreExt) { //缺货订单和完成订单比小于1%得10分,比例每增加0.1%减1分 func ScoreAbsentGoodsOrder(storeList []*cms.StoreExt) { - + for _, storeInfo := range storeList { + storeID := storeInfo.ID + storeName := storeInfo.Name + db := dao.GetDB() + absentGoodsOrderCount, _ := dao.GetDailyAbsentGoodsOrderCount(db, storeID) + finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) + if finishOrderCount > 0 { + finalScore := 0 + absentGoodsOrderRatio := float64(absentGoodsOrderCount) * 100 / float64(finishOrderCount) + if absentGoodsOrderRatio <= AbsentGoodsOrderNormalRatio { + finalScore = ItemTotalScore + } else { + decScore := int(math.Round((absentGoodsOrderRatio - AbsentGoodsOrderNormalRatio) / 0.1)) + finalScore = ItemTotalScore - decScore + if finalScore < 0 { + finalScore = 0 + } + } + storeScoreDataWrapper.SetData(storeID, storeName, model.FieldAbsentGoodsOrder, finalScore) + } + } } //促销品数量20个以上为满分10分,每少2个扣1分 @@ -461,11 +481,16 @@ func GetFilterStoreListEx(storeList []*cms.StoreExt, storeIDMap map[int]int) (ou continue } } + var tempStoreMaps []map[string]interface{} for _, vendorStoreInfo := range storeInfo.StoreMaps { vendorID := int(utils.MustInterface2Int64(vendorStoreInfo["vendorID"])) if _, ok := fullVendorList[vendorID]; !ok { continue } + tempStoreMaps = append(tempStoreMaps, vendorStoreInfo) + } + if len(tempStoreMaps) > 0 { + storeInfo.StoreMaps = tempStoreMaps outStoreList = append(outStoreList, storeInfo) } } diff --git a/business/model/dao/dao_order.go b/business/model/dao/dao_order.go index c5297e687..e103524e1 100644 --- a/business/model/dao/dao_order.go +++ b/business/model/dao/dao_order.go @@ -306,30 +306,42 @@ func GetDailyFinishOrderList(db *DaoDB, storeID int) (orderList []*model.OrderPi return orderList, GetRows(db, &orderList, sql, sqlParams...) } -func GetDailyBadCommentOrderCount(db *DaoDB, storeID int) (num int64, err error) { +func GetDailyBadCommentOrderCount(db *DaoDB, storeID int) (count int64, err error) { sql := `select count(*) from jx_bad_comments where DATE(createtime) = CURDATE() and jxstoreid = ?` sqlParams := []interface{}{ storeID, } - return ExecuteSQL(db, sql, sqlParams) + err = GetRow(db, &count, sql, sqlParams...) + + return count, err } func GetDailyUnFinishOrderCount(db *DaoDB, storeID int) (num int64, err error) { - return GetDailyEndOrderCount(db, storeID, []int{model.OrderStatusCanceled}) + return GetDailyEndOrderCount(db, storeID, []int{model.OrderStatusCanceled}, false) } func GetDailyFinishOrderCount(db *DaoDB, storeID int) (num int64, err error) { - return GetDailyEndOrderCount(db, storeID, []int{model.OrderStatusFinished}) + return GetDailyEndOrderCount(db, storeID, []int{model.OrderStatusFinished}, false) } -func GetDailyEndOrderCount(db *DaoDB, storeID int, statusList []int) (num int64, err error) { - sql := `select count(*) from goods_order - where DATE(order_finished_at) = CURDATE() - and jx_store_id = ? - and status in (` + GenQuestionMarks(len(statusList)) + `)` +func GetDailyAbsentGoodsOrderCount(db *DaoDB, storeID int) (num int64, err error) { + return GetDailyEndOrderCount(db, storeID, []int{model.OrderStatusFinished, model.OrderStatusCanceled}, true) +} + +func GetDailyEndOrderCount(db *DaoDB, storeID int, statusList []int, isAbsentOrder bool) (count int64, err error) { + sql := `SELECT COUNT(*) FROM goods_order + WHERE DATE(order_finished_at) = CURDATE() + AND jx_store_id = ? + AND status IN (` + GenQuestionMarks(len(statusList)) + `)` + if isAbsentOrder { + sql += ` + AND adjust_count > 0` + } sqlParams := []interface{}{ storeID, } sqlParams = append(sqlParams, statusList) - return ExecuteSQL(db, sql, sqlParams) + err = GetRow(db, &count, sql, sqlParams...) + + return count, err } From 40586e19a6df5b37332147efb0846c4e9951e874 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Tue, 10 Sep 2019 15:42:26 +0800 Subject: [PATCH 12/32] =?UTF-8?q?=E5=A2=9E=E5=8A=A0StoreScoreEx=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E6=9D=A5=E8=8E=B7=E5=8F=96=E9=97=A8=E5=BA=97=E5=90=8D?= =?UTF-8?q?=E5=AD=97,=E5=8E=BB=E6=8E=89=E8=A1=A8=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E5=AD=97=E6=AE=B5StoreName?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 94 +++++++++++++++++----------- business/model/api.go | 4 +- business/model/dao/store_score.go | 17 ++--- business/model/store_score.go | 8 ++- 4 files changed, 70 insertions(+), 53 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index 6300a2066..d1330032d 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -10,6 +10,7 @@ import ( "git.rosy.net.cn/jx-callback/business/jxstore/cms" "git.rosy.net.cn/jx-callback/business/jxutils" "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/model" "git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/globals/refutil" @@ -63,9 +64,34 @@ var ( } storeScoreDataWrapper StoreScoreDataWrapper - allStoreSkus map[int]map[int]*cms.StoreSkuNameExt + allStoreSkusWrapper AllStoreSkusWrapper ) +type AllStoreSkusWrapper struct { + allStoreSkus map[int]map[int]*cms.StoreSkuNameExt + locker sync.RWMutex +} + +func (a *AllStoreSkusWrapper) InitData() { + a.allStoreSkus = make(map[int]map[int]*cms.StoreSkuNameExt) +} + +func (a *AllStoreSkusWrapper) ClearData() { + a.allStoreSkus = nil +} + +func (a *AllStoreSkusWrapper) SetData(storeID int, skuMapData map[int]*cms.StoreSkuNameExt) { + a.locker.Lock() + defer a.locker.Unlock() + a.allStoreSkus[storeID] = skuMapData +} + +func (a *AllStoreSkusWrapper) GetData(storeID int) map[int]*cms.StoreSkuNameExt { + a.locker.RLock() + defer a.locker.RUnlock() + return a.allStoreSkus[storeID] +} + type StoreScoreDataWrapper struct { storeScoreData map[int]*model.StoreScore locker sync.RWMutex @@ -75,14 +101,13 @@ func (s *StoreScoreDataWrapper) InitData() { s.storeScoreData = make(map[int]*model.StoreScore) } -func (s *StoreScoreDataWrapper) SetData(storeID int, storeName, valueName string, value int) { +func (s *StoreScoreDataWrapper) SetData(storeID int, valueName string, value int) { s.locker.Lock() defer s.locker.Unlock() data := s.storeScoreData[storeID] if data == nil { data = &model.StoreScore{} data.StoreID = storeID - data.StoreName = storeName s.storeScoreData[storeID] = data } valueInfo := reflect.ValueOf(data).Elem() @@ -91,8 +116,9 @@ func (s *StoreScoreDataWrapper) SetData(storeID int, storeName, valueName string //得到所有门店的商品 func GetAllStoreSkus(ctx *jxcontext.Context, storeList []*cms.StoreExt) { - allStoreSkus = make(map[int]map[int]*cms.StoreSkuNameExt) - for _, storeInfo := range storeList { + allStoreSkusWrapper.InitData() + taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + storeInfo := batchItemList[0].(*cms.StoreExt) storeID := storeInfo.ID jxSkuInfoData, _ := cms.GetStoreSkus(ctx, storeID, []int{}, true, "", true, map[string]interface{}{}, 0, -1) jxSkuMapData := make(map[int]*cms.StoreSkuNameExt) @@ -104,12 +130,12 @@ func GetAllStoreSkus(ctx *jxcontext.Context, storeList []*cms.StoreExt) { } } } - allStoreSkus[storeID] = jxSkuMapData + allStoreSkusWrapper.SetData(storeID, jxSkuMapData) + return retVal, err } -} - -func ClearAllStoreSkus() { - allStoreSkus = nil + taskParallel := tasksch.NewParallelTask("GetAllStoreSkus", nil, ctx, taskFunc, storeList) + tasksch.HandleTask(taskParallel, nil, true).Run() + taskParallel.GetResult(0) } func GetOpenTime(opTimeList []int16) (opTime float64) { @@ -130,7 +156,6 @@ func GetOpenTime(opTimeList []int16) (opTime float64) { func ScoreStoreOpenTime(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID - storeName := storeInfo.Name storeStatus := storeInfo.Status isStoreOpen := storeStatus == model.StoreStatusOpened for _, storeMap := range storeInfo.StoreMaps { @@ -149,7 +174,7 @@ func ScoreStoreOpenTime(storeList []*cms.StoreExt) { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, storeName, model.FieldStoreOpenTime, finalScore) + storeScoreDataWrapper.SetData(storeID, model.FieldStoreOpenTime, finalScore) } } } @@ -159,8 +184,7 @@ func ScoreStoreOpenTime(storeList []*cms.StoreExt) { func ScoreSaleSkuCount(ctx *jxcontext.Context, storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID - storeName := storeInfo.Name - skusMapData := allStoreSkus[storeID] + skusMapData := allStoreSkusWrapper.GetData(storeID) if len(skusMapData) > 0 { finalScore := 0 saleSkuCount := 0 @@ -176,7 +200,7 @@ func ScoreSaleSkuCount(ctx *jxcontext.Context, storeList []*cms.StoreExt) { if finalScore > ItemTotalScore { finalScore = ItemTotalScore } - storeScoreDataWrapper.SetData(storeID, storeName, model.FieldSaleSkuCount, finalScore) + storeScoreDataWrapper.SetData(storeID, model.FieldSaleSkuCount, finalScore) } } } @@ -185,7 +209,6 @@ func ScoreSaleSkuCount(ctx *jxcontext.Context, storeList []*cms.StoreExt) { func ScoreAveragePickupTime(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID - storeName := storeInfo.Name db := dao.GetDB() orderList, err := dao.GetDailyFinishOrderList(db, storeID) orderListCount := len(orderList) @@ -206,7 +229,7 @@ func ScoreAveragePickupTime(storeList []*cms.StoreExt) { } } finalScore := totalScore / orderListCount - storeScoreDataWrapper.SetData(storeID, storeName, model.FieldAveragePickupTime, finalScore) + storeScoreDataWrapper.SetData(storeID, model.FieldAveragePickupTime, finalScore) } } } @@ -215,7 +238,6 @@ func ScoreAveragePickupTime(storeList []*cms.StoreExt) { func ScoreBadCommentOrder(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID - storeName := storeInfo.Name db := dao.GetDB() badCommentOrderCount, _ := dao.GetDailyBadCommentOrderCount(db, storeID) finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) @@ -231,7 +253,7 @@ func ScoreBadCommentOrder(storeList []*cms.StoreExt) { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, storeName, model.FieldBadCommentOrder, finalScore) + storeScoreDataWrapper.SetData(storeID, model.FieldBadCommentOrder, finalScore) } } } @@ -240,7 +262,6 @@ func ScoreBadCommentOrder(storeList []*cms.StoreExt) { func ScoreUnfinishOrder(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID - storeName := storeInfo.Name db := dao.GetDB() unFinishOrderCount, _ := dao.GetDailyUnFinishOrderCount(db, storeID) finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) @@ -256,7 +277,7 @@ func ScoreUnfinishOrder(storeList []*cms.StoreExt) { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, storeName, model.FieldUnfinishOrder, finalScore) + storeScoreDataWrapper.SetData(storeID, model.FieldUnfinishOrder, finalScore) } } } @@ -265,7 +286,6 @@ func ScoreUnfinishOrder(storeList []*cms.StoreExt) { func ScoreAbsentGoodsOrder(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID - storeName := storeInfo.Name db := dao.GetDB() absentGoodsOrderCount, _ := dao.GetDailyAbsentGoodsOrderCount(db, storeID) finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) @@ -281,7 +301,7 @@ func ScoreAbsentGoodsOrder(storeList []*cms.StoreExt) { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, storeName, model.FieldAbsentGoodsOrder, finalScore) + storeScoreDataWrapper.SetData(storeID, model.FieldAbsentGoodsOrder, finalScore) } } } @@ -290,7 +310,6 @@ func ScoreAbsentGoodsOrder(storeList []*cms.StoreExt) { func ScorePromotionSku(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { storeID := storeInfo.ID - storeName := storeInfo.Name db := dao.GetDB() beginTime := time.Now() endTime := time.Now() @@ -313,7 +332,7 @@ func ScorePromotionSku(storeList []*cms.StoreExt) { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, storeName, model.FieldPromotionSku, finalScore) + storeScoreDataWrapper.SetData(storeID, model.FieldPromotionSku, finalScore) } } } @@ -324,7 +343,6 @@ func ScoreFullVendor(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { finalScore := 0 storeID := storeInfo.ID - storeName := storeInfo.Name storeStatus := storeInfo.Status isStoreOpen := storeStatus == model.StoreStatusOpened count := 0 @@ -345,7 +363,7 @@ func ScoreFullVendor(storeList []*cms.StoreExt) { finalScore = ItemTotalScore - decScore } } - storeScoreDataWrapper.SetData(storeID, storeName, model.FieldFullVendor, finalScore) + storeScoreDataWrapper.SetData(storeID, model.FieldFullVendor, finalScore) } } @@ -365,7 +383,6 @@ func ScoreStoreRange(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { finalScore := 0 storeID := storeInfo.ID - storeName := storeInfo.Name if storeInfo.DeliveryRangeType == model.DeliveryRangeTypePolygon { points := jxutils.CoordinateStr2Points(storeInfo.DeliveryRange) area := CalcPolygonArea(points) @@ -392,7 +409,7 @@ func ScoreStoreRange(storeList []*cms.StoreExt) { finalScore = ItemTotalScore - int(math.Round(diff*ratio)) } } - storeScoreDataWrapper.SetData(storeID, storeName, model.FieldStoreRange, finalScore) + storeScoreDataWrapper.SetData(storeID, model.FieldStoreRange, finalScore) } } @@ -419,7 +436,8 @@ func GetStoreSkusAveragePrice(storeList []*cms.StoreExt) map[int]int { skusAveragePrice := make(map[int]int) for _, storeInfo := range storeList { storeID := storeInfo.ID - for _, value := range allStoreSkus[storeID] { + storeSkuMapData := allStoreSkusWrapper.GetData(storeID) + for _, value := range storeSkuMapData { skuID := value.Skus2[0].SkuID skuPrice := value.Skus2[0].BindPrice skusTotalPrice[skuID] += skuPrice @@ -433,7 +451,8 @@ func GetStoreSkusAveragePrice(storeList []*cms.StoreExt) map[int]int { } func GetSkusCountLessEqualAvgPrice(storeID int, skusAveragePrice map[int]int) (count int) { - for _, value := range allStoreSkus[storeID] { + storeSkuMapData := allStoreSkusWrapper.GetData(storeID) + for _, value := range storeSkuMapData { skuID := value.Skus2[0].SkuID skuPrice := value.Skus2[0].BindPrice skuAvgPrice := skusAveragePrice[skuID] @@ -450,8 +469,7 @@ func ScoreSaleSkuPrice(ctx *jxcontext.Context, storeList []*cms.StoreExt) { for _, storeInfo := range storeList { finalScore := 0 storeID := storeInfo.ID - storeName := storeInfo.Name - totalCount := len(allStoreSkus[storeID]) + totalCount := len(allStoreSkusWrapper.GetData(storeID)) if totalCount > 0 { rangeStoreList := GetRangeStoreList(storeID, storeInfo.FloatLng, storeInfo.FloatLat, 5, storeList) skusAveragePrice := GetStoreSkusAveragePrice(rangeStoreList) @@ -468,7 +486,7 @@ func ScoreSaleSkuPrice(ctx *jxcontext.Context, storeList []*cms.StoreExt) { } } } - storeScoreDataWrapper.SetData(storeID, storeName, model.FieldSaleSkuPrice, finalScore) + storeScoreDataWrapper.SetData(storeID, model.FieldSaleSkuPrice, finalScore) } } } @@ -516,7 +534,7 @@ func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, ScoreStoreRange(storeList) ScoreSaleSkuPrice(ctx, storeList) InsertStoreScore() - ClearAllStoreSkus() + allStoreSkusWrapper.ClearData() return retVal, err } @@ -555,8 +573,8 @@ func Time2Week(t time.Time) int { return week } -func SplitToSingleWeekDataList(storeScoreList []*model.StoreScore) (weekDataList [][]*model.StoreScore) { - singelWeekData := []*model.StoreScore{} +func SplitToSingleWeekDataList(storeScoreList []*model.StoreScoreEx) (weekDataList [][]*model.StoreScoreEx) { + singelWeekData := []*model.StoreScoreEx{} weekIndex := 0 for _, value := range storeScoreList { if weekIndex == 0 { @@ -566,7 +584,7 @@ func SplitToSingleWeekDataList(storeScoreList []*model.StoreScore) (weekDataList singelWeekData = append(singelWeekData, value) } else { weekDataList = append(weekDataList, singelWeekData) - singelWeekData = []*model.StoreScore{} + singelWeekData = []*model.StoreScoreEx{} weekIndex = 0 singelWeekData = append(singelWeekData, value) } diff --git a/business/model/api.go b/business/model/api.go index 79dddef04..19d026c1d 100644 --- a/business/model/api.go +++ b/business/model/api.go @@ -75,6 +75,6 @@ type OrderFinancialSkuExt struct { } type OrderPickupTime struct { - StatusTime time.Time `orm:"type(datetime)" json:"statusTime"` - PickDeadline time.Time `orm:"type(datetime)" json:"pickDeadline"` + StatusTime time.Time + PickDeadline time.Time } diff --git a/business/model/dao/store_score.go b/business/model/dao/store_score.go index dfc19fc30..87858865f 100644 --- a/business/model/dao/store_score.go +++ b/business/model/dao/store_score.go @@ -12,17 +12,12 @@ func InsertStoreScore(storeScore *model.StoreScore) error { return CreateEntity(nil, storeScore) } -func GetLatestWeeklyStoreScoreList(db *DaoDB, storeID, weekNum int) (storeScoreList []*model.StoreScore, err error) { - // sql := ` - // SET @dayInWeek = IF(DAYOFWEEK(CURDATE()) - 1 = 0, 7, DAYOFWEEK(CURDATE()) - 1); - // SET @endDate = DATE_SUB(CURDATE(), INTERVAL @dayInWeek DAY); - // SET @beginData = DATE_SUB(@endDate, INTERVAL ? DAY); - // SELECT * FROM store_score - // WHERE store_id = ? AND DATE(created_at) >= @beginData AND DATE(created_at) <= @endDate ORDER BY created_at DESC - // ` +func GetLatestWeeklyStoreScoreList(db *DaoDB, storeID, weekNum int) (storeScoreList []*model.StoreScoreEx, err error) { sql := ` - SELECT * FROM store_score WHERE store_id = ? - AND DATE(created_at) >= DATE_SUB( + SELECT t2.name store_name, t1.* FROM store_score t1 + JOIN store t2 ON t1.store_id = t2.id + WHERE store_id = ? + AND DATE(t1.created_at) >= DATE_SUB( DATE_SUB( CURDATE(), INTERVAL @@ -34,7 +29,7 @@ func GetLatestWeeklyStoreScoreList(db *DaoDB, storeID, weekNum int) (storeScoreL ), INTERVAL ? DAY ) - AND DATE(created_at) <= DATE_SUB( + AND DATE(t1.created_at) <= DATE_SUB( CURDATE(), INTERVAL IF ( diff --git a/business/model/store_score.go b/business/model/store_score.go index 13e121088..c8207a7cd 100644 --- a/business/model/store_score.go +++ b/business/model/store_score.go @@ -21,7 +21,6 @@ type StoreScore struct { ID int `orm:"column(id)" json:"id"` CreatedAt time.Time `orm:"auto_now_add;type(datetime)" json:"createdAt"` StoreID int `orm:"column(store_id)" json:"storeID"` - StoreName string `orm:"column(store_name)" json:"storeName"` StoreOpenTime int `orm:"column(store_open_time)" json:"storeOpenTime"` SaleSkuCount int `orm:"column(sale_sku_count)" json:"saleSkuCount"` @@ -35,8 +34,13 @@ type StoreScore struct { SaleSkuPrice int `orm:"column(sale_sku_price)" json:"saleSkuPrice"` } -type WeeklyStoreScore struct { +type StoreScoreEx struct { StoreScore + StoreName string `json:"storeName"` +} + +type WeeklyStoreScore struct { + StoreScoreEx BeginTime time.Time `json:"beginTime"` EndTime time.Time `json:"endTime"` TotalScore int `json:"totalScore"` From f62268821ea1c1da2e741ef1495e2c2b1acc61f3 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Wed, 11 Sep 2019 10:15:28 +0800 Subject: [PATCH 13/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E9=85=8D=E9=80=81?= =?UTF-8?q?=E9=9D=A2=E7=A7=AF=E8=AE=A1=E7=AE=97(=E6=A0=B9=E6=8D=AE?= =?UTF-8?q?=E7=BB=8F=E7=BA=AC=E5=BA=A6=E8=AE=A1=E7=AE=97=E5=A4=9A=E8=BE=B9?= =?UTF-8?q?=E5=BD=A2=E7=90=83=E9=9D=A2=E7=A7=AF-=E5=87=B8=E5=A4=9A?= =?UTF-8?q?=E8=BE=B9=E5=BD=A2=E5=92=8C=E5=87=B9=E5=A4=9A=E8=BE=B9=E5=BD=A2?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 15 +-- business/jxutils/jxutils.go | 169 +++++++++++++++++++++++++++ 2 files changed, 171 insertions(+), 13 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index d1330032d..8a550369f 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -367,17 +367,6 @@ func ScoreFullVendor(storeList []*cms.StoreExt) { } } -func CalcPolygonArea(points [][2]float64) (area float64) { - count := len(points) - for i := 0; i < count-1; i++ { - area += (points[i][0] - points[i+1][0]) * (points[i][1] + points[i+1][1]) - } - area += (points[count-1][0] - points[0][0]) * (points[count-1][1] + points[0][1]) - area = math.Abs(area) / 2 - - return area -} - //经营范围面积大于半径2km的圆得满分10分,低于1km得分0 func ScoreStoreRange(storeList []*cms.StoreExt) { for _, storeInfo := range storeList { @@ -385,7 +374,7 @@ func ScoreStoreRange(storeList []*cms.StoreExt) { storeID := storeInfo.ID if storeInfo.DeliveryRangeType == model.DeliveryRangeTypePolygon { points := jxutils.CoordinateStr2Points(storeInfo.DeliveryRange) - area := CalcPolygonArea(points) + area := jxutils.CalcPolygonAreaByLngAndLat(points) goodArea := math.Pi * StoreRangeGoodRadius * StoreRangeGoodRadius badArea := math.Pi * StoreRangeBadRadius * StoreRangeBadRadius if area >= goodArea { @@ -398,7 +387,7 @@ func ScoreStoreRange(storeList []*cms.StoreExt) { finalScore = ItemTotalScore - int(math.Round(diff*ratio)) } } else if storeInfo.DeliveryRangeType == model.DeliveryRangeTypeRadius { - deliveryRadius := utils.Str2Float64WithDefault(storeInfo.DeliveryRange, 0) + deliveryRadius := utils.Str2Float64(storeInfo.DeliveryRange) / 1000 if deliveryRadius >= StoreRangeGoodRadius { finalScore = ItemTotalScore } else if deliveryRadius <= StoreRangeBadRadius { diff --git a/business/jxutils/jxutils.go b/business/jxutils/jxutils.go index ef91ef5ef..a43839c51 100644 --- a/business/jxutils/jxutils.go +++ b/business/jxutils/jxutils.go @@ -192,6 +192,175 @@ func EarthDistance(lng1, lat1, lng2, lat2 float64) float64 { return dist * radius } +//计算多边形平面面积 +func CalcPolygonArea(points [][2]float64) (area float64) { + count := len(points) + for i := 0; i < count-1; i++ { + area += (points[i][0] - points[i+1][0]) * (points[i][1] + points[i+1][1]) + } + area += (points[count-1][0] - points[0][0]) * (points[count-1][1] + points[0][1]) + area = math.Abs(area) / 2 + + return area +} + +func ConvertToRadian(value float64) float64 { + return value * math.Pi / 180 +} + +//计算凹多边形球面积根据经纬度(KM) +func CalcConcavePolygonAreaByLngAndLatFix(points [][2]float64) (area float64) { + radius := 6378.137 + for i := 0; i < len(points)-1; i++ { + p1 := points[i] + p2 := points[i+1] + area += ConvertToRadian(p2[0]-p1[0]) * (2 + math.Sin(ConvertToRadian(p1[1])) + math.Sin(ConvertToRadian(p2[1]))) + } + + area = area * radius * radius / 2 + + return math.Abs(area) +} + +//计算凸多边形球面积根据经纬度(KM) +func CalcConvexPolygonAreaByLngAndLat(points [][2]float64) (area float64) { + Count := len(points) + LowX := 0.0 + LowY := 0.0 + MiddleX := 0.0 + MiddleY := 0.0 + HighX := 0.0 + HighY := 0.0 + + AM := 0.0 + BM := 0.0 + CM := 0.0 + + AL := 0.0 + BL := 0.0 + CL := 0.0 + + AH := 0.0 + BH := 0.0 + CH := 0.0 + + CoefficientL := 0.0 + CoefficientH := 0.0 + + ALtangent := 0.0 + BLtangent := 0.0 + CLtangent := 0.0 + + AHtangent := 0.0 + BHtangent := 0.0 + CHtangent := 0.0 + + ANormalLine := 0.0 + BNormalLine := 0.0 + CNormalLine := 0.0 + + OrientationValue := 0.0 + + AngleCos := 0.0 + + Sum1 := 0.0 + Sum2 := 0.0 + Count2 := 0 + Count1 := 0 + + Sum := 0.0 + Radius := 6378.137 + + for i := 0; i < Count; i++ { + if i == 0 { + LowX = ConvertToRadian(points[Count-1][0]) + LowY = ConvertToRadian(points[Count-1][1]) + MiddleX = ConvertToRadian(points[0][0]) + MiddleY = ConvertToRadian(points[0][1]) + HighX = ConvertToRadian(points[1][0]) + HighY = ConvertToRadian(points[1][1]) + } else if i == Count-1 { + LowX = ConvertToRadian(points[Count-2][0]) + LowY = ConvertToRadian(points[Count-2][1]) + MiddleX = ConvertToRadian(points[Count-1][0]) + MiddleY = ConvertToRadian(points[Count-1][1]) + HighX = ConvertToRadian(points[0][0]) + HighY = ConvertToRadian(points[0][1]) + } else { + LowX = ConvertToRadian(points[i-1][0]) + LowY = ConvertToRadian(points[i-1][1]) + MiddleX = ConvertToRadian(points[i][0]) + MiddleY = ConvertToRadian(points[i][1]) + HighX = ConvertToRadian(points[i+1][0]) + HighY = ConvertToRadian(points[i+1][1]) + } + + AM = math.Cos(MiddleY) * math.Cos(MiddleX) + BM = math.Cos(MiddleY) * math.Sin(MiddleX) + CM = math.Sin(MiddleY) + AL = math.Cos(LowY) * math.Cos(LowX) + BL = math.Cos(LowY) * math.Sin(LowX) + CL = math.Sin(LowY) + AH = math.Cos(HighY) * math.Cos(HighX) + BH = math.Cos(HighY) * math.Sin(HighX) + CH = math.Sin(HighY) + + CoefficientL = (AM*AM + BM*BM + CM*CM) / (AM*AL + BM*BL + CM*CL) + CoefficientH = (AM*AM + BM*BM + CM*CM) / (AM*AH + BM*BH + CM*CH) + + ALtangent = CoefficientL*AL - AM + BLtangent = CoefficientL*BL - BM + CLtangent = CoefficientL*CL - CM + AHtangent = CoefficientH*AH - AM + BHtangent = CoefficientH*BH - BM + CHtangent = CoefficientH*CH - CM + + AngleCos = (AHtangent*ALtangent + BHtangent*BLtangent + CHtangent*CLtangent) / (math.Sqrt(AHtangent*AHtangent+BHtangent*BHtangent+CHtangent*CHtangent) * math.Sqrt(ALtangent*ALtangent+BLtangent*BLtangent+CLtangent*CLtangent)) + AngleCos = math.Acos(AngleCos) + + ANormalLine = BHtangent*CLtangent - CHtangent*BLtangent + BNormalLine = 0 - (AHtangent*CLtangent - CHtangent*ALtangent) + CNormalLine = AHtangent*BLtangent - BHtangent*ALtangent + + if AM != 0 { + OrientationValue = ANormalLine / AM + } else if BM != 0 { + OrientationValue = BNormalLine / BM + } else { + OrientationValue = CNormalLine / CM + } + + if OrientationValue > 0 { + Sum1 += AngleCos + Count1++ + } else { + Sum2 += AngleCos + Count2++ + } + + } + + if Sum1 > Sum2 { + Sum = Sum1 + 2*math.Pi*float64(Count2) - Sum2 + } else { + Sum = 2*math.Pi*float64(Count1) - Sum1 + Sum2 + } + + area = (Sum - float64(Count-2)*math.Pi) * Radius * Radius + + return area +} + +//计算多边形球面积根据经纬度(KM) +func CalcPolygonAreaByLngAndLat(points [][2]float64) (area float64) { + area = CalcConvexPolygonAreaByLngAndLat(points) + if math.IsNaN(area) { + area = CalcConcavePolygonAreaByLngAndLatFix(points) + } + + return area +} + func StandardCoordinate2Int(value float64) int { return int(math.Round(value * 1000000)) } From 3784696334e10a03df3ec964c781726964ea2f27 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Wed, 11 Sep 2019 10:35:54 +0800 Subject: [PATCH 14/32] =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/model/dao/store_score.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/business/model/dao/store_score.go b/business/model/dao/store_score.go index 87858865f..596a37bc0 100644 --- a/business/model/dao/store_score.go +++ b/business/model/dao/store_score.go @@ -16,7 +16,7 @@ func GetLatestWeeklyStoreScoreList(db *DaoDB, storeID, weekNum int) (storeScoreL sql := ` SELECT t2.name store_name, t1.* FROM store_score t1 JOIN store t2 ON t1.store_id = t2.id - WHERE store_id = ? + WHERE t1.store_id = ? AND DATE(t1.created_at) >= DATE_SUB( DATE_SUB( CURDATE(), From bfaea1b9981c3ad8465f8ad0c72573877fe0d1b3 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Wed, 11 Sep 2019 14:49:59 +0800 Subject: [PATCH 15/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E8=AF=84=E5=88=86?= =?UTF-8?q?=E5=B9=B6=E5=8F=91=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 489 ++++++++++++++------------- 1 file changed, 251 insertions(+), 238 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index 8a550369f..7548926f8 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -6,6 +6,7 @@ import ( "sync" "time" + "git.rosy.net.cn/baseapi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxstore/cms" "git.rosy.net.cn/jx-callback/business/jxutils" @@ -18,6 +19,7 @@ import ( const ( EnableScheduleScoreStore = !true + ParallelCount = 5 GoldMedalScore = 90 SilverMedalScore = 80 @@ -38,7 +40,8 @@ const ( AbsentGoodsOrderNormalRatio = 1.0 //百分比 StoreRangeGoodRadius = 2.0 //千米 StoreRangeBadRadius = 1.0 //千米 - SaleSkuPriceRatio = 90 //百分比 + SaleSkuPriceRatio = 90 //千米 + SaleSkuCheckRange = 5.0 //千米 ) var ( @@ -115,7 +118,7 @@ func (s *StoreScoreDataWrapper) SetData(storeID int, valueName string, value int } //得到所有门店的商品 -func GetAllStoreSkus(ctx *jxcontext.Context, storeList []*cms.StoreExt) { +func GetAllStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeList []*cms.StoreExt) { allStoreSkusWrapper.InitData() taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { storeInfo := batchItemList[0].(*cms.StoreExt) @@ -133,8 +136,8 @@ func GetAllStoreSkus(ctx *jxcontext.Context, storeList []*cms.StoreExt) { allStoreSkusWrapper.SetData(storeID, jxSkuMapData) return retVal, err } - taskParallel := tasksch.NewParallelTask("GetAllStoreSkus", nil, ctx, taskFunc, storeList) - tasksch.HandleTask(taskParallel, nil, true).Run() + taskParallel := tasksch.NewParallelTask("得到所有门店商品", nil, ctx, taskFunc, storeList) + tasksch.HandleTask(taskParallel, parentTask, true).Run() taskParallel.GetResult(0) } @@ -153,263 +156,244 @@ func GetOpenTime(opTimeList []int16) (opTime float64) { } //营业时间12小时及以上满分,总分10分,每少一个小时扣1分 -func ScoreStoreOpenTime(storeList []*cms.StoreExt) { - for _, storeInfo := range storeList { - storeID := storeInfo.ID - storeStatus := storeInfo.Status - isStoreOpen := storeStatus == model.StoreStatusOpened - for _, storeMap := range storeInfo.StoreMaps { - vendorStoreStatus := int(utils.MustInterface2Int64(storeMap["status"])) - isVendorStoreOpen := vendorStoreStatus == model.StoreStatusOpened - opTimeList := storeInfo.GetOpTimeList() - if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen { - finalScore := 0 - opTime := GetOpenTime(opTimeList) - if opTime >= StoreOpenTimeNormalTime { - finalScore = ItemTotalScore - } else { - decScore := int(math.Round(StoreOpenTimeNormalTime - opTime)) - finalScore = ItemTotalScore - decScore - if finalScore < 0 { - finalScore = 0 - } +func ScoreStoreOpenTime(storeInfo *cms.StoreExt) { + storeID := storeInfo.ID + storeStatus := storeInfo.Status + isStoreOpen := storeStatus == model.StoreStatusOpened + for _, storeMap := range storeInfo.StoreMaps { + vendorStoreStatus := int(utils.MustInterface2Int64(storeMap["status"])) + isVendorStoreOpen := vendorStoreStatus == model.StoreStatusOpened + opTimeList := storeInfo.GetOpTimeList() + if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen { + finalScore := 0 + opTime := GetOpenTime(opTimeList) + if opTime >= StoreOpenTimeNormalTime { + finalScore = ItemTotalScore + } else { + decScore := int(math.Round(StoreOpenTimeNormalTime - opTime)) + finalScore = ItemTotalScore - decScore + if finalScore < 0 { + finalScore = 0 } - storeScoreDataWrapper.SetData(storeID, model.FieldStoreOpenTime, finalScore) } + storeScoreDataWrapper.SetData(storeID, model.FieldStoreOpenTime, finalScore) } } } //可售商品数量大于1000,总分10分,按比例扣 -func ScoreSaleSkuCount(ctx *jxcontext.Context, storeList []*cms.StoreExt) { - for _, storeInfo := range storeList { - storeID := storeInfo.ID - skusMapData := allStoreSkusWrapper.GetData(storeID) - if len(skusMapData) > 0 { - finalScore := 0 - saleSkuCount := 0 - for _, value := range skusMapData { - for _, skuInfo := range value.Skus2 { - saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus) - if saleStatus == model.SkuStatusNormal { - saleSkuCount++ - } +func ScoreSaleSkuCount(storeInfo *cms.StoreExt) { + storeID := storeInfo.ID + skusMapData := allStoreSkusWrapper.GetData(storeID) + if len(skusMapData) > 0 { + finalScore := 0 + saleSkuCount := 0 + for _, value := range skusMapData { + for _, skuInfo := range value.Skus2 { + saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus) + if saleStatus == model.SkuStatusNormal { + saleSkuCount++ } } - finalScore = int(math.Round(float64(saleSkuCount) * SaleSkuScorePerUnit)) - if finalScore > ItemTotalScore { - finalScore = ItemTotalScore - } - storeScoreDataWrapper.SetData(storeID, model.FieldSaleSkuCount, finalScore) } + finalScore = int(math.Round(float64(saleSkuCount) * SaleSkuScorePerUnit)) + if finalScore > ItemTotalScore { + finalScore = ItemTotalScore + } + storeScoreDataWrapper.SetData(storeID, model.FieldSaleSkuCount, finalScore) } } //平均捡货时间小于等于拣货截止时间为10分满分,每超出1分钟,减1分 -func ScoreAveragePickupTime(storeList []*cms.StoreExt) { - for _, storeInfo := range storeList { - storeID := storeInfo.ID - db := dao.GetDB() - orderList, err := dao.GetDailyFinishOrderList(db, storeID) - orderListCount := len(orderList) - if err == nil && orderListCount > 0 { - totalScore := 0 - for _, value := range orderList { - statusTime := value.StatusTime.Unix() - pickDeadline := value.PickDeadline.Unix() - if statusTime <= pickDeadline { - totalScore += ItemTotalScore - } else { - decScore := int(math.Round(float64(statusTime-pickDeadline) / 60)) - tempScore := ItemTotalScore - decScore - if tempScore < 0 { - tempScore = 0 - } - totalScore += tempScore +func ScoreAveragePickupTime(storeInfo *cms.StoreExt) { + storeID := storeInfo.ID + db := dao.GetDB() + orderList, err := dao.GetDailyFinishOrderList(db, storeID) + orderListCount := len(orderList) + if err == nil && orderListCount > 0 { + totalScore := 0 + for _, value := range orderList { + statusTime := value.StatusTime.Unix() + pickDeadline := value.PickDeadline.Unix() + if statusTime <= pickDeadline { + totalScore += ItemTotalScore + } else { + decScore := int(math.Round(float64(statusTime-pickDeadline) / 60)) + tempScore := ItemTotalScore - decScore + if tempScore < 0 { + tempScore = 0 } + totalScore += tempScore } - finalScore := totalScore / orderListCount - storeScoreDataWrapper.SetData(storeID, model.FieldAveragePickupTime, finalScore) } + finalScore := totalScore / orderListCount + storeScoreDataWrapper.SetData(storeID, model.FieldAveragePickupTime, finalScore) } } //差评订单和完成订单比例小于0.2%,得满分10分,每增加0.1%减1分 -func ScoreBadCommentOrder(storeList []*cms.StoreExt) { - for _, storeInfo := range storeList { - storeID := storeInfo.ID - db := dao.GetDB() - badCommentOrderCount, _ := dao.GetDailyBadCommentOrderCount(db, storeID) - finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) - if finishOrderCount > 0 { - finalScore := 0 - badCommentOrderRatio := float64(badCommentOrderCount) * 100 / float64(finishOrderCount) - if badCommentOrderRatio <= BadCommentOrderNormalRatio { - finalScore = ItemTotalScore - } else { - decScore := int(math.Round((badCommentOrderRatio - BadCommentOrderNormalRatio) / 0.1)) - finalScore = ItemTotalScore - decScore - if finalScore < 0 { - finalScore = 0 - } +func ScoreBadCommentOrder(storeInfo *cms.StoreExt) { + storeID := storeInfo.ID + db := dao.GetDB() + badCommentOrderCount, _ := dao.GetDailyBadCommentOrderCount(db, storeID) + finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) + if finishOrderCount > 0 { + finalScore := 0 + badCommentOrderRatio := float64(badCommentOrderCount) * 100 / float64(finishOrderCount) + if badCommentOrderRatio <= BadCommentOrderNormalRatio { + finalScore = ItemTotalScore + } else { + decScore := int(math.Round((badCommentOrderRatio - BadCommentOrderNormalRatio) / 0.1)) + finalScore = ItemTotalScore - decScore + if finalScore < 0 { + finalScore = 0 } - storeScoreDataWrapper.SetData(storeID, model.FieldBadCommentOrder, finalScore) } + storeScoreDataWrapper.SetData(storeID, model.FieldBadCommentOrder, finalScore) } } //未完成订单和完成订单比小于1%,得满分10分,比例每增加5%,分数减1 -func ScoreUnfinishOrder(storeList []*cms.StoreExt) { - for _, storeInfo := range storeList { - storeID := storeInfo.ID - db := dao.GetDB() - unFinishOrderCount, _ := dao.GetDailyUnFinishOrderCount(db, storeID) - finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) - if finishOrderCount > 0 { - finalScore := 0 - unfinishOrderRatio := float64(unFinishOrderCount) * 100 / float64(finishOrderCount) - if unfinishOrderRatio <= UnfinishOrderNormalRatio { - finalScore = ItemTotalScore - } else { - decScore := int(math.Round((unfinishOrderRatio - UnfinishOrderNormalRatio) / 5)) - finalScore = ItemTotalScore - decScore - if finalScore < 0 { - finalScore = 0 - } +func ScoreUnfinishOrder(storeInfo *cms.StoreExt) { + storeID := storeInfo.ID + db := dao.GetDB() + unFinishOrderCount, _ := dao.GetDailyUnFinishOrderCount(db, storeID) + finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) + if finishOrderCount > 0 { + finalScore := 0 + unfinishOrderRatio := float64(unFinishOrderCount) * 100 / float64(finishOrderCount) + if unfinishOrderRatio <= UnfinishOrderNormalRatio { + finalScore = ItemTotalScore + } else { + decScore := int(math.Round((unfinishOrderRatio - UnfinishOrderNormalRatio) / 5)) + finalScore = ItemTotalScore - decScore + if finalScore < 0 { + finalScore = 0 } - storeScoreDataWrapper.SetData(storeID, model.FieldUnfinishOrder, finalScore) } + storeScoreDataWrapper.SetData(storeID, model.FieldUnfinishOrder, finalScore) } } //缺货订单和完成订单比小于1%得10分,比例每增加0.1%减1分 -func ScoreAbsentGoodsOrder(storeList []*cms.StoreExt) { - for _, storeInfo := range storeList { - storeID := storeInfo.ID - db := dao.GetDB() - absentGoodsOrderCount, _ := dao.GetDailyAbsentGoodsOrderCount(db, storeID) - finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) - if finishOrderCount > 0 { - finalScore := 0 - absentGoodsOrderRatio := float64(absentGoodsOrderCount) * 100 / float64(finishOrderCount) - if absentGoodsOrderRatio <= AbsentGoodsOrderNormalRatio { - finalScore = ItemTotalScore - } else { - decScore := int(math.Round((absentGoodsOrderRatio - AbsentGoodsOrderNormalRatio) / 0.1)) - finalScore = ItemTotalScore - decScore - if finalScore < 0 { - finalScore = 0 - } +func ScoreAbsentGoodsOrder(storeInfo *cms.StoreExt) { + storeID := storeInfo.ID + db := dao.GetDB() + absentGoodsOrderCount, _ := dao.GetDailyAbsentGoodsOrderCount(db, storeID) + finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) + if finishOrderCount > 0 { + finalScore := 0 + absentGoodsOrderRatio := float64(absentGoodsOrderCount) * 100 / float64(finishOrderCount) + if absentGoodsOrderRatio <= AbsentGoodsOrderNormalRatio { + finalScore = ItemTotalScore + } else { + decScore := int(math.Round((absentGoodsOrderRatio - AbsentGoodsOrderNormalRatio) / 0.1)) + finalScore = ItemTotalScore - decScore + if finalScore < 0 { + finalScore = 0 } - storeScoreDataWrapper.SetData(storeID, model.FieldAbsentGoodsOrder, finalScore) } + storeScoreDataWrapper.SetData(storeID, model.FieldAbsentGoodsOrder, finalScore) } } //促销品数量20个以上为满分10分,每少2个扣1分 -func ScorePromotionSku(storeList []*cms.StoreExt) { - for _, storeInfo := range storeList { - storeID := storeInfo.ID - db := dao.GetDB() - beginTime := time.Now() - endTime := time.Now() - actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, -1, []int{}, []int{storeID}, []int{}, beginTime, endTime) - if err == nil && len(actStoreSkuList) > 0 { - finalScore := 0 - actStoreSkuMap := make(map[int]int) - for _, value := range actStoreSkuList { - if value.Type != model.ActSkuFake { - actStoreSkuMap[value.SkuID] = 1 - } +func ScorePromotionSku(storeInfo *cms.StoreExt) { + storeID := storeInfo.ID + db := dao.GetDB() + beginTime := time.Now() + endTime := time.Now() + actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, -1, []int{}, []int{storeID}, []int{}, beginTime, endTime) + if err == nil && len(actStoreSkuList) > 0 { + finalScore := 0 + actStoreSkuMap := make(map[int]int) + for _, value := range actStoreSkuList { + if value.Type != model.ActSkuFake { + actStoreSkuMap[value.SkuID] = 1 } - promotionSkuCount := len(actStoreSkuMap) - if promotionSkuCount >= PromotionSkuNormalCount { - finalScore = ItemTotalScore - } else { - decScore := (PromotionSkuNormalCount - promotionSkuCount) / 2 - finalScore = ItemTotalScore - decScore - if finalScore < 0 { - finalScore = 0 - } - } - storeScoreDataWrapper.SetData(storeID, model.FieldPromotionSku, finalScore) } + promotionSkuCount := len(actStoreSkuMap) + if promotionSkuCount >= PromotionSkuNormalCount { + finalScore = ItemTotalScore + } else { + decScore := (PromotionSkuNormalCount - promotionSkuCount) / 2 + finalScore = ItemTotalScore - decScore + if finalScore < 0 { + finalScore = 0 + } + } + storeScoreDataWrapper.SetData(storeID, model.FieldPromotionSku, finalScore) } } //经营全平台满分10分,每少一个平台扣2分(一个平台没有得0分) -func ScoreFullVendor(storeList []*cms.StoreExt) { +func ScoreFullVendor(storeInfo *cms.StoreExt) { fullVendorCount := len(fullVendorList) - for _, storeInfo := range storeList { - finalScore := 0 - storeID := storeInfo.ID - storeStatus := storeInfo.Status - isStoreOpen := storeStatus == model.StoreStatusOpened - count := 0 - for _, storeMap := range storeInfo.StoreMaps { - vendorStoreStatus := int(utils.MustInterface2Int64(storeMap["status"])) - isVendorStoreOpen := vendorStoreStatus == model.StoreStatusOpened - opTimeList := storeInfo.GetOpTimeList() - if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen { - count++ - } + finalScore := 0 + storeID := storeInfo.ID + storeStatus := storeInfo.Status + isStoreOpen := storeStatus == model.StoreStatusOpened + count := 0 + for _, storeMap := range storeInfo.StoreMaps { + vendorStoreStatus := int(utils.MustInterface2Int64(storeMap["status"])) + isVendorStoreOpen := vendorStoreStatus == model.StoreStatusOpened + opTimeList := storeInfo.GetOpTimeList() + if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen { + count++ } - - if count > 0 { - if count == fullVendorCount { - finalScore = ItemTotalScore - } else { - decScore := (fullVendorCount - count) * 2 - finalScore = ItemTotalScore - decScore - } - } - storeScoreDataWrapper.SetData(storeID, model.FieldFullVendor, finalScore) } + if count > 0 { + if count == fullVendorCount { + finalScore = ItemTotalScore + } else { + decScore := (fullVendorCount - count) * 2 + finalScore = ItemTotalScore - decScore + } + } + storeScoreDataWrapper.SetData(storeID, model.FieldFullVendor, finalScore) } //经营范围面积大于半径2km的圆得满分10分,低于1km得分0 -func ScoreStoreRange(storeList []*cms.StoreExt) { - for _, storeInfo := range storeList { - finalScore := 0 - storeID := storeInfo.ID - if storeInfo.DeliveryRangeType == model.DeliveryRangeTypePolygon { - points := jxutils.CoordinateStr2Points(storeInfo.DeliveryRange) - area := jxutils.CalcPolygonAreaByLngAndLat(points) - goodArea := math.Pi * StoreRangeGoodRadius * StoreRangeGoodRadius - badArea := math.Pi * StoreRangeBadRadius * StoreRangeBadRadius - if area >= goodArea { - finalScore = ItemTotalScore - } else if area <= badArea { - finalScore = 0 - } else { - diff := goodArea - area - ratio := float64(ItemTotalScore) / (goodArea - badArea) - finalScore = ItemTotalScore - int(math.Round(diff*ratio)) - } - } else if storeInfo.DeliveryRangeType == model.DeliveryRangeTypeRadius { - deliveryRadius := utils.Str2Float64(storeInfo.DeliveryRange) / 1000 - if deliveryRadius >= StoreRangeGoodRadius { - finalScore = ItemTotalScore - } else if deliveryRadius <= StoreRangeBadRadius { - finalScore = 0 - } else { - diff := StoreRangeGoodRadius - deliveryRadius - ratio := float64(ItemTotalScore) / (StoreRangeGoodRadius - StoreRangeBadRadius) - finalScore = ItemTotalScore - int(math.Round(diff*ratio)) - } +func ScoreStoreRange(storeInfo *cms.StoreExt) { + finalScore := 0 + storeID := storeInfo.ID + if storeInfo.DeliveryRangeType == model.DeliveryRangeTypePolygon { + points := jxutils.CoordinateStr2Points(storeInfo.DeliveryRange) + area := jxutils.CalcPolygonAreaByLngAndLat(points) + goodArea := math.Pi * StoreRangeGoodRadius * StoreRangeGoodRadius + badArea := math.Pi * StoreRangeBadRadius * StoreRangeBadRadius + if area >= goodArea { + finalScore = ItemTotalScore + } else if area <= badArea { + finalScore = 0 + } else { + diff := goodArea - area + ratio := float64(ItemTotalScore) / (goodArea - badArea) + finalScore = ItemTotalScore - int(math.Round(diff*ratio)) + } + } else if storeInfo.DeliveryRangeType == model.DeliveryRangeTypeRadius { + deliveryRadius := utils.Str2Float64WithDefault(storeInfo.DeliveryRange, 0) / 1000 + if deliveryRadius >= StoreRangeGoodRadius { + finalScore = ItemTotalScore + } else if deliveryRadius <= StoreRangeBadRadius { + finalScore = 0 + } else { + diff := StoreRangeGoodRadius - deliveryRadius + ratio := float64(ItemTotalScore) / (StoreRangeGoodRadius - StoreRangeBadRadius) + finalScore = ItemTotalScore - int(math.Round(diff*ratio)) } - storeScoreDataWrapper.SetData(storeID, model.FieldStoreRange, finalScore) } + storeScoreDataWrapper.SetData(storeID, model.FieldStoreRange, finalScore) } //得到距离某个门店多少KM内的所有门店信息 -func GetRangeStoreList(storeID int, lng, lat, checkDist float64, storeList []*cms.StoreExt) (outStoreList []*cms.StoreExt) { +func GetRangeStoreList(storeID int, lng, lat, checkRange float64, storeList []*cms.StoreExt) (outStoreList []*cms.StoreExt) { for _, storeInfo := range storeList { if storeInfo.ID == storeID { outStoreList = append(outStoreList, storeInfo) } else { distance := jxutils.EarthDistance(lng, lat, storeInfo.FloatLng, storeInfo.FloatLat) - if distance <= checkDist { + if distance <= checkRange { outStoreList = append(outStoreList, storeInfo) } } @@ -454,29 +438,27 @@ func GetSkusCountLessEqualAvgPrice(storeID int, skusAveragePrice map[int]int) (c } //可售商品价格在附近5km内门店比较,价格低于等于平均值的商品数占90%以上满分10分,比例每降低10%减1分,100%超标得0分 -func ScoreSaleSkuPrice(ctx *jxcontext.Context, storeList []*cms.StoreExt) { - for _, storeInfo := range storeList { - finalScore := 0 - storeID := storeInfo.ID - totalCount := len(allStoreSkusWrapper.GetData(storeID)) - if totalCount > 0 { - rangeStoreList := GetRangeStoreList(storeID, storeInfo.FloatLng, storeInfo.FloatLat, 5, storeList) - skusAveragePrice := GetStoreSkusAveragePrice(rangeStoreList) - count := GetSkusCountLessEqualAvgPrice(storeID, skusAveragePrice) - if count > 0 { - ratio := int(math.Round(float64(count) * 100 / float64(totalCount))) - if ratio >= SaleSkuPriceRatio { - finalScore = ItemTotalScore - } else { - decScore := (SaleSkuPriceRatio - ratio) / 10 - finalScore = ItemTotalScore - decScore - if finalScore < 0 { - finalScore = 0 - } +func ScoreSaleSkuPrice(storeInfo *cms.StoreExt, storeList []*cms.StoreExt) { + finalScore := 0 + storeID := storeInfo.ID + totalCount := len(allStoreSkusWrapper.GetData(storeID)) + if totalCount > 0 { + rangeStoreList := GetRangeStoreList(storeID, storeInfo.FloatLng, storeInfo.FloatLat, SaleSkuCheckRange, storeList) + skusAveragePrice := GetStoreSkusAveragePrice(rangeStoreList) + count := GetSkusCountLessEqualAvgPrice(storeID, skusAveragePrice) + if count > 0 { + ratio := int(math.Round(float64(count) * 100 / float64(totalCount))) + if ratio >= SaleSkuPriceRatio { + finalScore = ItemTotalScore + } else { + decScore := (SaleSkuPriceRatio - ratio) / 10 + finalScore = ItemTotalScore - decScore + if finalScore < 0 { + finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, model.FieldSaleSkuPrice, finalScore) } + storeScoreDataWrapper.SetData(storeID, model.FieldSaleSkuPrice, finalScore) } } @@ -506,24 +488,55 @@ func GetFilterStoreListEx(storeList []*cms.StoreExt, storeIDMap map[int]int) (ou } func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, err error) { - storeScoreDataWrapper.InitData() - storeList, err := GetStoreList(ctx) - storeIDMap := jxutils.IntList2Map(storeIDList) - storeList = GetFilterStoreListEx(storeList, storeIDMap) - - GetAllStoreSkus(ctx, storeList) - ScoreStoreOpenTime(storeList) - ScoreSaleSkuCount(ctx, storeList) - ScoreAveragePickupTime(storeList) - ScoreBadCommentOrder(storeList) - ScoreUnfinishOrder(storeList) - ScoreAbsentGoodsOrder(storeList) - ScorePromotionSku(storeList) - ScoreFullVendor(storeList) - ScoreStoreRange(storeList) - ScoreSaleSkuPrice(ctx, storeList) - InsertStoreScore() - allStoreSkusWrapper.ClearData() + var storeList []*cms.StoreExt + taskCount := 4 + taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { + switch step { + case 0: + baseapi.SugarLogger.Debugf("ScoreStore step0 begin") + storeScoreDataWrapper.InitData() + storeList, err = GetStoreList(ctx) + storeIDMap := jxutils.IntList2Map(storeIDList) + storeList = GetFilterStoreListEx(storeList, storeIDMap) + baseapi.SugarLogger.Debugf("ScoreStore step0 end") + case 1: + baseapi.SugarLogger.Debugf("ScoreStore step1 begin") + GetAllStoreSkus(ctx, task, storeList) + baseapi.SugarLogger.Debugf("ScoreStore step1 end") + case 2: + baseapi.SugarLogger.Debugf("ScoreStore step2 begin") + taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + storeInfo := batchItemList[0].(*cms.StoreExt) + ScoreStoreOpenTime(storeInfo) + ScoreSaleSkuCount(storeInfo) + ScoreAveragePickupTime(storeInfo) + ScoreBadCommentOrder(storeInfo) + ScoreUnfinishOrder(storeInfo) + ScoreAbsentGoodsOrder(storeInfo) + ScorePromotionSku(storeInfo) + ScoreFullVendor(storeInfo) + ScoreStoreRange(storeInfo) + ScoreSaleSkuPrice(storeInfo, storeList) + return retVal, err + } + taskParallel := tasksch.NewParallelTask("计算门店得分", tasksch.NewParallelConfig().SetParallelCount(ParallelCount), ctx, taskFunc, storeList) + tasksch.HandleTask(taskParallel, task, true).Run() + taskParallel.GetResult(0) + _, err = taskParallel.GetResult(0) + if err != nil { + baseapi.SugarLogger.Debugf("ScoreStore taskParallel error:%v", err) + } + baseapi.SugarLogger.Debugf("ScoreStore step2 end") + case 3: + baseapi.SugarLogger.Debugf("ScoreStore step3 begin") + InsertStoreScore() + allStoreSkusWrapper.ClearData() + baseapi.SugarLogger.Debugf("ScoreStore step3 end") + } + return result, err + } + taskSeq := tasksch.NewSeqTask("门店评分-序列任务", ctx, taskSeqFunc, taskCount) + tasksch.HandleTask(taskSeq, nil, true).Run() return retVal, err } From 8a955013d93429f8e59e9dacab3bf65fbaa83cc6 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Wed, 11 Sep 2019 17:37:27 +0800 Subject: [PATCH 16/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E8=AF=84=E5=88=86-?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 41 +++++++++++++++++++++------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index 7548926f8..39019098a 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -19,7 +19,7 @@ import ( const ( EnableScheduleScoreStore = !true - ParallelCount = 5 + ParallelCount = 10 GoldMedalScore = 90 SilverMedalScore = 80 @@ -232,11 +232,15 @@ func ScoreAveragePickupTime(storeInfo *cms.StoreExt) { } //差评订单和完成订单比例小于0.2%,得满分10分,每增加0.1%减1分 -func ScoreBadCommentOrder(storeInfo *cms.StoreExt) { +func ScoreBadCommentOrder(storeInfo *cms.StoreExt, paramFinishOrderCount int64) (finishOrderCount int64) { storeID := storeInfo.ID db := dao.GetDB() badCommentOrderCount, _ := dao.GetDailyBadCommentOrderCount(db, storeID) - finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) + if paramFinishOrderCount == -1 { + finishOrderCount, _ = dao.GetDailyFinishOrderCount(db, storeID) + } else { + finishOrderCount = paramFinishOrderCount + } if finishOrderCount > 0 { finalScore := 0 badCommentOrderRatio := float64(badCommentOrderCount) * 100 / float64(finishOrderCount) @@ -251,14 +255,20 @@ func ScoreBadCommentOrder(storeInfo *cms.StoreExt) { } storeScoreDataWrapper.SetData(storeID, model.FieldBadCommentOrder, finalScore) } + + return finishOrderCount } //未完成订单和完成订单比小于1%,得满分10分,比例每增加5%,分数减1 -func ScoreUnfinishOrder(storeInfo *cms.StoreExt) { +func ScoreUnfinishOrder(storeInfo *cms.StoreExt, paramFinishOrderCount int64) (finishOrderCount int64) { storeID := storeInfo.ID db := dao.GetDB() unFinishOrderCount, _ := dao.GetDailyUnFinishOrderCount(db, storeID) - finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) + if paramFinishOrderCount == -1 { + finishOrderCount, _ = dao.GetDailyFinishOrderCount(db, storeID) + } else { + finishOrderCount = paramFinishOrderCount + } if finishOrderCount > 0 { finalScore := 0 unfinishOrderRatio := float64(unFinishOrderCount) * 100 / float64(finishOrderCount) @@ -273,14 +283,20 @@ func ScoreUnfinishOrder(storeInfo *cms.StoreExt) { } storeScoreDataWrapper.SetData(storeID, model.FieldUnfinishOrder, finalScore) } + + return finishOrderCount } //缺货订单和完成订单比小于1%得10分,比例每增加0.1%减1分 -func ScoreAbsentGoodsOrder(storeInfo *cms.StoreExt) { +func ScoreAbsentGoodsOrder(storeInfo *cms.StoreExt, paramFinishOrderCount int64) (finishOrderCount int64) { storeID := storeInfo.ID db := dao.GetDB() absentGoodsOrderCount, _ := dao.GetDailyAbsentGoodsOrderCount(db, storeID) - finishOrderCount, _ := dao.GetDailyFinishOrderCount(db, storeID) + if paramFinishOrderCount == -1 { + finishOrderCount, _ = dao.GetDailyFinishOrderCount(db, storeID) + } else { + finishOrderCount = paramFinishOrderCount + } if finishOrderCount > 0 { finalScore := 0 absentGoodsOrderRatio := float64(absentGoodsOrderCount) * 100 / float64(finishOrderCount) @@ -295,6 +311,8 @@ func ScoreAbsentGoodsOrder(storeInfo *cms.StoreExt) { } storeScoreDataWrapper.SetData(storeID, model.FieldAbsentGoodsOrder, finalScore) } + + return finishOrderCount } //促销品数量20个以上为满分10分,每少2个扣1分 @@ -507,16 +525,19 @@ func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, baseapi.SugarLogger.Debugf("ScoreStore step2 begin") taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { storeInfo := batchItemList[0].(*cms.StoreExt) + storeID := storeInfo.ID + baseapi.SugarLogger.Debugf("Begin store id:%d", storeID) ScoreStoreOpenTime(storeInfo) ScoreSaleSkuCount(storeInfo) ScoreAveragePickupTime(storeInfo) - ScoreBadCommentOrder(storeInfo) - ScoreUnfinishOrder(storeInfo) - ScoreAbsentGoodsOrder(storeInfo) + finishOrderCount := ScoreBadCommentOrder(storeInfo, -1) + ScoreUnfinishOrder(storeInfo, finishOrderCount) + ScoreAbsentGoodsOrder(storeInfo, finishOrderCount) ScorePromotionSku(storeInfo) ScoreFullVendor(storeInfo) ScoreStoreRange(storeInfo) ScoreSaleSkuPrice(storeInfo, storeList) + baseapi.SugarLogger.Debugf("End store id:%d", storeID) return retVal, err } taskParallel := tasksch.NewParallelTask("计算门店得分", tasksch.NewParallelConfig().SetParallelCount(ParallelCount), ctx, taskFunc, storeList) From 30a7c1dbe2a387066a1799a00cd2d7f76ae6ed21 Mon Sep 17 00:00:00 2001 From: gazebo Date: Wed, 11 Sep 2019 17:37:57 +0800 Subject: [PATCH 17/32] =?UTF-8?q?-=20=E9=97=A8=E5=BA=97=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=8A=A5=E8=AD=A6=E6=8F=90=E7=A4=BA=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/cms/store.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/business/jxstore/cms/store.go b/business/jxstore/cms/store.go index c01cb6aca..cc2eadf7f 100644 --- a/business/jxstore/cms/store.go +++ b/business/jxstore/cms/store.go @@ -1716,8 +1716,8 @@ func SendAlarmVendorSnapshot(ctx *jxcontext.Context, parentTask tasksch.ITask, p curSnapshot := curSnapshotMap[v.GenMapKey()] // storeDetail := storeDetailMap[v.StoreID] curStoreStatus := "下线" - if curSnapshot != nil && curSnapshot.Status == model.StoreStatusOpened { - curStoreStatus = "上线" + if curSnapshot != nil { + curStoreStatus = model.StoreStatusName[curSnapshot.Status] } txtAlarm = append(txtAlarm, fmt.Sprintf("您的门店:%s,平台:%s,%s了", v.StoreName, model.VendorChineseNames[v.VendorID], curStoreStatus)) } From ad2acc3a7ed897b952e556b8e267b04399f9f277 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Thu, 12 Sep 2019 08:40:25 +0800 Subject: [PATCH 18/32] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index 39019098a..1ca80b052 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -46,7 +46,7 @@ const ( var ( scoreStoreTimeList = []string{ - "23:30:00", + "22:00:00", } fullVendorList = map[int]bool{ model.VendorIDJD: true, From 86d35d58c55461dab528be44a86a437868f3dc7f Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Thu, 12 Sep 2019 11:42:20 +0800 Subject: [PATCH 19/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E8=AF=84=E5=88=86-?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=86=85=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 131 ++++++++++++++++----------- 1 file changed, 80 insertions(+), 51 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index 1ca80b052..65882fac9 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -71,25 +71,38 @@ var ( ) type AllStoreSkusWrapper struct { - allStoreSkus map[int]map[int]*cms.StoreSkuNameExt + //allStoreSkus map[int]map[int]*cms.StoreSkuNameExt + allStoreSkus map[int]map[int]int locker sync.RWMutex } func (a *AllStoreSkusWrapper) InitData() { - a.allStoreSkus = make(map[int]map[int]*cms.StoreSkuNameExt) + // a.allStoreSkus = make(map[int]map[int]*cms.StoreSkuNameExt) + a.allStoreSkus = make(map[int]map[int]int) } func (a *AllStoreSkusWrapper) ClearData() { a.allStoreSkus = nil } -func (a *AllStoreSkusWrapper) SetData(storeID int, skuMapData map[int]*cms.StoreSkuNameExt) { +// func (a *AllStoreSkusWrapper) SetData(storeID int, skuMapData map[int]*cms.StoreSkuNameExt) { +// a.locker.Lock() +// defer a.locker.Unlock() +// a.allStoreSkus[storeID] = skuMapData +// } + +// func (a *AllStoreSkusWrapper) GetData(storeID int) map[int]*cms.StoreSkuNameExt { +// a.locker.RLock() +// defer a.locker.RUnlock() +// return a.allStoreSkus[storeID] +// } +func (a *AllStoreSkusWrapper) SetData(storeID int, skuMapData map[int]int) { a.locker.Lock() defer a.locker.Unlock() a.allStoreSkus[storeID] = skuMapData } -func (a *AllStoreSkusWrapper) GetData(storeID int) map[int]*cms.StoreSkuNameExt { +func (a *AllStoreSkusWrapper) GetData(storeID int) map[int]int { a.locker.RLock() defer a.locker.RUnlock() return a.allStoreSkus[storeID] @@ -117,23 +130,25 @@ func (s *StoreScoreDataWrapper) SetData(storeID int, valueName string, value int valueInfo.FieldByName(valueName).SetInt(int64(value)) } -//得到所有门店的商品 +//得到所有门店的可售商品(优化内存,只存商品的价格) func GetAllStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeList []*cms.StoreExt) { allStoreSkusWrapper.InitData() taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { storeInfo := batchItemList[0].(*cms.StoreExt) storeID := storeInfo.ID jxSkuInfoData, _ := cms.GetStoreSkus(ctx, storeID, []int{}, true, "", true, map[string]interface{}{}, 0, -1) - jxSkuMapData := make(map[int]*cms.StoreSkuNameExt) + //jxSkuMapData := make(map[int]*cms.StoreSkuNameExt) + jxSkuPriceMapData := make(map[int]int) for _, value := range jxSkuInfoData.SkuNames { for _, skuInfo := range value.Skus2 { saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus) if saleStatus == model.SkuStatusNormal { - jxSkuMapData[skuInfo.SkuID] = value + //jxSkuMapData[skuInfo.SkuID] = value + jxSkuPriceMapData[skuInfo.SkuID] = skuInfo.BindPrice } } } - allStoreSkusWrapper.SetData(storeID, jxSkuMapData) + allStoreSkusWrapper.SetData(storeID, jxSkuPriceMapData) return retVal, err } taskParallel := tasksch.NewParallelTask("得到所有门店商品", nil, ctx, taskFunc, storeList) @@ -160,48 +175,51 @@ func ScoreStoreOpenTime(storeInfo *cms.StoreExt) { storeID := storeInfo.ID storeStatus := storeInfo.Status isStoreOpen := storeStatus == model.StoreStatusOpened - for _, storeMap := range storeInfo.StoreMaps { - vendorStoreStatus := int(utils.MustInterface2Int64(storeMap["status"])) - isVendorStoreOpen := vendorStoreStatus == model.StoreStatusOpened - opTimeList := storeInfo.GetOpTimeList() - if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen { - finalScore := 0 - opTime := GetOpenTime(opTimeList) - if opTime >= StoreOpenTimeNormalTime { - finalScore = ItemTotalScore - } else { - decScore := int(math.Round(StoreOpenTimeNormalTime - opTime)) - finalScore = ItemTotalScore - decScore - if finalScore < 0 { - finalScore = 0 + finalScore := 0 + if isStoreOpen { + for _, storeMap := range storeInfo.StoreMaps { + vendorStoreStatus := int(utils.MustInterface2Int64(storeMap["status"])) + isVendorStoreOpen := vendorStoreStatus == model.StoreStatusOpened + opTimeList := storeInfo.GetOpTimeList() + if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen { + opTime := GetOpenTime(opTimeList) + if opTime >= StoreOpenTimeNormalTime { + finalScore = ItemTotalScore + } else { + decScore := int(math.Round(StoreOpenTimeNormalTime - opTime)) + finalScore = ItemTotalScore - decScore + if finalScore < 0 { + finalScore = 0 + } } } - storeScoreDataWrapper.SetData(storeID, model.FieldStoreOpenTime, finalScore) } } + storeScoreDataWrapper.SetData(storeID, model.FieldStoreOpenTime, finalScore) } //可售商品数量大于1000,总分10分,按比例扣 func ScoreSaleSkuCount(storeInfo *cms.StoreExt) { storeID := storeInfo.ID skusMapData := allStoreSkusWrapper.GetData(storeID) + finalScore := 0 if len(skusMapData) > 0 { - finalScore := 0 - saleSkuCount := 0 - for _, value := range skusMapData { - for _, skuInfo := range value.Skus2 { - saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus) - if saleStatus == model.SkuStatusNormal { - saleSkuCount++ - } - } - } + saleSkuCount := len(skusMapData) + // saleSkuCount := 0 + // for _, value := range skusMapData { + // for _, skuInfo := range value.Skus2 { + // saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus) + // if saleStatus == model.SkuStatusNormal { + // saleSkuCount++ + // } + // } + // } finalScore = int(math.Round(float64(saleSkuCount) * SaleSkuScorePerUnit)) if finalScore > ItemTotalScore { finalScore = ItemTotalScore } - storeScoreDataWrapper.SetData(storeID, model.FieldSaleSkuCount, finalScore) } + storeScoreDataWrapper.SetData(storeID, model.FieldSaleSkuCount, finalScore) } //平均捡货时间小于等于拣货截止时间为10分满分,每超出1分钟,减1分 @@ -210,6 +228,7 @@ func ScoreAveragePickupTime(storeInfo *cms.StoreExt) { db := dao.GetDB() orderList, err := dao.GetDailyFinishOrderList(db, storeID) orderListCount := len(orderList) + finalScore := 0 if err == nil && orderListCount > 0 { totalScore := 0 for _, value := range orderList { @@ -226,9 +245,9 @@ func ScoreAveragePickupTime(storeInfo *cms.StoreExt) { totalScore += tempScore } } - finalScore := totalScore / orderListCount - storeScoreDataWrapper.SetData(storeID, model.FieldAveragePickupTime, finalScore) + finalScore = totalScore / orderListCount } + storeScoreDataWrapper.SetData(storeID, model.FieldAveragePickupTime, finalScore) } //差评订单和完成订单比例小于0.2%,得满分10分,每增加0.1%减1分 @@ -241,8 +260,8 @@ func ScoreBadCommentOrder(storeInfo *cms.StoreExt, paramFinishOrderCount int64) } else { finishOrderCount = paramFinishOrderCount } + finalScore := 0 if finishOrderCount > 0 { - finalScore := 0 badCommentOrderRatio := float64(badCommentOrderCount) * 100 / float64(finishOrderCount) if badCommentOrderRatio <= BadCommentOrderNormalRatio { finalScore = ItemTotalScore @@ -253,8 +272,8 @@ func ScoreBadCommentOrder(storeInfo *cms.StoreExt, paramFinishOrderCount int64) finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, model.FieldBadCommentOrder, finalScore) } + storeScoreDataWrapper.SetData(storeID, model.FieldBadCommentOrder, finalScore) return finishOrderCount } @@ -269,8 +288,8 @@ func ScoreUnfinishOrder(storeInfo *cms.StoreExt, paramFinishOrderCount int64) (f } else { finishOrderCount = paramFinishOrderCount } + finalScore := 0 if finishOrderCount > 0 { - finalScore := 0 unfinishOrderRatio := float64(unFinishOrderCount) * 100 / float64(finishOrderCount) if unfinishOrderRatio <= UnfinishOrderNormalRatio { finalScore = ItemTotalScore @@ -281,8 +300,8 @@ func ScoreUnfinishOrder(storeInfo *cms.StoreExt, paramFinishOrderCount int64) (f finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, model.FieldUnfinishOrder, finalScore) } + storeScoreDataWrapper.SetData(storeID, model.FieldUnfinishOrder, finalScore) return finishOrderCount } @@ -297,8 +316,8 @@ func ScoreAbsentGoodsOrder(storeInfo *cms.StoreExt, paramFinishOrderCount int64) } else { finishOrderCount = paramFinishOrderCount } + finalScore := 0 if finishOrderCount > 0 { - finalScore := 0 absentGoodsOrderRatio := float64(absentGoodsOrderCount) * 100 / float64(finishOrderCount) if absentGoodsOrderRatio <= AbsentGoodsOrderNormalRatio { finalScore = ItemTotalScore @@ -309,8 +328,8 @@ func ScoreAbsentGoodsOrder(storeInfo *cms.StoreExt, paramFinishOrderCount int64) finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, model.FieldAbsentGoodsOrder, finalScore) } + storeScoreDataWrapper.SetData(storeID, model.FieldAbsentGoodsOrder, finalScore) return finishOrderCount } @@ -322,8 +341,8 @@ func ScorePromotionSku(storeInfo *cms.StoreExt) { beginTime := time.Now() endTime := time.Now() actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, -1, []int{}, []int{storeID}, []int{}, beginTime, endTime) + finalScore := 0 if err == nil && len(actStoreSkuList) > 0 { - finalScore := 0 actStoreSkuMap := make(map[int]int) for _, value := range actStoreSkuList { if value.Type != model.ActSkuFake { @@ -340,8 +359,8 @@ func ScorePromotionSku(storeInfo *cms.StoreExt) { finalScore = 0 } } - storeScoreDataWrapper.SetData(storeID, model.FieldPromotionSku, finalScore) } + storeScoreDataWrapper.SetData(storeID, model.FieldPromotionSku, finalScore) } //经营全平台满分10分,每少一个平台扣2分(一个平台没有得0分) @@ -428,9 +447,13 @@ func GetStoreSkusAveragePrice(storeList []*cms.StoreExt) map[int]int { for _, storeInfo := range storeList { storeID := storeInfo.ID storeSkuMapData := allStoreSkusWrapper.GetData(storeID) - for _, value := range storeSkuMapData { - skuID := value.Skus2[0].SkuID - skuPrice := value.Skus2[0].BindPrice + // for _, value := range storeSkuMapData { + // skuID := value.Skus2[0].SkuID + // skuPrice := value.Skus2[0].BindPrice + // skusTotalPrice[skuID] += skuPrice + // skusCount[skuID]++ + // } + for skuID, skuPrice := range storeSkuMapData { skusTotalPrice[skuID] += skuPrice skusCount[skuID]++ } @@ -443,9 +466,15 @@ func GetStoreSkusAveragePrice(storeList []*cms.StoreExt) map[int]int { func GetSkusCountLessEqualAvgPrice(storeID int, skusAveragePrice map[int]int) (count int) { storeSkuMapData := allStoreSkusWrapper.GetData(storeID) - for _, value := range storeSkuMapData { - skuID := value.Skus2[0].SkuID - skuPrice := value.Skus2[0].BindPrice + // for _, value := range storeSkuMapData { + // skuID := value.Skus2[0].SkuID + // skuPrice := value.Skus2[0].BindPrice + // skuAvgPrice := skusAveragePrice[skuID] + // if skuPrice <= skuAvgPrice { + // count++ + // } + // } + for skuID, skuPrice := range storeSkuMapData { skuAvgPrice := skusAveragePrice[skuID] if skuPrice <= skuAvgPrice { count++ @@ -476,8 +505,8 @@ func ScoreSaleSkuPrice(storeInfo *cms.StoreExt, storeList []*cms.StoreExt) { } } } - storeScoreDataWrapper.SetData(storeID, model.FieldSaleSkuPrice, finalScore) } + storeScoreDataWrapper.SetData(storeID, model.FieldSaleSkuPrice, finalScore) } func GetFilterStoreListEx(storeList []*cms.StoreExt, storeIDMap map[int]int) (outStoreList []*cms.StoreExt) { From 6b3b0bcd3522c692ae16232d1506147de698d411 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Thu, 12 Sep 2019 15:36:39 +0800 Subject: [PATCH 20/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E8=AF=84=E5=88=86-?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=95=B0=E6=8D=AE=E8=AF=BB=E5=8F=96=E9=80=9F?= =?UTF-8?q?=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 193 ++++++++++++++++----------- business/model/dao/dao_order.go | 38 +++--- business/model/store_score.go | 5 + 3 files changed, 139 insertions(+), 97 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index 65882fac9..0ab3a6056 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -19,7 +19,7 @@ import ( const ( EnableScheduleScoreStore = !true - ParallelCount = 10 + ParallelCount = 5 GoldMedalScore = 90 SilverMedalScore = 80 @@ -71,13 +71,11 @@ var ( ) type AllStoreSkusWrapper struct { - //allStoreSkus map[int]map[int]*cms.StoreSkuNameExt allStoreSkus map[int]map[int]int locker sync.RWMutex } func (a *AllStoreSkusWrapper) InitData() { - // a.allStoreSkus = make(map[int]map[int]*cms.StoreSkuNameExt) a.allStoreSkus = make(map[int]map[int]int) } @@ -85,17 +83,6 @@ func (a *AllStoreSkusWrapper) ClearData() { a.allStoreSkus = nil } -// func (a *AllStoreSkusWrapper) SetData(storeID int, skuMapData map[int]*cms.StoreSkuNameExt) { -// a.locker.Lock() -// defer a.locker.Unlock() -// a.allStoreSkus[storeID] = skuMapData -// } - -// func (a *AllStoreSkusWrapper) GetData(storeID int) map[int]*cms.StoreSkuNameExt { -// a.locker.RLock() -// defer a.locker.RUnlock() -// return a.allStoreSkus[storeID] -// } func (a *AllStoreSkusWrapper) SetData(storeID int, skuMapData map[int]int) { a.locker.Lock() defer a.locker.Unlock() @@ -109,12 +96,28 @@ func (a *AllStoreSkusWrapper) GetData(storeID int) map[int]int { } type StoreScoreDataWrapper struct { - storeScoreData map[int]*model.StoreScore - locker sync.RWMutex + storeScoreData map[int]*model.StoreScore + dailyBadCommentOrderCount map[int]int + dailyUnFinishOrderCount map[int]int + dailyFinishOrderCount map[int]int + dailyAbsentGoodsOrderCount map[int]int + locker sync.RWMutex } func (s *StoreScoreDataWrapper) InitData() { s.storeScoreData = make(map[int]*model.StoreScore) + s.dailyBadCommentOrderCount = make(map[int]int) + s.dailyUnFinishOrderCount = make(map[int]int) + s.dailyFinishOrderCount = make(map[int]int) + s.dailyAbsentGoodsOrderCount = make(map[int]int) +} + +func (s *StoreScoreDataWrapper) ClearData() { + s.storeScoreData = nil + s.dailyBadCommentOrderCount = nil + s.dailyUnFinishOrderCount = nil + s.dailyFinishOrderCount = nil + s.dailyAbsentGoodsOrderCount = nil } func (s *StoreScoreDataWrapper) SetData(storeID int, valueName string, value int) { @@ -130,6 +133,78 @@ func (s *StoreScoreDataWrapper) SetData(storeID int, valueName string, value int valueInfo.FieldByName(valueName).SetInt(int64(value)) } +func (s *StoreScoreDataWrapper) SetDailyBadCommentOrderCount(storeCountList []*model.StoreCount) { + s.locker.Lock() + defer s.locker.Unlock() + for _, value := range storeCountList { + s.dailyBadCommentOrderCount[value.StoreID] = value.Count + } +} + +func (s *StoreScoreDataWrapper) GetDailyBadCommentOrderCount(storeID int) int { + s.locker.RLock() + defer s.locker.RUnlock() + if count, ok := s.dailyBadCommentOrderCount[storeID]; ok { + return count + } + + return 0 +} + +func (s *StoreScoreDataWrapper) SetDailyUnFinishOrderCount(storeCountList []*model.StoreCount) { + for _, value := range storeCountList { + s.dailyUnFinishOrderCount[value.StoreID] = value.Count + } +} + +func (s *StoreScoreDataWrapper) GetDailyUnFinishOrderCount(storeID int) int { + s.locker.RLock() + defer s.locker.RUnlock() + if count, ok := s.dailyUnFinishOrderCount[storeID]; ok { + return count + } + + return 0 +} + +func (s *StoreScoreDataWrapper) SetDailyFinishOrderCount(storeCountList []*model.StoreCount) { + for _, value := range storeCountList { + s.dailyFinishOrderCount[value.StoreID] = value.Count + } +} + +func (s *StoreScoreDataWrapper) GetDailyFinishOrderCount(storeID int) int { + s.locker.RLock() + defer s.locker.RUnlock() + if count, ok := s.dailyFinishOrderCount[storeID]; ok { + return count + } + + return 0 +} + +func (s *StoreScoreDataWrapper) SetDailyAbsentGoodsOrderCount(storeCountList []*model.StoreCount) { + for _, value := range storeCountList { + s.dailyAbsentGoodsOrderCount[value.StoreID] = value.Count + } +} + +func (s *StoreScoreDataWrapper) GetDailyAbsentGoodsOrderCount(storeID int) int { + s.locker.RLock() + defer s.locker.RUnlock() + if count, ok := s.dailyAbsentGoodsOrderCount[storeID]; ok { + return count + } + + return 0 +} + +func (s *StoreScoreDataWrapper) InsertStoreScore() { + for _, value := range s.storeScoreData { + dao.InsertStoreScore(value) + } +} + //得到所有门店的可售商品(优化内存,只存商品的价格) func GetAllStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeList []*cms.StoreExt) { allStoreSkusWrapper.InitData() @@ -137,13 +212,11 @@ func GetAllStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeList storeInfo := batchItemList[0].(*cms.StoreExt) storeID := storeInfo.ID jxSkuInfoData, _ := cms.GetStoreSkus(ctx, storeID, []int{}, true, "", true, map[string]interface{}{}, 0, -1) - //jxSkuMapData := make(map[int]*cms.StoreSkuNameExt) jxSkuPriceMapData := make(map[int]int) for _, value := range jxSkuInfoData.SkuNames { for _, skuInfo := range value.Skus2 { saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus) if saleStatus == model.SkuStatusNormal { - //jxSkuMapData[skuInfo.SkuID] = value jxSkuPriceMapData[skuInfo.SkuID] = skuInfo.BindPrice } } @@ -151,7 +224,7 @@ func GetAllStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeList allStoreSkusWrapper.SetData(storeID, jxSkuPriceMapData) return retVal, err } - taskParallel := tasksch.NewParallelTask("得到所有门店商品", nil, ctx, taskFunc, storeList) + taskParallel := tasksch.NewParallelTask("得到所有门店商品", tasksch.NewParallelConfig().SetParallelCount(ParallelCount), ctx, taskFunc, storeList) tasksch.HandleTask(taskParallel, parentTask, true).Run() taskParallel.GetResult(0) } @@ -251,15 +324,10 @@ func ScoreAveragePickupTime(storeInfo *cms.StoreExt) { } //差评订单和完成订单比例小于0.2%,得满分10分,每增加0.1%减1分 -func ScoreBadCommentOrder(storeInfo *cms.StoreExt, paramFinishOrderCount int64) (finishOrderCount int64) { +func ScoreBadCommentOrder(storeInfo *cms.StoreExt) { storeID := storeInfo.ID - db := dao.GetDB() - badCommentOrderCount, _ := dao.GetDailyBadCommentOrderCount(db, storeID) - if paramFinishOrderCount == -1 { - finishOrderCount, _ = dao.GetDailyFinishOrderCount(db, storeID) - } else { - finishOrderCount = paramFinishOrderCount - } + badCommentOrderCount := storeScoreDataWrapper.GetDailyBadCommentOrderCount(storeID) + finishOrderCount := storeScoreDataWrapper.GetDailyFinishOrderCount(storeID) finalScore := 0 if finishOrderCount > 0 { badCommentOrderRatio := float64(badCommentOrderCount) * 100 / float64(finishOrderCount) @@ -274,20 +342,13 @@ func ScoreBadCommentOrder(storeInfo *cms.StoreExt, paramFinishOrderCount int64) } } storeScoreDataWrapper.SetData(storeID, model.FieldBadCommentOrder, finalScore) - - return finishOrderCount } //未完成订单和完成订单比小于1%,得满分10分,比例每增加5%,分数减1 -func ScoreUnfinishOrder(storeInfo *cms.StoreExt, paramFinishOrderCount int64) (finishOrderCount int64) { +func ScoreUnfinishOrder(storeInfo *cms.StoreExt) { storeID := storeInfo.ID - db := dao.GetDB() - unFinishOrderCount, _ := dao.GetDailyUnFinishOrderCount(db, storeID) - if paramFinishOrderCount == -1 { - finishOrderCount, _ = dao.GetDailyFinishOrderCount(db, storeID) - } else { - finishOrderCount = paramFinishOrderCount - } + unFinishOrderCount := storeScoreDataWrapper.GetDailyUnFinishOrderCount(storeID) + finishOrderCount := storeScoreDataWrapper.GetDailyFinishOrderCount(storeID) finalScore := 0 if finishOrderCount > 0 { unfinishOrderRatio := float64(unFinishOrderCount) * 100 / float64(finishOrderCount) @@ -302,20 +363,13 @@ func ScoreUnfinishOrder(storeInfo *cms.StoreExt, paramFinishOrderCount int64) (f } } storeScoreDataWrapper.SetData(storeID, model.FieldUnfinishOrder, finalScore) - - return finishOrderCount } //缺货订单和完成订单比小于1%得10分,比例每增加0.1%减1分 -func ScoreAbsentGoodsOrder(storeInfo *cms.StoreExt, paramFinishOrderCount int64) (finishOrderCount int64) { +func ScoreAbsentGoodsOrder(storeInfo *cms.StoreExt) { storeID := storeInfo.ID - db := dao.GetDB() - absentGoodsOrderCount, _ := dao.GetDailyAbsentGoodsOrderCount(db, storeID) - if paramFinishOrderCount == -1 { - finishOrderCount, _ = dao.GetDailyFinishOrderCount(db, storeID) - } else { - finishOrderCount = paramFinishOrderCount - } + absentGoodsOrderCount := storeScoreDataWrapper.GetDailyAbsentGoodsOrderCount(storeID) + finishOrderCount := storeScoreDataWrapper.GetDailyFinishOrderCount(storeID) finalScore := 0 if finishOrderCount > 0 { absentGoodsOrderRatio := float64(absentGoodsOrderCount) * 100 / float64(finishOrderCount) @@ -330,8 +384,6 @@ func ScoreAbsentGoodsOrder(storeInfo *cms.StoreExt, paramFinishOrderCount int64) } } storeScoreDataWrapper.SetData(storeID, model.FieldAbsentGoodsOrder, finalScore) - - return finishOrderCount } //促销品数量20个以上为满分10分,每少2个扣1分 @@ -447,12 +499,6 @@ func GetStoreSkusAveragePrice(storeList []*cms.StoreExt) map[int]int { for _, storeInfo := range storeList { storeID := storeInfo.ID storeSkuMapData := allStoreSkusWrapper.GetData(storeID) - // for _, value := range storeSkuMapData { - // skuID := value.Skus2[0].SkuID - // skuPrice := value.Skus2[0].BindPrice - // skusTotalPrice[skuID] += skuPrice - // skusCount[skuID]++ - // } for skuID, skuPrice := range storeSkuMapData { skusTotalPrice[skuID] += skuPrice skusCount[skuID]++ @@ -466,14 +512,6 @@ func GetStoreSkusAveragePrice(storeList []*cms.StoreExt) map[int]int { func GetSkusCountLessEqualAvgPrice(storeID int, skusAveragePrice map[int]int) (count int) { storeSkuMapData := allStoreSkusWrapper.GetData(storeID) - // for _, value := range storeSkuMapData { - // skuID := value.Skus2[0].SkuID - // skuPrice := value.Skus2[0].BindPrice - // skuAvgPrice := skusAveragePrice[skuID] - // if skuPrice <= skuAvgPrice { - // count++ - // } - // } for skuID, skuPrice := range storeSkuMapData { skuAvgPrice := skusAveragePrice[skuID] if skuPrice <= skuAvgPrice { @@ -536,7 +574,7 @@ func GetFilterStoreListEx(storeList []*cms.StoreExt, storeIDMap map[int]int) (ou func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, err error) { var storeList []*cms.StoreExt - taskCount := 4 + taskCount := 5 taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { switch step { case 0: @@ -551,6 +589,16 @@ func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, GetAllStoreSkus(ctx, task, storeList) baseapi.SugarLogger.Debugf("ScoreStore step1 end") case 2: + db := dao.GetDB() + storeCountList, _ := dao.GetDailyBadCommentOrderCount(db) + storeScoreDataWrapper.SetDailyBadCommentOrderCount(storeCountList) + storeCountList, _ = dao.GetDailyUnFinishOrderCount(db) + storeScoreDataWrapper.SetDailyUnFinishOrderCount(storeCountList) + storeCountList, _ = dao.GetDailyFinishOrderCount(db) + storeScoreDataWrapper.SetDailyFinishOrderCount(storeCountList) + storeCountList, _ = dao.GetDailyAbsentGoodsOrderCount(db) + storeScoreDataWrapper.SetDailyAbsentGoodsOrderCount(storeCountList) + case 3: baseapi.SugarLogger.Debugf("ScoreStore step2 begin") taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { storeInfo := batchItemList[0].(*cms.StoreExt) @@ -559,9 +607,9 @@ func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, ScoreStoreOpenTime(storeInfo) ScoreSaleSkuCount(storeInfo) ScoreAveragePickupTime(storeInfo) - finishOrderCount := ScoreBadCommentOrder(storeInfo, -1) - ScoreUnfinishOrder(storeInfo, finishOrderCount) - ScoreAbsentGoodsOrder(storeInfo, finishOrderCount) + ScoreBadCommentOrder(storeInfo) + ScoreUnfinishOrder(storeInfo) + ScoreAbsentGoodsOrder(storeInfo) ScorePromotionSku(storeInfo) ScoreFullVendor(storeInfo) ScoreStoreRange(storeInfo) @@ -577,9 +625,10 @@ func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, baseapi.SugarLogger.Debugf("ScoreStore taskParallel error:%v", err) } baseapi.SugarLogger.Debugf("ScoreStore step2 end") - case 3: + case 4: baseapi.SugarLogger.Debugf("ScoreStore step3 begin") - InsertStoreScore() + storeScoreDataWrapper.InsertStoreScore() + storeScoreDataWrapper.ClearData() allStoreSkusWrapper.ClearData() baseapi.SugarLogger.Debugf("ScoreStore step3 end") } @@ -591,12 +640,6 @@ func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, return retVal, err } -func InsertStoreScore() { - for _, value := range storeScoreDataWrapper.storeScoreData { - dao.InsertStoreScore(value) - } -} - func ScheduleScoreStore() { if EnableScheduleScoreStore { ScheduleTimerFunc("ScheduleScoreStore", func() { diff --git a/business/model/dao/dao_order.go b/business/model/dao/dao_order.go index e103524e1..4a979dfb5 100644 --- a/business/model/dao/dao_order.go +++ b/business/model/dao/dao_order.go @@ -306,42 +306,36 @@ func GetDailyFinishOrderList(db *DaoDB, storeID int) (orderList []*model.OrderPi return orderList, GetRows(db, &orderList, sql, sqlParams...) } -func GetDailyBadCommentOrderCount(db *DaoDB, storeID int) (count int64, err error) { - sql := `select count(*) from jx_bad_comments where DATE(createtime) = CURDATE() and jxstoreid = ?` - sqlParams := []interface{}{ - storeID, - } - err = GetRow(db, &count, sql, sqlParams...) +func GetDailyBadCommentOrderCount(db *DaoDB) (storeCountList []*model.StoreCount, err error) { + sql := `select jxstoreid store_id, COUNT(*) count from jx_bad_comments where DATE(createtime) = CURDATE() GROUP BY jxstoreid` + err = GetRows(db, &storeCountList, sql) - return count, err + return storeCountList, err } -func GetDailyUnFinishOrderCount(db *DaoDB, storeID int) (num int64, err error) { - return GetDailyEndOrderCount(db, storeID, []int{model.OrderStatusCanceled}, false) +func GetDailyUnFinishOrderCount(db *DaoDB) (storeCountList []*model.StoreCount, err error) { + return GetDailyEndOrderCount(db, []int{model.OrderStatusCanceled}, false) } -func GetDailyFinishOrderCount(db *DaoDB, storeID int) (num int64, err error) { - return GetDailyEndOrderCount(db, storeID, []int{model.OrderStatusFinished}, false) +func GetDailyFinishOrderCount(db *DaoDB) (storeCountList []*model.StoreCount, err error) { + return GetDailyEndOrderCount(db, []int{model.OrderStatusFinished}, false) } -func GetDailyAbsentGoodsOrderCount(db *DaoDB, storeID int) (num int64, err error) { - return GetDailyEndOrderCount(db, storeID, []int{model.OrderStatusFinished, model.OrderStatusCanceled}, true) +func GetDailyAbsentGoodsOrderCount(db *DaoDB) (storeCountList []*model.StoreCount, err error) { + return GetDailyEndOrderCount(db, []int{model.OrderStatusFinished, model.OrderStatusCanceled}, true) } -func GetDailyEndOrderCount(db *DaoDB, storeID int, statusList []int, isAbsentOrder bool) (count int64, err error) { - sql := `SELECT COUNT(*) FROM goods_order +func GetDailyEndOrderCount(db *DaoDB, statusList []int, isAbsentOrder bool) (storeCountList []*model.StoreCount, err error) { + sql := `SELECT jx_store_id store_id, COUNT(*) count FROM goods_order WHERE DATE(order_finished_at) = CURDATE() - AND jx_store_id = ? AND status IN (` + GenQuestionMarks(len(statusList)) + `)` if isAbsentOrder { sql += ` AND adjust_count > 0` } - sqlParams := []interface{}{ - storeID, - } - sqlParams = append(sqlParams, statusList) - err = GetRow(db, &count, sql, sqlParams...) + sql += ` + GROUP BY jx_store_id` + err = GetRow(db, &storeCountList, sql) - return count, err + return storeCountList, err } diff --git a/business/model/store_score.go b/business/model/store_score.go index c8207a7cd..5529b4269 100644 --- a/business/model/store_score.go +++ b/business/model/store_score.go @@ -47,3 +47,8 @@ type WeeklyStoreScore struct { ItemTotalScore int `json:"itemTotalScore"` Level int `json:"level"` } + +type StoreCount struct { + StoreID int `orm:"column(store_id)"` + Count int +} From dfdcc671f6d101959611873d1eb8201c1392b133 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Thu, 12 Sep 2019 16:30:16 +0800 Subject: [PATCH 21/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E8=AF=84=E5=88=86-?= =?UTF-8?q?=E5=87=8F=E5=B0=91=E5=B9=B6=E5=8F=91=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 4 ++-- controllers/cms_store.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index 0ab3a6056..7edceb20d 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -18,8 +18,8 @@ import ( ) const ( - EnableScheduleScoreStore = !true - ParallelCount = 5 + EnableScheduleScoreStore = true + ParallelCount = 3 GoldMedalScore = 90 SilverMedalScore = 80 diff --git a/controllers/cms_store.go b/controllers/cms_store.go index ca293dda1..95b1c7b1b 100644 --- a/controllers/cms_store.go +++ b/controllers/cms_store.go @@ -442,8 +442,8 @@ func (c *StoreController) ScoreStore() { }) } -// @Title 得到门店周平均分数数据 -// @Description 得到门店周平均分数数据 +// @Title 得到门店近期周平均分数数据 +// @Description 得到门店近期周平均分数数据 // @Param token header string true "认证token" // @Param storeID query int true "京西门店ID" // @Param weekIndex query int true "周索引(起始索引为0, -1为所有周数据)" From f2b4f885732fd0410ba8caf9f2929b9b1cc3bf4c Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Thu, 12 Sep 2019 16:53:15 +0800 Subject: [PATCH 22/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E8=AF=84=E5=88=86-?= =?UTF-8?q?=E5=87=8F=E5=B0=91=E5=B9=B6=E5=8F=91=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index 7edceb20d..f912eabc0 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -19,7 +19,7 @@ import ( const ( EnableScheduleScoreStore = true - ParallelCount = 3 + ParallelCount = 2 GoldMedalScore = 90 SilverMedalScore = 80 From 00603a0a3426121b15c3d24cb82bc3905bc68e52 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Thu, 12 Sep 2019 17:22:02 +0800 Subject: [PATCH 23/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E8=AF=84=E5=88=86-?= =?UTF-8?q?=E5=87=8F=E5=B0=91=E5=B9=B6=E5=8F=91=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index f912eabc0..b4750e227 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -19,7 +19,7 @@ import ( const ( EnableScheduleScoreStore = true - ParallelCount = 2 + ParallelCount = 1 GoldMedalScore = 90 SilverMedalScore = 80 From e35d86f6901ff3f1f62c822fa240bf39666272a8 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Mon, 16 Sep 2019 16:20:46 +0800 Subject: [PATCH 24/32] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=97=A8=E5=BA=97?= =?UTF-8?q?=E8=AF=84=E5=88=86=E7=BB=86=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 60 +++++++++++++++++++--------- business/jxutils/jxutils.go | 12 ------ business/model/api.go | 5 --- business/model/dao/dao_order.go | 59 +++++++++++++++++---------- business/model/dao/store_score.go | 22 ++++++++-- business/model/store_score.go | 6 +++ 6 files changed, 104 insertions(+), 60 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index b4750e227..d984d31e0 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -1,6 +1,7 @@ package misc import ( + "fmt" "math" "reflect" "sync" @@ -48,7 +49,8 @@ var ( scoreStoreTimeList = []string{ "22:00:00", } - fullVendorList = map[int]bool{ + scoreStoreCheckTimeEnd = "23:30:00" + fullVendorList = map[int]bool{ model.VendorIDJD: true, model.VendorIDMTWM: true, model.VendorIDEBAI: true, @@ -68,6 +70,8 @@ var ( storeScoreDataWrapper StoreScoreDataWrapper allStoreSkusWrapper AllStoreSkusWrapper + scoreDate time.Time + isScoring bool ) type AllStoreSkusWrapper struct { @@ -127,6 +131,7 @@ func (s *StoreScoreDataWrapper) SetData(storeID int, valueName string, value int if data == nil { data = &model.StoreScore{} data.StoreID = storeID + data.ScoreDate = scoreDate s.storeScoreData[storeID] = data } valueInfo := reflect.ValueOf(data).Elem() @@ -251,10 +256,11 @@ func ScoreStoreOpenTime(storeInfo *cms.StoreExt) { finalScore := 0 if isStoreOpen { for _, storeMap := range storeInfo.StoreMaps { + isSyncStoreSku := int(utils.MustInterface2Int64(storeMap["isSync"])) vendorStoreStatus := int(utils.MustInterface2Int64(storeMap["status"])) isVendorStoreOpen := vendorStoreStatus == model.StoreStatusOpened opTimeList := storeInfo.GetOpTimeList() - if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen { + if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen && isSyncStoreSku != 0 { opTime := GetOpenTime(opTimeList) if opTime >= StoreOpenTimeNormalTime { finalScore = ItemTotalScore @@ -278,15 +284,6 @@ func ScoreSaleSkuCount(storeInfo *cms.StoreExt) { finalScore := 0 if len(skusMapData) > 0 { saleSkuCount := len(skusMapData) - // saleSkuCount := 0 - // for _, value := range skusMapData { - // for _, skuInfo := range value.Skus2 { - // saleStatus := jxutils.MergeSkuStatus(skuInfo.SkuStatus, skuInfo.StoreSkuStatus) - // if saleStatus == model.SkuStatusNormal { - // saleSkuCount++ - // } - // } - // } finalScore = int(math.Round(float64(saleSkuCount) * SaleSkuScorePerUnit)) if finalScore > ItemTotalScore { finalScore = ItemTotalScore @@ -299,7 +296,7 @@ func ScoreSaleSkuCount(storeInfo *cms.StoreExt) { func ScoreAveragePickupTime(storeInfo *cms.StoreExt) { storeID := storeInfo.ID db := dao.GetDB() - orderList, err := dao.GetDailyFinishOrderList(db, storeID) + orderList, err := dao.GetDailyFinishOrderList(db, storeID, scoreDate) orderListCount := len(orderList) finalScore := 0 if err == nil && orderListCount > 0 { @@ -392,7 +389,7 @@ func ScorePromotionSku(storeInfo *cms.StoreExt) { db := dao.GetDB() beginTime := time.Now() endTime := time.Now() - actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, -1, []int{}, []int{storeID}, []int{}, beginTime, endTime) + actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, -1, nil, []int{storeID}, nil, beginTime, endTime) finalScore := 0 if err == nil && len(actStoreSkuList) > 0 { actStoreSkuMap := make(map[int]int) @@ -424,10 +421,11 @@ func ScoreFullVendor(storeInfo *cms.StoreExt) { isStoreOpen := storeStatus == model.StoreStatusOpened count := 0 for _, storeMap := range storeInfo.StoreMaps { + isSyncStoreSku := int(utils.MustInterface2Int64(storeMap["isSync"])) vendorStoreStatus := int(utils.MustInterface2Int64(storeMap["status"])) isVendorStoreOpen := vendorStoreStatus == model.StoreStatusOpened opTimeList := storeInfo.GetOpTimeList() - if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen { + if len(opTimeList) > 0 && isStoreOpen && isVendorStoreOpen && isSyncStoreSku != 0 { count++ } } @@ -573,6 +571,8 @@ func GetFilterStoreListEx(storeList []*cms.StoreExt, storeIDMap map[int]int) (ou } func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, err error) { + isScoring = true + scoreDate = utils.GetCurDate() var storeList []*cms.StoreExt taskCount := 5 taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { @@ -590,13 +590,13 @@ func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, baseapi.SugarLogger.Debugf("ScoreStore step1 end") case 2: db := dao.GetDB() - storeCountList, _ := dao.GetDailyBadCommentOrderCount(db) + storeCountList, _ := dao.GetDailyBadCommentOrderCount(db, scoreDate) storeScoreDataWrapper.SetDailyBadCommentOrderCount(storeCountList) - storeCountList, _ = dao.GetDailyUnFinishOrderCount(db) + storeCountList, _ = dao.GetDailyUnFinishOrderCount(db, scoreDate) storeScoreDataWrapper.SetDailyUnFinishOrderCount(storeCountList) - storeCountList, _ = dao.GetDailyFinishOrderCount(db) + storeCountList, _ = dao.GetDailyFinishOrderCount(db, scoreDate) storeScoreDataWrapper.SetDailyFinishOrderCount(storeCountList) - storeCountList, _ = dao.GetDailyAbsentGoodsOrderCount(db) + storeCountList, _ = dao.GetDailyAbsentGoodsOrderCount(db, scoreDate) storeScoreDataWrapper.SetDailyAbsentGoodsOrderCount(storeCountList) case 3: baseapi.SugarLogger.Debugf("ScoreStore step2 begin") @@ -631,6 +631,7 @@ func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, storeScoreDataWrapper.ClearData() allStoreSkusWrapper.ClearData() baseapi.SugarLogger.Debugf("ScoreStore step3 end") + isScoring = false } return result, err } @@ -643,8 +644,29 @@ func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, func ScheduleScoreStore() { if EnableScheduleScoreStore { ScheduleTimerFunc("ScheduleScoreStore", func() { - ScoreStore(jxcontext.AdminCtx, []int{}) + if !isScoring { + ScoreStore(jxcontext.AdminCtx, nil) + } }, scoreStoreTimeList) + CheckScoreStore() + } +} + +func CheckScoreStore() { + if !isScoring { + curTime := time.Now() + year, month, day := curTime.Date() + checkTimeStr1 := fmt.Sprintf("%d-%d-%d "+scoreStoreTimeList[0], year, int(month), day) + checkTime1 := utils.Str2Time(checkTimeStr1) + checkTimeStr2 := fmt.Sprintf("%d-%d-%d "+scoreStoreCheckTimeEnd, year, int(month), day) + checkTime2 := utils.Str2Time(checkTimeStr2) + if curTime.Unix() >= checkTime1.Unix() && curTime.Unix() <= checkTime2.Unix() { + db := dao.GetDB() + hasStoreScoreData, err := dao.CheckHasStoreScoreData(db, time.Now()) + if err == nil && !hasStoreScoreData { + ScoreStore(jxcontext.AdminCtx, nil) + } + } } } diff --git a/business/jxutils/jxutils.go b/business/jxutils/jxutils.go index d3297cdb8..c8f793a05 100644 --- a/business/jxutils/jxutils.go +++ b/business/jxutils/jxutils.go @@ -194,18 +194,6 @@ func EarthDistance(lng1, lat1, lng2, lat2 float64) float64 { return dist * radius } -//计算多边形平面面积 -func CalcPolygonArea(points [][2]float64) (area float64) { - count := len(points) - for i := 0; i < count-1; i++ { - area += (points[i][0] - points[i+1][0]) * (points[i][1] + points[i+1][1]) - } - area += (points[count-1][0] - points[0][0]) * (points[count-1][1] + points[0][1]) - area = math.Abs(area) / 2 - - return area -} - func ConvertToRadian(value float64) float64 { return value * math.Pi / 180 } diff --git a/business/model/api.go b/business/model/api.go index 19d026c1d..1a3396774 100644 --- a/business/model/api.go +++ b/business/model/api.go @@ -73,8 +73,3 @@ type OrderFinancialSkuExt struct { OrderSkuFinancial Image string `json:"image"` } - -type OrderPickupTime struct { - StatusTime time.Time - PickDeadline time.Time -} diff --git a/business/model/dao/dao_order.go b/business/model/dao/dao_order.go index 4a979dfb5..a365377ed 100644 --- a/business/model/dao/dao_order.go +++ b/business/model/dao/dao_order.go @@ -291,51 +291,70 @@ func GetStoreAfsOrderSkuList(db *DaoDB, storeIDs []int, finishedAtBegin, finishe return afsSkuList, err } -func GetDailyFinishOrderList(db *DaoDB, storeID int) (orderList []*model.OrderPickupTime, err error) { +func GetDailyFinishOrderList(db *DaoDB, storeID int, dateTime time.Time) (orderList []*model.OrderPickupTime, err error) { sql := ` - select t2.status_time, t1.pick_deadline - from goods_order t1 - left join order_status t2 on t1.vendor_order_id = t2.vendor_order_id - where t1.jx_store_id = ? and t2.order_type = ? and t2.status = ? and DATE(t1.order_finished_at) = CURDATE() + SELECT t2.status_time, t1.pick_deadline + FROM goods_order t1 + JOIN order_status t2 ON t1.vendor_order_id = t2.vendor_order_id AND t1.vendor_id = t2.vendor_id + WHERE t1.jx_store_id = ? AND t2.order_type = ? AND t2.status = ? AND DATE(t1.order_finished_at) = DATE(?) ` sqlParams := []interface{}{ storeID, 1, model.OrderStatusFinishedPickup, + dateTime, } return orderList, GetRows(db, &orderList, sql, sqlParams...) } -func GetDailyBadCommentOrderCount(db *DaoDB) (storeCountList []*model.StoreCount, err error) { - sql := `select jxstoreid store_id, COUNT(*) count from jx_bad_comments where DATE(createtime) = CURDATE() GROUP BY jxstoreid` - err = GetRows(db, &storeCountList, sql) +func GetDailyBadCommentOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) { + sql := ` + SELECT jxstoreid store_id, COUNT(*) count + FROM jx_bad_comments + WHERE DATE(createtime) = DATE(?) + GROUP BY jxstoreid + ` + sqlParams := []interface{}{ + dateTime, + } + err = GetRows(db, &storeCountList, sql, sqlParams) return storeCountList, err } -func GetDailyUnFinishOrderCount(db *DaoDB) (storeCountList []*model.StoreCount, err error) { - return GetDailyEndOrderCount(db, []int{model.OrderStatusCanceled}, false) +func GetDailyUnFinishOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) { + return GetDailyEndOrderCount(db, []int{model.OrderStatusCanceled}, false, dateTime) } -func GetDailyFinishOrderCount(db *DaoDB) (storeCountList []*model.StoreCount, err error) { - return GetDailyEndOrderCount(db, []int{model.OrderStatusFinished}, false) +func GetDailyFinishOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) { + return GetDailyEndOrderCount(db, []int{model.OrderStatusFinished}, false, dateTime) } -func GetDailyAbsentGoodsOrderCount(db *DaoDB) (storeCountList []*model.StoreCount, err error) { - return GetDailyEndOrderCount(db, []int{model.OrderStatusFinished, model.OrderStatusCanceled}, true) +func GetDailyAbsentGoodsOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) { + return GetDailyEndOrderCount(db, []int{model.OrderStatusFinished, model.OrderStatusCanceled}, true, dateTime) } -func GetDailyEndOrderCount(db *DaoDB, statusList []int, isAbsentOrder bool) (storeCountList []*model.StoreCount, err error) { - sql := `SELECT jx_store_id store_id, COUNT(*) count FROM goods_order - WHERE DATE(order_finished_at) = CURDATE() - AND status IN (` + GenQuestionMarks(len(statusList)) + `)` +func GetDailyEndOrderCount(db *DaoDB, statusList []int, isAbsentOrder bool, dateTime time.Time) (storeCountList []*model.StoreCount, err error) { + sql := ` + SELECT jx_store_id store_id, COUNT(*) count + FROM goods_order + WHERE DATE(order_finished_at) = DATE(?) + ` + sqlParams := []interface{}{ + dateTime, + } + if len(statusList) > 0 { + sql += ` AND status IN (` + GenQuestionMarks(len(statusList)) + `)` + sqlParams = append(sqlParams, statusList) + } if isAbsentOrder { sql += ` - AND adjust_count > 0` + AND adjust_count > 0 + ` } sql += ` GROUP BY jx_store_id` - err = GetRow(db, &storeCountList, sql) + err = GetRow(db, &storeCountList, sql, sqlParams) return storeCountList, err } diff --git a/business/model/dao/store_score.go b/business/model/dao/store_score.go index 596a37bc0..142d3525d 100644 --- a/business/model/dao/store_score.go +++ b/business/model/dao/store_score.go @@ -6,7 +6,6 @@ import ( "git.rosy.net.cn/jx-callback/business/model" ) -// func InsertStoreScore(storeID int, scores map[string]int) error { func InsertStoreScore(storeScore *model.StoreScore) error { storeScore.CreatedAt = time.Now() return CreateEntity(nil, storeScore) @@ -17,7 +16,7 @@ func GetLatestWeeklyStoreScoreList(db *DaoDB, storeID, weekNum int) (storeScoreL SELECT t2.name store_name, t1.* FROM store_score t1 JOIN store t2 ON t1.store_id = t2.id WHERE t1.store_id = ? - AND DATE(t1.created_at) >= DATE_SUB( + AND DATE(t1.ScoreDate) >= DATE_SUB( DATE_SUB( CURDATE(), INTERVAL @@ -29,7 +28,7 @@ func GetLatestWeeklyStoreScoreList(db *DaoDB, storeID, weekNum int) (storeScoreL ), INTERVAL ? DAY ) - AND DATE(t1.created_at) <= DATE_SUB( + AND DATE(t1.ScoreDate) <= DATE_SUB( CURDATE(), INTERVAL IF ( @@ -38,7 +37,7 @@ func GetLatestWeeklyStoreScoreList(db *DaoDB, storeID, weekNum int) (storeScoreL DAYOFWEEK(CURDATE()) - 1 ) DAY ) - ORDER BY created_at DESC + ORDER BY ScoreDate DESC ` if weekNum <= 0 { weekNum = 1 @@ -51,3 +50,18 @@ func GetLatestWeeklyStoreScoreList(db *DaoDB, storeID, weekNum int) (storeScoreL err = GetRows(db, &storeScoreList, sql, sqlParams) return storeScoreList, err } + +func CheckHasStoreScoreData(db *DaoDB, dateTime time.Time) (hasStoreScoreData bool, err error) { + sql := ` + SELECT COUNT(*) count + FROM store_score + WHERE DATE(createtime) = DATE(?) + ` + sqlParams := []interface{}{ + dateTime, + } + count := 0 + err = GetRow(db, &count, sql, sqlParams) + hasStoreScoreData = count > 0 + return hasStoreScoreData, err +} diff --git a/business/model/store_score.go b/business/model/store_score.go index 5529b4269..84596ee80 100644 --- a/business/model/store_score.go +++ b/business/model/store_score.go @@ -20,6 +20,7 @@ const ( type StoreScore struct { ID int `orm:"column(id)" json:"id"` CreatedAt time.Time `orm:"auto_now_add;type(datetime)" json:"createdAt"` + ScoreDate time.Time `orm:"auto_now_add;type(datetime)" json:"scoreDate"` StoreID int `orm:"column(store_id)" json:"storeID"` StoreOpenTime int `orm:"column(store_open_time)" json:"storeOpenTime"` @@ -52,3 +53,8 @@ type StoreCount struct { StoreID int `orm:"column(store_id)"` Count int } + +type OrderPickupTime struct { + StatusTime time.Time + PickDeadline time.Time +} From f88b273f925b06ad51f956c472bb9044dfbe3d4e Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Mon, 16 Sep 2019 17:42:32 +0800 Subject: [PATCH 25/32] =?UTF-8?q?=E4=BF=AE=E6=94=B9SQL=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/model/dao/store_score.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/business/model/dao/store_score.go b/business/model/dao/store_score.go index 142d3525d..e144a1cbb 100644 --- a/business/model/dao/store_score.go +++ b/business/model/dao/store_score.go @@ -16,7 +16,7 @@ func GetLatestWeeklyStoreScoreList(db *DaoDB, storeID, weekNum int) (storeScoreL SELECT t2.name store_name, t1.* FROM store_score t1 JOIN store t2 ON t1.store_id = t2.id WHERE t1.store_id = ? - AND DATE(t1.ScoreDate) >= DATE_SUB( + AND DATE(t1.score_date) >= DATE_SUB( DATE_SUB( CURDATE(), INTERVAL @@ -28,7 +28,7 @@ func GetLatestWeeklyStoreScoreList(db *DaoDB, storeID, weekNum int) (storeScoreL ), INTERVAL ? DAY ) - AND DATE(t1.ScoreDate) <= DATE_SUB( + AND DATE(t1.score_date) <= DATE_SUB( CURDATE(), INTERVAL IF ( @@ -37,7 +37,7 @@ func GetLatestWeeklyStoreScoreList(db *DaoDB, storeID, weekNum int) (storeScoreL DAYOFWEEK(CURDATE()) - 1 ) DAY ) - ORDER BY ScoreDate DESC + ORDER BY score_date DESC ` if weekNum <= 0 { weekNum = 1 From 12194ac987ee4d29b1dfa222bac9132fe2026b51 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Mon, 16 Sep 2019 17:46:42 +0800 Subject: [PATCH 26/32] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 2 +- business/model/dao/store_score.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index d984d31e0..390674fa2 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -662,7 +662,7 @@ func CheckScoreStore() { checkTime2 := utils.Str2Time(checkTimeStr2) if curTime.Unix() >= checkTime1.Unix() && curTime.Unix() <= checkTime2.Unix() { db := dao.GetDB() - hasStoreScoreData, err := dao.CheckHasStoreScoreData(db, time.Now()) + hasStoreScoreData, err := dao.CheckHasStoreScoreData(db, curTime) if err == nil && !hasStoreScoreData { ScoreStore(jxcontext.AdminCtx, nil) } diff --git a/business/model/dao/store_score.go b/business/model/dao/store_score.go index e144a1cbb..604a3b52c 100644 --- a/business/model/dao/store_score.go +++ b/business/model/dao/store_score.go @@ -55,7 +55,7 @@ func CheckHasStoreScoreData(db *DaoDB, dateTime time.Time) (hasStoreScoreData bo sql := ` SELECT COUNT(*) count FROM store_score - WHERE DATE(createtime) = DATE(?) + WHERE DATE(score_date) = DATE(?) ` sqlParams := []interface{}{ dateTime, From 05809c3a50acea46925284225b08b400f23ae675 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Tue, 17 Sep 2019 08:41:13 +0800 Subject: [PATCH 27/32] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index 390674fa2..1a3c750c5 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -445,18 +445,20 @@ func ScoreStoreRange(storeInfo *cms.StoreExt) { finalScore := 0 storeID := storeInfo.ID if storeInfo.DeliveryRangeType == model.DeliveryRangeTypePolygon { - points := jxutils.CoordinateStr2Points(storeInfo.DeliveryRange) - area := jxutils.CalcPolygonAreaByLngAndLat(points) - goodArea := math.Pi * StoreRangeGoodRadius * StoreRangeGoodRadius - badArea := math.Pi * StoreRangeBadRadius * StoreRangeBadRadius - if area >= goodArea { - finalScore = ItemTotalScore - } else if area <= badArea { - finalScore = 0 - } else { - diff := goodArea - area - ratio := float64(ItemTotalScore) / (goodArea - badArea) - finalScore = ItemTotalScore - int(math.Round(diff*ratio)) + if storeInfo.DeliveryRange != "" { + points := jxutils.CoordinateStr2Points(storeInfo.DeliveryRange) + area := jxutils.CalcPolygonAreaByLngAndLat(points) + goodArea := math.Pi * StoreRangeGoodRadius * StoreRangeGoodRadius + badArea := math.Pi * StoreRangeBadRadius * StoreRangeBadRadius + if area >= goodArea { + finalScore = ItemTotalScore + } else if area <= badArea { + finalScore = 0 + } else { + diff := goodArea - area + ratio := float64(ItemTotalScore) / (goodArea - badArea) + finalScore = ItemTotalScore - int(math.Round(diff*ratio)) + } } } else if storeInfo.DeliveryRangeType == model.DeliveryRangeTypeRadius { deliveryRadius := utils.Str2Float64WithDefault(storeInfo.DeliveryRange, 0) / 1000 From f208fea6a10e97a18868752468777ce96629c30a Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Tue, 17 Sep 2019 09:26:35 +0800 Subject: [PATCH 28/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E9=85=8D=E9=80=81?= =?UTF-8?q?=E8=8C=83=E5=9B=B4-=E4=BF=AE=E6=94=B9=E5=A4=9A=E8=BE=B9?= =?UTF-8?q?=E5=BD=A2=E8=AE=A1=E7=AE=97=E5=85=AC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 2 +- business/jxutils/jxutils.go | 157 --------------------------- 2 files changed, 1 insertion(+), 158 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index 1a3c750c5..fe19faf5f 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -447,7 +447,7 @@ func ScoreStoreRange(storeInfo *cms.StoreExt) { if storeInfo.DeliveryRangeType == model.DeliveryRangeTypePolygon { if storeInfo.DeliveryRange != "" { points := jxutils.CoordinateStr2Points(storeInfo.DeliveryRange) - area := jxutils.CalcPolygonAreaByLngAndLat(points) + area := jxutils.CalcPolygonAreaAutonavi(points) goodArea := math.Pi * StoreRangeGoodRadius * StoreRangeGoodRadius badArea := math.Pi * StoreRangeBadRadius * StoreRangeBadRadius if area >= goodArea { diff --git a/business/jxutils/jxutils.go b/business/jxutils/jxutils.go index c8f793a05..1366dd7da 100644 --- a/business/jxutils/jxutils.go +++ b/business/jxutils/jxutils.go @@ -194,163 +194,6 @@ func EarthDistance(lng1, lat1, lng2, lat2 float64) float64 { return dist * radius } -func ConvertToRadian(value float64) float64 { - return value * math.Pi / 180 -} - -//计算凹多边形球面积根据经纬度(KM) -func CalcConcavePolygonAreaByLngAndLatFix(points [][2]float64) (area float64) { - radius := 6378.137 - for i := 0; i < len(points)-1; i++ { - p1 := points[i] - p2 := points[i+1] - area += ConvertToRadian(p2[0]-p1[0]) * (2 + math.Sin(ConvertToRadian(p1[1])) + math.Sin(ConvertToRadian(p2[1]))) - } - - area = area * radius * radius / 2 - - return math.Abs(area) -} - -//计算凸多边形球面积根据经纬度(KM) -func CalcConvexPolygonAreaByLngAndLat(points [][2]float64) (area float64) { - Count := len(points) - LowX := 0.0 - LowY := 0.0 - MiddleX := 0.0 - MiddleY := 0.0 - HighX := 0.0 - HighY := 0.0 - - AM := 0.0 - BM := 0.0 - CM := 0.0 - - AL := 0.0 - BL := 0.0 - CL := 0.0 - - AH := 0.0 - BH := 0.0 - CH := 0.0 - - CoefficientL := 0.0 - CoefficientH := 0.0 - - ALtangent := 0.0 - BLtangent := 0.0 - CLtangent := 0.0 - - AHtangent := 0.0 - BHtangent := 0.0 - CHtangent := 0.0 - - ANormalLine := 0.0 - BNormalLine := 0.0 - CNormalLine := 0.0 - - OrientationValue := 0.0 - - AngleCos := 0.0 - - Sum1 := 0.0 - Sum2 := 0.0 - Count2 := 0 - Count1 := 0 - - Sum := 0.0 - Radius := 6378.137 - - for i := 0; i < Count; i++ { - if i == 0 { - LowX = ConvertToRadian(points[Count-1][0]) - LowY = ConvertToRadian(points[Count-1][1]) - MiddleX = ConvertToRadian(points[0][0]) - MiddleY = ConvertToRadian(points[0][1]) - HighX = ConvertToRadian(points[1][0]) - HighY = ConvertToRadian(points[1][1]) - } else if i == Count-1 { - LowX = ConvertToRadian(points[Count-2][0]) - LowY = ConvertToRadian(points[Count-2][1]) - MiddleX = ConvertToRadian(points[Count-1][0]) - MiddleY = ConvertToRadian(points[Count-1][1]) - HighX = ConvertToRadian(points[0][0]) - HighY = ConvertToRadian(points[0][1]) - } else { - LowX = ConvertToRadian(points[i-1][0]) - LowY = ConvertToRadian(points[i-1][1]) - MiddleX = ConvertToRadian(points[i][0]) - MiddleY = ConvertToRadian(points[i][1]) - HighX = ConvertToRadian(points[i+1][0]) - HighY = ConvertToRadian(points[i+1][1]) - } - - AM = math.Cos(MiddleY) * math.Cos(MiddleX) - BM = math.Cos(MiddleY) * math.Sin(MiddleX) - CM = math.Sin(MiddleY) - AL = math.Cos(LowY) * math.Cos(LowX) - BL = math.Cos(LowY) * math.Sin(LowX) - CL = math.Sin(LowY) - AH = math.Cos(HighY) * math.Cos(HighX) - BH = math.Cos(HighY) * math.Sin(HighX) - CH = math.Sin(HighY) - - CoefficientL = (AM*AM + BM*BM + CM*CM) / (AM*AL + BM*BL + CM*CL) - CoefficientH = (AM*AM + BM*BM + CM*CM) / (AM*AH + BM*BH + CM*CH) - - ALtangent = CoefficientL*AL - AM - BLtangent = CoefficientL*BL - BM - CLtangent = CoefficientL*CL - CM - AHtangent = CoefficientH*AH - AM - BHtangent = CoefficientH*BH - BM - CHtangent = CoefficientH*CH - CM - - AngleCos = (AHtangent*ALtangent + BHtangent*BLtangent + CHtangent*CLtangent) / (math.Sqrt(AHtangent*AHtangent+BHtangent*BHtangent+CHtangent*CHtangent) * math.Sqrt(ALtangent*ALtangent+BLtangent*BLtangent+CLtangent*CLtangent)) - AngleCos = math.Acos(AngleCos) - - ANormalLine = BHtangent*CLtangent - CHtangent*BLtangent - BNormalLine = 0 - (AHtangent*CLtangent - CHtangent*ALtangent) - CNormalLine = AHtangent*BLtangent - BHtangent*ALtangent - - if AM != 0 { - OrientationValue = ANormalLine / AM - } else if BM != 0 { - OrientationValue = BNormalLine / BM - } else { - OrientationValue = CNormalLine / CM - } - - if OrientationValue > 0 { - Sum1 += AngleCos - Count1++ - } else { - Sum2 += AngleCos - Count2++ - } - - } - - if Sum1 > Sum2 { - Sum = Sum1 + 2*math.Pi*float64(Count2) - Sum2 - } else { - Sum = 2*math.Pi*float64(Count1) - Sum1 + Sum2 - } - - area = (Sum - float64(Count-2)*math.Pi) * Radius * Radius - - return area -} - -//计算多边形球面积根据经纬度(KM) -func CalcPolygonAreaByLngAndLat(points [][2]float64) (area float64) { - area = CalcConvexPolygonAreaByLngAndLat(points) - if math.IsNaN(area) { - area = CalcConcavePolygonAreaByLngAndLatFix(points) - } - - return area -} - func StandardCoordinate2Int(value float64) int { return int(math.Round(value * 1000000)) } From dbdf04d83cf388ea46f965322d270e6dd9f2e6e9 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Tue, 17 Sep 2019 09:29:13 +0800 Subject: [PATCH 29/32] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routers/commentsRouter_controllers.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index 6d031b32f..86bd3bf1f 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -475,6 +475,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:FoodRecipeController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:FoodRecipeController"], + beego.ControllerComments{ + Method: "CreateFoodRecipe", + Router: `/CreateFoodRecipe`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:InitDataController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:InitDataController"], beego.ControllerComments{ Method: "BuildSkuFromEbaiStore", From 957db0454472a3668e8a3d860650ece4f3305d43 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Tue, 17 Sep 2019 10:32:49 +0800 Subject: [PATCH 30/32] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BB=86=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/cms/store_sku_check.go | 49 +++++++++++-------------- business/jxstore/misc/misc2_test.go | 3 +- business/jxstore/misc/store_score.go | 5 +-- 3 files changed, 25 insertions(+), 32 deletions(-) diff --git a/business/jxstore/cms/store_sku_check.go b/business/jxstore/cms/store_sku_check.go index 34dd94871..eed0d6c1f 100644 --- a/business/jxstore/cms/store_sku_check.go +++ b/business/jxstore/cms/store_sku_check.go @@ -5,6 +5,7 @@ import ( "strings" "sync" "time" + "git.rosy.net.cn/baseapi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils" @@ -18,17 +19,17 @@ import ( ) const ( - canWriteTolocal = false - needStatistic = true + canWriteTolocal = false + needStatistic = true isFilterToBeCreateAndNotSale = true - parallelCount = 5 - fileExt = ".xlsx" + parallelCount = 5 + fileExt = ".xlsx" ) var ( - diffFileName = map[bool]string { - true : "export/JXCSAndVendorSkuDiff", - false : "export/JXGYAndVendorSkuDiff", + diffFileName = map[bool]string{ + true: "export/JXCSAndVendorSkuDiff", + false: "export/JXGYAndVendorSkuDiff", } vendorNameList = map[int]string{ model.VendorIDMTWM: model.VendorChineseNames[model.VendorIDMTWM], @@ -86,7 +87,7 @@ type DiffData struct { SkuID string `json:"SkuID"` SyncStatus string `json:"同步状态"` ToBeCreate string `json:"待创建"` - ToBeDel string `json:"待删除"` + ToBeDel string `json:"待删除"` JxSkuName string `json:"京西商品名"` VendorSkuName string `json:"平台商品名"` JxStatus string `json:"京西可售状态"` @@ -94,11 +95,11 @@ type DiffData struct { } type StatisticData struct { - JxVendorStatus string `json:"京西和平台商品状态"` - ToBeCreate string `json:"待创建"` - JxSaleStatus string `json:"京西可售状态"` - Count string `json:"数量"` - Percent string `json:"占比"` + JxVendorStatus string `json:"京西和平台商品状态"` + ToBeCreate string `json:"待创建"` + JxSaleStatus string `json:"京西可售状态"` + Count string `json:"数量"` + Percent string `json:"占比"` } func (d *DiffDataLock) AppendData(vendorID int, diffData DiffData) { @@ -111,14 +112,6 @@ func (d *DiffDataLock) InitData() { d.diffDataMap = make(map[int][]DiffData) } -func IsMultiStore(vendorID int) bool { - if _, ok := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler); ok { - return true - } - - return false -} - func InitMultiStoreData() { multiStoreAllSkuInfoMap = make(map[int]map[int]*partner.SkuNameInfo) multiStoreAllSkuInfoList = make(map[int][]*partner.StoreSkuInfo) @@ -141,7 +134,7 @@ func GetMultiStoreAllSkuInfo(ctx *jxcontext.Context, vendorMap map[int]bool) { continue } } - if IsMultiStore(vendorID) { + if partner.IsMultiStore(vendorID) { multiHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler) allSkuNameInfoList, err := multiHandler.GetSkus(ctx, 0, "", "") if err != nil { @@ -267,7 +260,7 @@ func CompareJxAndVendor(vendorID int, storeIDStr, vendorStoreID, storeName strin syncStatus := utils.Int2Str(int(status)) toBeCreate := GetBoolName(model.IsSyncStatusNeedCreate(status)) toBeDel := GetBoolName(model.IsSyncStatusNeedDelete(status)) - + if vendorSkuInfo != nil { vendorSkuDetailName := vendorSkuInfo.SkuList[0].SkuName vendorSkuSaleStatusName := GetSkuSaleStatusName(vendorSkuInfo.SkuList[0].Status) @@ -276,7 +269,7 @@ func CompareJxAndVendor(vendorID int, storeIDStr, vendorStoreID, storeName strin isNameDiff := jxSkuDetailName != vendorSkuDetailName if jxSkuDetailName != "" && vendorSkuDetailName != "" && strings.Contains(jxSkuDetailName, vendorSkuDetailName) { isNameDiff = false - } + } if isSaleStatusDiff || isNameDiff { outPutData := DiffData{storeIDStr, vendorStoreID, storeName, skuIDStr, syncStatus, toBeCreate, toBeDel, jxSkuDetailName, vendorSkuDetailName, jxSkuSaleStatusName, vendorSkuSaleStatusName} diffData.AppendData(vendorID, outPutData) @@ -334,7 +327,7 @@ func CheckSkuDiffBetweenJxAndVendor(ctx *jxcontext.Context, vendorIDList []int, var filterJxSkuInfoMap map[int]*StoreSkuNameExt for _, vendorListValue := range jxStoreInfoListValue.StoreMaps { vendorID := int(utils.MustInterface2Int64(vendorListValue["vendorID"])) - + if isGetJxSkuInfoData == false { //only get once jx sku info list every store id isGetJxSkuInfoData = true jxSkuInfoData, _ := GetStoreSkus(ctx, storeID, []int{}, true, "", true, map[string]interface{}{}, 0, -1) @@ -344,7 +337,7 @@ func CheckSkuDiffBetweenJxAndVendor(ctx *jxcontext.Context, vendorIDList []int, vendorStoreID := utils.Interface2String(vendorListValue["vendorStoreID"]) baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor storeID:%d vendorID:%d vendorStoreID:%s vendorListValue:%v", storeID, vendorID, vendorStoreID, vendorListValue) - if IsMultiStore(vendorID) { + if partner.IsMultiStore(vendorID) { singleStoreHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformStoreSkuHandler) allSkuInfoList := GetMultiStoreAllSkuInfoList(vendorID) skuBareInfoList, err := singleStoreHandler.GetStoreSkusBareInfo(ctx, task, storeID, vendorStoreID, allSkuInfoList) @@ -433,14 +426,14 @@ func AddStatisticSheet(sheetName string, data []DiffData) (sheet *excel.Obj2Exce } } for index, value := range count { - percent[index] = float32(value * 100) / float32(totalCount) + percent[index] = float32(value*100) / float32(totalCount) countStr := utils.Int2Str(value) percentStr := fmt.Sprintf("%.2f%%", percent[index]) subStatisticData := statisticDataList[index] statisticData[index] = StatisticData{subStatisticData[0], subStatisticData[1], subStatisticData[2], countStr, percentStr} } sheetName = sheetName + "统计" - sheet = &excel.Obj2ExcelSheetConfig { + sheet = &excel.Obj2ExcelSheetConfig{ Title: sheetName, Data: statisticData, CaptionList: statisticTitleList, diff --git a/business/jxstore/misc/misc2_test.go b/business/jxstore/misc/misc2_test.go index f4eee87f1..e6627a75a 100644 --- a/business/jxstore/misc/misc2_test.go +++ b/business/jxstore/misc/misc2_test.go @@ -2,9 +2,10 @@ package misc import ( "testing" + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" ) func TestStartOrEndOpStore(t *testing.T) { - StartOrEndOpStore(jxcontext.AdminCtx, true, []int{}, []int{}, 0, 0, false, true) + StartOrEndOpStore(jxcontext.AdminCtx, true, nil, nil, 0, 0, false, true) } diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index fe19faf5f..e4949b1aa 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -657,10 +657,9 @@ func ScheduleScoreStore() { func CheckScoreStore() { if !isScoring { curTime := time.Now() - year, month, day := curTime.Date() - checkTimeStr1 := fmt.Sprintf("%d-%d-%d "+scoreStoreTimeList[0], year, int(month), day) + checkTimeStr1 := fmt.Sprintf("%s %s", utils.Time2DateStr(curTime), scoreStoreTimeList[0]) checkTime1 := utils.Str2Time(checkTimeStr1) - checkTimeStr2 := fmt.Sprintf("%d-%d-%d "+scoreStoreCheckTimeEnd, year, int(month), day) + checkTimeStr2 := fmt.Sprintf("%s %s", utils.Time2DateStr(curTime), scoreStoreCheckTimeEnd) checkTime2 := utils.Str2Time(checkTimeStr2) if curTime.Unix() >= checkTime1.Unix() && curTime.Unix() <= checkTime2.Unix() { db := dao.GetDB() From 6b1a2f19fc614c2782bf90b45d2392f35f43a046 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Tue, 17 Sep 2019 16:30:43 +0800 Subject: [PATCH 31/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E8=AF=84=E5=88=86-?= =?UTF-8?q?=E4=BF=AE=E6=94=B9BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 44 ++++++++++++++++++++-------- business/model/dao/dao_order.go | 2 +- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index e4949b1aa..e52e0c4e9 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -591,17 +591,35 @@ func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, GetAllStoreSkus(ctx, task, storeList) baseapi.SugarLogger.Debugf("ScoreStore step1 end") case 2: - db := dao.GetDB() - storeCountList, _ := dao.GetDailyBadCommentOrderCount(db, scoreDate) - storeScoreDataWrapper.SetDailyBadCommentOrderCount(storeCountList) - storeCountList, _ = dao.GetDailyUnFinishOrderCount(db, scoreDate) - storeScoreDataWrapper.SetDailyUnFinishOrderCount(storeCountList) - storeCountList, _ = dao.GetDailyFinishOrderCount(db, scoreDate) - storeScoreDataWrapper.SetDailyFinishOrderCount(storeCountList) - storeCountList, _ = dao.GetDailyAbsentGoodsOrderCount(db, scoreDate) - storeScoreDataWrapper.SetDailyAbsentGoodsOrderCount(storeCountList) - case 3: baseapi.SugarLogger.Debugf("ScoreStore step2 begin") + db := dao.GetDB() + storeCountList, err := dao.GetDailyBadCommentOrderCount(db, scoreDate) + if err == nil { + storeScoreDataWrapper.SetDailyBadCommentOrderCount(storeCountList) + } else { + baseapi.SugarLogger.Debugf("ScoreStore GetDailyBadCommentOrderCount %v", err) + } + storeCountList, err = dao.GetDailyUnFinishOrderCount(db, scoreDate) + if err == nil { + storeScoreDataWrapper.SetDailyUnFinishOrderCount(storeCountList) + } else { + baseapi.SugarLogger.Debugf("ScoreStore GetDailyUnFinishOrderCount %v", err) + } + storeCountList, err = dao.GetDailyFinishOrderCount(db, scoreDate) + if err == nil { + storeScoreDataWrapper.SetDailyFinishOrderCount(storeCountList) + } else { + baseapi.SugarLogger.Debugf("ScoreStore GetDailyFinishOrderCount %v", err) + } + storeCountList, err = dao.GetDailyAbsentGoodsOrderCount(db, scoreDate) + if err == nil { + storeScoreDataWrapper.SetDailyAbsentGoodsOrderCount(storeCountList) + } else { + baseapi.SugarLogger.Debugf("ScoreStore GetDailyAbsentGoodsOrderCount %v", err) + } + baseapi.SugarLogger.Debugf("ScoreStore step2 end") + case 3: + baseapi.SugarLogger.Debugf("ScoreStore step3 begin") taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { storeInfo := batchItemList[0].(*cms.StoreExt) storeID := storeInfo.ID @@ -626,13 +644,13 @@ func ScoreStore(ctx *jxcontext.Context, storeIDList []int) (retVal interface{}, if err != nil { baseapi.SugarLogger.Debugf("ScoreStore taskParallel error:%v", err) } - baseapi.SugarLogger.Debugf("ScoreStore step2 end") + baseapi.SugarLogger.Debugf("ScoreStore step3 end") case 4: - baseapi.SugarLogger.Debugf("ScoreStore step3 begin") + baseapi.SugarLogger.Debugf("ScoreStore step4 begin") storeScoreDataWrapper.InsertStoreScore() storeScoreDataWrapper.ClearData() allStoreSkusWrapper.ClearData() - baseapi.SugarLogger.Debugf("ScoreStore step3 end") + baseapi.SugarLogger.Debugf("ScoreStore step4 end") isScoring = false } return result, err diff --git a/business/model/dao/dao_order.go b/business/model/dao/dao_order.go index a365377ed..bbb20e382 100644 --- a/business/model/dao/dao_order.go +++ b/business/model/dao/dao_order.go @@ -354,7 +354,7 @@ func GetDailyEndOrderCount(db *DaoDB, statusList []int, isAbsentOrder bool, date } sql += ` GROUP BY jx_store_id` - err = GetRow(db, &storeCountList, sql, sqlParams) + err = GetRows(db, &storeCountList, sql, sqlParams) return storeCountList, err } From 0d92a2edd16a8d7d609e111088540462162dff66 Mon Sep 17 00:00:00 2001 From: Rosy-zhudan Date: Wed, 18 Sep 2019 09:13:33 +0800 Subject: [PATCH 32/32] =?UTF-8?q?=E9=97=A8=E5=BA=97=E8=AF=84=E5=88=86-?= =?UTF-8?q?=E4=BF=AE=E6=94=B9bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/misc/store_score.go | 36 +++++++++++++++------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index e52e0c4e9..1c613526c 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -43,6 +43,8 @@ const ( StoreRangeBadRadius = 1.0 //千米 SaleSkuPriceRatio = 90 //千米 SaleSkuCheckRange = 5.0 //千米 + + WeekNum = 5 //得到门店近期周的数量 ) var ( @@ -710,23 +712,23 @@ func Time2Week(t time.Time) int { } func SplitToSingleWeekDataList(storeScoreList []*model.StoreScoreEx) (weekDataList [][]*model.StoreScoreEx) { - singelWeekData := []*model.StoreScoreEx{} + singleWeekData := []*model.StoreScoreEx{} weekIndex := 0 for _, value := range storeScoreList { if weekIndex == 0 { - weekIndex = Time2Week(value.CreatedAt) + weekIndex = Time2Week(value.ScoreDate) } - if weekIndex == Time2Week(value.CreatedAt) { - singelWeekData = append(singelWeekData, value) + if weekIndex == Time2Week(value.ScoreDate) { + singleWeekData = append(singleWeekData, value) } else { - weekDataList = append(weekDataList, singelWeekData) - singelWeekData = []*model.StoreScoreEx{} + weekDataList = append(weekDataList, singleWeekData) + singleWeekData = []*model.StoreScoreEx{} weekIndex = 0 - singelWeekData = append(singelWeekData, value) + singleWeekData = append(singleWeekData, value) } } - if len(singelWeekData) > 0 { - weekDataList = append(weekDataList, singelWeekData) + if len(singleWeekData) > 0 { + weekDataList = append(weekDataList, singleWeekData) } return weekDataList @@ -745,9 +747,9 @@ func GetStoreScoreLevel(score int) int { return level } -func GetWeeklyStoreScore(storeID, weekIndex int) (outWeeklyStoreScoreDataList []*model.WeeklyStoreScore, err error) { +func GetWeeklyStoreScore(storeID, weekIndexParam int) (outWeeklyStoreScoreDataList []*model.WeeklyStoreScore, err error) { db := dao.GetDB() - storeScoreList, err := dao.GetLatestWeeklyStoreScoreList(db, storeID, 5) + storeScoreList, err := dao.GetLatestWeeklyStoreScoreList(db, storeID, WeekNum) if err == nil && len(storeScoreList) > 0 { weeklyStoreScoreDataList := []*model.WeeklyStoreScore{} weekDataList := SplitToSingleWeekDataList(storeScoreList) @@ -765,13 +767,13 @@ func GetWeeklyStoreScore(storeID, weekIndex int) (outWeeklyStoreScoreDataList [] refutil.SetObjFieldByName(weeklyData, fieldName, destFieldValue+srcFieldValue) } if weekDataCount == 1 { - weeklyData.BeginTime = dayData.CreatedAt - weeklyData.EndTime = dayData.CreatedAt + weeklyData.BeginTime = dayData.ScoreDate + weeklyData.EndTime = dayData.ScoreDate } else { if dayIndex == 0 { - weeklyData.EndTime = dayData.CreatedAt + weeklyData.EndTime = dayData.ScoreDate } else if dayIndex == weekDataCount-1 { - weeklyData.BeginTime = dayData.CreatedAt + weeklyData.BeginTime = dayData.ScoreDate } } weeklyData.StoreName = dayData.StoreName @@ -787,10 +789,10 @@ func GetWeeklyStoreScore(storeID, weekIndex int) (outWeeklyStoreScoreDataList [] } weeklyData.Level = GetStoreScoreLevel(weeklyData.TotalScore) } - if weekIndex == -1 { + if weekIndexParam == -1 { outWeeklyStoreScoreDataList = weeklyStoreScoreDataList } else { - outWeeklyStoreScoreDataList = []*model.WeeklyStoreScore{weeklyStoreScoreDataList[weekIndex]} + outWeeklyStoreScoreDataList = []*model.WeeklyStoreScore{weeklyStoreScoreDataList[weekIndexParam]} } }