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 ( IncludeToday = true CheckStoreAlertOneMonthDayNum = 30 CheckStoreAlertOneDayNum = 1 CheckStoreAlertOneWeekDayNum = 7 MonthCheckOnWeekDay = 1 AlertTypePickTimeOrderDaDa = 0 AlertTypeBadCommentOrder = 1 AlertTypeAbsentGoodsOrder = 2 AlertTypeStandardFinishTimeOrderSelfDelivery = 3 AlertTypeStandardPickUpTimeOrderDaDa = 4 OneDayName = "单日" OneWeekDayName = "七日" OneMonthDayName = "三十日" YellowAlertInfo = "您的店铺京西菜市-%s,由于%s%s%s%v%%,可能会被系统下线,请及时补救。" RedAlertInfo = "您的店铺京西菜市-%s,由于%s%s%s%v%%,会被系统下线,需要马上补救。" NoOrderAlertInfo = "您的店铺京西菜市-%s,由于近%s无订单,会被系统下线,需要马上补救。" RiskOrderAlertInfo = "系统检测到您的店铺可能有虚假定单,定单号为:%s,可能会被罚款,请及时与运营联系!" ) var ( checkStoreAlertTimeList = []string{ "18:30:00", } AlertTypeNameMap = map[int]string{ AlertTypePickTimeOrderDaDa: "拣货履约率(达达)", AlertTypeBadCommentOrder: "差评率", AlertTypeAbsentGoodsOrder: "缺货率", AlertTypeStandardFinishTimeOrderSelfDelivery: "按时履约率(商家自送)", AlertTypeStandardPickUpTimeOrderDaDa: "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 ConvertListToMapEx(listData []*model.StoreOrder) (mapData map[int][]string) { mapData = make(map[int][]string) for _, value := range listData { if mapData[value.StoreID] == nil { mapData[value.StoreID] = []string{} } mapData[value.StoreID] = append(mapData[value.StoreID], value.VendorOrderID) } return mapData } func GetAlertInfo(dayNum int, isRedAlert bool, storeName string, alertType int, logicCondition string, ratio float64) (info string) { if dayNum == CheckStoreAlertOneDayNum { if isRedAlert { info = fmt.Sprintf(RedAlertInfo, storeName, OneDayName, AlertTypeNameMap[alertType], logicCondition, ratio) } else { info = fmt.Sprintf(YellowAlertInfo, storeName, OneDayName, AlertTypeNameMap[alertType], logicCondition, ratio) } } else if dayNum == CheckStoreAlertOneWeekDayNum { if isRedAlert { info = fmt.Sprintf(RedAlertInfo, storeName, OneWeekDayName, AlertTypeNameMap[alertType], logicCondition, ratio) } else { info = fmt.Sprintf(YellowAlertInfo, storeName, OneWeekDayName, AlertTypeNameMap[alertType], logicCondition, ratio) } } else if dayNum == CheckStoreAlertOneMonthDayNum { info = fmt.Sprintf(NoOrderAlertInfo, storeName, OneMonthDayName) } return info } func CheckAlert(alertType int, dayNum int, ratio float64, count int) (isYellowAlert, isRedAlert bool, logicCondtion string, outRatio float64) { yellowRatio := float64(-1) redRatio := float64(-1) extraCount := -1 conditionLessEqual := false switch alertType { case AlertTypePickTimeOrderDaDa: if dayNum == CheckStoreAlertOneDayNum { redRatio = 0 } else if dayNum == CheckStoreAlertOneWeekDayNum { yellowRatio = 70 redRatio = 50 extraCount = 5 } conditionLessEqual = true case AlertTypeBadCommentOrder: if dayNum == CheckStoreAlertOneDayNum { redRatio = 100 } else if dayNum == CheckStoreAlertOneWeekDayNum { yellowRatio = 1 redRatio = 3 extraCount = 5 } conditionLessEqual = false case AlertTypeAbsentGoodsOrder: if dayNum == CheckStoreAlertOneDayNum { redRatio = 100 } else if dayNum == CheckStoreAlertOneWeekDayNum { yellowRatio = 3 redRatio = 5 extraCount = 5 } conditionLessEqual = false case AlertTypeStandardFinishTimeOrderSelfDelivery: yellowRatio = 85 redRatio = 70 conditionLessEqual = true case AlertTypeStandardPickUpTimeOrderDaDa: yellowRatio = 85 redRatio = 70 conditionLessEqual = true } if conditionLessEqual { logicCondtion = "<=" if extraCount != -1 && count >= extraCount { isRedAlert = true } else if redRatio != -1 && ratio <= redRatio { isRedAlert = true outRatio = redRatio } else if yellowRatio != -1 && ratio <= yellowRatio { isYellowAlert = true outRatio = yellowRatio } } else { logicCondtion = ">=" if extraCount != -1 && count >= extraCount { isRedAlert = true } else if redRatio != -1 && ratio >= redRatio { isRedAlert = true outRatio = redRatio } else if yellowRatio != -1 && ratio >= yellowRatio { isYellowAlert = true outRatio = yellowRatio } } return isYellowAlert, isRedAlert, logicCondtion, outRatio } func SendAlertInfo(storeID int, alertInfo string) { fmt.Printf("SendAlertInfo:%d %s\n", storeID, alertInfo) } func SendAlertInfoWrapper(storeID int, storeName string, dayNum, alertType, count, totalCount int) { if totalCount > 0 { ratio := float64(count) * 100 / float64(totalCount) yellowAlert, redAlert, logicCondtion, outRatio := CheckAlert(alertType, dayNum, ratio, count) isAlert := false isRedAlert := redAlert isAlert = yellowAlert || redAlert if isAlert { alertInfo := GetAlertInfo(dayNum, isRedAlert, storeName, alertType, logicCondtion, outRatio) SendAlertInfo(storeID, alertInfo) } } } func CheckStoreDayAlert(storeMapData map[int]*cms.StoreExt, dayNum int) { db := dao.GetDB() //拣货履约订单(达达) pickTimeOrderCountDaDaList, _ := dao.GetStandardPickTimeOrderCountByDaDa(db, dayNum, IncludeToday) pickTimeOrderCountDaDaMapData := ConvertListToMap(pickTimeOrderCountDaDaList) //完成订单(达达) finishOrderCountDaDaList, _ := dao.GetFinishOrderCountByDaDa(db, dayNum, IncludeToday) finishOrderCountDaDaMapData := ConvertListToMap(finishOrderCountDaDaList) //差评订单 badCommentOrderCountList, _ := dao.GetBadCommentOrderCountByDayNum(db, dayNum, IncludeToday) badCommentOrderCountMapData := ConvertListToMap(badCommentOrderCountList) //缺货订单 absentGoodsOrderCountList, _ := dao.GetAbsentGoodsOrderCountByDayNum(db, dayNum, IncludeToday) absentGoodsOrderCountMapData := ConvertListToMap(absentGoodsOrderCountList) //完成订单 finishOrderCountList, _ := dao.GetFinishOrderCountByDayNum(db, dayNum, IncludeToday) finishOrderCountMapData := ConvertListToMap(finishOrderCountList) var standardFinishTimeOrderCountSelfDeliveryList []*model.StoreCount var standardFinishTimeOrderCountSelfDeliveryMapData map[int]int var finishOrderCountSelfDeliveryList []*model.StoreCount var finishOrderCountSelfDeliveryMapData map[int]int var standardPickUpTimeOrderCountDaDaList []*model.StoreCount var standardPickUpTimeOrderCountDaDaMapData map[int]int isOneWeekDay := dayNum == CheckStoreAlertOneWeekDayNum if isOneWeekDay { //按时履约订单(商家自送) standardFinishTimeOrderCountSelfDeliveryList, _ = dao.GetStandardFinishTimeOrderCountBySelfDelivery(db, dayNum, IncludeToday) standardFinishTimeOrderCountSelfDeliveryMapData = ConvertListToMap(standardFinishTimeOrderCountSelfDeliveryList) //完成订单(商家自送) finishOrderCountSelfDeliveryList, _ = dao.GetFinishOrderCountBySelfDelivery(db, dayNum, IncludeToday) finishOrderCountSelfDeliveryMapData = ConvertListToMap(finishOrderCountSelfDeliveryList) //10分钟取货完成订单(达达) standardPickUpTimeOrderCountDaDaList, _ = dao.GetStandardPickUpTimeOrderCountByDaDa(db, dayNum, IncludeToday) standardPickUpTimeOrderCountDaDaMapData = ConvertListToMap(standardPickUpTimeOrderCountDaDaList) } for _, storeInfo := range storeMapData { storeID := storeInfo.ID storeName := storeInfo.Name count := pickTimeOrderCountDaDaMapData[storeID] totalCount := finishOrderCountDaDaMapData[storeID] SendAlertInfoWrapper(storeID, storeName, dayNum, AlertTypePickTimeOrderDaDa, count, totalCount) count = badCommentOrderCountMapData[storeID] totalCount = finishOrderCountMapData[storeID] SendAlertInfoWrapper(storeID, storeName, dayNum, AlertTypeBadCommentOrder, count, totalCount) count = absentGoodsOrderCountMapData[storeID] SendAlertInfoWrapper(storeID, storeName, dayNum, AlertTypeAbsentGoodsOrder, count, totalCount) if isOneWeekDay { count = standardFinishTimeOrderCountSelfDeliveryMapData[storeID] totalCount = finishOrderCountSelfDeliveryMapData[storeID] SendAlertInfoWrapper(storeID, storeName, dayNum, AlertTypeStandardFinishTimeOrderSelfDelivery, count, totalCount) count = standardPickUpTimeOrderCountDaDaMapData[storeID] totalCount = finishOrderCountDaDaMapData[storeID] SendAlertInfoWrapper(storeID, storeName, dayNum, AlertTypeStandardPickUpTimeOrderDaDa, count, totalCount) } } } func CheckStoreMonthAlert(storeMapData map[int]*cms.StoreExt) { db := dao.GetDB() storeCountList, _ := dao.GetFinishOrderCountByDayNum(db, CheckStoreAlertOneMonthDayNum, IncludeToday) storeCountMapData := make(map[int]int) for _, value := range storeCountList { storeCountMapData[value.StoreID] = value.Count } for _, storeInfo := range storeMapData { storeID := storeInfo.ID storeName := storeInfo.Name if _, ok := storeCountMapData[storeID]; !ok { alertInfo := GetAlertInfo(CheckStoreAlertOneMonthDayNum, true, storeName, -1, "", -1) SendAlertInfo(storeID, alertInfo) } } } func CheckStoreRiskOrderAlert(storeMapData map[int]*cms.StoreExt, dayNum int) { db := dao.GetDB() storeOrderList, _ := dao.GetRiskOrderCount(db, dayNum, IncludeToday) storeOrderMapData := ConvertListToMapEx(storeOrderList) for _, storeInfo := range storeMapData { storeID := storeInfo.ID vendorOrderIDList := storeOrderMapData[storeID] if vendorOrderIDList != nil { vendorOrderIDStr := "" for index, vendorOrderID := range vendorOrderIDList { if index == 0 { vendorOrderIDStr += vendorOrderID } else { vendorOrderIDStr += "," + vendorOrderID } } alertInfo := fmt.Sprintf(RiskOrderAlertInfo, vendorOrderIDStr) SendAlertInfo(storeID, alertInfo) } } } func GetWeekDay() int { return int(time.Now().Weekday()) } 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) CheckStoreRiskOrderAlert(storeMapData, CheckStoreAlertOneDayNum) } func ScheduleCheckStoreAlert() { ScheduleTimerFunc("ScheduleCheckStoreAlert", func() { CheckStoreAlert(jxcontext.AdminCtx) }, checkStoreAlertTimeList) }