2025-07-21 16:09:02 +08:00

1345 lines
48 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// 用户端
/// </summary>
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;
}
/// <summary>
/// 获取场馆列表
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<PageDataDto<StadiumListDto>> 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<StadiumListDto>
{
Total = totalCount,
Datas = list
};
}
/// <summary>
/// 场馆详情
/// </summary>
/// <param name="stadiumId"></param>
/// <returns></returns>
public async Task<StadiumDetailsDto> 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;
}
/// <summary>
/// 教学类别
/// </summary>
/// <returns></returns>
public async Task<List<ComboBoxDto>> CurricularTaxonomyList()
{
var res = await _sportsContext.CurricularTaxonomy.Where(x => x.CurricularType == 1).Select(x => new ComboBoxDto()
{
Id = x.Id,
Name = x.TaxonomyName
}).ToListAsync();
return res;
}
/// <summary>
/// 付费课程
/// </summary>
/// <returns></returns>
public async Task<List<PaidCoursesListDto>> 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;
}
/// <summary>
/// 付费课程购买
/// </summary>
/// <returns></returns>
public async Task<bool> PaidCoursesBuy(string redeemCode)
{
var paidCoursesList = new List<Y_CurricularPurchaseRecord>();
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;
}
/// <summary>
/// 教学列表
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
public async Task<PageDataDto<CurricularListDto>> 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<CurricularListDto>
{
Total = totalCount,
Datas = list
};
}
/// <summary>
/// 热门视频
/// </summary>
/// <returns></returns>
public async Task<List<CurricularListDto>> 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;
}
/// <summary>
/// 视频播放
/// </summary>
/// <param name="curricularId"></param>
/// <returns></returns>
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();
}
/// <summary>
/// 场馆预约
/// </summary>
/// <param name="stadiumId"></param>
/// <returns></returns>
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();
}
}
/// <summary>
/// 各项目排行
/// </summary>
/// <param name="categoryId"></param>
/// <returns></returns>
public async Task<List<RankingDto>> 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;
}
/// <summary>
/// 文章列表
/// </summary>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<PageDataDto<ArticlesDto>> 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<ArticlesDto>();
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;
}
/// <summary>
/// 创建群组
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 获取群组列表
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
public async Task<PageDataDto<UserGruopDto>> GetUserGruop(GetUserGruopDto dto)
{
var userId = UserLoginContext.Current.UserId;
var res = new PageDataDto<UserGruopDto>();
IQueryable<WCA_UserGroup> 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<UserGruopDto>();
// 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<UserGruopDto>();
// 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;
}
/// <summary>
/// 是否再群组中
/// </summary>
/// <param name="groupId"></param>
/// <returns></returns>
public async Task<bool> IsInGroup(int groupId)
{
var userId = UserLoginContext.Current.UserId;
var any = await _userContext.GroupMembers.AnyAsync(x => x.UserId == userId && x.UserGroupId == groupId);
return any;
}
/// <summary>
/// 加入群组
/// </summary>
/// <param name="groupId"></param>
/// <returns></returns>
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();
}
/// <summary>
/// 群成员列表
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
public async Task<PageDataDto<MembersDto>> GetMembers(GetMembersDto dto)
{
var res = new PageDataDto<MembersDto>();
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;
}
/// <summary>
/// 创建群组任务
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
public async Task CreateGroupTask(CreateGroupTaskDto dto)
{
List<WCA_GroupTask> taskEntities = new List<WCA_GroupTask>();
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<WCA_GroupTask>(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<WCA_GroupTask>(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();
}
/// <summary>
/// 删除群组任务
/// </summary>
/// <param name="groupTaskId"></param>
/// <returns></returns>
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();
}
/// <summary>
/// 获取群任务列表
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
public async Task<PageDataDto<GroupTaskDto>> GetGroupTasks(GetGroupTaskDto dto)
{
var res = new PageDataDto<GroupTaskDto>();
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;
}
/// <summary>
/// 获取群任务详情
/// </summary>
/// <param name="groupTaskId"></param>
/// <returns></returns>
public async Task<GroupTaskDetailsDto> 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;
}
/// <summary>
/// 添加团队运动成绩
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
public async Task<TaskResultDto> 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 };
}
}
}
/// <summary>
/// 获取成绩列表
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
public async Task<GroupTaskResultDto> 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;
}
/// <summary>
/// 统计汇总
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
public async Task<AggregateStatisticsDto> 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;
}
/// <summary>
/// 运动记录
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
public async Task<PageDataDto<SportsRecordDto>> 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<SportsRecordDto>
{
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<SportsRecordDto>
//{
// Total = totalCount,
// Datas = list
//};
}
/// <summary>
/// 创建个人目标
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
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();
}
/// <summary>
/// 获取个人目标
/// </summary>
/// <returns></returns>
public async Task<CetPersonalGoalDto> 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;
}
/// <summary>
/// 添加个人目标数据
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
public async Task<TaskResultDto> 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 };
}
/// <summary>
/// 获取得分和等级
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
public async Task<PersonalScoreRankDto> 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 ?? ""
};
}
/// <summary>
/// 获取地区项目时长
/// </summary>
/// <returns></returns>
public async Task<List<AreaCategoryDto>> CetAreaCategory()
{
var healthStandard = await _sportsContext.AreaCategory.Select(x => new AreaCategoryDto()
{
Id = x.Id,
Area = x.Area,
Duration = x.Duration
}).ToListAsync();
return healthStandard;
}
/// <summary>
/// 获取中考得分
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
public async Task<PersonalScoreRankDto> 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 ?? ""
};
}
/// <summary>
/// 获取打卡记录
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
public async Task<List<CheckInRecordDto>> 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;
}
/// <summary>
/// 学校账号预约
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
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();
}
}
}