using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using VOL.Entity.DomainModels;
using YD_WeChatApplet.Api.Entitys;
using YD_WeChatApplet.Api.SmartSportsEntitys;
using YD_WeChatApplet.Api.Utilities;
using YD_WeChatApplet.Commons.Dto;
using YD_WeChatApplet.Commons.Dto.ClientSide;
using YD_WeChatApplet.Commons.Dto.HomeWork;
using YD_WeChatApplet.Commons.Dto.Patriarch;
using YD_WeChatApplet.Commons.Dto.Resource;
using YD_WeChatApplet.Commons.Dto.School;
using YD_WeChatApplet.Commons.Dto.SportsTest;
using YD_WeChatApplet.Commons.Dto.Teacher;
using YD_WeChatApplet.Commons.Enum;
using YD_WeChatApplet.Commons.Utils;
using YD_WeChatApplet.Context;
using YD_WeChatApplet.Services;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
namespace YD_WeChatApplet.Api.Services.Impl
{
///
/// 用户端
///
public class ClientSideService : IClientSideService
{
public UserContext _userContext;
public SmartSportsContext _sportsContext;
private readonly IMapper _mapper;
public ClientSideService(UserContext userContext, SmartSportsContext sportsContext, IMapper mapper)
{
_userContext = userContext;
_sportsContext = sportsContext;
_mapper = mapper;
}
///
/// 获取场馆列表
///
///
///
///
public async Task> StadiumList(GetStadiumListDto dto)
{
//double centerLat = dto.Latitude;
//double centerLng = dto.Longitude;
//double radiusInKm = 10.0;
var query = _sportsContext.Stadium;
//.Where(x =>
// 6371 * 2 * Math.Asin(Math.Sqrt(
// Math.Pow(Math.Sin((x.Latitude - centerLat) * Math.PI / 180 / 2), 2) +
// Math.Cos(centerLat * Math.PI / 180) *
// Math.Cos(x.Latitude * Math.PI / 180) *
// Math.Pow(Math.Sin((x.Longitude - centerLng) * Math.PI / 180 / 2), 2)
// )) <= radiusInKm
//);
var totalCount = await query.CountAsync();
var list = await query
.Select(x => new StadiumListDto
{
Id = x.Id,
StadiumName = x.StadiumName,
Address = x.Address,
CoverImage = x.StadiumResourceList.Select(x => x.Url).FirstOrDefault(),
Latitude = x.Latitude,
Longitude = x.Longitude
})
.Skip((dto.PageIndex - 1) * dto.PageSize)
.Take(dto.PageSize)
.ToListAsync();
return new PageDataDto
{
Total = totalCount,
Datas = list
};
}
///
/// 场馆详情
///
///
///
public async Task StadiumDetails(int stadiumId)
{
var res = await _sportsContext.Stadium.Where(x => x.Id == stadiumId).Select(x => new StadiumDetailsDto()
{
Id = x.Id,
StadiumName = x.StadiumName,
Address = x.Address,
CoverImage = x.CoverImage,
Intro = x.Intro,
Latitude = x.Latitude,
Longitude = x.Longitude,
PhoneNo = x.PhoneNo,
StadiumResourceList = x.StadiumResourceList.Select(x => new StadiumResourceDto()
{
Id = x.Id,
Type = x.Type,
Url = x.Url
}).ToList()
}).FirstOrDefaultAsync();
return res;
}
///
/// 教学类别
///
///
public async Task> CurricularTaxonomyList()
{
var res = await _sportsContext.CurricularTaxonomy.Where(x => x.CurricularType == 1).Select(x => new ComboBoxDto()
{
Id = x.Id,
Name = x.TaxonomyName
}).ToListAsync();
return res;
}
///
/// 付费课程
///
///
public async Task> PaidCoursesList()
{
var userId = UserLoginContext.Current.UserId;
var paidCourses = await _sportsContext.CurricularPurchaseRecord.Where(x => x.UserId == userId).ToListAsync();
var res = await _sportsContext.CurricularTaxonomy.Where(x => x.CurricularType == 2).Select(x => new PaidCoursesListDto()
{
Id = x.Id,
Name = x.TaxonomyName,
IsPurchase = paidCourses.Any(x => x.TaxonomyId == x.Id)
}).ToListAsync();
return res;
}
///
/// 付费课程购买
///
///
public async Task PaidCoursesBuy(string redeemCode)
{
var paidCoursesList = new List();
var paidCourses = await _sportsContext.CurricularTaxonomy.Where(x => x.CurricularType == 2).ToListAsync();
foreach (var paidCourse in paidCourses)
{
paidCoursesList.Add(new Y_CurricularPurchaseRecord()
{
TaxonomyId = paidCourse.Id,
UserId = UserLoginContext.Current.UserId,
RedeemCode = redeemCode,
Remarks = "",
CreateDate = DateTime.Now
});
}
await _sportsContext.AddRangeAsync(paidCoursesList);
return await _sportsContext.SaveChangesAsync() > 0;
}
///
/// 教学列表
///
///
///
public async Task> CurricularList(CurricularDto dto)
{
var query = _sportsContext.Curricular;
var totalCount = await query.CountAsync();
var list = await query
.Select(x => new CurricularListDto()
{
Id = x.Id,
TaxonomyId = x.TaxonomyId,
CurricularName = x.CurricularName,
CoverImage = x.CoverImage,
Hits = x.Hits,
Url = x.Url
}).Where(x => x.TaxonomyId == dto.TaxonomyId)
.Skip((dto.PageIndex - 1) * dto.PageSize)
.Take(dto.PageSize)
.ToListAsync();
return new PageDataDto
{
Total = totalCount,
Datas = list
};
}
///
/// 热门视频
///
///
public async Task> PopularCurricularList()
{
var res = await _sportsContext.PopularCurricular
.Join(_sportsContext.Curricular, a => a.CurricularId, s => s.Id, (a, s) => new CurricularListDto()
{
Id = a.Id,
CurricularName = s.CurricularName,
CoverImage = s.CoverImage,
Url = s.Url,
Hits = s.Hits
}).ToListAsync();
return res;
}
///
/// 视频播放
///
///
///
public async Task VideoPlay(int curricularId)
{
var entity = await _sportsContext.Curricular.Where(x => x.Id == curricularId).FirstAsync();
entity.Hits = entity.Hits + 1;
_sportsContext.Curricular.Update(entity);
await _sportsContext.SaveChangesAsync();
}
///
/// 场馆预约
///
///
///
public async Task StadiumVisiting(int stadiumId)
{
if (stadiumId == 0)
throw new Exception("场馆信息有误");
var userId = UserLoginContext.Current.UserId;
var user = await _userContext.Users.FirstAsync(x => x.User_Id == userId);
var stadiumVisiting = await _sportsContext.StadiumVisiting.FirstOrDefaultAsync(x => x.PhoneNo == user.PhoneNo && x.StadiumId == stadiumId);
if (stadiumVisiting == null)
{
var entity = new Y_StadiumVisiting()
{
StadiumId = stadiumId,
Status = 1,
PhoneNo = user.PhoneNo,
UserName = user.UserTrueName,
VisitingTime = DateTime.Now
};
await _sportsContext.StadiumVisiting.AddAsync(entity);
await _sportsContext.SaveChangesAsync();
}
}
///
/// 各项目排行
///
///
///
public async Task> Ranking(int categoryId)
{
var res = await _userContext.ExerciseData
.Where(x => x.WorkType == categoryId)
.GroupBy(x => x.UserId)
.Select(g => new RankingDto()
{
UserId = g.Key,
UserName = g.FirstOrDefault().UserName,
Value = g.Sum(x => x.Amount ?? 0)
})
.OrderByDescending(x => x.Value)
.ToListAsync();
return res;
}
///
/// 文章列表
///
///
///
public async Task> Articles(PageDto dto)
{
//try
//{
// // 获取 access_token
// var accessToken = await GetAccessTokenAsync();
// int offset = dto.PageIndex - 1 == 0 ? 0 : (dto.PageIndex - 1) * dto.PageSize - 1;
// // 获取文章列表
// var articles = await GetArticlesAsync(accessToken, offset, dto.PageSize);
// // 返回文章列表数据
// return new { articles };
//}
//catch (Exception ex)
//{
// return new { message = "Error retrieving articles", error = ex.Message };
//}
var res = new PageDataDto();
res.Total = await _sportsContext.Article.CountAsync();
var data = await _sportsContext.Article.Select(x => new ArticlesDto()
{
Id = x.Id,
Abstract = x.Abstract,
ArticleUrl = x.ArticleUrl,
CoverImage = x.CoverImage,
Title = x.Title,
UpdateDate = x.UpdateDate
})
.OrderByDescending(x => x.UpdateDate)
.Skip((dto.PageIndex - 1) * dto.PageSize)
.Take(dto.PageSize)
.ToListAsync();
res.Datas = data;
return res;
}
///
/// 创建群组
///
///
///
public async Task CreateUserGruop(CreateUserGruopDto dto)
{
using var transaction = await _userContext.Database.BeginTransactionAsync();
try
{
var userId = UserLoginContext.Current.UserId;
var entity = new WCA_UserGroup()
{
GroupName = dto.GroupName,
UserId = userId,
CreaterId = userId,
CreateTime = DateTime.Now
};
await _userContext.UserGroup.AddAsync(entity);
await _userContext.SaveChangesAsync();
//var user = await _userContext.Users.FirstAsync(x => x.User_Id == userId);
var member = new WCA_GroupMembers()
{
UserId = userId,
//HeadImageUrl = user.HeadImageUrl,
//NickName = user.UserTrueName ?? "",
UserGroupId = entity.Id,
//PhoneNo = user.PhoneNo,
CreateTime = DateTime.Now,
};
await _userContext.GroupMembers.AddAsync(member);
await _userContext.SaveChangesAsync();
await transaction.CommitAsync();
}
catch
{
await transaction.RollbackAsync();
throw;
}
}
///
/// 获取群组列表
///
///
///
public async Task> GetUserGruop(GetUserGruopDto dto)
{
var userId = UserLoginContext.Current.UserId;
var res = new PageDataDto();
IQueryable query;
if (dto.IsCreated)
{
// 查询我创建的群组
query = _userContext.UserGroup.Where(x => x.UserId == userId);
}
else
{
// 1. 先查询我加入的所有群组ID
var joinedGroupIds = await _userContext.GroupMembers
.Where(x => x.UserId == userId)
.Select(x => x.UserGroupId)
.ToListAsync();
if (!joinedGroupIds.Any())
return new PageDataDto();
// 2. 再查询我创建的群组ID
var createdGroupIds = await _userContext.UserGroup
.Where(x => x.UserId == userId)
.Select(x => x.Id)
.ToListAsync();
// 3. 使用Except排除我创建的群组
var filteredGroupIds = joinedGroupIds.Except(createdGroupIds).ToList();
if (!filteredGroupIds.Any())
return new PageDataDto();
// 4. 最终查询:我加入但不是我创建的群组
query = _userContext.UserGroup.Where(x => filteredGroupIds.Contains(x.Id));
}
// 分页逻辑保持不变
res.Total = await query.CountAsync();
res.Datas = await query
.Select(x => new UserGruopDto
{
GroupId = x.Id,
GroupName = x.GroupName,
MemberCount = _userContext.GroupMembers.Count(gm => gm.UserGroupId == x.Id)
})
.OrderByDescending(x => x.GroupId)
.Skip((dto.PageIndex - 1) * dto.PageSize)
.Take(dto.PageSize)
.ToListAsync();
return res;
}
///
/// 是否再群组中
///
///
///
public async Task IsInGroup(int groupId)
{
var userId = UserLoginContext.Current.UserId;
var any = await _userContext.GroupMembers.AnyAsync(x => x.UserId == userId && x.UserGroupId == groupId);
return any;
}
///
/// 加入群组
///
///
///
public async Task JoinGroup(int groupId)
{
var userId = UserLoginContext.Current.UserId;
var any = await _userContext.GroupMembers.AnyAsync(x => x.UserId == userId && x.UserGroupId == groupId);
if (any)
{
return;
}
if (groupId == 0)
throw new Exception("未找到组Id");
//var user = await _userContext.Users.FirstAsync(x => x.User_Id == userId);
var entity = new WCA_GroupMembers()
{
UserId = userId,
//HeadImageUrl = user.HeadImageUrl,
//NickName = user.UserTrueName ?? "",
UserGroupId = groupId,
//PhoneNo = user.PhoneNo,
CreateTime = DateTime.Now,
};
await _userContext.GroupMembers.AddAsync(entity);
await _userContext.SaveChangesAsync();
}
///
/// 群成员列表
///
///
///
public async Task> GetMembers(GetMembersDto dto)
{
var res = new PageDataDto();
var nowTime = DateTime.Now;
var group = await _userContext.UserGroup.FirstAsync(gm => gm.Id == dto.GroupId);
var query = _userContext.GroupMembers.Join(_userContext.Users, x => x.UserId, u => u.User_Id, (x, u) => new MembersDto
{
GroupName = group.GroupName,
UserId = x.UserId,
UserGroupId = x.UserGroupId,
HeadImageUrl = u.HeadImageUrl,
NickName = u.UserTrueName,
PhoneNo = u.PhoneNo,
CreateTime = x.CreateTime
}).Where(x => x.UserGroupId == dto.GroupId);
res.Total = await query.CountAsync();
res.Datas = await query
.OrderByDescending(x => x.CreateTime)
.Skip((dto.PageIndex - 1) * dto.PageSize)
.Take(dto.PageSize)
.ToListAsync();
return res;
}
///
/// 创建群组任务
///
///
///
public async Task CreateGroupTask(CreateGroupTaskDto dto)
{
List taskEntities = new List();
DateTime startDate = dto.StartTime;
DateTime endDate = dto.EndTime;
var weekList = dto.WeekList;
if (dto.IsRepeat)
{
for (var currentDate = startDate; currentDate <= endDate; currentDate = currentDate.AddDays(1))
{
if (weekList.Contains(((int)currentDate.DayOfWeek == 0 ? 7 : (int)currentDate.DayOfWeek)))
{
var taskEntity = _mapper.Map(dto);
taskEntity.CreateTime = DateTime.Now;
taskEntity.WorkText = "";
taskEntity.CreateTime = DateTime.Now;
taskEntity.StartTime = currentDate.Date;
taskEntity.RepetitionPeriod = string.Join(',', weekList);
taskEntity.EndTime = currentDate.Date.AddDays(1).AddSeconds(-1);
taskEntities.Add(taskEntity);
}
}
}
else
{
var taskEntity = _mapper.Map(dto);
taskEntity.CreateTime = DateTime.Now;
taskEntity.WorkText = "";
taskEntity.StartTime = startDate;
taskEntity.RepetitionPeriod = "1";
taskEntity.EndTime = endDate;
taskEntities.Add(taskEntity);
}
await _userContext.GroupTask.AddRangeAsync(taskEntities);
await _userContext.SaveChangesAsync();
}
///
/// 删除群组任务
///
///
///
public async Task DeleteGroupTask(int groupTaskId)
{
var nowTime = DateTime.Now;
var model = await _userContext.GroupTask.Where(x => x.Id == groupTaskId).FirstOrDefaultAsync();
if (model == null)
throw new Exception("未找到符合条件的群任务!");
_userContext.GroupTask.Remove(model);
await _userContext.SaveChangesAsync();
}
///
/// 获取群任务列表
///
///
///
public async Task> GetGroupTasks(GetGroupTaskDto dto)
{
var res = new PageDataDto();
var nowTime = DateTime.Now;
var query = _userContext.GroupTask.Where(x => x.UserGroupId == dto.GroupId)
.Select(x => new GroupTaskDto
{
Id = x.Id,
Amount = x.Amount,
Duration = x.Duration,
StartTime = x.StartTime,
EndTime = x.EndTime,
GroupTaskName = x.GroupTaskName,
IsRepeat = x.IsRepeat,
RepetitionPeriod = x.RepetitionPeriod,
WorkModeType = x.WorkModeType,
WorkModeTypeName = x.WorkModeTypeName,
Status = dto.Status
});
switch (dto.Status)
{
case 1:
query = query.Where(x => x.StartTime < nowTime && x.EndTime > nowTime);
break;
case 2:
query = query.Where(x => x.StartTime > nowTime);
break;
case 3:
query = query.Where(x => x.EndTime < nowTime);
break;
}
res.Total = await query.CountAsync();
res.Datas = await query
.OrderByDescending(x => x.Id)
.Skip((dto.PageIndex - 1) * dto.PageSize)
.Take(dto.PageSize)
.ToListAsync();
return res;
}
///
/// 获取群任务详情
///
///
///
public async Task GetGroupTaskDetails(int groupTaskId)
{
var res = _userContext.GroupTask.Where(x => x.Id == groupTaskId).Select(x => new GroupTaskDetailsDto()
{
Id = x.Id,
Amount = x.Amount,
CreateTime = x.CreateTime,
Duration = x.Duration,
EndTime = x.EndTime,
GroupNumber = x.GroupNumber,
GroupTaskName = x.GroupTaskName,
IsRepeat = x.IsRepeat,
RepetitionPeriod = x.RepetitionPeriod,
StartTime = x.StartTime,
WorkModeType = x.WorkModeType,
WorkModeTypeName = x.WorkModeTypeName,
WorkText = x.WorkText,
WorkTypeName = x.WorkTypeName
}).FirstOrDefault();
return res;
}
///
/// 添加团队运动成绩
///
///
///
public async Task AddGroupTaskResult(AddGroupTaskResultDto dto)
{
var userId = UserLoginContext.Current.UserId;
var user = await _userContext.Users.Where(x => x.User_Id == userId).Select(x => new { x.User_Id, x.UserTrueName, x.HeadImageUrl }).FirstAsync();
if (dto.WorkModeType == WorkModeType.CountTimer || dto.WorkModeType == WorkModeType.TimerCount)
{
var entity = new WCA_GroupTaskResult()
{
UserId = userId,
DataSource = dto.DataSource,
Amount = dto.Amount,
Duration = dto.Duration,
GroupTaskId = dto.GroupTaskId,
WorkModeType = dto.WorkModeType,
WorkModeTypeName = dto.WorkModeTypeName,
//NickName = user.UserTrueName,
//HeadImageUrl = user.HeadImageUrl,
CreateTime = DateTime.Now
};
await _userContext.AddAsync(entity);
await _userContext.SaveChangesAsync();
return new TaskResultDto() { TaskResultId = entity.Id };
}
else
{
var taskResult = await _userContext.GroupTaskResult.Where(x => x.UserId == userId && x.GroupTaskId == dto.GroupTaskId).FirstOrDefaultAsync();
if (taskResult == null)
{
var entity = new WCA_GroupTaskResult()
{
UserId = userId,
Amount = dto.Amount,
Duration = dto.Duration,
GroupTaskId = dto.GroupTaskId,
WorkModeType = dto.WorkModeType,
WorkModeTypeName = dto.WorkModeTypeName,
CreateTime = DateTime.Now
};
await _userContext.AddAsync(entity);
await _userContext.SaveChangesAsync();
return new TaskResultDto() { TaskResultId = entity.Id };
}
else
{
taskResult.Duration += dto.Duration;
taskResult.Amount += dto.Amount;
_userContext.GroupTaskResult.Update(taskResult);
await _userContext.SaveChangesAsync();
return new TaskResultDto() { TaskResultId = taskResult.Id };
}
}
}
///
/// 获取成绩列表
///
///
///
public async Task GetGroupTaskResult(GetGroupTaskResultDto dto)
{
var userId = UserLoginContext.Current.UserId;
var res = new GroupTaskResultDto();
// 获取组任务基本信息
var groupTask = await _userContext.GroupTask
.Where(x => x.Id == dto.GroupTaskId)
.Select(x => new { x.WorkModeType, x.Amount, x.Duration })
.FirstAsync();
res.TeamGoal = groupTask.WorkModeType == WorkModeType.TimerCount || groupTask.WorkModeType == WorkModeType.GroupCount
? groupTask.Amount
: groupTask.Duration;
// 获取结果列表
var resultList = await _userContext.GroupTaskResult
.Where(x => x.GroupTaskId == dto.GroupTaskId)
.Join(_userContext.Users,
x => x.UserId,
u => u.User_Id,
(x, u) => new TaskResultListDto
{
UserId = x.UserId,
HeadImageUrl = u.HeadImageUrl,
NickName = u.UserTrueName,
Amount = x.Amount,
Duration = x.Duration
})
.ToListAsync();
if (!resultList.Any())
{
return res;
}
// 根据工作模式排序并计算排名
var isAmountBased = groupTask.WorkModeType == WorkModeType.TimerCount
|| groupTask.WorkModeType == WorkModeType.GroupCount;
var sortedQuery = isAmountBased
? resultList.OrderByDescending(x => x.Amount).ToList()
: resultList.OrderByDescending(x => x.Duration).ToList();
// 分配排名
for (int i = 0; i < sortedQuery.Count; i++)
{
sortedQuery[i].Ranking = i + 1;
}
// 设置用户特定信息
var userResult = sortedQuery.FirstOrDefault(x => x.UserId == userId);
res.CurrentRanking = sortedQuery
.FindIndex(x => x.UserId == userId) + 1;
res.NickName = userResult?.NickName ?? "";
res.HeadImageUrl = userResult?.HeadImageUrl ?? "";
// 计算完成度和贡献值
res.Complete = isAmountBased
? sortedQuery.Sum(x => x.Amount)
: sortedQuery.Sum(x => x.Duration);
res.Contribute = isAmountBased
? userResult?.Amount ?? 0
: userResult?.Duration ?? 0;
res.TaskResults = sortedQuery;
return res;
}
///
/// 统计汇总
///
///
///
public async Task AggregateStatistics(GetAggregateStatisticsDto dto)
{
var userId = UserLoginContext.Current.UserId;
var res = new AggregateStatisticsDto();
var groupResults = await _userContext.GroupTaskResult.Where(x => x.UserId == userId).Select(x => new
{
x.Duration,
x.Amount,
x.CreateTime
}).ToListAsync();
var personalResults = await _userContext.PersonalGoalResult.Where(x => x.UserId == userId).Select(x => new
{
x.Duration,
x.Amount,
x.CreateTime
}).ToListAsync();
var results = groupResults.Concat(personalResults);
res.AccumulatedDuration = results.Sum(x => x.Duration);
res.AccumulatedCount = results.Sum(x => x.Amount);
res.AccumulatedConsume = res.AccumulatedCount / 10;
// 根据周期类型确定时间范围
var now = DateTime.Now;
var culture = CultureInfo.CurrentCulture;
DateTime startDate;
// 结束时间设为明天零点
DateTime endDate = now.Date.AddDays(1);
switch (dto.CycleType)
{
case CycleType.Day: // 日
startDate = now.Date;
break;
case CycleType.Week: // 周
startDate = now.Date.AddDays(-(int)now.DayOfWeek + 1); // 本周一(调整为周一到周日)
break;
case CycleType.Month: // 月
startDate = new DateTime(now.Year, now.Month, 1);
break;
case CycleType.Year: // 年
startDate = new DateTime(now.Year, 1, 1);
break;
default:
startDate = DateTime.MinValue;
break;
}
results = results.Where(x => x.CreateTime >= startDate && x.CreateTime <= endDate).ToList();
// 根据周期类型进行分组并优化显示格式
var groupedData = dto.CycleType switch
{
// 日:按小时分组 (0-23),格式:2024-03-16/1
CycleType.Day => results.GroupBy(x => x.CreateTime.Hour)
.OrderBy(g => g.Key)
.Select(g => new
{
//TimePeriod = $"{now:yyyy-MM-dd}/{g.Key}",
TimePeriod = $"{g.Key}:00",
Count = g.Sum(x => x.Amount),
Duration = g.Sum(x => x.Duration),
}).ToList(),
// 周:按星期几分组 (1-7 对应周一到周日),显示本地化星期名称
CycleType.Week => Enumerable.Range(1, 7) // 确保显示完整的周一到周日
.Select(day => new
{
DayOfWeek = day,
DayName = culture.DateTimeFormat.GetDayName((DayOfWeek)(day % 7)),
Data = results.Where(x => (int)x.CreateTime.DayOfWeek == day % 7)
})
.Select(g => new
{
TimePeriod = g.DayName,
Count = g.Data.Sum(x => x.Amount),
Duration = g.Data.Sum(x => x.Duration),
}).ToList(),
// 月:按日分组,格式:2025-03-06
CycleType.Month => results.GroupBy(x => x.CreateTime.Day)
.OrderBy(g => g.Key)
.Select(g => new
{
TimePeriod = $"{now:yyyy-MM}-{g.Key:D2}",
Count = g.Sum(x => x.Amount),
Duration = g.Sum(x => x.Duration),
}).ToList(),
// 年:按月分组,显示本地化月份名称(一月、二月...)
CycleType.Year => Enumerable.Range(1, 12) // 确保显示完整的12个月
.Select(month => new
{
Month = month,
MonthName = culture.DateTimeFormat.GetMonthName(month),
Data = results.Where(x => x.CreateTime.Month == month)
})
.Select(g => new
{
TimePeriod = g.MonthName,
Count = g.Data.Sum(x => x.Amount),
Duration = g.Data.Sum(x => x.Duration),
}).ToList()
};
res.ChartDataByCount = new ChartDataDto
{
AxisX = groupedData.Select(x => x.TimePeriod).ToList(),
AxisY = groupedData.Select(x => x.Count).ToList()
};
res.ChartDataByDuration = new ChartDataDto
{
AxisX = groupedData.Select(x => x.TimePeriod).ToList(),
AxisY = groupedData.Select(x => x.Duration).ToList()
};
res.ChartDataByConsume = new ChartDataDto
{
AxisX = groupedData.Select(x => x.TimePeriod).ToList(),
AxisY = groupedData.Select(x => x.Count / 10).ToList()
};
res.TotalCount = results.Sum(x => x.Amount);
res.BestResult = results.Select(x => x.Amount).DefaultIfEmpty(0).Max();
return res;
}
///
/// 运动记录
///
///
///
public async Task> SportsRecord(PageDto dto)
{
var userId = UserLoginContext.Current.UserId;
//var groupList = await _userContext.GroupTaskResult
// .Join(_userContext.GroupTask, r => r.GroupTaskId, t => t.Id, (r, t) => new SportsRecordDto
// {
// UserId = r.UserId,
// Count = r.Amount,
// CreateTime = r.CreateTime,
// Duration = r.Duration,
// Consume = r.Amount / 10,
// GroupTaskName = t.GroupTaskName,
// })
// .Where(x => x.UserId == userId).ToListAsync();
var groupQueryss = await _userContext.GroupTaskResult.Where(x => x.UserId == userId).Select(x => new SportsRecordDto
{
UserId = x.UserId,
Count = x.Amount,
CreateTime = x.CreateTime,
Duration = x.Duration,
Consume = x.Amount / 10,
GroupTaskName = "团队训练"
}).ToListAsync();
var personalQuerysss = await _userContext.PersonalGoalResult.Where(x => x.UserId == userId).Select(x => new SportsRecordDto
{
UserId = x.UserId,
Count = x.Amount,
CreateTime = x.CreateTime,
Duration = x.Duration,
Consume = x.Amount / 10,
GroupTaskName = x.PersonalGoalName
}).ToListAsync();
var combinedData = groupQueryss.Concat(personalQuerysss);
return new PageDataDto
{
Total = combinedData.Count(),
Datas = combinedData
.OrderByDescending(x => x.CreateTime)
.Skip((dto.PageIndex - 1) * dto.PageSize)
.Take(dto.PageSize)
.ToList()
};
//var totalCounts = combinedQuerys.Count();
//var groupQuery = _userContext.GroupTaskResult.Where(x => x.UserId == userId).Select(x => new SportsRecordDto
//{
// UserId = x.UserId,
// Count = x.Amount,
// CreateTime = x.CreateTime,
// Duration = x.Duration,
// Consume = x.Amount / 10,
// GroupTaskName = "团队训练"
//});
//var personalQuery = _userContext.PersonalGoalResult.Where(x => x.UserId == userId).Select(x => new SportsRecordDto
//{
// UserId = x.UserId,
// Count = x.Amount,
// CreateTime = x.CreateTime,
// Duration = x.Duration,
// Consume = x.Amount / 10,
// GroupTaskName = x.PersonalGoalName
//});
//var combinedQuery = groupQuery.Concat(personalQuery);
//var totalCount = await combinedQuery.CountAsync();
//var list = await combinedQuery
// .OrderByDescending(x => x.CreateTime)
// .Skip((dto.PageIndex - 1) * dto.PageSize)
// .Take(dto.PageSize)
// .ToListAsync();
//return new PageDataDto
//{
// Total = totalCount,
// Datas = list
//};
}
///
/// 创建个人目标
///
///
///
public async Task CreatePersonalGoal(CreatePersonalGoalDto dto)
{
var userId = UserLoginContext.Current.UserId;
var today = DateTime.Now.Date;
var personalGoal = await _userContext.PersonalGoal
.FirstOrDefaultAsync(x => x.GoalDate.Date == today && x.UserId == userId);
if (personalGoal == null)
{
var entity = new WCA_PersonalGoal()
{
UserId = userId,
GoalDuration = dto.GoalDuration,
GoalAmount = dto.GoalAmount,
GoalDate = dto.GoalDate.Date,
};
await _userContext.AddAsync(entity);
}
else
{
personalGoal.GoalDuration = dto.GoalDuration;
personalGoal.GoalAmount = dto.GoalAmount;
_userContext.Update(personalGoal);
}
await _userContext.SaveChangesAsync();
}
///
/// 获取个人目标
///
///
public async Task CetPersonalGoal()
{
var res = new CetPersonalGoalDto();
var userId = UserLoginContext.Current.UserId;
var today = DateTime.Now.Date;
var personalGoals = await _userContext.PersonalGoal
.Join(_userContext.PersonalGoalResult, a => a.Id, s => s.PersonalGoalId, (a, s) => new
{
a.GoalAmount,
a.GoalDate,
a.GoalDuration,
s.PersonalGoalName,
s.PersonalGoalType,
s.Amount,
s.PersonalGoalId,
s.Duration,
s.CreateTime,
s.WorkModeType,
s.UserId
}).Where(x => x.UserId == userId).ToListAsync();
var personalGoal = await _userContext.PersonalGoal.Where(x => x.GoalDate.Date == today && x.UserId == userId).FirstOrDefaultAsync();
var teamData = await _userContext.GroupTaskResult.Where(x => x.UserId == userId).Select(x => new { x.CreateTime, x.Amount }).ToListAsync();
var personData = await _userContext.PersonalGoalResult.Where(x => x.UserId == userId).Select(x => new { x.CreateTime, x.Amount }).ToListAsync();
if (personalGoal != null)
{
res.GoalAmount = personalGoal.GoalAmount;
res.CompletedCount = teamData.Where(x => x.CreateTime.Date == today).Sum(x => x.Amount) + personData.Where(x => x.CreateTime.Date == today).Sum(x => x.Amount);
res.CompletionRate = res.GoalAmount > 0 ? $"{(decimal)res.CompletedCount / res.GoalAmount * 100:F0}%" : "0%";
}
// 取最新的一条
var concatData = teamData.Concat(personData).OrderByDescending(x => x.CreateTime).ToList();
res.LastCount = concatData.FirstOrDefault()?.Amount ?? 0;
res.AccumulatedCount = concatData.Sum(x => x.Amount);
var userGoals = personalGoals
.OrderBy(x => x.GoalDate)
.GroupBy(x => x.GoalDate.Date)
.Select(g => new
{
Date = g.Key,
TotalAmount = g.Sum(x => x.Amount),
GoalAmount = g.First().GoalAmount,
Achieved = g.Sum(x => x.Amount) >= g.First().GoalAmount
})
.OrderBy(d => d.Date)
.ToList();
int currentStreak = 0;
DateTime? prevDay = null;
foreach (var day in userGoals.OrderByDescending(d => d.Date))
{
if (prevDay == null && !day.Achieved)
{
currentStreak = 0;
break;
}
if (day.Achieved)
{
if (prevDay == null)
{
currentStreak = 1;
}
else if ((prevDay.Value - day.Date).Days == 1)
{
currentStreak++;
}
else
{
break;
}
}
else
{
currentStreak = 0;
break;
}
prevDay = day.Date;
}
res.ContinuousDays = currentStreak;
return res;
}
///
/// 添加个人目标数据
///
///
///
public async Task AddPersonalGoalResult(AddPersonalGoalResultDto dto)
{
var userId = UserLoginContext.Current.UserId;
var today = DateTime.Now.Date;
var personalGoal = await _userContext.PersonalGoal
.FirstOrDefaultAsync(x => x.GoalDate.Date == today && x.UserId == userId);
var entity = new WCA_PersonalGoalResult()
{
UserId = userId,
DataSource = dto.DataSource,
Amount = dto.Amount,
Score = dto.Score,
PersonalGoalType = dto.PersonalGoalType,
Duration = dto.Duration,
PersonalGoalName = dto.PersonalGoalName,
PersonalGoalId = personalGoal?.Id ?? 0,
WorkModeType = dto.WorkModeType,
WorkModeTypeName = dto.WorkModeTypeName,
CreateTime = DateTime.Now
};
await _userContext.AddAsync(entity);
await _userContext.SaveChangesAsync();
return new TaskResultDto() { TaskResultId = entity.Id };
}
///
/// 获取得分和等级
///
///
///
public async Task CetPersonalScoreRank(CetPersonalScoreRankDto dto)
{
var healthStandard = await _sportsContext.HealthStandards.Where(x =>
x.CategoryEnum == "OneMinuteJumpRope" &&
x.GradeId == dto.GradeId &&
x.Sex == dto.Sex &&
dto.Amount >= x.MinValue &&
dto.Amount < x.MaxValue
).FirstOrDefaultAsync();
return new PersonalScoreRankDto()
{
Score = healthStandard?.Score ?? 0,
Rank = healthStandard?.Rank ?? ""
};
}
///
/// 获取地区项目时长
///
///
public async Task> CetAreaCategory()
{
var healthStandard = await _sportsContext.AreaCategory.Select(x => new AreaCategoryDto()
{
Id = x.Id,
Area = x.Area,
Duration = x.Duration
}).ToListAsync();
return healthStandard;
}
///
/// 获取中考得分
///
///
///
public async Task CetAreaCategoryScoreRank(CetAreaCategoryScoreRankDto dto)
{
var healthStandard = await _sportsContext.AreaStandards.Where(x =>
x.AreaCategoryId == dto.AreaId &&
x.Sex == dto.Sex &&
dto.Amount >= x.MinValue &&
dto.Amount < x.MaxValue
).FirstOrDefaultAsync();
return new PersonalScoreRankDto()
{
Score = healthStandard?.Score ?? 0,
Rank = healthStandard?.Rank ?? ""
};
}
///
/// 获取打卡记录
///
///
///
public async Task> CetCheckInRecord(CetCheckInRecordDto dto)
{
var userId = UserLoginContext.Current.UserId;
var dailyGoals = await _userContext.PersonalGoal
.Where(g => g.UserId == userId && g.GoalDate >= dto.StartTime && g.GoalDate <= dto.EndTime)
.GroupBy(g => g.GoalDate.Day)
.Select(g => new
{
Day = g.Key,
Goal = g.First(),
HasGoal = true
})
.ToListAsync();
var results = await _userContext.PersonalGoalResult
.Where(r => r.UserId == userId && r.CreateTime >= dto.StartTime && r.CreateTime <= dto.EndTime)
.ToListAsync();
var dailyRecords = dailyGoals.Select(g => new CheckInRecordDto
{
Day = g.Day,
GoalAmount = g.Goal.GoalAmount,
CompletedCount = results
.Where(r => r.PersonalGoalId == g.Goal.Id)
.Sum(r => r.Amount)
})
.OrderBy(x => x.Day)
.ToList();
return dailyRecords;
}
///
/// 学校账号预约
///
///
///
public async Task SchoolAccountApplication(SchoolAccountApplicationDto dto)
{
var timeNow = DateTime.Now;
var entity = new Y_SchoolAccountApplication()
{
SchoolName = dto.SchoolName,
SchoolAddress = dto.SchoolAddress,
PhoneNo = dto.PhoneNo,
UserName = dto.UserName,
Remarks = dto.Remarks,
Status = 1,
VisitingTime = timeNow,
UpdateTime = timeNow
};
await _sportsContext.SchoolAccountApplication.AddAsync(entity);
await _sportsContext.SaveChangesAsync();
}
}
}