专栏首页挖坑填坑使用.net core ABP和Angular模板构建博客管理系统(实现自己的业务逻辑)

使用.net core ABP和Angular模板构建博客管理系统(实现自己的业务逻辑)

之前写到使用.net core ABP 和Angular模板构建项目,创建后端服务。文章地址:http://www.jianshu.com/p/fde1ea20331f 创建完成后的api基本是不能用的,现在根据我们自己的业务逻辑来实现后端服务。

部分业务逻辑流程图

其他功能流程省略

创建Dto并添加数据校验

关于ABP的数据校验可以参考我这篇文章:http://www.jianshu.com/p/144f5cdd3ac8 ICustomValidate 接口用于自定义数据验证,IShouldNormalize接口用于数据标准化 这里就直接贴代码了

namespace MZC.Blog.Notes
{
    /// <summary>
    /// 创建的时候不需要太多信息,内容更新主要依靠update
    /// 在用户点击创建的时候数据库便创建数据,在用户编辑过程中自动更新保存数据。
    /// </summary>
    public class CreateNoteDto : IShouldNormalize
    {
        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime? CreationTime { get; set; }
        /// <summary>
        /// 创建人
        /// </summary>
        public long CreatorUserId { get; set; }
        /// <summary>
        /// 内容的数据类型 markdown内容,html内容,或者其他
        /// </summary>
        public int TextType { get; set; }

        public void Normalize()
        {
            if (!CreationTime.HasValue) CreationTime = DateTime.Now;
        }
    }
    /// <summary>
    /// 自动更新所传的数据
    /// </summary>
    public class UpdateNoteDto : EntityDto<int>, IShouldNormalize
    {
        /// <summary>
        /// 标题
        /// </summary>
        public string Title { get; set; }
        /// <summary>
        /// 内容
        /// </summary>
        public string Content { get; set; }
        /// <summary>
        /// 上次修改时间
        /// </summary>
        public DateTime? LastModificationTime { get; set; }

        public virtual void Normalize()
        {
            if (!LastModificationTime.HasValue)
            {
                LastModificationTime = DateTime.Now;
            }
        }
    }
    /// <summary>
    /// 发布更新时所用
    /// </summary>
    public class PublicNoteDto : UpdateNoteDto, ICustomValidate, IShouldNormalize
    {
        /// <summary>
        /// 简单描述,用于微信推送时的描述或者其他
        /// </summary>
        public string Des { get; set; }
        /// <summary>
        /// 封面图片,可用于微信推送时或者其他
        /// </summary>
        [Required]
        public string Img { get; set; }
        /// <summary>
        /// 关键字,可用于搜索,分类等
        /// </summary>
        public string Tags { get; set; }
        /// <summary>
        /// 是否发布
        /// </summary>
        public bool? IsPublic { get; set; }

        public override void Normalize()
        {
            base.Normalize();
            IsPublic = true;
        }

        public void AddValidationErrors(CustomValidationContext context)
        {
            if (string.IsNullOrEmpty(Des))
            {
                string error = "描述不能为空!";
                context.Results.Add(new ValidationResult(error));
            }
            if (Des.Length < 10)
            {
                string error = "描述不能少于10个字!";
                context.Results.Add(new ValidationResult(error));
            }
            if (Des.Length > 200)
            {
                string error = "描述不能大于200个字!";
                context.Results.Add(new ValidationResult(error));
            }
        }
    }
    /// <summary>
    /// 用于列表展示
    /// </summary>
    public class NoteDto : EntityDto<int>
    {
        /// <summary>
        /// 标题
        /// </summary>
        public string Title { get; set; }
        /// <summary>
        /// 创建时间
        /// </summary>
        public string CreationTime { get; set; }
        /// <summary>
        /// 点赞次数
        /// </summary>
        public long Like { get; set; }
        /// <summary>
        /// 收藏次数
        /// </summary>
        public long Collect { get; set; }
        /// <summary>
        /// 浏览次数
        /// </summary>
        public long Scan { get; set; }
        /// <summary>
        /// 是否发布
        /// </summary>
        public string IsPublic { get; set; }
    }

    public class GetNoteListDto: PagedResultRequestDto
    {
        /// <summary>
        /// 用于搜索的关键字
        /// </summary>
        public string key { get; set; }
    }
}

创建映射

创建NoteMapProfile.cs文件,并添加相关映射 关于ABP框架映射的更多内容请参考我这篇文章:http://www.jianshu.com/p/6ef125e873e9

namespace MZC.Blog.Notes
{
    public class NoteMapProfile : Profile
    {
        public NoteMapProfile()
        {
            CreateMap<CreateNoteDto, Note>();
            CreateMap<UpdateNoteDto, Note>();
            CreateMap<PublicNoteDto, Note>();
            //使用自定义解析
            CreateMap<Note, NoteDto>().ForMember(x=>x.IsPublic,opt=> {
                opt.ResolveUsing<NoteToNoteDtoResolver>();
            });
            CreateMap<Note, PublicNoteDto>();
        }
    }
    /// <summary>
    /// 自定义解析
    /// </summary>
    public class NoteToNoteDtoResolver : IValueResolver<Note, NoteDto, string>
    {
        public string Resolve(Note source, NoteDto destination, string destMember, ResolutionContext context)
        {
            return source.IsPublic ? "已发布" : "未发布";
        }
    }
}

使用授权

关于ABP授权详细的介绍和使用请看我的另一篇文章:http://www.jianshu.com/p/6e224f4f9705 在core项目Authorization文件夹下有模板提供的授权模块。 在PermissionNames 中定义权限,在AuthorizationProvider中添加定义的权限,然后再项目中就可以通过AbpAuthorize特性或者PermissionChecker类来验证

    public static class PermissionNames
    {
        public const string Pages_Tenants = "Pages.Tenants";

        public const string Pages_Users = "Pages.Users";

        public const string Pages_Roles = "Pages.Roles";
        /// <summary>
        /// 博客管理页面权限
        /// </summary>
        public const string Pages_Blogs = "Pages.Blogs";
        public const string Pages_Blogs_Notes = "Pages.Blogs.Notes";
        public const string Blogs_Notes_Edit = "Pages.Blogs.Notes.Edit";
        public const string Blogs_Notes_Delete = "Pages.Blogs.Notes.Delete";
    }
public class MZCAuthorizationProvider : AuthorizationProvider
    {
        public override void SetPermissions(IPermissionDefinitionContext context)
        {
            context.CreatePermission(PermissionNames.Pages_Users, L("Users"));
            context.CreatePermission(PermissionNames.Pages_Roles, L("Roles"));
            context.CreatePermission(PermissionNames.Pages_Tenants, L("Tenants"), multiTenancySides: MultiTenancySides.Host);

            var BlogPermission = context.CreatePermission(PermissionNames.Pages_Blogs, L("Blogs"));
            var NotePermission = BlogPermission.CreateChildPermission(PermissionNames.Pages_Blogs_Notes,L("Notes"));
            NotePermission.CreateChildPermission(PermissionNames.Blogs_Notes_Edit, L("EditNotes"));
            NotePermission.CreateChildPermission(PermissionNames.Blogs_Notes_Delete, L("DeleteNotes"));
        }

        private static ILocalizableString L(string name)
        {
            return new LocalizableString(name, MZCConsts.LocalizationSourceName);
        }
    }

完善我们的服务和接口

因为是自己的博客系统,没必要那么麻烦就只使用了入口权限定义在类的上面。

    public interface INoteAppServer: IAsyncCrudAppService<NoteDto,int, GetNoteListDto, CreateNoteDto,UpdateNoteDto>
    {
        Task PublicNote(PublicNoteDto input);

        Task<PublicNoteDto> GetNote(EntityDto<int> input);
        
    }
    [AbpAuthorize(PermissionNames.Pages_Blogs_Notes)]
    public class NoteAppServer : AsyncCrudAppService<Note, NoteDto, int, GetNoteListDto, CreateNoteDto, UpdateNoteDto>, INoteAppServer
    {

        public NoteAppServer(IRepository<Note> repository)
            : base(repository)
        {

        }

        public override async Task<NoteDto> Create(CreateNoteDto input)
        {
            var note = ObjectMapper.Map<Note>(input);
            var result = await Repository.InsertAsync(note);
            return ObjectMapper.Map<NoteDto>(result);
        }

        public async Task PublicNote(PublicNoteDto input)
        {
            var note = Repository.Get(input.Id);
            ObjectMapper.Map(input,note);
            var result = await Repository.UpdateAsync(note);
        }

        public override async Task<NoteDto> Update(UpdateNoteDto input)
        {
            var note = Repository.Get(input.Id);
            ObjectMapper.Map(input,note);
            var result = await Repository.UpdateAsync(note);
            return ObjectMapper.Map<NoteDto>(result);
        }
        public override async Task<PagedResultDto<NoteDto>> GetAll(GetNoteListDto input)
        {
            var data = Repository.GetAll().Where(m => !m.IsDeleted);
            data = data.WhereIf(!string.IsNullOrEmpty(input.key), m => m.Title.Contains(input.key) || m.Tags.Contains(input.key));
            int count = await data.CountAsync();
            var notes = await data.OrderByDescending(q => q.CreationTime)
                            .PageBy(input)
                            .ToListAsync();
            return new PagedResultDto<NoteDto>()
            {
                TotalCount = count,
                Items = ObjectMapper.Map<List<NoteDto>>(notes)
            };
        }

        public async Task<PublicNoteDto> GetNote(EntityDto<int> input)
        {
            var note = await Repository.GetAsync(input.Id);
            return ObjectMapper.Map<PublicNoteDto>(note);
        }
    }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 使用.net core ABP和Angular模板构建博客管理系统(创建后端服务)

    易兒善
  • Asp.net+Vue2构建简单记账WebApp之二(使用ABP迅速搭建.Net后台)

    ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称。 ASP.NET Boilerplate是一个用最佳实践...

    易兒善
  • ABP框架学习之——数据校验

    易兒善
  • AutoFac在项目中的应用

    技能大全:http://www.cnblogs.com/dunitian/p/4822808.html#skill 完整Demo:https://github....

    逸鹏
  • 我在工作中使用的自己实现的超简易ORM工具

    我在7月份到了家新公司,要维护一个在原来.net1.1上的系统。我进去一看代码就傻了眼了,满屏的SQL语句,看得脑袋嗡嗡的.但是苦于.net1.1,又不敢大动直...

    用户1687945
  • asp.net core权限模块的快速构建

    此处的自定义的特性标记不能继承Attribute,因无法在AdminAuthorizeAttribute中的上下文filterContext.Filters中获...

    易墨
  • WPF 封装 dotnet remoting 调用其他进程

    在 WPF 使用RPC调用其他进程 已经告诉大家调用的原理,但是大家可以看到,如果自己写一个框架是比较难的。

    林德熙
  • java设计模式(9)-桥接模式

    这篇推文分享一下桥接模式,JDBC原理也是运用了桥接模式,先设置驱动名称,链接,来获得数据库链接,降低耦合,减少维护

    爱敲代码的猫
  • Spring Boot Async异步执行任务

    异步调用就是不用等待结果的返回就执行后面的逻辑,同步调用则需要等带结果再执行后面的逻辑。

    猿天地
  • 浅谈设计模式(一):状态模式|外观模式|代理模式

    在状态模式的设计方案里,一个主类(称为context类),可以在内部状态变化的时候一次性改变它的「所有行为」,而这个「所有行为」会被我们聚合到不同的类(stat...

    外婆的彭湖湾

扫码关注云+社区

领取腾讯云代金券