feat:搭建积分领域
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Volo.Abp;
|
||||
using Volo.Abp.Application.Services;
|
||||
using Volo.Abp.Uow;
|
||||
using Yi.Framework.Bbs.Application.Contracts.Dtos.Argee;
|
||||
using Yi.Framework.Bbs.Domain.Entities.Forum;
|
||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||
|
||||
namespace Yi.Framework.Bbs.Application.Services.Forum
|
||||
{
|
||||
/// <summary>
|
||||
/// 点赞功能
|
||||
/// </summary>
|
||||
public class AgreeService : ApplicationService, IApplicationService
|
||||
{
|
||||
public AgreeService(ISqlSugarRepository<AgreeEntity> repository, ISqlSugarRepository<DiscussEntity> discssRepository)
|
||||
{
|
||||
_repository = repository;
|
||||
_discssRepository = discssRepository;
|
||||
}
|
||||
|
||||
private ISqlSugarRepository<AgreeEntity> _repository { get; set; }
|
||||
|
||||
private ISqlSugarRepository<DiscussEntity> _discssRepository { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 点赞,返回true为点赞+1,返回false为点赞-1
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[UnitOfWork]
|
||||
[Authorize]
|
||||
public async Task<AgreeDto> PostOperateAsync(Guid discussId)
|
||||
{
|
||||
var entity = await _repository.GetFirstAsync(x => x.DiscussId == discussId && x.CreatorId == CurrentUser.Id);
|
||||
//判断是否已经点赞过
|
||||
if (entity is null)
|
||||
{
|
||||
|
||||
//没点赞过,添加记录即可,,修改总点赞数量
|
||||
await _repository.InsertAsync(new AgreeEntity(discussId));
|
||||
var discussEntity = await _discssRepository.GetByIdAsync(discussId);
|
||||
if (discussEntity is null)
|
||||
{
|
||||
throw new UserFriendlyException("主题为空");
|
||||
}
|
||||
discussEntity.AgreeNum += 1;
|
||||
await _discssRepository.UpdateAsync(discussEntity);
|
||||
|
||||
return new AgreeDto(true);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//点赞过,删除即可,修改总点赞数量
|
||||
await _repository.DeleteByIdAsync(entity.Id);
|
||||
var discussEntity = await _discssRepository.GetByIdAsync(discussId);
|
||||
if (discussEntity is null)
|
||||
{
|
||||
throw new UserFriendlyException("主题为空");
|
||||
}
|
||||
discussEntity.AgreeNum -= 1;
|
||||
await _discssRepository.UpdateAsync(discussEntity);
|
||||
|
||||
return new AgreeDto(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using SqlSugar;
|
||||
using Volo.Abp;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
using Volo.Abp.Domain.Repositories;
|
||||
using Yi.Framework.Bbs.Application.Contracts.Dtos.Article;
|
||||
using Yi.Framework.Bbs.Application.Contracts.Dtos.Plate;
|
||||
using Yi.Framework.Bbs.Application.Contracts.IServices;
|
||||
using Yi.Framework.Bbs.Domain.Entities.Forum;
|
||||
using Yi.Framework.Bbs.Domain.Extensions;
|
||||
using Yi.Framework.Bbs.Domain.Managers;
|
||||
using Yi.Framework.Bbs.Domain.Repositories;
|
||||
using Yi.Framework.Bbs.Domain.Shared.Consts;
|
||||
using Yi.Framework.Bbs.Domain.Shared.Model;
|
||||
using Yi.Framework.Core.Extensions;
|
||||
using Yi.Framework.Ddd.Application;
|
||||
using Yi.Framework.Rbac.Domain.Authorization;
|
||||
using Yi.Framework.Rbac.Domain.Shared.Consts;
|
||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||
|
||||
namespace Yi.Framework.Bbs.Application.Services.Forum
|
||||
{
|
||||
/// <summary>
|
||||
/// Article服务实现
|
||||
/// </summary>
|
||||
|
||||
public class ArticleService : YiCrudAppService<ArticleEntity, ArticleGetOutputDto, ArticleGetListOutputDto, Guid, ArticleGetListInputVo, ArticleCreateInputVo, ArticleUpdateInputVo>,
|
||||
IArticleService
|
||||
{
|
||||
public ArticleService(IArticleRepository articleRepository,
|
||||
ISqlSugarRepository<DiscussEntity> discussRepository,
|
||||
IDiscussService discussService,
|
||||
ForumManager forumManager) : base(articleRepository)
|
||||
{
|
||||
|
||||
_articleRepository = articleRepository;
|
||||
_discussRepository = discussRepository;
|
||||
_discussService = discussService;
|
||||
_forumManager = forumManager;
|
||||
|
||||
}
|
||||
private ForumManager _forumManager;
|
||||
private IArticleRepository _articleRepository;
|
||||
private ISqlSugarRepository<DiscussEntity> _discussRepository;
|
||||
private IDiscussService _discussService;
|
||||
|
||||
public override async Task<PagedResultDto<ArticleGetListOutputDto>> GetListAsync(ArticleGetListInputVo input)
|
||||
{
|
||||
RefAsync<int> total = 0;
|
||||
|
||||
var entities = await _articleRepository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.Name), x => x.Name.Contains(input.Name!))
|
||||
//.WhereIF(!string.IsNullOrEmpty(input.Code), x => x.Name.Contains(input.Code!))
|
||||
.WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime)
|
||||
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
|
||||
return new PagedResultDto<ArticleGetListOutputDto>(total, await MapToGetListOutputDtosAsync(entities));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取文章全部树级信息
|
||||
/// </summary>
|
||||
/// <param name="discussId"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="UserFriendlyException"></exception>
|
||||
[Route("article/all/discuss-id/{discussId}")]
|
||||
public async Task<List<ArticleAllOutputDto>> GetAllAsync([FromRoute] Guid discussId)
|
||||
{
|
||||
await _discussService.VerifyDiscussPermissionAsync(discussId);
|
||||
|
||||
|
||||
var entities = await _articleRepository.GetTreeAsync(x => x.DiscussId == discussId);
|
||||
//var result = entities.Tile();
|
||||
var items = entities.Adapt<List<ArticleAllOutputDto>>();
|
||||
return items;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询文章
|
||||
/// </summary>
|
||||
/// <param name="discussId"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="UserFriendlyException"></exception>
|
||||
public async Task<List<ArticleGetListOutputDto>> GetDiscussIdAsync([FromRoute] Guid discussId)
|
||||
{
|
||||
if (!await _discussRepository.IsAnyAsync(x => x.Id == discussId))
|
||||
{
|
||||
throw new UserFriendlyException(DiscussConst.No_Exist);
|
||||
}
|
||||
|
||||
var entities = await _articleRepository.GetTreeAsync(x => x.DiscussId == discussId);
|
||||
var items = await MapToGetListOutputDtosAsync(entities);
|
||||
return items;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发表文章
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="UserFriendlyException"></exception>
|
||||
[Permission("bbs:article:add")]
|
||||
[Authorize]
|
||||
public async override Task<ArticleGetOutputDto> CreateAsync(ArticleCreateInputVo input)
|
||||
{
|
||||
await VerifyDiscussCreateIdAsync(input.DiscussId);
|
||||
return await base.CreateAsync(input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新文章
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task<ArticleGetOutputDto> UpdateAsync(Guid id, ArticleUpdateInputVo input)
|
||||
{
|
||||
var entity = await _articleRepository.GetByIdAsync(id);
|
||||
await VerifyDiscussCreateIdAsync(entity.DiscussId);
|
||||
return await base.UpdateAsync(id, input);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 删除文章
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task DeleteAsync(Guid id)
|
||||
{
|
||||
var entity = await _articleRepository.GetByIdAsync(id);
|
||||
await VerifyDiscussCreateIdAsync(entity.DiscussId);
|
||||
await base.DeleteAsync(id);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 导入文章
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task PostImportAsync([FromQuery] ArticleImprotDto input, [FromForm][Required] IFormFileCollection file)
|
||||
{
|
||||
var fileObjs = new List<FileObject>();
|
||||
if (file.Count > 0)
|
||||
{
|
||||
foreach (var item in file)
|
||||
{
|
||||
if (item.Length > 0)
|
||||
{
|
||||
using (var stream = item.OpenReadStream())
|
||||
{
|
||||
using (var fileStream = new MemoryStream())
|
||||
{
|
||||
await item.CopyToAsync(fileStream);
|
||||
var bytes = fileStream.ToArray();
|
||||
|
||||
// 将字节转换成字符串
|
||||
var content = Encoding.UTF8.GetString(bytes);
|
||||
fileObjs.Add(new FileObject() { FileName = item.FileName, Content = content });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new UserFriendlyException("未选择文件");
|
||||
}
|
||||
//使用简单工厂根据传入的类型进行判断
|
||||
await _forumManager.PostImportAsync(input.DiscussId, input.ArticleParentId, fileObjs, input.ImportType);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 效验创建权限,userId为主题创建者
|
||||
/// </summary>
|
||||
/// <param name="disucssId"></param>
|
||||
/// <returns></returns>
|
||||
private async Task VerifyDiscussCreateIdAsync(Guid disucssId)
|
||||
{
|
||||
var discuss = await _discussRepository.GetFirstAsync(x => x.Id == disucssId);
|
||||
if (discuss is null)
|
||||
{
|
||||
throw new UserFriendlyException(DiscussConst.No_Exist);
|
||||
}
|
||||
|
||||
//这块有点绕,这个版本的写法比较清晰
|
||||
bool result = false;
|
||||
|
||||
if (CurrentUser.GetPermissions().Contains(UserConst.AdminPermissionCode))
|
||||
{
|
||||
//如果是超管,直接跳过
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//如果不是超管,必须满足作者是自己,同时还有发布的权限
|
||||
if (discuss.CreatorId == CurrentUser.Id)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
throw new UserFriendlyException("权限不足,请联系主题作者或管理员申请开通");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using SqlSugar;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
using Volo.Abp.Domain.Repositories;
|
||||
using Yi.Framework.Bbs.Application.Contracts.Dtos.Banner;
|
||||
using Yi.Framework.Bbs.Application.Contracts.IServices;
|
||||
using Yi.Framework.Bbs.Domain.Entities.Forum;
|
||||
using Yi.Framework.Ddd.Application;
|
||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||
|
||||
namespace Yi.Framework.Bbs.Application.Services.Forum
|
||||
{
|
||||
/// <summary>
|
||||
/// Banner服务实现
|
||||
/// </summary>
|
||||
public class BannerService : YiCrudAppService<BannerEntity, BannerGetOutputDto, BannerGetListOutputDto, Guid, BannerGetListInputVo, BannerCreateInputVo, BannerUpdateInputVo>,
|
||||
IBannerService
|
||||
{
|
||||
private ISqlSugarRepository<BannerEntity, Guid> _repository;
|
||||
public BannerService(ISqlSugarRepository<BannerEntity, Guid> repository) : base(repository)
|
||||
{
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
public override async Task<PagedResultDto<BannerGetListOutputDto>> GetListAsync(BannerGetListInputVo input)
|
||||
{
|
||||
RefAsync<int> total = 0;
|
||||
var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.Name), x => x.Name.Contains(input.Name!))
|
||||
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
|
||||
return new PagedResultDto<BannerGetListOutputDto>(total, await MapToGetListOutputDtosAsync(entities));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SqlSugar;
|
||||
using Volo.Abp;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
using Yi.Framework.Bbs.Application.Contracts.Dtos.BbsUser;
|
||||
using Yi.Framework.Bbs.Application.Contracts.Dtos.Comment;
|
||||
using Yi.Framework.Bbs.Application.Contracts.IServices;
|
||||
using Yi.Framework.Bbs.Domain.Entities.Forum;
|
||||
using Yi.Framework.Bbs.Domain.Extensions;
|
||||
using Yi.Framework.Bbs.Domain.Managers;
|
||||
using Yi.Framework.Bbs.Domain.Shared.Consts;
|
||||
using Yi.Framework.Ddd.Application;
|
||||
using Yi.Framework.Rbac.Domain.Authorization;
|
||||
using Yi.Framework.Rbac.Domain.Shared.Consts;
|
||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||
|
||||
namespace Yi.Framework.Bbs.Application.Services.Forum
|
||||
{
|
||||
/// <summary>
|
||||
/// 评论
|
||||
/// </summary>
|
||||
public class CommentService : YiCrudAppService<CommentEntity, CommentGetOutputDto, CommentGetListOutputDto, Guid, CommentGetListInputVo, CommentCreateInputVo, CommentUpdateInputVo>,
|
||||
ICommentService
|
||||
{
|
||||
private readonly ISqlSugarRepository<CommentEntity, Guid> _repository;
|
||||
private readonly BbsUserManager _bbsUserManager;
|
||||
public CommentService(ForumManager forumManager, ISqlSugarRepository<DiscussEntity> discussRepository, IDiscussService discussService, ISqlSugarRepository<CommentEntity, Guid> CommentRepository, BbsUserManager bbsUserManager) : base(CommentRepository)
|
||||
{
|
||||
_forumManager = forumManager;
|
||||
_discussRepository = discussRepository;
|
||||
_discussService = discussService;
|
||||
_repository = CommentRepository;
|
||||
_bbsUserManager = bbsUserManager;
|
||||
}
|
||||
|
||||
private ForumManager _forumManager { get; set; }
|
||||
|
||||
|
||||
|
||||
private ISqlSugarRepository<DiscussEntity> _discussRepository { get; set; }
|
||||
|
||||
private IDiscussService _discussService { get; set; }
|
||||
/// <summary>
|
||||
/// 获取改主题下的评论,结构为二维列表,该查询无分页
|
||||
/// </summary>
|
||||
/// <param name="discussId"></param>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PagedResultDto<CommentGetListOutputDto>> GetDiscussIdAsync([FromRoute] Guid discussId, [FromQuery] CommentGetListInputVo input)
|
||||
{
|
||||
await _discussService.VerifyDiscussPermissionAsync(discussId);
|
||||
|
||||
var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.Content), x => x.Content.Contains(input.Content))
|
||||
.Where(x => x.DiscussId == discussId)
|
||||
.Includes(x => x.CreateUser)
|
||||
.ToListAsync();
|
||||
|
||||
//该实体需要进行转换
|
||||
|
||||
//同时为所有用户id进行bbs的扩展即可
|
||||
List<Guid> userIds = entities.Where(x => x.CreatorId != null).Select(x => x.CreatorId ?? Guid.Empty).ToList();
|
||||
var bbsUserInfoDic = (await _bbsUserManager.GetBbsUserInfoAsync(userIds)).ToDictionary(x => x.Id);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//------数据查询完成------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//从根目录开始组装
|
||||
//结果初始值,第一层等于全部根节点
|
||||
var allOutPut = entities.OrderByDescending(x => x.CreationTime).ToList();
|
||||
|
||||
//获取全量主题评论, 先获取顶级的,将其他子组合到顶级下,形成一个二维,先转成dto
|
||||
List<CommentGetListOutputDto> allOutoutDto = await MapToGetListOutputDtosAsync(allOutPut);
|
||||
|
||||
//开始映射额外用户信息字段
|
||||
allOutoutDto?.ForEach(x => x.CreateUser = bbsUserInfoDic[x.CreatorId ?? Guid.Empty].Adapt<BbsUserGetOutputDto>());
|
||||
|
||||
//开始组装dto的层级关系
|
||||
//将全部数据进行hash
|
||||
var dic = allOutoutDto.ToDictionary(x => x.Id);
|
||||
|
||||
foreach (var comment in allOutoutDto)
|
||||
{
|
||||
//不是根节点,需要赋值 被评论者用户信息等
|
||||
if (comment.ParentId != Guid.Empty)
|
||||
{
|
||||
if (dic.ContainsKey(comment.ParentId))
|
||||
{
|
||||
var parentComment = dic[comment.ParentId];
|
||||
comment.CommentedUser = parentComment.CreateUser;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//root或者parent id,根节点都是等于0的
|
||||
var id = comment.RootId;
|
||||
if (id != Guid.Empty)
|
||||
{
|
||||
dic[id].Children.Add(comment);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//子类需要排序
|
||||
var rootOutoutDto = allOutoutDto.Where(x => x.ParentId == Guid.Empty).ToList();
|
||||
rootOutoutDto?.ForEach(x =>
|
||||
{
|
||||
x.Children = x.Children.OrderByDescending(x => x.CreationTime).ToList();
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
return new PagedResultDto<CommentGetListOutputDto>(entities.Count(), rootOutoutDto);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 发表评论
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="UserFriendlyException"></exception>
|
||||
[Permission("bbs:comment:add")]
|
||||
[Authorize]
|
||||
public override async Task<CommentGetOutputDto> CreateAsync(CommentCreateInputVo input)
|
||||
{
|
||||
var discuess = await _discussRepository.GetFirstAsync(x => x.Id == input.DiscussId);
|
||||
if (discuess is null)
|
||||
{
|
||||
throw new UserFriendlyException(DiscussConst.No_Exist);
|
||||
}
|
||||
//不是超级管理员,且主题开启禁止评论
|
||||
|
||||
if (discuess.IsDisableCreateComment == true && !CurrentUser.GetPermissions().Contains(UserConst.AdminPermissionCode))
|
||||
{
|
||||
throw new UserFriendlyException("该主题已禁止评论功能");
|
||||
}
|
||||
|
||||
|
||||
var entity = await _forumManager.CreateCommentAsync(input.DiscussId, input.ParentId, input.RootId, input.Content);
|
||||
return await MapToGetOutputDtoAsync(entity);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SqlSugar;
|
||||
using Volo.Abp;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
using Volo.Abp.EventBus.Local;
|
||||
using Volo.Abp.Users;
|
||||
using Yi.Framework.Bbs.Application.Contracts.Dtos.BbsUser;
|
||||
using Yi.Framework.Bbs.Application.Contracts.Dtos.Discuss;
|
||||
using Yi.Framework.Bbs.Application.Contracts.IServices;
|
||||
using Yi.Framework.Bbs.Domain.Entities;
|
||||
using Yi.Framework.Bbs.Domain.Entities.Forum;
|
||||
using Yi.Framework.Bbs.Domain.Extensions;
|
||||
using Yi.Framework.Bbs.Domain.Managers;
|
||||
using Yi.Framework.Bbs.Domain.Shared.Consts;
|
||||
using Yi.Framework.Bbs.Domain.Shared.Enums;
|
||||
using Yi.Framework.Bbs.Domain.Shared.Etos;
|
||||
using Yi.Framework.Ddd.Application;
|
||||
using Yi.Framework.Rbac.Application.Contracts.Dtos.User;
|
||||
using Yi.Framework.Rbac.Domain.Authorization;
|
||||
using Yi.Framework.Rbac.Domain.Entities;
|
||||
using Yi.Framework.Rbac.Domain.Shared.Consts;
|
||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||
|
||||
namespace Yi.Framework.Bbs.Application.Services.Forum
|
||||
{
|
||||
/// <summary>
|
||||
/// Discuss应用服务实现,用于参数效验、领域服务业务组合、日志记录、事务处理、账户信息
|
||||
/// </summary>
|
||||
public class DiscussService : YiCrudAppService<DiscussEntity, DiscussGetOutputDto, DiscussGetListOutputDto, Guid, DiscussGetListInputVo, DiscussCreateInputVo, DiscussUpdateInputVo>,
|
||||
IDiscussService
|
||||
{
|
||||
private ISqlSugarRepository<DiscussTopEntity> _discussTopEntityRepository;
|
||||
public DiscussService(ForumManager forumManager, ISqlSugarRepository<DiscussTopEntity> discussTopEntityRepository, ISqlSugarRepository<PlateEntity> plateEntityRepository, ILocalEventBus localEventBus) : base(forumManager._discussRepository)
|
||||
{
|
||||
_forumManager = forumManager;
|
||||
_plateEntityRepository = plateEntityRepository;
|
||||
_localEventBus = localEventBus;
|
||||
_discussTopEntityRepository = discussTopEntityRepository;
|
||||
}
|
||||
private readonly ILocalEventBus _localEventBus;
|
||||
private ForumManager _forumManager { get; set; }
|
||||
|
||||
|
||||
private ISqlSugarRepository<PlateEntity> _plateEntityRepository { get; set; }
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 单查
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public async override Task<DiscussGetOutputDto> GetAsync(Guid id)
|
||||
{
|
||||
|
||||
//查询主题发布 浏览主题 事件,浏览数+1
|
||||
var item = await _forumManager._discussRepository._DbQueryable.LeftJoin<UserEntity>((discuss, user) => discuss.CreatorId == user.Id)
|
||||
.LeftJoin<BbsUserExtraInfoEntity>((discuss, user, info) => user.Id == info.UserId)
|
||||
.LeftJoin<PlateEntity>((discuss, user, info, plate) => plate.Id == discuss.PlateId)
|
||||
.Select((discuss, user, info, plate) => new DiscussGetOutputDto
|
||||
{
|
||||
Id = discuss.Id,
|
||||
IsAgree = SqlFunc.Subqueryable<AgreeEntity>().WhereIF(CurrentUser.Id != null, x => x.CreatorId == CurrentUser.Id && x.DiscussId == discuss.Id).Any(),
|
||||
User = new BbsUserGetListOutputDto()
|
||||
{
|
||||
UserName = user.UserName,
|
||||
Nick = user.Nick,
|
||||
Icon = user.Icon,
|
||||
Id = user.Id,
|
||||
Level = info.Level,
|
||||
UserLimit = info.UserLimit
|
||||
},
|
||||
Plate = new Contracts.Dtos.Plate.PlateGetOutputDto()
|
||||
{
|
||||
Name = plate.Name,
|
||||
Id = plate.Id,
|
||||
Code = plate.Code,
|
||||
Introduction = plate.Introduction,
|
||||
Logo = plate.Logo
|
||||
|
||||
}
|
||||
}, true)
|
||||
.SingleAsync(discuss => discuss.Id == id);
|
||||
|
||||
if (item is not null)
|
||||
{
|
||||
await VerifyDiscussPermissionAsync(item.Id);
|
||||
await _localEventBus.PublishAsync(new SeeDiscussEventArgs { DiscussId = item.Id, OldSeeNum = item.SeeNum });
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 查询
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task<PagedResultDto<DiscussGetListOutputDto>> GetListAsync([FromQuery] DiscussGetListInputVo input)
|
||||
{
|
||||
//需要关联创建者用户
|
||||
RefAsync<int> total = 0;
|
||||
var items = await _forumManager._discussRepository._DbQueryable
|
||||
.WhereIF(!string.IsNullOrEmpty(input.Title), x => x.Title.Contains(input.Title))
|
||||
.WhereIF(input.PlateId is not null, x => x.PlateId == input.PlateId)
|
||||
.WhereIF(input.IsTop is not null, x => x.IsTop == input.IsTop)
|
||||
.LeftJoin<UserEntity>((discuss, user) => discuss.CreatorId == user.Id)
|
||||
.LeftJoin<BbsUserExtraInfoEntity>((discuss, user, info) => user.Id == info.UserId)
|
||||
|
||||
.OrderByDescending(discuss => discuss.OrderNum)
|
||||
.OrderByIF(input.Type == QueryDiscussTypeEnum.New, discuss => discuss.CreationTime, OrderByType.Desc)
|
||||
.OrderByIF(input.Type == QueryDiscussTypeEnum.Host, discuss => discuss.SeeNum, OrderByType.Desc)
|
||||
.OrderByIF(input.Type == QueryDiscussTypeEnum.Suggest, discuss => discuss.AgreeNum, OrderByType.Desc)
|
||||
|
||||
.Select((discuss, user, info) => new DiscussGetListOutputDto
|
||||
{
|
||||
Id = discuss.Id,
|
||||
IsAgree = SqlFunc.Subqueryable<AgreeEntity>().WhereIF(CurrentUser.Id != null, x => x.CreatorId == CurrentUser.Id && x.DiscussId == discuss.Id).Any(),
|
||||
|
||||
User = new BbsUserGetListOutputDto()
|
||||
{
|
||||
Id = user.Id,
|
||||
UserName = user.UserName,
|
||||
Nick = user.Nick,
|
||||
Icon = user.Icon,
|
||||
Level = info.Level,
|
||||
UserLimit = info.UserLimit
|
||||
}
|
||||
|
||||
}, true)
|
||||
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
|
||||
|
||||
//查询完主题之后,要过滤一下私有的主题信息
|
||||
items.ApplyPermissionTypeFilter(CurrentUser.Id ?? Guid.Empty);
|
||||
return new PagedResultDto<DiscussGetListOutputDto>(total, items);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取首页的置顶主题
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<DiscussGetListOutputDto>> GetListTopAsync()
|
||||
{
|
||||
var output = await _discussTopEntityRepository._DbQueryable.LeftJoin<DiscussEntity>((top, discuss) => top.DiscussId == discuss.Id)
|
||||
.LeftJoin<UserEntity>((top, discuss, user) => discuss.CreatorId == user.Id)
|
||||
.LeftJoin<BbsUserExtraInfoEntity>((top, discuss, user, info) => user.Id == info.UserId)
|
||||
.OrderByDescending(top => top.OrderNum)
|
||||
.Select((top, discuss, user, info) => new DiscussGetListOutputDto
|
||||
{
|
||||
Id = discuss.Id,
|
||||
IsAgree = SqlFunc.Subqueryable<AgreeEntity>().WhereIF(CurrentUser.Id != null, x => x.CreatorId == CurrentUser.Id && x.DiscussId == discuss.Id).Any(),
|
||||
User = new BbsUserGetListOutputDto
|
||||
{
|
||||
Id = user.Id,
|
||||
Name = user.Name,
|
||||
Sex = user.Sex,
|
||||
State = user.State,
|
||||
Address = user.Address,
|
||||
Age = user.Age,
|
||||
CreationTime = user.CreationTime,
|
||||
|
||||
Level = info.Level,
|
||||
Introduction = user.Introduction,
|
||||
Icon = user.Icon,
|
||||
Nick = user.Nick,
|
||||
UserName = user.UserName,
|
||||
Remark = user.Remark,
|
||||
UserLimit = info.UserLimit
|
||||
|
||||
}
|
||||
}, true)
|
||||
.ToListAsync();
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建主题
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[Permission("bbs:discuss:add")]
|
||||
[Authorize]
|
||||
public override async Task<DiscussGetOutputDto> CreateAsync(DiscussCreateInputVo input)
|
||||
{
|
||||
var plate = await _plateEntityRepository.FindAsync(x => x.Id == input.PlateId);
|
||||
if (plate is null)
|
||||
{
|
||||
throw new UserFriendlyException(PlateConst.No_Exist);
|
||||
}
|
||||
|
||||
//如果开启了禁用创建主题
|
||||
if (plate.IsDisableCreateDiscuss == true)
|
||||
{
|
||||
//只有超级管理员权限才能进行发布
|
||||
if (!CurrentUser.GetPermissions().Contains(UserConst.AdminPermissionCode))
|
||||
{
|
||||
throw new UserFriendlyException("该板块已禁止创建主题,请在其他板块中发布");
|
||||
}
|
||||
}
|
||||
|
||||
var entity = await _forumManager.CreateDiscussAsync(await MapToEntityAsync(input));
|
||||
return await MapToGetOutputDtoAsync(entity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 效验主题查询权限
|
||||
/// </summary>
|
||||
/// <param name="discussId"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="UserFriendlyException"></exception>
|
||||
public async Task VerifyDiscussPermissionAsync(Guid discussId)
|
||||
{
|
||||
var discuss = await _forumManager._discussRepository.GetFirstAsync(x => x.Id == discussId);
|
||||
if (discuss is null)
|
||||
{
|
||||
throw new UserFriendlyException(DiscussConst.No_Exist);
|
||||
}
|
||||
if (discuss.PermissionType == DiscussPermissionTypeEnum.Oneself)
|
||||
{
|
||||
if (discuss.CreatorId != CurrentUser.Id)
|
||||
{
|
||||
throw new UserFriendlyException(DiscussConst.Privacy);
|
||||
}
|
||||
}
|
||||
if (discuss.PermissionType == DiscussPermissionTypeEnum.User)
|
||||
{
|
||||
if (discuss.CreatorId != CurrentUser.Id && !discuss.PermissionUserIds.Contains(CurrentUser.Id ?? Guid.Empty))
|
||||
{
|
||||
throw new UserFriendlyException(DiscussConst.Privacy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using Volo.Abp.Application.Dtos;
|
||||
using Volo.Abp.Data;
|
||||
using Yi.Framework.Bbs.Application.Contracts.Dtos.MyType;
|
||||
using Yi.Framework.Bbs.Application.Contracts.IServices;
|
||||
using Yi.Framework.Bbs.Domain.Entities.Forum;
|
||||
using Yi.Framework.Ddd.Application;
|
||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||
|
||||
namespace Yi.Framework.Bbs.Application.Services.Forum
|
||||
{
|
||||
/// <summary>
|
||||
/// Label服务实现
|
||||
/// </summary>
|
||||
public class MyTypeService : YiCrudAppService<MyTypeEntity, MyTypeOutputDto, MyTypeGetListOutputDto, Guid, MyTypeGetListInputVo, MyTypeCreateInputVo, MyTypeUpdateInputVo>,
|
||||
IMyTypeService
|
||||
{
|
||||
private ISqlSugarRepository<MyTypeEntity, Guid> _repository;
|
||||
public MyTypeService(ISqlSugarRepository<MyTypeEntity, Guid> repository, IDataFilter dataFilter) : base(repository)
|
||||
{
|
||||
_repository = repository;
|
||||
_dataFilter = dataFilter;
|
||||
}
|
||||
|
||||
private IDataFilter _dataFilter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前用户的主题类型
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public Task<PagedResultDto<MyTypeGetListOutputDto>> GetListCurrentAsync(MyTypeGetListInputVo input)
|
||||
{
|
||||
//过滤器需要更换
|
||||
//_dataFilter.Enable<MyTypeEntity>(x => x.UserId == CurrentUser.Id);
|
||||
|
||||
//_dataFilter.AddFilter<MyTypeEntity>(x => x.UserId == CurrentUser.Id);
|
||||
return base.GetListAsync(input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task<MyTypeOutputDto> CreateAsync(MyTypeCreateInputVo input)
|
||||
{
|
||||
var entity = await MapToEntityAsync(input);
|
||||
entity.UserId = CurrentUser.Id ?? Guid.Empty;
|
||||
entity.IsDeleted = false;
|
||||
var outputEntity = await _repository.InsertReturnEntityAsync(entity);
|
||||
return await MapToGetOutputDtoAsync(outputEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using SqlSugar;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
using Volo.Abp.Domain.Repositories;
|
||||
using Yi.Framework.Bbs.Application.Contracts.Dtos.Plate;
|
||||
using Yi.Framework.Bbs.Application.Contracts.IServices;
|
||||
using Yi.Framework.Bbs.Domain.Entities.Forum;
|
||||
using Yi.Framework.Ddd.Application;
|
||||
using Yi.Framework.Rbac.Application.Contracts.Dtos.Config;
|
||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||
|
||||
namespace Yi.Framework.Bbs.Application.Services.Forum
|
||||
{
|
||||
/// <summary>
|
||||
/// Plate服务实现
|
||||
/// </summary>
|
||||
public class PlateService : YiCrudAppService<PlateEntity, PlateGetOutputDto, PlateGetListOutputDto, Guid, PlateGetListInputVo, PlateCreateInputVo, PlateUpdateInputVo>,
|
||||
IPlateService
|
||||
{
|
||||
private ISqlSugarRepository<PlateEntity, Guid> _repository;
|
||||
public PlateService(ISqlSugarRepository<PlateEntity, Guid> repository) : base(repository)
|
||||
{
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
public override async Task<PagedResultDto<PlateGetListOutputDto>> GetListAsync(PlateGetListInputVo input)
|
||||
{
|
||||
RefAsync<int> total = 0;
|
||||
|
||||
var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.Name), x => x.Name.Contains(input.Name!))
|
||||
.WhereIF(!string.IsNullOrEmpty(input.Code), x => x.Name.Contains(input.Code!))
|
||||
.WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime)
|
||||
.OrderByDescending(x => x.OrderNum)
|
||||
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
|
||||
return new PagedResultDto<PlateGetListOutputDto>(total, await MapToGetListOutputDtosAsync(entities));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user