4

基于.NetCore开发博客项目 StarBlog - (3) 模型设计 - 程序设计实验室

 2 years ago
source link: https://www.cnblogs.com/deali/p/16180920.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

基于.NetCore开发博客项目 StarBlog

  • 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客?
  • 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目
  • 基于.NetCore开发博客项目 StarBlog - (3) 模型设计
  • 基于.NetCore开发博客项目 StarBlog - 接口返回值包装
  • 基于.NetCore开发博客项目 StarBlog - 上传图片功能
  • 基于.NetCore开发博客项目 StarBlog - 身份认证功能
  • 基于.NetCore开发博客项目 StarBlog - 前端相关
  • 基于.NetCore开发博客项目 StarBlog - 前端开发 (1) 准备篇
  • 基于.NetCore开发博客项目 StarBlog - 前端开发 (2) 页面路由
  • 基于.NetCore开发博客项目 StarBlog - 前端开发 (3) SASS与SCSS
  • 基于.NetCore开发博客项目 StarBlog - 前端开发 (4) FontAwesome图标
  • 基于.NetCore开发博客项目 StarBlog - 前端开发 (5) Axios网络请求封装
  • 基于.NetCore开发博客项目 StarBlog - 前端开发 (6) 登录页面
  • 基于.NetCore开发博客项目 StarBlog - 前端开发 (7) 主页面
  • 基于.NetCore开发博客项目 StarBlog - 前端开发 (8) Vuex与状态管理
  • 基于.NetCore开发博客项目 StarBlog - 前端开发之文件上传
  • 基于.NetCore开发博客项目 StarBlog - 前端开发之瀑布流图片列表
  • 基于.NetCore开发博客项目 StarBlog - 前端开发之导航守卫

上一篇文章介绍(水)了新建项目的操作,本文开始终于进入正题要开始写代码了!

对了,上一篇文章有朋友留言问管理端的用户名和密码是多少,这个是我疏忽了,没有做一个便捷的项目初始化功能,目前登录管理端需要在数据库的User表创建一个用户,后续我会完善角色和权限控制部分,然后给项目加一些命令行工具,就像django-admin那样。

OK,本文介绍StarBlog博客项目的模型设计。

根据博客的功能需求,数据分成三类:

  • 文章相关(文章、文章分类)
  • 摄影/相册相关
  • 推荐内容配置(推荐文章、分类、图片;置顶文章、分类)

由于我还没学DDD,(后续学了Abp vNext框架的话可能会用新技术进行重构),所以先用传统的MVC架构来规划项目~

回顾上一篇文章,我们新建了几个项目,现在,我们要把数据模型写在StarBlog.Data项目中。

打开IDE,在StarBlog.Data项目中新建一个目录,名为 Models,接下来的数据模型全都要放到这个目录/命名空间下。

由于项目代码已经在GitHub开源了,数据模型代码我就不全部贴上来了,先看看创建完成之后的目录结构。

代码可以这里看到:https://github.com/Deali-Axy/StarBlog/tree/master/StarBlog.Data/Models

Models
├── Category.cs			 # 文章分类
├── FeaturedCategory.cs  # 推荐分类
├── FeaturedPhoto.cs     # 推荐图片
├── FeaturedPost.cs      # 推荐文章
├── Photo.cs             # 摄影图片
├── Post.cs              # 文章
├── TopPost.cs           # 置顶文章
└── User.cs              # 用户

为了便于读者理解项目设计和模型间的关系,我们挑几个关键的说一下。

Category.cs

文章分类。完整代码见:https://github.com/Deali-Axy/StarBlog/blob/master/StarBlog.Data/Models/Category.cs

StarBlog博客支持markdown批量导入,然后以目录结构作为文章的分类,目录名就是分类名,且支持多级分类。

部分代码如下:

public class Category {
    public int Id { get; set; }
    public string Name { get; set; }
    public int ParentId { get; set; }
    public bool Visible { get; set; } = true;
}

Post.cs

完整代码见:https://github.com/Deali-Axy/StarBlog/blob/master/StarBlog.Data/Models/Post.cs

博客网站,最重要的就是文章,文章的模型部分代码如下

namespace StarBlog.Data.Models;

public class Post {
    // 省略部分字段...
    public string? Status { get; set; }
    public bool IsPublish { get; set; }
    public string? Path { get; set; }
    public DateTime CreationTime { get; set; }
    public DateTime LastUpdateTime { get; set; }
    public string? Categories { get; set; }
}

首先看StatusIsPublish字段,一个是文章状态(未完成、未修改、未发布),一个是否发布。最终决定文章是否在网站上展示是IsPublish字段,那Status字段存在的意义是啥?

答案:为了保留导入前的文章状态。

本项目的博客支持导入整个目录markdown文件作为文章,我的习惯是会在markdown文件的文件名最前面写上这个文章的状态,比如一篇未完成的文章,它的文件名是:(未完成)StarBlog博客开发笔记(3):模型设计,所以这个Status字段就是要把(未完成)中的这个状态识别提取出来,(具体用到的是正则表达式,这是后面要介绍的内容)。

然后是Path字段,这个字段表示文章作为markdown文件导入前存放的相对位置,比如导入了D:\blog这个目录里的所有文章,而这个目录的结构是这样的:

blog
├── Asp-Net-Core学习笔记
│   ├── Asp-Net-Core学习笔记:1.MVC入门篇.md
│   ├── Asp-Net-Core学习笔记:2.MVC视图、模型、持久化、文件、错误处理、日志.md
│   ├── Asp-Net-Core学习笔记:3.使用SignalR实时通信框架开发聊天室.md
│   ├── Asp-Net-Core学习笔记:4.Blazor-WebAssembly入门.md
│   ├── Asp-Net-Core学习笔记:5.构建和部署.md
│   ├── Asp-Net-Core学习笔记:WebApi开发实践.md
│   ├── Asp-Net-Core学习笔记:身份认证入门.md
│   ├── Asp-Net-Core学习笔记:部署,早知道,还是docker,以及一点碎碎念.md
├── Asp-Net-Core开发笔记
│   ├── Asp-Net-Core开发笔记:使用NPM和gulp管理前端静态文件.md
│   ├── Asp-Net-Core开发笔记:在docker部署时遇到一个小坑.md
│   └── Asp-Net-Core开发笔记:接口返回json对象出现套娃递归问题.md
├── 不吹不黑,跨平台框架AspNetCore开发实践杂谈.md
├── 梦想家装平台开发记录,Asp-Net-Core上手实践.md
├── (未修改)How-to-Connect-to-MySQL-from--NET-Core.md
├── (未修改)使用Ocelot实现Api网关.md
├── (未发布)跨域配置.md
├── (未完成)ASP-NET-Core-使用-Hangfire-定时任务.md
├── (未完成)Core-定时任务之HangFire.md
├── (未完成)使用-ASP-NET-Core-和-Hangfire-实现-HTTP-异步化方案.md
├── (未完成)使用Sentry.md
└── (未完成)在xunit里使用依赖注入.md

那对于在blog/AspNetCore目录下的文章(未发布)跨域配置.md 来说,它的Path字段就是AspNetCore

对于在blog/AspNetCore/Asp-Net-Core学习笔记目录下的文章来说,Path字段就是AspNetCore/Asp-Net-Core学习笔记

这个Path字段的意义,就在于实现前面说的多级分类,同时最下面的Categories字段,也是为了实现多级分类准备的。

在文章导入的过程中,目录名称作为文章分类名创建了文章的分类,同时记录分类ID到文章的CategoryId字段中,如果是多级分类的话,文章的CategoryId字段记录的是最后一个分类,父分类是不在这个CategoryId里的,虽然Category有个ParentId字段可以找到父分类,但是在实际使用的时候比较麻烦,所以我又加了这个 Categories 字段,把文章的分类层级记录起来,其内容类似这样 1,2,3 ,用逗号分隔开分类ID

这样前台展示的时候只需要用 servicesCategories 字段处理成 List<Category> 就可以了。

Photo.cs

对了,还有图片模型,因为平时有空会拍照,所以做个摄影分享的功能,这个模型就存上传的图片。

部分代码如下

public class Photo {
    // 省略部分字段...
    public string Location { get; set; }
    public string FilePath { get; set; }
    public long Height { get; set; }
    public long Width { get; set; }
}

图片的高度和宽度字段我一开始是没考虑的,不过在做瀑布流展示的时候发现没有宽高度不行,于是找到了 SixLabors.ImageSharp 这个库读取图片信息,这个库功能还挺强的,推荐一波~

Location拍摄地点现在只能手动输入,我之前用Python做过一个相册的项目,可以根据图片的Exif信息读取拍摄的GPS信息,然后用逆地址解析的方法解析出拍摄的地址,这个先记个todo,后面来实现~

三个Featured开头的是推荐相关的,可以在后台配置;

然后置顶文章和置顶分类只能分别设置一个,展示在网站主页。

大概就这些了,下篇文章见~

同时所有项目代码已经上传GitHub,欢迎各位大佬Star/Fork!

__EOF__


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK