• 基于.NetCore开发博客项目 StarBlog (13) 加入友情链接功能


    系列文章

    前言

    很快啊,pia的一下,博客上线已经一周时间了(网址:http://blog.deali.cn

    阅读量不高,不过对于没有做过SEO的网站来说已经不错了~

    这段时间虽然忙不过一直在写代码给博客添砖加瓦(Github上的Commit每天不断的)

    这不,友情链接功能来了~

    本文来一步步介绍这个功能的实现。

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

    先看效果

    image

    分析

    先分析一下功能

    友情链接,既可以自己手动添加,也可以由访问网站的人申请

    其他站长可以申请互换友链,提交申请之后在博客后台可以看到,确认之后就会显示到网站中啦~

    这就是初步的功能设计

    当然我还想到了一些扩展的功能,比如根据链接的点击量来调整链接的显示顺序(百度:听起来怎么那么熟悉)

    建模

    根据需求,需要俩模型

    一个是要显示的友情链接,一个是友情链接申请记录

    那开始吧

    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接口开发部分讲~

    所以先直接在数据库中添加吧~

    image

    页面展示

    数据模型和逻辑都实现了,接下来就是找一个合适的地方显示

    参考了几个同类的博客之后,我决定把友链放在主页底部

    编辑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>
    

    官网上的例子效果是这样的

    image

    勉强还行,不过都是一样的颜色太单调了,我要七彩的!

    封装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>
    

    最终效果就是一开始展示的那样,每次访问都会有不同的颜色,老炫酷了~

    搞定

    完成了,很简单的一个功能,可以给单调的博客小小增色一下~

    同时也欢迎各位站长大佬来交换友链~!

  • 相关阅读:
    JAVA多线程实现和应用总结
    大话程序猿眼里的高并发
    重写Dijkstra
    再做一遍floyed
    优美的二分模型
    ACwing : 798. 差分矩阵
    ACwing_789. 数的范围
    快速排序超级强的模板
    1829:【02NOIP提高组】自由落体
    【02NOIP提高组】均分纸牌
  • 原文地址:https://www.cnblogs.com/deali/p/16421699.html
Copyright © 2020-2023  润新知