/// <summary> /// 获取指定据点的评分 /// </summary> /// <param name="pointId">据点 ID</param> /// <exception cref="ArgumentNullException"><paramref name="pointId"/> 为 null</exception> /// <returns>据点评分</returns> public async Task <PointRatingsDto> GetRatingsAsync([NotNull] string pointId) { if (pointId == null) { throw new ArgumentNullException(nameof(pointId)); } var cacheKey = RatingCacheKey(pointId); var redisDb = _redis.GetDatabase(); var cacheResult = await redisDb.StringGetAsync(cacheKey); if (cacheResult.HasValue) { return(RedisProvider.Deserialize <PointRatingsDto>(cacheResult)); } var ratings = new PointRatingsDto(); var userRatings = new Dictionary <string, UserRating>(); foreach (var ratingEntry in await _dbContext.Articles .Where(a => a.TargetPointId == pointId && a.Rating != null && a.Archived == ArchivedState.None && a.Rejected == false) .Select(a => new { a.AuthorId, a.Rating }) .Union(_dbContext.Activities .Where(a => a.TargetPointId == pointId && a.Rating != null) .Select(a => new { a.AuthorId, a.Rating })) .ToListAsync()) { switch (ratingEntry.Rating.Value) { case 1: ratings.OneStarCount++; break; case 2: ratings.TwoStarCount++; break; case 3: ratings.ThreeStarCount++; break; case 4: ratings.FourStarCount++; break; case 5: ratings.FiveStarCount++; break; default: continue; } UserRating userRating; if (!userRatings.TryGetValue(ratingEntry.AuthorId, out userRating)) { userRatings[ratingEntry.AuthorId] = userRating = new UserRating(); } userRating.Count++; userRating.Total += ratingEntry.Rating.Value; } ratings.AverageRating = userRatings.Count < 3 ? (double?)null : Math.Round(userRatings.Values.Sum(r => r.Total * 2 / (double)r.Count) / userRatings.Count, 1); await redisDb.StringSetAsync(cacheKey, RedisProvider.Serialize(ratings), RatingUpdatePeriod); return(ratings); }