门店红线警告
This commit is contained in:
255
business/jxstore/misc/Store_Alert_Inform.go
Normal file
255
business/jxstore/misc/Store_Alert_Inform.go
Normal file
@@ -0,0 +1,255 @@
|
||||
package misc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
|
||||
"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 (
|
||||
CheckStoreAlertOneMonthDayNum = 30
|
||||
CheckStoreAlertOneDayNum = 1
|
||||
CheckStoreAlertOneWeekDayNum = 7
|
||||
MonthCheckOnWeekDay = 1
|
||||
|
||||
AlertTypePickTimeOrderDaDa = 0
|
||||
AlertTypeBadCommentOrder = 1
|
||||
AlertTypeAbsentGoodsOrder = 2
|
||||
AlertTypePickTimeOrderSelfDelivery = 3
|
||||
AlertTypePickUpTimeOrderDaDa = 4
|
||||
|
||||
OneDayName = "单日"
|
||||
OneWeekDayName = "七日"
|
||||
OneMonthDayName = "三十日"
|
||||
YellowAlertInfo = "您的店铺京西菜市-%s,由于%s%s>=%d%%,可能会被系统下线,请及时补救。"
|
||||
RedAlertInfo = "您的店铺京西菜市-%s,由于%s%s>=%d%%,会被系统下线,需要马上补救。"
|
||||
NoOrderAlertInfo = "您的店铺京西菜市-%s,由于近%s无订单,会被系统下线,需要马上补救。"
|
||||
)
|
||||
|
||||
var (
|
||||
checkStoreAlertTimeList = []string{
|
||||
"18:30:00",
|
||||
}
|
||||
|
||||
AlertTypeNameMap = map[int]string{
|
||||
AlertTypePickTimeOrderDaDa: "拣货履约率(达达)",
|
||||
AlertTypeBadCommentOrder: "差评率",
|
||||
AlertTypeAbsentGoodsOrder: "缺货率",
|
||||
AlertTypePickTimeOrderSelfDelivery: "按时履约率(商家自送)",
|
||||
AlertTypePickUpTimeOrderDaDa: "10分钟取货完成率(达达)",
|
||||
}
|
||||
)
|
||||
|
||||
func ConvertListToMap(listData []*model.StoreCount) (mapData map[int]int) {
|
||||
mapData = make(map[int]int)
|
||||
for _, value := range listData {
|
||||
mapData[value.StoreID] = value.Count
|
||||
}
|
||||
|
||||
return mapData
|
||||
}
|
||||
|
||||
func GetAlertInfo(dayNum int, isRedAlert bool, storeName string, alertType int, ratio int) (info string) {
|
||||
if dayNum == CheckStoreAlertOneDayNum {
|
||||
if isRedAlert {
|
||||
info = fmt.Sprintf(RedAlertInfo, storeName, OneDayName, AlertTypeNameMap[alertType], ratio)
|
||||
} else {
|
||||
info = fmt.Sprintf(YellowAlertInfo, storeName, OneDayName, AlertTypeNameMap[alertType], ratio)
|
||||
}
|
||||
} else if dayNum == CheckStoreAlertOneWeekDayNum {
|
||||
if isRedAlert {
|
||||
info = fmt.Sprintf(RedAlertInfo, storeName, OneWeekDayName, AlertTypeNameMap[alertType], ratio)
|
||||
} else {
|
||||
info = fmt.Sprintf(YellowAlertInfo, storeName, OneWeekDayName, AlertTypeNameMap[alertType], ratio)
|
||||
}
|
||||
} else if dayNum == CheckStoreAlertOneMonthDayNum {
|
||||
info = fmt.Sprintf(NoOrderAlertInfo, storeName, OneMonthDayName)
|
||||
}
|
||||
|
||||
return info
|
||||
}
|
||||
|
||||
func GetAlertRatio(alertType int, dayNum int) (yellowRatio, redRatio float64) {
|
||||
switch alertType {
|
||||
case AlertTypePickTimeOrderDaDa:
|
||||
if dayNum == CheckStoreAlertOneDayNum {
|
||||
yellowRatio = -1
|
||||
redRatio = 0
|
||||
} else {
|
||||
yellowRatio = 70
|
||||
redRatio = 50
|
||||
}
|
||||
case AlertTypeBadCommentOrder:
|
||||
if dayNum == CheckStoreAlertOneDayNum {
|
||||
yellowRatio = -1
|
||||
redRatio = 100
|
||||
} else {
|
||||
yellowRatio = 1
|
||||
redRatio = 3
|
||||
}
|
||||
case AlertTypeAbsentGoodsOrder:
|
||||
if dayNum == CheckStoreAlertOneDayNum {
|
||||
yellowRatio = -1
|
||||
redRatio = 100
|
||||
} else {
|
||||
yellowRatio = 3
|
||||
redRatio = 5
|
||||
}
|
||||
case AlertTypePickTimeOrderSelfDelivery:
|
||||
yellowRatio = 85
|
||||
redRatio = 70
|
||||
case AlertTypePickUpTimeOrderDaDa:
|
||||
yellowRatio = 85
|
||||
redRatio = 70
|
||||
default:
|
||||
yellowRatio = -1
|
||||
redRatio = -1
|
||||
}
|
||||
|
||||
return float64(yellowRatio), float64(redRatio)
|
||||
}
|
||||
|
||||
func CheckStoreDayAlert(storeMapData map[int]*cms.StoreExt, dayNum int) (retVal interface{}, err error) {
|
||||
db := dao.GetDB()
|
||||
//拣货履约率(达达)
|
||||
pickTimeOrderCountDaDa, err := dao.GetStandardPickTimeOrderCountByDaDa(db, dayNum, true)
|
||||
pickTimeOrderCountDaDaMapData := ConvertListToMap(pickTimeOrderCountDaDa)
|
||||
//完成订单(达达)
|
||||
finishOrderCountDaDa, err := dao.GetFinishOrderCountByDaDa(db, dayNum, true)
|
||||
finishOrderCountDaDaMapData := ConvertListToMap(finishOrderCountDaDa)
|
||||
//差评订单
|
||||
badCommentOrderCount, err := dao.GetBadCommentOrderCountByDayNum(db, dayNum, true)
|
||||
badCommentOrderCountMapData := ConvertListToMap(badCommentOrderCount)
|
||||
//缺货订单
|
||||
absentGoodsOrderCount, err := dao.GetAbsentGoodsOrderCountByDayNum(db, dayNum, true)
|
||||
absentGoodsOrderCountMapData := ConvertListToMap(absentGoodsOrderCount)
|
||||
//完成订单
|
||||
finishOrderCount, err := dao.GetFinishOrderCountByDayNum(db, dayNum, true)
|
||||
finishOrderCountMapData := ConvertListToMap(finishOrderCount)
|
||||
//按时履约订单(商家自送)
|
||||
standardFinishTimeOrderCountSelfDelivery, err := dao.GetStandardFinishTimeOrderCountBySelfDelivery(db, dayNum, true)
|
||||
standardFinishTimeOrderCountSelfDeliveryMapData := ConvertListToMap(standardFinishTimeOrderCountSelfDelivery)
|
||||
//完成订单(商家自送)
|
||||
finishOrderCountSelfDelivery, err := dao.GetFinishOrderCountBySelfDelivery(db, dayNum, true)
|
||||
finishOrderCountSelfDeliveryMapData := ConvertListToMap(finishOrderCountSelfDelivery)
|
||||
//10分钟取货完成订单量(达达)
|
||||
standardPickUpTimeOrderCountSelfDelivery, err := dao.GetStandardPickUpTimeOrderCountBySelfDelivery(db, dayNum, true)
|
||||
standardPickUpTimeOrderCountSelfDeliveryMapData := ConvertListToMap(standardPickUpTimeOrderCountSelfDelivery)
|
||||
|
||||
pickTimeOrderDaDaStoreIDListRed := []int{}
|
||||
badCommentOrderStoreIDListRed := []int{}
|
||||
absentGoodsOrderStoreIDListRed := []int{}
|
||||
|
||||
pickTimeOrderDaDaStoreIDListYellow := []int{}
|
||||
badCommentOrderStoreIDListYellow := []int{}
|
||||
absentGoodsOrderStoreIDListYellow := []int{}
|
||||
for _, storeInfo := range storeMapData {
|
||||
storeID := storeInfo.ID
|
||||
pickTimeOrderCountDaDa := pickTimeOrderCountDaDaMapData[storeID]
|
||||
finishOrderCountDaDa := finishOrderCountDaDaMapData[storeID]
|
||||
if finishOrderCountDaDa > 0 {
|
||||
pickTimeOrderDaDaRatio := float64(pickTimeOrderCountDaDa) * 100 / float64(finishOrderCountDaDa)
|
||||
yellowRatio, redRatio := GetAlertRatio(AlertTypePickTimeOrderDaDa, dayNum)
|
||||
if redRatio != -1 && pickTimeOrderDaDaRatio <= redRatio {
|
||||
pickTimeOrderDaDaStoreIDListRed = append(pickTimeOrderDaDaStoreIDListRed, storeID)
|
||||
} else if yellowRatio != -1 && pickTimeOrderDaDaRatio <= yellowRatio {
|
||||
pickTimeOrderDaDaStoreIDListYellow = append(pickTimeOrderDaDaStoreIDListYellow, storeID)
|
||||
}
|
||||
}
|
||||
|
||||
badCommentOrderCount := badCommentOrderCountMapData[storeID]
|
||||
absentGoodsOrderCount := absentGoodsOrderCountMapData[storeID]
|
||||
finishOrderCount := finishOrderCountMapData[storeID]
|
||||
if finishOrderCount > 0 {
|
||||
badCommentOrderRatio := float64(badCommentOrderCount) * 100 / float64(finishOrderCount)
|
||||
yellowRatio, redRatio := GetAlertRatio(AlertTypeBadCommentOrder, dayNum)
|
||||
if redRatio != -1 && badCommentOrderRatio >= redRatio {
|
||||
badCommentOrderStoreIDListRed = append(badCommentOrderStoreIDListRed, storeID)
|
||||
} else if yellowRatio != -1 && badCommentOrderRatio >= yellowRatio {
|
||||
badCommentOrderStoreIDListYellow = append(badCommentOrderStoreIDListYellow, storeID)
|
||||
}
|
||||
|
||||
absentGoodsOrderRatio := float64(absentGoodsOrderCount) * 100 / float64(finishOrderCount)
|
||||
yellowRatio, redRatio = GetAlertRatio(AlertTypeAbsentGoodsOrder, dayNum)
|
||||
if redRatio != -1 && absentGoodsOrderRatio >= redRatio {
|
||||
absentGoodsOrderStoreIDListRed = append(absentGoodsOrderStoreIDListRed, storeID)
|
||||
} else if yellowRatio != -1 && absentGoodsOrderRatio >= yellowRatio {
|
||||
absentGoodsOrderStoreIDListYellow = append(absentGoodsOrderStoreIDListYellow, storeID)
|
||||
}
|
||||
}
|
||||
|
||||
if dayNum == CheckStoreAlertOneWeekDayNum {
|
||||
standardFinishTimeOrderCountSelfDelivery := standardFinishTimeOrderCountSelfDeliveryMapData[storeID]
|
||||
finishOrderCountSelfDelivery := finishOrderCountSelfDeliveryMapData[storeID]
|
||||
if finishOrderCountSelfDelivery > 0 {
|
||||
standardFinishTimeOrderSelfDeliveryRatio := float64(standardFinishTimeOrderCountSelfDelivery) * 100 / float64(finishOrderCountSelfDelivery)
|
||||
yellowRatio, redRatio := GetAlertRatio(AlertTypePickTimeOrderSelfDelivery, dayNum)
|
||||
if redRatio != -1 && standardFinishTimeOrderSelfDeliveryRatio <= redRatio {
|
||||
|
||||
} else if yellowRatio != -1 && standardFinishTimeOrderSelfDeliveryRatio <= yellowRatio {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
standardPickUpTimeOrderCountSelfDelivery := standardPickUpTimeOrderCountSelfDeliveryMapData[storeID]
|
||||
finishOrderCountDaDa := finishOrderCountDaDaMapData[storeID]
|
||||
if finishOrderCountSelfDelivery > 0 {
|
||||
standardPickUpTimeOrderSelfDeliveryRatio := float64(standardPickUpTimeOrderCountSelfDelivery) * 100 / float64(finishOrderCountDaDa)
|
||||
yellowRatio, redRatio := GetAlertRatio(AlertTypePickUpTimeOrderDaDa, dayNum)
|
||||
if redRatio != -1 && standardPickUpTimeOrderSelfDeliveryRatio <= redRatio {
|
||||
|
||||
} else if yellowRatio != -1 && standardPickUpTimeOrderSelfDeliveryRatio <= yellowRatio {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
func CheckStoreMonthAlert(storeMapData map[int]*cms.StoreExt) (retVal interface{}, err error) {
|
||||
db := dao.GetDB()
|
||||
storeCountList, err := dao.GetFinishOrderCountByDayNum(db, CheckStoreAlertOneMonthDayNum, true)
|
||||
storeCountMapData := make(map[int]int)
|
||||
for _, value := range storeCountList {
|
||||
storeCountMapData[value.StoreID] = value.Count
|
||||
}
|
||||
|
||||
alertStoreIDList := []int{}
|
||||
for _, storeInfo := range storeMapData {
|
||||
storeID := storeInfo.ID
|
||||
if _, ok := storeCountMapData[storeID]; !ok {
|
||||
alertStoreIDList = append(alertStoreIDList, storeID)
|
||||
}
|
||||
}
|
||||
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
func CheckStoreAlert(ctx *jxcontext.Context) {
|
||||
storeList, _ := GetStoreList(ctx)
|
||||
storeMapData := make(map[int]*cms.StoreExt)
|
||||
for _, value := range storeList {
|
||||
storeMapData[value.ID] = value
|
||||
}
|
||||
if GetWeekDay() == MonthCheckOnWeekDay {
|
||||
CheckStoreMonthAlert(storeMapData)
|
||||
}
|
||||
CheckStoreDayAlert(storeMapData, CheckStoreAlertOneDayNum)
|
||||
CheckStoreDayAlert(storeMapData, CheckStoreAlertOneWeekDayNum)
|
||||
}
|
||||
|
||||
func GetWeekDay() int {
|
||||
return int(time.Now().Weekday())
|
||||
}
|
||||
|
||||
func ScheduleCheckStoreAlert() {
|
||||
ScheduleTimerFunc("ScheduleCheckStoreAlert", func() {
|
||||
CheckStoreAlert(jxcontext.AdminCtx)
|
||||
}, checkStoreAlertTimeList)
|
||||
}
|
||||
Reference in New Issue
Block a user