门店评分-优化数据读取速度
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user