203 lines
6.6 KiB
Go
203 lines
6.6 KiB
Go
package statistics
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"nCovTrack-Backend/global"
|
|
"nCovTrack-Backend/models"
|
|
"nCovTrack-Backend/utils"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
rds_NCOV_STATISTIC_KEY = "nCovStatistic"
|
|
rds_CHINA_TOTAL_KEY = "chinaTotal"
|
|
rds_CHINA_ADD_KEY = "chinaAdd"
|
|
rds_COUNTRY_LEVEL_KEY = "countryLevel"
|
|
rds_COUNTRY_LEVEL_CHILD_KEY = "countryLevelChild"
|
|
rds_PROVINCE_LEVEL_CHILD_KEY = "provinceLevelChild"
|
|
rds_PROVINCE_LEVEL_NOW_CONFIRM_KEY = "provinceLevelNowConfirm"
|
|
rds_PROVINCE_LEVEL_TODAY_CONFIRM_KEY = "provinceLevelTodayConfirm"
|
|
rds_PROVINCE_LEVEL_TOTAL_CONFIRM_KEY = "provinceLevelTotalConfirm"
|
|
rds_CITY_LEVEL_CHILD_KEY = "cityLevelChild"
|
|
rds_CITY_LEVEL_NOW_CONFIRM_KEY = "cityLevelNowConfirm"
|
|
rds_CITY_LEVEL_TODAY_CONFIRM_KEY = "cityLevelTodayConfirm"
|
|
rds_CITY_LEVEL_TOTAL_CONFIRM_KEY = "cityLevelTotalConfirm"
|
|
rds_LAST_UPDATE_TIME = "statisticsLastUpdateTime"
|
|
rds_LAST_CACHE_TIME = "statisticsLastCacheTime"
|
|
rds_CHINA_DAY_ADD_LIST_KEY = "chinaDayAdd"
|
|
rds_CHINA_DAY_LIST_KEY = "chinaDay"
|
|
|
|
SORT_TODAY_CONFIRM = "today"
|
|
SORT_TOTAL_CONFIRM = "total"
|
|
SORT_NOW_CONFIRM = "now"
|
|
D
|
|
json_FOREIGN_COUNTRY = "境外"
|
|
json_FOREIGN_CITY = "外地"
|
|
json_TO_BE_CONFIRM = "待确认"
|
|
)
|
|
|
|
var (
|
|
sortBy string
|
|
)
|
|
|
|
type AreaSlice []models.AreaInfo
|
|
|
|
func cacheNCovStatistics() {
|
|
resp := utils.GetWhioutHeader(global.CHINA_NCOV_STATISTIC_URL)
|
|
var nCovRes map[string]interface{}
|
|
json.Unmarshal([]byte(resp), &nCovRes)
|
|
nCovResData := (nCovRes["data"].(map[string]interface{}))["diseaseh5Shelf"].(map[string]interface{})
|
|
if !needToRecache(nCovResData) {
|
|
return
|
|
}
|
|
cacheChinaInfo(nCovResData)
|
|
cacheLevelInfo(nCovResData)
|
|
cacheLastUpdateTime(nCovResData)
|
|
resp = utils.GetWhioutHeader(global.CHINA_NCOV_STATISTIC_TREND_URL)
|
|
}
|
|
|
|
func CacheNCovTrend() {
|
|
resp := utils.GetWhioutHeader(global.CHINA_NCOV_STATISTIC_TREND_URL)
|
|
var nCovRes map[string]interface{}
|
|
json.Unmarshal([]byte(resp), &nCovRes)
|
|
nCovResData := nCovRes["data"].(map[string]interface{})
|
|
cacheChinaTrend(nCovResData)
|
|
}
|
|
|
|
func cacheChinaTrend(data map[string]interface{}) {
|
|
chinaDayAdd, _ := json.Marshal(data["chinaDayAddList"])
|
|
chinaDay, _ := json.Marshal(data["chinaDayList"])
|
|
global.Redis.Set(rds_CHINA_DAY_ADD_LIST_KEY, chinaDayAdd, 0)
|
|
global.Redis.Set(rds_CHINA_DAY_LIST_KEY, chinaDay, 0)
|
|
}
|
|
|
|
func cacheChinaInfo(data map[string]interface{}) {
|
|
chinaTotal, _ := json.Marshal(data["chinaTotal"])
|
|
chinaAdd, _ := json.Marshal(data["chinaAdd"])
|
|
global.Redis.Set(rds_CHINA_TOTAL_KEY, chinaTotal, time.Duration(12*time.Hour))
|
|
global.Redis.Set(rds_CHINA_ADD_KEY, chinaAdd, time.Duration(12*time.Hour))
|
|
}
|
|
|
|
func cacheLastUpdateTime(data map[string]interface{}) {
|
|
global.Redis.Set(rds_LAST_UPDATE_TIME, data["lastUpdateTime"], time.Duration(12*time.Hour))
|
|
global.Redis.Set(rds_LAST_CACHE_TIME, time.Now().String(), time.Duration(12*time.Hour))
|
|
}
|
|
|
|
func needToRecache(data map[string]interface{}) bool {
|
|
rdsLastUpdateTime := global.Redis.Get(rds_LAST_UPDATE_TIME).Val()
|
|
newestUpdateTime := fmt.Sprintf("%v", data["lastUpdateTime"])
|
|
return rdsLastUpdateTime != newestUpdateTime
|
|
}
|
|
|
|
func cacheLevelInfo(data map[string]interface{}) {
|
|
areaTree, _ := json.Marshal(data["areaTree"])
|
|
|
|
// Get Every Level's Info
|
|
var countryLevels []models.AreaInfo
|
|
json.Unmarshal(areaTree, &countryLevels)
|
|
provinceLevels := children(countryLevels)
|
|
cityLevels := children(provinceLevels)
|
|
|
|
// Country Level Area Info With Child
|
|
cacheList(rds_COUNTRY_LEVEL_CHILD_KEY, areaInfoToJson(countryLevels)...)
|
|
// Country Level Area Info
|
|
areaInfoChildNil(&countryLevels)
|
|
cacheList(rds_COUNTRY_LEVEL_KEY, areaInfoToJson(countryLevels)...)
|
|
|
|
// Province Level Area Info With Child
|
|
cacheList(rds_PROVINCE_LEVEL_CHILD_KEY, areaInfoToJson(provinceLevels)...)
|
|
areaInfoChildNil(&provinceLevels)
|
|
// City Level Area Info With Child
|
|
cacheList(rds_CITY_LEVEL_CHILD_KEY, areaInfoToJson(cityLevels)...)
|
|
areaInfoChildNil(&provinceLevels)
|
|
|
|
// Province Level Area Info Sorted by Now Confirm
|
|
provinceLevelsSlice := AreaSlice(provinceLevels)
|
|
sort.Sort(provinceLevelsSlice)
|
|
cacheList(rds_PROVINCE_LEVEL_NOW_CONFIRM_KEY, areaInfoToJson(provinceLevelsSlice)...)
|
|
// City Level Area Info Sorted By Now Confirm
|
|
cityLevelsSlice := AreaSlice(cityLevels)
|
|
sort.Sort(cityLevelsSlice)
|
|
cacheList(rds_CITY_LEVEL_NOW_CONFIRM_KEY, areaInfoToJson(cityLevelsSlice)...)
|
|
|
|
sortBy = SORT_TODAY_CONFIRM
|
|
// Province Level Area Info Sorted by Today Confirm
|
|
sort.Sort(provinceLevelsSlice)
|
|
cacheList(rds_PROVINCE_LEVEL_TODAY_CONFIRM_KEY, areaInfoToJson(provinceLevelsSlice)...)
|
|
// City Level Area Info Sorted by Today Confirm
|
|
sort.Sort(cityLevelsSlice)
|
|
cacheList(rds_CITY_LEVEL_TODAY_CONFIRM_KEY, areaInfoToJson(cityLevelsSlice)...)
|
|
|
|
sortBy = SORT_TOTAL_CONFIRM
|
|
// Province Level Area Info Sorted by Total Confirm
|
|
sort.Sort(provinceLevelsSlice)
|
|
cacheList(rds_PROVINCE_LEVEL_TOTAL_CONFIRM_KEY, areaInfoToJson(provinceLevelsSlice)...)
|
|
// City Level Area Info Sorted by Total Confirm
|
|
sort.Sort(cityLevelsSlice)
|
|
cacheList(rds_CITY_LEVEL_TOTAL_CONFIRM_KEY, areaInfoToJson(cityLevelsSlice)...)
|
|
|
|
}
|
|
|
|
func cacheList(key string, values ...interface{}) {
|
|
global.Redis.Del(key)
|
|
global.Redis.RPush(key, values...)
|
|
}
|
|
|
|
func children(parents []models.AreaInfo) []models.AreaInfo {
|
|
var areaInfos []models.AreaInfo
|
|
for _, parent := range parents {
|
|
if parent.Children == nil {
|
|
continue
|
|
}
|
|
for _, item := range parent.Children {
|
|
name := item.Name
|
|
item.Parent = parent.Name
|
|
if !strings.Contains(name, json_FOREIGN_CITY) && !strings.Contains(name, json_FOREIGN_COUNTRY) && !strings.Contains(name, json_TO_BE_CONFIRM) {
|
|
areaInfos = append(areaInfos, item)
|
|
}
|
|
}
|
|
}
|
|
return areaInfos
|
|
}
|
|
|
|
func areaInfoToJson(areaInfos []models.AreaInfo) []interface{} {
|
|
return utils.Map(areaInfos, func(item models.AreaInfo) interface{} {
|
|
jsonByte, _ := json.Marshal(item)
|
|
return jsonByte
|
|
})
|
|
}
|
|
|
|
func areaInfoChildNil(areaInfos *[]models.AreaInfo) {
|
|
utils.ForEach(areaInfos, func(item *models.AreaInfo) {
|
|
item.Children = nil
|
|
})
|
|
}
|
|
|
|
func checkCache() {
|
|
if global.Redis.Get(rds_LAST_UPDATE_TIME).Val() == "" {
|
|
cacheNCovStatistics()
|
|
}
|
|
}
|
|
|
|
func (s AreaSlice) Len() int { return len(s) }
|
|
|
|
func (s AreaSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
|
|
|
func (s AreaSlice) Less(i, j int) bool {
|
|
if sortBy == SORT_TODAY_CONFIRM {
|
|
return s[i].Today.Comfirm > s[j].Today.Comfirm
|
|
}
|
|
if sortBy == SORT_TOTAL_CONFIRM {
|
|
return s[i].Total.Confirm > s[j].Total.Confirm
|
|
}
|
|
// Default sorted by now confirm
|
|
return s[i].Total.NowConfirm > s[j].Total.NowConfirm
|
|
}
|
|
|
|
func CacheNCov() {
|
|
cacheNCovStatistics()
|
|
}
|