天天看點

基于.NetCore開發部落格項目 StarBlog - (13) 加入友情連結功能

系列文章

  • 基于.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

先看效果

基于.NetCore開發部落格項目 StarBlog - (13) 加入友情連結功能

分析

先分析一下功能

友情連結,既可以自己手動添加,也可以由通路網站的人申請

其他站長可以申請互換友鍊,送出申請之後在部落格背景可以看到,确認之後就會顯示到網站中啦~

這就是初步的功能設計

當然我還想到了一些擴充的功能,比如根據連結的點選量來調整連結的顯示順序(百度:聽起來怎麼那麼熟悉)

模組化

根據需求,需要倆模型

一個是要顯示的友情連結,一個是友情連結申請記錄

那開始吧

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接口開發部分講~

是以先直接在資料庫中添加吧~

基于.NetCore開發部落格項目 StarBlog - (13) 加入友情連結功能

頁面展示

資料模型和邏輯都實作了,接下來就是找一個合适的地方顯示

參考了幾個同類的部落格之後,我決定把友鍊放在首頁底部

編輯

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>
           

官網上的例子效果是這樣的

基于.NetCore開發部落格項目 StarBlog - (13) 加入友情連結功能

勉強還行,不過都是一樣的顔色太單調了,我要七彩的!

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

最終效果就是一開始展示的那樣,每次通路都會有不同的顔色,老炫酷了~

搞定

完成了,很簡單的一個功能,可以給單調的部落格小小增色一下~

同時也歡迎各位站長大佬來交換友鍊~!

微信公衆号:「程式設計實驗室」

專注于網際網路熱門新技術探索與團隊靈活開發實踐,包括架構設計、機器學習與資料分析算法、移動端開發、Linux、Web前後端開發等,歡迎一起探讨技術,分享學習實踐經驗。

繼續閱讀