diff --git a/business/jxstore/misc/Store_Alert_Inform.go b/business/jxstore/misc/Store_Alert_Inform.go new file mode 100644 index 000000000..68135d9e8 --- /dev/null +++ b/business/jxstore/misc/Store_Alert_Inform.go @@ -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) +} diff --git a/business/jxstore/misc/store_score.go b/business/jxstore/misc/store_score.go index 7079b5966..61b40fb50 100644 --- a/business/jxstore/misc/store_score.go +++ b/business/jxstore/misc/store_score.go @@ -808,10 +808,11 @@ func GetWeeklyStoreScore(storeID, weekIndexParam int) (outWeeklyStoreScoreDataLi return outWeeklyStoreScoreDataList, err } -func GetStoreTotalScoreList(storeIDList []int, cityCode int, keyWord string, beginTime, endTime time.Time, isDesc bool, checkScoreLow, checkScoreHigh int) (outStoreTotalScoreList []*model.StoreTotalScore, err error) { +func GetStoreTotalScoreList(storeIDList []int, cityCode int, keyWord string, beginTime, endTime time.Time, isDesc bool, checkScoreLow, checkScoreHigh, offset, pageSize int) (storeTotalScoreEx model.StoreTotalScoreEx, err error) { db := dao.GetDB() storeTotalScoreMapData := make(map[int]*model.StoreTotalScore) storeTotalScoreList, err := dao.GetStoreTotalScoreList(db, storeIDList, cityCode, keyWord, beginTime, endTime) + var filterStoreTotalScoreList []*model.StoreTotalScore if err == nil && len(storeTotalScoreList) > 0 { countDayNum := make(map[int]int) for _, value := range storeTotalScoreList { @@ -837,13 +838,13 @@ func GetStoreTotalScoreList(storeIDList []int, cityCode int, keyWord string, beg needAdd = false } if needAdd { - outStoreTotalScoreList = append(outStoreTotalScoreList, value) + filterStoreTotalScoreList = append(filterStoreTotalScoreList, value) } } if isDesc { - sort.Slice(outStoreTotalScoreList, func(i, j int) bool { - data1 := outStoreTotalScoreList[i] - data2 := outStoreTotalScoreList[j] + sort.Slice(filterStoreTotalScoreList, func(i, j int) bool { + data1 := filterStoreTotalScoreList[i] + data2 := filterStoreTotalScoreList[j] if data1.StoreScore == data2.StoreScore { return data1.StoreID < data2.StoreID } else { @@ -851,9 +852,9 @@ func GetStoreTotalScoreList(storeIDList []int, cityCode int, keyWord string, beg } }) } else { - sort.Slice(outStoreTotalScoreList, func(i, j int) bool { - data1 := outStoreTotalScoreList[i] - data2 := outStoreTotalScoreList[j] + sort.Slice(filterStoreTotalScoreList, func(i, j int) bool { + data1 := filterStoreTotalScoreList[i] + data2 := filterStoreTotalScoreList[j] if data1.StoreScore == data2.StoreScore { return data1.StoreID < data2.StoreID } else { @@ -863,5 +864,15 @@ func GetStoreTotalScoreList(storeIDList []int, cityCode int, keyWord string, beg } } - return outStoreTotalScoreList, err + offset = jxutils.FormalizePageOffset(offset) + pageSize = jxutils.FormalizePageSize(pageSize) + var pagedStoreTotalScoreList []*model.StoreTotalScore + for i := offset; i < offset+pageSize && i < len(filterStoreTotalScoreList); i++ { + pagedStoreTotalScoreList = append(pagedStoreTotalScoreList, filterStoreTotalScoreList[i]) + } + + storeTotalScoreEx.TotalCount = len(filterStoreTotalScoreList) + storeTotalScoreEx.StoreTotalScoreList = pagedStoreTotalScoreList + + return storeTotalScoreEx, err } diff --git a/business/model/Store_Alert_Inform.go b/business/model/Store_Alert_Inform.go new file mode 100644 index 000000000..6b799489c --- /dev/null +++ b/business/model/Store_Alert_Inform.go @@ -0,0 +1,16 @@ +package model + +import "time" + +type StoreOrderTime struct { + StoreID int `orm:"column(store_id)"` + OrderCreateTime time.Time `orm:"column(order_created_at)"` + OrderFinishedTime time.Time `orm:"column(order_finished_at)"` +} + +type StoreOrderStatus struct { + StoreID int `orm:"column(store_id)"` + VendorOrderID string `orm:"column(vendor_order_id)"` + StatusTime time.Time `orm:"column(status_time)"` + Status int `orm:"column(status)"` +} diff --git a/business/model/dao/Store_Alert_Inform.go b/business/model/dao/Store_Alert_Inform.go new file mode 100644 index 000000000..35b7c14c7 --- /dev/null +++ b/business/model/dao/Store_Alert_Inform.go @@ -0,0 +1,3 @@ +package dao + + diff --git a/business/model/dao/dao_order.go b/business/model/dao/dao_order.go index bbb20e382..4c771ea07 100644 --- a/business/model/dao/dao_order.go +++ b/business/model/dao/dao_order.go @@ -300,7 +300,7 @@ func GetDailyFinishOrderList(db *DaoDB, storeID int, dateTime time.Time) (orderL ` sqlParams := []interface{}{ storeID, - 1, + model.OrderTypeOrder, model.OrderStatusFinishedPickup, dateTime, } @@ -308,14 +308,25 @@ func GetDailyFinishOrderList(db *DaoDB, storeID int, dateTime time.Time) (orderL } func GetDailyBadCommentOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) { + beginTime, endTime := utils.GetTimeRange(dateTime, 1, true) + return GetBadCommentOrderCount(db, beginTime, endTime) +} + +func GetBadCommentOrderCountByDayNum(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { + beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday) + return GetBadCommentOrderCount(db, beginTime, endTime) +} + +func GetBadCommentOrderCount(db *DaoDB, beginTime, endTime time.Time) (storeCountList []*model.StoreCount, err error) { sql := ` SELECT jxstoreid store_id, COUNT(*) count FROM jx_bad_comments - WHERE DATE(createtime) = DATE(?) + WHERE createtime >= ? AND createtime <= ? GROUP BY jxstoreid ` sqlParams := []interface{}{ - dateTime, + beginTime, + endTime, } err = GetRows(db, &storeCountList, sql, sqlParams) @@ -323,31 +334,64 @@ func GetDailyBadCommentOrderCount(db *DaoDB, dateTime time.Time) (storeCountList } func GetDailyUnFinishOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) { - return GetDailyEndOrderCount(db, []int{model.OrderStatusCanceled}, false, dateTime) + beginTime, endTime := utils.GetTimeRange(dateTime, 1, true) + return GetUnFinishOrderCount(db, beginTime, endTime) } func GetDailyFinishOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) { - return GetDailyEndOrderCount(db, []int{model.OrderStatusFinished}, false, dateTime) + beginTime, endTime := utils.GetTimeRange(dateTime, 1, true) + return GetFinishOrderCount(db, beginTime, endTime) } func GetDailyAbsentGoodsOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) { - return GetDailyEndOrderCount(db, []int{model.OrderStatusFinished, model.OrderStatusCanceled}, true, dateTime) + beginTime, endTime := utils.GetTimeRange(dateTime, 1, true) + return GetAbsentGoodsOrderCount(db, beginTime, endTime) } -func GetDailyEndOrderCount(db *DaoDB, statusList []int, isAbsentOrder bool, dateTime time.Time) (storeCountList []*model.StoreCount, err error) { +func GetUnFinishOrderCount(db *DaoDB, beginTime, endTime time.Time) (storeCountList []*model.StoreCount, err error) { + return GetEndOrderCount(db, []int{model.OrderStatusCanceled}, false, beginTime, endTime) +} + +func GetFinishOrderCount(db *DaoDB, beginTime, endTime time.Time) (storeCountList []*model.StoreCount, err error) { + return GetEndOrderCount(db, []int{model.OrderStatusFinished}, false, beginTime, endTime) +} + +func GetAbsentGoodsOrderCount(db *DaoDB, beginTime, endTime time.Time) (storeCountList []*model.StoreCount, err error) { + return GetEndOrderCount(db, []int{model.OrderStatusFinished}, true, beginTime, endTime) +} + +func GetUnFinishOrderCountByDayNum(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { + return GetEndOrderCountByDayNum(db, []int{model.OrderStatusCanceled}, false, dayNum, includeToday) +} + +func GetFinishOrderCountByDayNum(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { + return GetEndOrderCountByDayNum(db, []int{model.OrderStatusFinished}, false, dayNum, includeToday) +} + +func GetAbsentGoodsOrderCountByDayNum(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { + return GetEndOrderCountByDayNum(db, []int{model.OrderStatusFinished}, true, dayNum, includeToday) +} + +func GetEndOrderCountByDayNum(db *DaoDB, statusList []int, checkAbsentOrder bool, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { + beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday) + return GetEndOrderCount(db, statusList, checkAbsentOrder, beginTime, endTime) +} + +func GetEndOrderCount(db *DaoDB, statusList []int, checkAbsentOrder bool, beginTime, endTime 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(?) + WHERE order_finished_at >= ? AND order_finished_at <= ? ` sqlParams := []interface{}{ - dateTime, + beginTime, + endTime, } if len(statusList) > 0 { sql += ` AND status IN (` + GenQuestionMarks(len(statusList)) + `)` sqlParams = append(sqlParams, statusList) } - if isAbsentOrder { + if checkAbsentOrder { sql += ` AND adjust_count > 0 ` @@ -358,3 +402,163 @@ func GetDailyEndOrderCount(db *DaoDB, statusList []int, isAbsentOrder bool, date return storeCountList, err } + +func GetFinishOrderCountByDaDa(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { + return GetFinishOrderCountByWayBillVendorID(db, model.VendorIDDada, dayNum, includeToday) +} + +func GetFinishOrderCountBySelfDelivery(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { + return GetFinishOrderCountByWayBillVendorID(db, model.VendorIDUnknown, dayNum, includeToday) +} + +//通过运单平台ID来统计完成的订单量 +func GetFinishOrderCountByWayBillVendorID(db *DaoDB, wayBillVendorID, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { + sql := ` + SELECT jx_store_id store_id, COUNT(*) count + FROM goods_order + where order_finished_at >= ? AND order_finished_at <= ? + AND status = ? + AND waybill_vendor_id = ? + GROUP BY jx_store_id + ` + beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday) + sqlParams := []interface{}{ + beginTime, + endTime, + model.OrderStatusFinished, + wayBillVendorID, + } + + return storeCountList, GetRows(db, &storeCountList, sql, sqlParams) +} + +//拣货履约订单量, 仅统计达达专送 +func GetStandardPickTimeOrderCountByDaDa(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { + sql := ` + SELECT jx_store_id store_id, COUNT(*) count + FROM goods_order t1 + JOIN order_status t2 ON t2.vendor_order_id = t1.vendor_order_id + where t1.order_finished_at >= ? AND t1.order_finished_at <= ? + AND t1.status = ? + AND t1.waybill_vendor_id = ? + AND t2.order_type = ? + AND t2.status = ? + AND t2.status_time <= t1.pick_deadline + GROUP BY jx_store_id + ` + beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday) + sqlParams := []interface{}{ + beginTime, + endTime, + model.OrderStatusFinished, + model.VendorIDDada, + model.OrderTypeOrder, + model.OrderStatusFinishedPickup, + } + + return storeCountList, GetRows(db, &storeCountList, sql, sqlParams) +} + +//按时履约订单量, 仅统计商家自送门店 +func GetStandardFinishTimeOrderCountBySelfDelivery(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { + sql := ` + SELECT jx_store_id store_id, order_created_at orderCreateTime, order_finished_at orderFinishTime + FROM goods_order + where order_finished_at >= ? AND order_finished_at <= ? + AND status = ? + AND waybill_vendor_id = ? + ` + beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday) + sqlParams := []interface{}{ + beginTime, + endTime, + model.OrderStatusFinished, + model.VendorIDUnknown, + } + + standardTime := int64(3600) + var storeOrderTimeList []*model.StoreOrderTime + storeOrderTimeMapData := make(map[int]int) + err = GetRows(db, &storeOrderTimeList, sql, sqlParams) + if err == nil && len(storeOrderTimeList) > 0 { + for _, value := range storeOrderTimeList { + if value.OrderFinishedTime.Unix()-value.OrderCreateTime.Unix() <= standardTime { + storeOrderTimeMapData[value.StoreID]++ + } + } + for storeID, count := range storeOrderTimeMapData { + storeCountList = append(storeCountList, &model.StoreCount{storeID, count}) + } + } + + return storeCountList, err +} + +//10分钟取货完成订单量, 仅统计达达专送 +func GetStandardPickUpTimeOrderCountBySelfDelivery(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { + sql := ` + SELECT t1.jx_store_id store_id, t1.vendor_order_id, t2.status_time, t2.status + FROM goods_order t1 + JOIN order_status t2 ON t2.vendor_order_id = t1.vendor_order_id + where t1.order_finished_at >= ? AND t1.order_finished_at <= ? + AND t1.status = ? + AND t1.waybill_vendor_id = ? + AND t2.status in (?, ?) + ORDER BY t1.vendor_order_id, t2.status_time + ` + beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday) + sqlParams := []interface{}{ + beginTime, + endTime, + model.OrderStatusFinished, + model.VendorIDDada, + model.OrderStatusFinishedPickup, + model.OrderStatusDelivering, + } + + standardTime := int64(600) + var storeOrderStatusList []*model.StoreOrderStatus + storeOrderTimeMapData := make(map[int][]*model.StoreOrderStatus) + err = GetRows(db, &storeOrderStatusList, sql, sqlParams) + if err == nil && len(storeOrderStatusList) > 0 { + for _, value := range storeOrderStatusList { + if storeOrderTimeMapData[value.StoreID] == nil { + storeOrderTimeSubList := []*model.StoreOrderStatus{} + storeOrderTimeMapData[value.StoreID] = storeOrderTimeSubList + } + storeOrderTimeSubList := storeOrderTimeMapData[value.StoreID] + storeOrderTimeSubList = append(storeOrderTimeSubList, value) + } + for storeID, valueList := range storeOrderTimeMapData { + count := 0 + vendorOrderID := "" + statusBeginTime := int64(0) + statusEndTime := int64(0) + for _, value := range valueList { + if vendorOrderID != value.VendorOrderID { + if statusBeginTime != 0 && statusEndTime != 0 { + if statusEndTime-statusBeginTime <= standardTime { + count++ + } + } + vendorOrderID = value.VendorOrderID + statusBeginTime = int64(0) + statusEndTime = int64(0) + } + if value.Status == model.OrderStatusFinishedPickup { + statusBeginTime = value.StatusTime.Unix() + } else if value.Status == model.OrderStatusDelivering { + statusEndTime = value.StatusTime.Unix() + } + } + if statusBeginTime != 0 && statusEndTime != 0 { + if statusEndTime-statusBeginTime <= standardTime { + count++ + } + } + storeCountList = append(storeCountList, &model.StoreCount{storeID, count}) + } + } + + return storeCountList, err +} diff --git a/business/model/store_score.go b/business/model/store_score.go index fe2239216..b9e10857a 100644 --- a/business/model/store_score.go +++ b/business/model/store_score.go @@ -56,6 +56,11 @@ type StoreTotalScore struct { CityName string `orm:"column(city_name)" json:"cityName"` } +type StoreTotalScoreEx struct { + StoreTotalScoreList []*StoreTotalScore `json:"storeTotalScoreList"` + TotalCount int `json:"totalCount"` +} + type StoreCount struct { StoreID int `orm:"column(store_id)"` Count int diff --git a/controllers/cms_store.go b/controllers/cms_store.go index a1d44ee0d..baa99e1aa 100644 --- a/controllers/cms_store.go +++ b/controllers/cms_store.go @@ -462,12 +462,14 @@ func (c *StoreController) GetWeeklyStoreScore() { // @Param token header string true "认证token" // @Param storeIDs formData string false "京西门店ID列表" // @Param cityCode formData int false "城市编码" -// @Param keyWord formData string false "关键字" +// @Param keyword formData string false "关键字" // @Param beginTime formData string true "开始日期" // @Param endTime formData string true "结束日期" // @Param isDesc formData bool true "是否降序" // @Param checkScoreLow formData int false "在某个分数范围-低" // @Param checkScoreHigh formData int false "在某个分数范围-高" +// @Param offset formData int false "列表起始序号(以0开始,缺省为0)" +// @Param pageSize formData int false "列表页大小(缺省为50,-1表示全部)" // @Success 200 {object} controllers.CallResult // @Failure 200 {object} controllers.CallResult // @router /GetStoreTotalScoreList [post] @@ -477,7 +479,7 @@ func (c *StoreController) GetStoreTotalScoreList() { if err == nil { var storeIDList []int if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDList); err == nil { - retVal, err = misc.GetStoreTotalScoreList(storeIDList, params.CityCode, params.KeyWord, timeList[0], timeList[1], params.IsDesc, params.CheckScoreLow, params.CheckScoreHigh) + retVal, err = misc.GetStoreTotalScoreList(storeIDList, params.CityCode, params.Keyword, timeList[0], timeList[1], params.IsDesc, params.CheckScoreLow, params.CheckScoreHigh, params.Offset, params.PageSize) } } return retVal, "", err diff --git a/controllers/temp_op.go b/controllers/temp_op.go index bc3ea66ff..30260038e 100644 --- a/controllers/temp_op.go +++ b/controllers/temp_op.go @@ -341,3 +341,17 @@ func (c *TempOpController) CreateConsumerFromOrders() { return retVal, "", err }) } + +// @Title 触犯红线通知 +// @Description 触犯红线通知 +// @Param token header string true "认证token" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /CheckStoreAlert [post] +func (c *TempOpController) CheckStoreAlert() { + c.callCheckStoreAlert(func(params *tTempopCheckStoreAlertParams) (retVal interface{}, errCode string, err error) { + misc.CheckStoreAlert(params.Ctx) + + return retVal, "", err + }) +} diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index 64d9f5cf2..439d0a4ae 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: "CheckStoreAlert", + Router: `/CheckStoreAlert`, + 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: "CreateConsumerFromOrders",