diff --git a/README.md b/README.md index 2f3c8177f4469ef5e622a1436763d34684039c1b..0c2892aa0fd0cec71820cbddefba2d87e014b56c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # SingleBlog 基于 ASP.NET CORE 2.0 轻量级个人开源博客系统 -# v1.0-开发预览版 +# v1.0-beta ## 亮点 * 使用 SQLite 本机数据库 @@ -11,11 +11,18 @@ * 支持所见即所得模式 * 支持站点在线配置 * 支持 SEO 关键字配置以及其他信息 -* 支持模版风格的切换 * 支持在线安装 +* 支持快速模块调用 * 使用 MVC 作为后台,Razor Page 作为前端,方便自己增加前端界面 * 前端使用最新的 Bootstrap 4.0 版本 +## 更新日志 +* 【新增】文章回复 +* 【新增】文章回复开关,可选择匿名形式 +* 【调整】架构调整,增加 host 配置 +* 【调整】界面调整,增加模块调用方式 +* 【删除】模版相关功能 + ## 框架 * Microsoft.AspNetCore.All * Microsoft.EntityFrameworkCore diff --git a/src/SingleBlog.Core/AnonymousUserModel.cs b/src/SingleBlog.Core/AnonymousUserModel.cs new file mode 100644 index 0000000000000000000000000000000000000000..98053102c15940dd17bf4fccdcb53e96e93a69c7 --- /dev/null +++ b/src/SingleBlog.Core/AnonymousUserModel.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Text; + +namespace SingleBlog +{ + /// + /// 匿名用户模型 + /// + public class AnonymousUserModel:IValidatableModel + { + /// + /// 昵称。 + /// + [Display(Name="昵称")] + [Required(ErrorMessage ="{0}不能为空")] + public string Name { get; set; } + + /// + /// 邮箱 + /// + [Display(Name = "邮箱")] + [Required(ErrorMessage = "{0}不能为空")] + [DataType(DataType.EmailAddress,ErrorMessage ="{0}格式不正确")] + public string Email { get; set; } + } +} diff --git a/src/SingleBlog.Core/Data/Article.cs b/src/SingleBlog.Core/Data/Article.cs index 64a0f617f3ad46c2f82e8b3b12d70baedc3f6302..342aef55e3c50e136321cd5906ebc561a5923499 100644 --- a/src/SingleBlog.Core/Data/Article.cs +++ b/src/SingleBlog.Core/Data/Article.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Identity; using System; +using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; @@ -30,7 +31,7 @@ namespace SingleBlog.Core.Data /// public DateTime CreateTime { get; set; } = DateTime.Now; /// - /// 分类 + /// 分类Id /// public int CategoryId { get; set; } /// @@ -38,18 +39,57 @@ namespace SingleBlog.Core.Data /// [Display(Name ="阅读量")] [Range(0,int.MaxValue,ErrorMessage ="{0}不能小于0")] - public int ViewCount { get; set; } + public int ViewCount { get; private set; } - public int UserId { get; set; } + /// + /// 是否推荐文章 + /// + [Display(Name = "推荐")] + public bool IsRecommand { get;private set; } + /// + /// 自定义排序顺序,从小到大排序。 + /// + [Display(Name = "排序", Description ="从小到大")] + public int DisplayOrder { get; set; } + /// + /// Gets or sets the user identifier. + /// + /// + /// The user identifier. + /// + public int UserId { get; set; } + /// /// 增加阅读量。 /// /// public void IncreseView(int step = 1) => this.ViewCount += step; + /// + /// 设置推荐 + /// + public void Recommand() => this.IsRecommand = true; + /// + /// 设置不推荐 + /// + public void Unrecommand() => this.IsRecommand = false; + #region 导航属性 + /// + /// 关联分类。 + /// public virtual Category Category { get; set; } + /// + /// 关联用户。 + /// public virtual SingleBlogUser User { get; set; } + + /// + /// 关联回复。 + /// + public virtual ICollection Comments { get; set; } = new HashSet(); + #endregion + } } diff --git a/src/SingleBlog.Core/Data/Category.cs b/src/SingleBlog.Core/Data/Category.cs index 17d894f185e8e629cf98932125f497d791dfb38b..f94bc183d6fedd31142eb3d0079157eb34f061a1 100644 --- a/src/SingleBlog.Core/Data/Category.cs +++ b/src/SingleBlog.Core/Data/Category.cs @@ -25,7 +25,7 @@ namespace SingleBlog.Core.Data public string Name { get; set; } /// - /// 排序 + /// 排序,从小到大排序。 /// public int OrderNo { get; set; } @@ -35,5 +35,10 @@ namespace SingleBlog.Core.Data public bool IsSystem { get; set; } public virtual ICollection
Articles { get; set; } = new HashSet
(); + + /// + /// 表示系统内置分类的名称。 + /// + public const string DEFAULT_NAME = "默认分类"; } } diff --git a/src/SingleBlog.Data/Data/Article.cs b/src/SingleBlog.Core/Data/Comment.cs similarity index 39% rename from src/SingleBlog.Data/Data/Article.cs rename to src/SingleBlog.Core/Data/Comment.cs index 4c084981631582ed866cb73ee42a78d132ea0a82..7c50e6deb43a70a4fc494cbf17dce67659bcff88 100644 --- a/src/SingleBlog.Data/Data/Article.cs +++ b/src/SingleBlog.Core/Data/Comment.cs @@ -4,31 +4,47 @@ using System.ComponentModel.DataAnnotations.Schema; namespace SingleBlog.Core.Data { - [Table("Articles")] - public class Article + /// + /// 文章回复 + /// + [Table("Comments")] + public class Comment { - /// - /// 自增Id。 - /// [Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } + + [Display(Name ="回复内容")] + [Required(ErrorMessage ="{0}不能为空")] + public string Content { get; set; } + /// - /// 标题。 + /// 登录后的用户Id。如果匿名用户,使用 字段。 /// - [Required,StringLength(60)] - public string Title { get; set; } + public int? UserId { get; set; } + /// - /// 内容。 + /// 文章Id /// - [Required] - public string Content { get; set; } + public int ArticleId { get; set; } + + /// + /// 匿名用户的信息 + /// + public string AnonymouseUserInfo { get; set; } + /// /// 创建时间。 /// - public DateTime CreateTime { get; set; } = DateTime.Now; + public DateTime CreatedTime { get; set; } = DateTime.Now; + + /// + /// 关联用户,如果 是 null,则该实体返回 null。 + /// + public virtual SingleBlogUser User { get; set; } + /// - /// 分类 + /// 关联的文章 /// - public int CategoryId { get; set; } + public virtual Article Article { get; set; } } } diff --git a/src/SingleBlog.Core/Data/IDataInitializer.cs b/src/SingleBlog.Core/Data/IDataInitializer.cs index 4ad4b19555571aea455acf7acdd35dbfaf401007..56fbc0ea9ea27107097aa6804158fa0a49fe7378 100644 --- a/src/SingleBlog.Core/Data/IDataInitializer.cs +++ b/src/SingleBlog.Core/Data/IDataInitializer.cs @@ -5,7 +5,7 @@ namespace SingleBlog.Core.Data { using Microsoft.EntityFrameworkCore; using Services; - using SingleBlog.Core.Models; + using SettingModels; using System; using System.Linq; using System.Transactions; @@ -33,14 +33,12 @@ namespace SingleBlog.Core.Data private readonly RoleManager _roleManager; private readonly SettingService _settingService; private readonly CategoryService _categoryService; - private readonly TemplateService _templateService; public DefaultDataIntializer( DbContext context, UserManager userManager, RoleManager roleManager, SettingService settingService, - CategoryService categoryService, - TemplateService templateService + CategoryService categoryService ) { _context = context; @@ -48,7 +46,6 @@ namespace SingleBlog.Core.Data _roleManager = roleManager; _settingService = settingService; _categoryService = categoryService; - _templateService = templateService; } /// @@ -68,19 +65,10 @@ namespace SingleBlog.Core.Data _settingService.SaveSetting(GeneralSettingModel.Default()); _settingService.SaveSetting(new SingleBlogInfoModel()); - await _templateService.SaveTemplateAsync(new Template - { - Copyright = "码农猩球", - DirName = "Default", - Name = "默认模版", - IsCurrent = true, - IsSystem = true, - Version = "1.0" - }); - await _categoryService.SaveCategoryAsync(new Category { Name = "未分类", IsSystem = true }); + await _categoryService.SaveCategoryAsync(new Category { Name = Category.DEFAULT_NAME, IsSystem = true }); - var roleResult = await _roleManager.CreateAsync(new SingleBlogRole { Name = "Administrator", NormalizedName = "管理员" }); + var roleResult = await _roleManager.CreateAsync(new SingleBlogRole { Name = SingleBlogRole.ADMINISTRATOR, NormalizedName = SingleBlogRole.ADMINISTRATOR_NAME }); if (!roleResult.Succeeded) { throw new DataInitializeException(roleResult.Errors.Select(m => m.Description).Join(Environment.NewLine)); @@ -93,7 +81,7 @@ namespace SingleBlog.Core.Data throw new DataInitializeException(userResult.Errors.Select(m => m.Description).Join(Environment.NewLine)); } - var addRoleResult = await _userManager.AddToRoleAsync(user, "Administrator"); + var addRoleResult = await _userManager.AddToRoleAsync(user, SingleBlogRole.ADMINISTRATOR); if (!addRoleResult.Succeeded) { throw new DataInitializeException(addRoleResult.Errors.Select(m=>m.Description).Join(Environment.NewLine)); diff --git a/src/SingleBlog.Core/Data/SingleBlogDbContext.cs b/src/SingleBlog.Core/Data/SingleBlogDbContext.cs index 630e23938673d42a41d8dcf7fd7c43ff27ec1ff9..286809371f2b2d2817fad4b7a80e531a2c996877 100644 --- a/src/SingleBlog.Core/Data/SingleBlogDbContext.cs +++ b/src/SingleBlog.Core/Data/SingleBlogDbContext.cs @@ -20,6 +20,12 @@ namespace SingleBlog.Core.Data { modelBuilder.Entity() .HasMany(m => m.Articles).WithOne(m => m.Category).HasForeignKey(m => m.CategoryId); + + modelBuilder.Entity() + .HasOne(m => m.User).WithMany(m => m.Comments).HasForeignKey(m => m.UserId); + + modelBuilder.Entity
() + .HasMany(m => m.Comments).WithOne(m => m.Article).HasForeignKey(m => m.ArticleId); modelBuilder.Entity().HasKey(m => m.Id); modelBuilder.Entity() @@ -47,10 +53,21 @@ namespace SingleBlog.Core.Data modelBuilder.Entity>().HasKey(m => new { m.UserId, m.LoginProvider }); } + /// + /// 文章 + /// public DbSet
Articles { get; set; } + + /// + /// 设置 + /// public DbSet Settings { get; set; } + + /// + /// 分类 + /// public DbSet Categories { get; set; } - public DbSet