187 lines
7.6 KiB
C#
187 lines
7.6 KiB
C#
![]() |
using Microsoft.EntityFrameworkCore;
|
|||
|
using YD_WeChatApplet.Api.Entitys;
|
|||
|
using YD_WeChatApplet.Api.SmartSportsEntitys;
|
|||
|
using YD_WeChatApplet.Commons.Dto.HomeWork;
|
|||
|
using YD_WeChatApplet.Commons.Dto.Resource;
|
|||
|
using YD_WeChatApplet.Commons.Dto.School;
|
|||
|
using YD_WeChatApplet.Commons.Enum;
|
|||
|
using YD_WeChatApplet.Context;
|
|||
|
using YD_WeChatApplet.Services;
|
|||
|
|
|||
|
namespace YD_WeChatApplet.Api.Services.Impl
|
|||
|
{
|
|||
|
public class ResourceService : IResourceService
|
|||
|
{
|
|||
|
public UserContext _userContext;
|
|||
|
public SmartSportsContext _sportsContext;
|
|||
|
public ResourceService(UserContext userContext, SmartSportsContext sportsContext)
|
|||
|
{
|
|||
|
_userContext = userContext;
|
|||
|
_sportsContext = sportsContext;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 获取资源类型列表
|
|||
|
/// </summary>
|
|||
|
/// <returns></returns>
|
|||
|
public async Task<List<ComboBoxDto>> ResourceTypes()
|
|||
|
{
|
|||
|
var res = await _userContext.ResourceType.Where(x => x.ParentId == 0).Select(x => new ComboBoxDto()
|
|||
|
{
|
|||
|
Id = x.Id,
|
|||
|
Name = x.TypeName
|
|||
|
}).ToListAsync();
|
|||
|
|
|||
|
return res;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 获取资源详情列表
|
|||
|
/// </summary>
|
|||
|
/// <param name="id"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public async Task<List<ResourceTypeTreeDto>> ResourceDetails(int id)
|
|||
|
{
|
|||
|
// 获取所有资源类型
|
|||
|
var allResourceTypes = await _userContext.ResourceType.ToListAsync();
|
|||
|
|
|||
|
// 获取所有资源详情并按类型分组
|
|||
|
var allDetails = await _userContext.ResourceDetails
|
|||
|
.Select(x => new ResourceDetailsDto
|
|||
|
{
|
|||
|
Id = x.Id,
|
|||
|
ResourceTypeId = x.ResourceTypeId,
|
|||
|
ResourceName = x.ResourceName,
|
|||
|
ImageUrl = x.ImageUrl,
|
|||
|
ResourceUrl = x.ResourceUrl
|
|||
|
})
|
|||
|
.ToListAsync();
|
|||
|
|
|||
|
var detailsLookup = allDetails.ToLookup(x => x.ResourceTypeId);
|
|||
|
|
|||
|
// 查找当前 id 对应的资源类型
|
|||
|
var currentType = allResourceTypes.FirstOrDefault(t => t.Id == id);
|
|||
|
|
|||
|
// 构建树形结构
|
|||
|
var rootTypes = allResourceTypes
|
|||
|
.Where(t => t.ParentId == id)
|
|||
|
.ToList();
|
|||
|
|
|||
|
// 如果没有子节点(rootTypes.Count == 0),直接返回当前类型的资源详情
|
|||
|
if (rootTypes.Count == 0)
|
|||
|
{
|
|||
|
return new List<ResourceTypeTreeDto>
|
|||
|
{
|
|||
|
new ResourceTypeTreeDto
|
|||
|
{
|
|||
|
Id = currentType.Id,
|
|||
|
TypeName = currentType.TypeName,
|
|||
|
ParentId = currentType.ParentId,
|
|||
|
IsLeaf = true, // 标记为叶子节点
|
|||
|
ResourceDetails = detailsLookup[currentType.Id].ToList()
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
var result = new List<ResourceTypeTreeDto>();
|
|||
|
|
|||
|
foreach (var type in rootTypes)
|
|||
|
{
|
|||
|
result.Add(BuildTreeWithLeafDetails(type, allResourceTypes, detailsLookup));
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
private ResourceTypeTreeDto BuildTreeWithLeafDetails(WCA_ResourceType type, List<WCA_ResourceType> allTypes, ILookup<int, ResourceDetailsDto> detailsLookup)
|
|||
|
{
|
|||
|
// 检查是否是叶子节点(没有子节点)
|
|||
|
var childrenTypes = allTypes.Where(t => t.ParentId == type.Id).ToList();
|
|||
|
var isLeaf = childrenTypes.Count == 0;
|
|||
|
|
|||
|
var node = new ResourceTypeTreeDto
|
|||
|
{
|
|||
|
Id = type.Id,
|
|||
|
TypeName = type.TypeName,
|
|||
|
ParentId = type.ParentId,
|
|||
|
IsLeaf = isLeaf,
|
|||
|
// 只有叶子节点才包含详情
|
|||
|
ResourceDetails = isLeaf ? detailsLookup[type.Id].ToList() : new List<ResourceDetailsDto>()
|
|||
|
};
|
|||
|
|
|||
|
// 递归构建子节点
|
|||
|
foreach (var childType in childrenTypes)
|
|||
|
{
|
|||
|
node.Children.Add(BuildTreeWithLeafDetails(childType, allTypes, detailsLookup));
|
|||
|
}
|
|||
|
|
|||
|
return node;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 获取教学资源
|
|||
|
/// </summary>
|
|||
|
/// <returns></returns>
|
|||
|
public async Task<List<SpecialDto>> SpecialLevelList()
|
|||
|
{
|
|||
|
var specials = await _sportsContext.Ai_Special.ToListAsync();
|
|||
|
var levels = await _sportsContext.Ai_SpecialLevel
|
|||
|
.Where(s => specials.Select(x => x.Id).Contains(s.SpecialId))
|
|||
|
.Include(s => s.SpecialActionList)
|
|||
|
.ToListAsync();
|
|||
|
|
|||
|
var levelDict = levels.GroupBy(s => s.SpecialId)
|
|||
|
.ToDictionary(g => g.Key, g => g.ToList());
|
|||
|
|
|||
|
return specials.Select(sp => new SpecialDto
|
|||
|
{
|
|||
|
Name = sp.SpecialName,
|
|||
|
LevelList = new List<Dictionary<string, List<SpecialLevelDto>>>
|
|||
|
{
|
|||
|
new()
|
|||
|
{
|
|||
|
{ "基本技能", levelDict.TryGetValue(sp.Id, out var levelsList)
|
|||
|
? levelsList.Select(level => new SpecialLevelDto
|
|||
|
{
|
|||
|
Name = level.LevelName,
|
|||
|
ActionList = level.SpecialActionList
|
|||
|
.Where(a => a.ActionType == SpecialActionType.BasicSkill)
|
|||
|
.Select(a => new SpecialActionDto
|
|||
|
{
|
|||
|
Id = a.Id,
|
|||
|
ActionName = a.ActionName,
|
|||
|
ActionType = a.ActionType,
|
|||
|
ActionVideoPath = a.ActionVideoPath,
|
|||
|
ExerciseVideoPath = a.ExerciseVideoPath,
|
|||
|
ExplainVideoPath = a.ExplainVideoPath,
|
|||
|
StandardVideoPath = a.StandardVideoPath
|
|||
|
}).ToList()
|
|||
|
}).ToList()
|
|||
|
: new List<SpecialLevelDto>()
|
|||
|
},
|
|||
|
{ "专项技能", levelDict.TryGetValue(sp.Id, out levelsList)
|
|||
|
? levelsList.Select(level => new SpecialLevelDto
|
|||
|
{
|
|||
|
Name = level.LevelName,
|
|||
|
ActionList = level.SpecialActionList
|
|||
|
.Where(a => a.ActionType == SpecialActionType.SpecialStamina)
|
|||
|
.Select(a => new SpecialActionDto
|
|||
|
{
|
|||
|
Id = a.Id,
|
|||
|
ActionName = a.ActionName,
|
|||
|
ActionType = a.ActionType,
|
|||
|
ActionVideoPath = a.ActionVideoPath,
|
|||
|
ExerciseVideoPath = a.ExerciseVideoPath,
|
|||
|
ExplainVideoPath = a.ExplainVideoPath,
|
|||
|
StandardVideoPath = a.StandardVideoPath
|
|||
|
}).ToList()
|
|||
|
}).ToList()
|
|||
|
: new List<SpecialLevelDto>()
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}).ToList();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|