系列文章
- 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客?
- 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目
- 基于.NetCore开发博客项目 StarBlog - (3) 模型设计
- 基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入
- 基于.NetCore开发博客项目 StarBlog - (5) 开始搭建Web项目
- 基于.NetCore开发博客项目 StarBlog - (6) 页面开发之博客文章列表
- 基于.NetCore开发博客项目 StarBlog - (7) 页面开发之文章详情页面
- 基于.NetCore开发博客项目 StarBlog - (8) 分类层级结构展示
- 基于.NetCore开发博客项目 StarBlog - (9) 图片批量导入
- 基于.NetCore开发博客项目 StarBlog - (10) 图片瀑布流
- 基于.NetCore开发博客项目 StarBlog - (11) 实现访问统计
- 基于.NetCore开发博客项目 StarBlog - (12) Razor页面动态编译
- 基于.NetCore开发博客项目 StarBlog - (13) 加入友情链接功能
- ...
前言
很快啊,pia的一下,博客上线已经一周时间了(网址:http://blog.deali.cn)
阅读量不高,不过对于没有做过SEO的网站来说已经不错了~
这段时间虽然忙不过一直在写代码给博客添砖加瓦(Github上的Commit每天不断的)
这不,友情链接功能来了~
本文来一步步介绍这个功能的实现。
同时所有项目代码已经上传GitHub,欢迎各位大佬Star/Fork!
- 博客后端+前台项目地址:https://github.com/Deali-Axy/StarBlog
- 管理后台前端项目地址:https://github.com/Deali-Axy/StarBlog-Admin
先看效果
分析
先分析一下功能
友情链接,既可以自己手动添加,也可以由访问网站的人申请
其他站长可以申请互换友链,提交申请之后在博客后台可以看到,确认之后就会显示到网站中啦~
这就是初步的功能设计
当然我还想到了一些扩展的功能,比如根据链接的点击量来调整链接的显示顺序(百度:听起来怎么那么熟悉)
建模
根据需求,需要俩模型
一个是要显示的友情链接,一个是友情链接申请记录
那开始吧
在StarBlog.Data/Models
中创建数据模型
/// <summary> /// 友情链接 /// </summary> public class Link { [Column(IsIdentity = true, IsPrimary = true)] public int Id { get; set; } /// <summary> /// 网站名称 /// </summary> public string Name { get; set; } /// <summary> /// 介绍 /// </summary> public string? Description { get; set; } /// <summary> /// 网址 /// </summary> public string Url { get; set; } /// <summary> /// 是否显示 /// </summary> public bool Visible { get; set; } }
还有这个
/// <summary> /// 友情链接申请记录 /// </summary> public class LinkExchange { [Column(IsIdentity = true, IsPrimary = true)] public int Id { get; set; } /// <summary> /// 网站名称 /// </summary> public string Name { get; set; } /// <summary> /// 介绍 /// </summary> public string? Description { get; set; } /// <summary> /// 网址 /// </summary> public string Url { get; set; } /// <summary> /// 站长 /// </summary> public string WebMaster { get; set; } /// <summary> /// 联系邮箱 /// </summary> public string Email { get; set; } /// <summary> /// 是否已验证 /// <para>友情链接需要验证后才显示在网站上</para> /// </summary> public bool Verified { get; set; } = false; /// <summary> /// 申请时间 /// </summary> public DateTime ApplyTime { get; set; } = DateTime.Now; }
Service
有了模型,接下来完善一下逻辑
在StarBlog.Web/Services
中写逻辑
首先是友情链接的,增删改查除外,还加一个设置可见性的快捷方式
public class LinkService { private IBaseRepository<Link> _repo; public LinkService(IBaseRepository<Link> repo) { _repo = repo; } /// <summary> /// 获取全部友情链接 /// </summary> /// <param name="onlyVisible">只获取显示的链接</param> /// <returns></returns> public List<Link> GetAll(bool onlyVisible = true) { return onlyVisible ? _repo.Where(a => a.Visible).ToList() : _repo.Select.ToList(); } public Link? GetById(int id) { return _repo.Where(a => a.Id == id).First(); } public Link? GetByName(string name) { return _repo.Where(a => a.Name == name).First(); } public Link AddOrUpdate(Link item) { return _repo.InsertOrUpdate(item); } public Link? SetVisibility(int id, bool visible) { var item = GetById(id); if (item == null) return null; item.Visible = visible; _repo.Update(item); return GetById(id); } public int DeleteById(int id) { return _repo.Delete(a => a.Id == id); } }
这个没啥特别的
继续
管理友情链接申请记录的逻辑,同样也是有增删改查,这部分代码跟上面的一样,省略了
这里只贴设置是否验证的代码
public class LinkExchangeService { private readonly IBaseRepository<LinkExchange> _repo; private readonly LinkService _linkService; public LinkExchangeService(IBaseRepository<LinkExchange> repo, LinkService linkService) { _repo = repo; _linkService = linkService; } // 设置是否验证 public LinkExchange? SetVerifyStatus(int id, bool status) { var item = GetById(id); if (item == null) return null; item.Verified = status; _repo.Update(item); var link = _linkService.GetByName(item.Name); if (status) { if (link == null) { _linkService.AddOrUpdate(new Link { Name = item.Name, Description = item.Description, Url = item.Url, Visible = true }); } else { _linkService.SetVisibility(link.Id, true); } } else { if (link != null) _linkService.DeleteById(link.Id); } return GetById(id); } }
在设置是否验证的方法中,实现了:
- 设置一个申请为已验证,自动将该申请的链接添加到友情链接中
- 设置一个申请为未验证,则自动将对应的友情链接删除(如果存在的话)
其他地方就跟上面的友情链接一样了。
写完之后别忘了注册服务
builder.Services.AddScoped<LinkExchangeService>(); builder.Services.AddScoped<LinkService>();
添加数据
虽然管理这些链接的接口我也写了,但目前本系列文章还处在介绍前台的部分,我打算把接口实现放到后面的RESTFul接口开发部分讲~
所以先直接在数据库中添加吧~
页面展示
数据模型和逻辑都实现了,接下来就是找一个合适的地方显示
参考了几个同类的博客之后,我决定把友链放在主页底部
编辑StarBlog.Web/ViewModels/HomeViewModel.cs
,添加一个新属性
public class HomeViewModel { /// <summary> /// 友情链接 /// </summary> public List<Link> Links { get; set; } = new(); }
用Bootstrap5的responsive variation来做响应式的友情链接展示
<div class="d-grid gap-2 d-md-block"> <button class="btn btn-primary" type="button">Button</button> <button class="btn btn-primary" type="button">Button</button> </div>
官网上的例子效果是这样的
勉强还行,不过都是一样的颜色太单调了,我要七彩的!
封装Razor组件
于是封装了一个名为ColorfulButton
的Razor组件
先定义ViewModel,用来配置这个组件
在StarBlog.Web/ViewModels
中新增ColorfulButtonViewModel.cs
文件,代码如下
public static class LinkTarget { public const string Blank = "_blank"; public const string Parent = "_parent"; public const string Self = "_self"; public const string Top = "_top"; } public class ColorfulButtonViewModel { public string Name { get; set; } public string Url { get; set; } = "#"; public string Target { get; set; } = "_self"; }
然后在StarBlog.Web/Views/Shared/Widgets
中新增ColorfulButton.cshtml
把Bootstrap支持的几种按钮颜色放进去,然后每次随机显示一个颜色~
@model ColorfulButtonViewModel @{ var rnd = Random.Shared; var colorList = new[] { "btn-outline-primary", "btn-outline-secondary", "btn-outline-success", "btn-outline-danger", "btn-outline-warning", "btn-outline-info", "btn-outline-dark", }; var btnColor = colorList[rnd.Next(0, colorList.Length)]; } <a href="@Model.Url" role="button" class="btn btn-sm @btnColor mb-1" target="@Model.Target"> @Model.Name </a>
添加到页面中
组件完成了,最后在主页中实现友情链接的展示
编辑StarBlog.Web/Views/Home/Index.cshtml
文件
在最底下(推荐博客板块下方)新增代码
<div class="container px-4 py-3"> <h2 class="pb-2 border-bottom">Link Exchange</h2> @if (Model.Links.Count > 0) { <div class="d-grid gap-2 d-md-block"> @foreach (var link in Model.Links) { @await Html.PartialAsync("Widgets/ColorfulButton", new ColorfulButtonViewModel { Name = link.Name, Url = link.Url }) } </div> } else { @await Html.PartialAsync("Widgets/PlaceholderCard", "友情链接") } </div>
最终效果就是一开始展示的那样,每次访问都会有不同的颜色,老炫酷了~
搞定
完成了,很简单的一个功能,可以给单调的博客小小增色一下~
同时也欢迎各位站长大佬来交换友链~!