485 lines
17 KiB
C#
485 lines
17 KiB
C#
using AutoMapper;
|
||
using Microsoft.AspNetCore.Http;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Microsoft.Extensions.DependencyInjection;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using VOL.Business.IRepositories;
|
||
using VOL.Business.IRepositories.Stadium;
|
||
using VOL.Business.IServices;
|
||
using VOL.Business.Repositories;
|
||
using VOL.Core.CacheManager;
|
||
using VOL.Core.Enums;
|
||
using VOL.Core.Extensions;
|
||
using VOL.Core.Extensions.AutofacManager;
|
||
using VOL.Core.ManageUser;
|
||
using VOL.Core.Utilities;
|
||
using VOL.Entity.DomainModels;
|
||
using VOL.Entity.DomainModels.YD;
|
||
using VOL.Model;
|
||
using VOL.Model.Ai;
|
||
using VOL.System.Repositories;
|
||
using static Dapper.SqlMapper;
|
||
|
||
namespace VOL.Business.Services
|
||
{
|
||
/// <summary>
|
||
/// 课程服务
|
||
/// </summary>
|
||
public class CurricularService : ICurricularService, IDependency
|
||
{
|
||
#region 初始化
|
||
private readonly IMapper _mapper;
|
||
private readonly ICacheService _cacheService;
|
||
private readonly ICurricularRepository _curricularRepository;
|
||
|
||
[ActivatorUtilitiesConstructor]
|
||
public CurricularService(IMapper mapper,
|
||
ICacheService cacheService,
|
||
ICurricularRepository curricularRepository)
|
||
{
|
||
_mapper = mapper;
|
||
_cacheService = cacheService;
|
||
_curricularRepository = curricularRepository;
|
||
}
|
||
#endregion
|
||
|
||
|
||
/// <summary>
|
||
/// 查询课程分类
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
public async Task<PageDataDto<CourseCategoryDto>> GetCourseCategories(CourseCategoryVo dto)
|
||
{
|
||
// 实现查询逻辑
|
||
var res = new PageDataDto<CourseCategoryDto>();
|
||
// 示例查询逻辑
|
||
var query = from c in _curricularRepository.DbContext.Set<Y_CurricularTaxonomy>()
|
||
select new CourseCategoryDto()
|
||
{
|
||
Id = c.Id,
|
||
CategoryName = c.TaxonomyName
|
||
};
|
||
|
||
if (!string.IsNullOrWhiteSpace(dto.CategoryName))
|
||
{
|
||
query = query.Where(x => x.CategoryName.Contains(dto.CategoryName));
|
||
}
|
||
|
||
res.Total = await query.CountAsync();
|
||
|
||
var list = await query
|
||
.Skip((dto.PageIndex - 1) * dto.PageSize)
|
||
.Take(dto.PageSize)
|
||
.OrderBy(x => x.Id)
|
||
.ToListAsync();
|
||
res.Datas = list;
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 新增课程分类
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
public async Task AddCourseCategory(CourseCategoryDto dto)
|
||
{
|
||
// 实现新增逻辑
|
||
var entity = new Y_CurricularTaxonomy
|
||
{
|
||
TaxonomyName = dto.CategoryName
|
||
};
|
||
_curricularRepository.Add<Y_CurricularTaxonomy>(entity);
|
||
await _curricularRepository.SaveChangesAsync();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新课程分类
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
public async Task UpdateCourseCategory(CourseCategoryDto dto)
|
||
{
|
||
// 实现更新逻辑
|
||
var entity = await _curricularRepository.FindAsyncFirst<Y_CurricularTaxonomy>(c => c.Id == dto.Id);
|
||
if (entity != null)
|
||
{
|
||
entity.TaxonomyName = dto.CategoryName;
|
||
// 其他属性更新
|
||
_curricularRepository.Update<Y_CurricularTaxonomy>(entity);
|
||
await _curricularRepository.SaveChangesAsync();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除课程分类
|
||
/// </summary>
|
||
/// <param name="categoryId"></param>
|
||
/// <returns></returns>
|
||
public async Task DeleteCourseCategory(int categoryId)
|
||
{
|
||
// 实现删除逻辑
|
||
var entity = await _curricularRepository.FindAsyncFirst<Y_CurricularTaxonomy>(c => c.Id == categoryId);
|
||
if (entity != null)
|
||
{
|
||
_curricularRepository.Delete<Y_CurricularTaxonomy>(entity);
|
||
await _curricularRepository.SaveChangesAsync();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 课程列表
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
public async Task<PageDataDto<CurricularListDto>> GetCurricularList(CurricularListVo dto)
|
||
{
|
||
var res = new PageDataDto<CurricularListDto>();
|
||
|
||
var query = from c in _curricularRepository.DbContext.Set<Y_Curricular>()
|
||
join t in _curricularRepository.DbContext.Set<Y_CurricularTaxonomy>()
|
||
on c.TaxonomyId equals t.Id into taxonomyGroup
|
||
from t in taxonomyGroup.DefaultIfEmpty()
|
||
select new CurricularListDto()
|
||
{
|
||
Id = c.Id,
|
||
TaxonomyId = c.TaxonomyId,
|
||
TaxonomyName = t != null ? t.TaxonomyName : string.Empty,
|
||
CurricularName = c.CurricularName,
|
||
CoverImage = c.CoverImage,
|
||
Url = c.Url,
|
||
Hits = c.Hits,
|
||
CreateDate = c.CreateDate
|
||
};
|
||
|
||
if (dto.TaxonomyId.HasValue)
|
||
{
|
||
query = query.Where(x => x.TaxonomyId == dto.TaxonomyId.Value);
|
||
}
|
||
|
||
if (!string.IsNullOrWhiteSpace(dto.CurricularName))
|
||
{
|
||
query = query.Where(x => x.CurricularName.Contains(dto.CurricularName));
|
||
}
|
||
|
||
if (dto.StartTime.HasValue)
|
||
{
|
||
query = query.Where(x => x.CreateDate >= dto.StartTime.Value);
|
||
}
|
||
|
||
if (dto.EndTime.HasValue)
|
||
{
|
||
query = query.Where(x => x.CreateDate <= dto.EndTime.Value);
|
||
}
|
||
|
||
res.Total = await query.CountAsync();
|
||
|
||
var list = await query
|
||
.OrderByDescending(x => x.CreateDate)
|
||
.Skip((dto.PageIndex - 1) * dto.PageSize)
|
||
.Take(dto.PageSize)
|
||
.ToListAsync();
|
||
|
||
res.Datas = list;
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 新增课程
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
public async Task AddCurricular(CurricularAddDto dto)
|
||
{
|
||
var entity = new Y_Curricular
|
||
{
|
||
TaxonomyId = dto.TaxonomyId,
|
||
CurricularName = dto.CurricularName,
|
||
CoverImage = dto.CoverImage,
|
||
Url = dto.Url,
|
||
Hits = 0,
|
||
CreateDate = DateTime.Now
|
||
};
|
||
|
||
_curricularRepository.Add<Y_Curricular>(entity);
|
||
await _curricularRepository.SaveChangesAsync();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取课程详情
|
||
/// </summary>
|
||
/// <param name="courseId"></param>
|
||
/// <returns></returns>
|
||
public async Task<CurricularAddDto> GetCourseDetails(int courseId)
|
||
{
|
||
var course = await _curricularRepository.DbContext.Set<Y_Curricular>()
|
||
.FirstOrDefaultAsync(c => c.Id == courseId);
|
||
if (course == null)
|
||
{
|
||
throw new Exception("课程不存在");
|
||
}
|
||
|
||
var taxonomies = await _curricularRepository.FindAsync<Y_CurricularTaxonomy>(c => true);
|
||
|
||
return new CurricularAddDto
|
||
{
|
||
Id = course.Id,
|
||
CurricularName = course.CurricularName,
|
||
CoverImage = course.CoverImage,
|
||
Url = course.Url,
|
||
TaxonomyId = course.TaxonomyId,
|
||
TaxonomyName = taxonomies.FirstOrDefault(c => c.Id == course.TaxonomyId).TaxonomyName,
|
||
CreateDate = course.CreateDate.GetValueOrDefault()
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新课程
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
/// <exception cref="Exception"></exception>
|
||
public async Task UpdateCourse(CurricularAddDto dto)
|
||
{
|
||
var course = await _curricularRepository.FindAsyncFirst<Y_Curricular>(c => c.Id == dto.Id);
|
||
|
||
if (course == null)
|
||
{
|
||
throw new Exception("课程不存在");
|
||
}
|
||
|
||
ALiYunOss.DeleteFilesByPrefix(course.CoverImage);
|
||
ALiYunOss.DeleteFilesByPrefix(course.Url);
|
||
|
||
course.CurricularName = dto.CurricularName;
|
||
course.CoverImage = dto.CoverImage;
|
||
course.Url = dto.Url;
|
||
course.TaxonomyId = dto.TaxonomyId;
|
||
course.ModifyDate = DateTime.Now;
|
||
|
||
_curricularRepository.Update(course);
|
||
await _curricularRepository.SaveChangesAsync();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除课程
|
||
/// </summary>
|
||
/// <param name="courseId"></param>
|
||
/// <returns></returns>
|
||
/// <exception cref="Exception"></exception>
|
||
public async Task DeleteCourse(int courseId)
|
||
{
|
||
var course = await _curricularRepository.FindAsyncFirst<Y_Curricular>(c => c.Id == courseId);
|
||
if (course == null)
|
||
{
|
||
throw new Exception("课程不存在");
|
||
}
|
||
|
||
ALiYunOss.DeleteFilesByPrefix(course.CoverImage);
|
||
ALiYunOss.DeleteFilesByPrefix(course.Url);
|
||
|
||
_curricularRepository.Delete<Y_Curricular>(course);
|
||
await _curricularRepository.SaveChangesAsync();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 热门课程列表查询
|
||
/// </summary>
|
||
/// <param name="dto">查询参数</param>
|
||
/// <returns>热门课程列表</returns>
|
||
public async Task<PageDataDto<PopularCurricularDto>> GetPopularCurricularList(PopularCurricularVo dto)
|
||
{
|
||
var res = new PageDataDto<PopularCurricularDto>();
|
||
|
||
// 验证展示数量至少为2
|
||
if (dto.DisplayMode == "自动" && dto.DisplayCount.HasValue && dto.DisplayCount.Value < 2)
|
||
{
|
||
throw new Exception("最少展示2节课程");
|
||
}
|
||
|
||
// 手动模式:从热门课程表中查询
|
||
if (dto.DisplayMode == "手动" || string.IsNullOrEmpty(dto.DisplayMode))
|
||
{
|
||
var query = from p in _curricularRepository.DbContext.Set<Y_PopularCurricular>()
|
||
join c in _curricularRepository.DbContext.Set<Y_Curricular>()
|
||
on p.CurricularId equals c.Id
|
||
join t in _curricularRepository.DbContext.Set<Y_CurricularTaxonomy>()
|
||
on c.TaxonomyId equals t.Id into taxonomyGroup
|
||
from t in taxonomyGroup.DefaultIfEmpty()
|
||
select new PopularCurricularDto
|
||
{
|
||
Id = p.Id,
|
||
CurricularId = p.CurricularId,
|
||
CurricularTaxonomyName = t != null ? t.TaxonomyName : string.Empty,
|
||
CurricularName = c.CurricularName,
|
||
CoverImage = c.CoverImage,
|
||
Hits = c.Hits,
|
||
CreateDate = c.CreateDate,
|
||
Remarks = p.Remarks
|
||
};
|
||
|
||
res.Total = await query.CountAsync();
|
||
|
||
var list = await query
|
||
.Skip((dto.PageIndex - 1) * dto.PageSize)
|
||
.Take(dto.PageSize)
|
||
.OrderByDescending(x => x.Id)
|
||
.ToListAsync();
|
||
res.Datas = list;
|
||
}
|
||
// 自动模式:根据规则从课程表中查询
|
||
else if (dto.DisplayMode == "自动")
|
||
{
|
||
var query = from c in _curricularRepository.DbContext.Set<Y_Curricular>()
|
||
join t in _curricularRepository.DbContext.Set<Y_CurricularTaxonomy>()
|
||
on c.TaxonomyId equals t.Id into taxonomyGroup
|
||
from t in taxonomyGroup.DefaultIfEmpty()
|
||
select new PopularCurricularDto
|
||
{
|
||
Id = c.Id, // 自动模式下,Id为0
|
||
CurricularId = c.Id,
|
||
CurricularTaxonomyName = t != null ? t.TaxonomyName : string.Empty,
|
||
CurricularName = c.CurricularName,
|
||
CoverImage = c.CoverImage,
|
||
Hits = c.Hits,
|
||
CreateDate = c.CreateDate,
|
||
Remarks = ""
|
||
};
|
||
|
||
// 根据展示规则排序
|
||
if (dto.DisplayRule == "最新上传")
|
||
{
|
||
query = query.OrderByDescending(x => x.CreateDate);
|
||
}
|
||
else if (dto.DisplayRule == "流量最大")
|
||
{
|
||
query = query.OrderByDescending(x => x.Hits);
|
||
}
|
||
else
|
||
{
|
||
query = query.OrderByDescending(x => x.CreateDate);
|
||
}
|
||
|
||
// 如果设置了展示数量,则按照展示数量返回
|
||
if (dto.DisplayCount.HasValue)
|
||
{
|
||
res.Total = Math.Min(await query.CountAsync(), dto.DisplayCount.Value);
|
||
var list = await query.Take(dto.DisplayCount.Value).ToListAsync();
|
||
res.Datas = list;
|
||
}
|
||
else
|
||
{
|
||
res.Total = await query.CountAsync();
|
||
var list = await query
|
||
.Skip((dto.PageIndex - 1) * dto.PageSize)
|
||
.Take(dto.PageSize)
|
||
.ToListAsync();
|
||
res.Datas = list;
|
||
}
|
||
}
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加热门课程
|
||
/// </summary>
|
||
/// <param name="dto">课程ID列表</param>
|
||
/// <returns></returns>
|
||
public async Task AddPopularCurricular(AddPopularCurricularDto dto)
|
||
{
|
||
if (dto.CurricularIds == null || !dto.CurricularIds.Any())
|
||
{
|
||
throw new Exception("课程ID不能为空");
|
||
}
|
||
|
||
// 验证课程是否存在
|
||
var curriculars = await _curricularRepository.DbContext.Set<Y_Curricular>()
|
||
.Where(c => dto.CurricularIds.Contains(c.Id))
|
||
.ToListAsync();
|
||
|
||
if (curriculars.Count != dto.CurricularIds.Count)
|
||
{
|
||
throw new Exception("部分课程不存在");
|
||
}
|
||
|
||
// 验证课程是否已经是热门课程
|
||
var existingPopulars = await _curricularRepository.DbContext.Set<Y_PopularCurricular>()
|
||
.Where(p => dto.CurricularIds.Contains(p.CurricularId))
|
||
.Select(p => p.CurricularId)
|
||
.ToListAsync();
|
||
|
||
// 过滤掉已经存在的课程ID
|
||
var newCurricularIds = dto.CurricularIds.Except(existingPopulars).ToList();
|
||
|
||
if (!newCurricularIds.Any())
|
||
{
|
||
throw new Exception("所选课程已经是热门课程");
|
||
}
|
||
|
||
// 批量添加热门课程
|
||
var entities = newCurricularIds.Select(id => new Y_PopularCurricular
|
||
{
|
||
CurricularId = id,
|
||
CreateDate = DateTime.Now,
|
||
Creator = UserContext.Current.UserId
|
||
}).ToList();
|
||
|
||
_curricularRepository.AddRange<Y_PopularCurricular>(entities);
|
||
await _curricularRepository.SaveChangesAsync();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除热门课程
|
||
/// </summary>
|
||
/// <param name="id">热门课程ID</param>
|
||
/// <returns></returns>
|
||
public async Task DeletePopularCurricular(int id)
|
||
{
|
||
var entity = await _curricularRepository.FindAsyncFirst<Y_PopularCurricular>(c => c.Id == id);
|
||
if (entity == null)
|
||
{
|
||
throw new Exception("热门课程不存在");
|
||
}
|
||
|
||
_curricularRepository.Delete(entity);
|
||
await _curricularRepository.SaveChangesAsync();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 上传视频
|
||
/// </summary>
|
||
public async Task<string> UploadVideo(IFormFile file)
|
||
{
|
||
var timeStampString = DateTime.Now.ToUnixTimeStamp();
|
||
var prefix = $"Upload/Curricular/";
|
||
// 删除文件
|
||
//ALiYunOss.DeleteFilesByPrefix(prefix);
|
||
// 上传文件
|
||
var url = ALiYunOss.Upload(file, prefix, timeStampString);
|
||
|
||
return url;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 上传封面图像
|
||
/// </summary>
|
||
/// <param name="file"></param>
|
||
/// <returns></returns>
|
||
public string UploadImage(IFormFile file)
|
||
{
|
||
var timeStampString = DateTime.Now.ToUnixTimeStamp();
|
||
var prefix = $"Upload/Curricular/";
|
||
|
||
var url = ALiYunOss.Upload(file, prefix, timeStampString);
|
||
|
||
return url;
|
||
}
|
||
}
|
||
} |