0

基于.NetCore开发博客项目 StarBlog - (13) 加入友情链接功能 - 程序设计实验室

 2 years ago
source link: https://www.cnblogs.com/deali/p/16421699.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.

基于.NetCore开发博客项目 StarBlog

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

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

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

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

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

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

866942-20220628233049830-392402874.png

先分析一下功能

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

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

这就是初步的功能设计

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

根据需求,需要俩模型

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

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

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

866942-20220628233110553-271695454.png

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

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

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

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

866942-20220628233311071-662978610.png

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

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

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

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

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

__EOF__


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK