Video教程的Domain設計

tokengo發表於2023-11-28

Domain設計

下面將介紹Video的表設計,和模型定義。

表設計

Videos設計


/// <summary>
/// 影片聚合
/// </summary>
public class Video : FullAggregateRoot<long, long>
{
    /// <summary>
    /// 影片標題
    /// </summary>
    public string title;

    /// <summary>
    /// 影片描述
    /// </summary>
    public string description;

    /// <summary>
    /// 影片地址
    /// </summary>
    public string url;

    /// <summary>
    /// 影片總長度(秒)
    /// </summary>
    public int duration;

    /// <summary>
    /// 瀏覽量
    /// </summary>
    public int views;

    /// <summary>
    /// 影片標籤
    /// </summary>
    public List<string> tags;

    /// <summary>
    /// 影片封面圖片地址
    /// </summary>
    public string thumbnailUrl;

    /// <summary>
    /// 影片播放次數
    /// </summary>
    public long playCount;

    /// <summary>
    /// 影片點贊數
    /// </summary>
    public long likes;

    /// <summary>
    /// 影片踩數
    /// </summary>
    public long dislikes;

    /// <summary>
    /// 影片評論數
    /// </summary>
    public long commentsCount;

    /// <summary>
    /// 影片標題
    /// </summary>
    public string Title { get => title; set => title = value; }

    /// <summary>
    /// 影片描述
    /// </summary>
    public string Description { get => description; set => description = value; }

    /// <summary>
    /// 影片地址
    /// </summary>
    public string Url { get => url; set => url = value; }

    /// <summary>
    /// 影片總長度(秒)
    /// </summary>
    public int Duration { get => duration; private set => duration = value; }

    /// <summary>
    /// 瀏覽量
    /// </summary>
    public int Views { get => views; private set => views = value; }

    /// <summary>
    /// 影片標籤
    /// </summary>
    public List<string> Tags { get => tags; set => tags = value; }

    /// <summary>
    /// 影片封面圖片地址
    /// </summary>
    public string ThumbnailUrl { get => thumbnailUrl; set => thumbnailUrl = value; }

    /// <summary>
    /// 影片播放次數
    /// </summary>
    public long PlayCount { get => playCount; private set => playCount = value; }

    /// <summary>
    /// 影片點贊數
    /// </summary>
    public long Likes { get => likes; private set => likes = value; }

    /// <summary>
    /// 影片踩數
    /// </summary>
    public long Dislikes { get => dislikes; private set => dislikes = value; }

    /// <summary>
    /// 影片評論數
    /// </summary>
    public long CommentsCount { get => commentsCount; private set => commentsCount = value; }

    protected Video()
    {
    }

    public Video(long id) : base(id)
    {
    }

    /// <summary>
    /// 修改影片總長度
    /// </summary>
    /// <param name="duration"></param>
    public void SetDuration(int duration)
    {
        Duration = duration;
    }
}

Users設計


/// <summary>
/// 使用者表
/// </summary>
public class VideoUsers : FullAggregateRoot<long, long>
{
    /// <summary>
    /// 使用者名稱
    /// </summary>
    private string username;

    /// <summary>
    /// 使用者密碼
    /// </summary>
    private string password;

    /// <summary>
    /// 使用者郵箱
    /// </summary>
    private string email;

    /// <summary>
    /// 使用者頭像
    /// </summary>
    private string avatar;

    /// <summary>
    /// 使用者描述
    /// </summary>
    private string description;

    /// <summary>
    /// 使用者名稱
    /// </summary>
    public string Username { get => username; private set => username = value; }

    /// <summary>
    /// 使用者密碼
    /// </summary>
    public string Password { get => password; private set => password = value; }

    /// <summary>
    /// 使用者郵箱
    /// </summary>
    public string Email { get => email; private set => email = value; }

    /// <summary>
    /// 使用者頭像
    /// </summary>
    public string Avatar { get => avatar; set => avatar = value; }

    /// <summary>
    /// 使用者描述
    /// </summary>
    public string Description { get => description; set => description = value; }

    protected VideoUsers()
    {

    }

    public VideoUsers(string username, string password, string email, string avatar, string description)
    {
        SetUserName(username);
        UpdateEmail(email);
        UpdatePassword(password);
        Avatar = avatar;
        Description = description;
    }

    /// <summary>
    /// 修改使用者名稱
    /// </summary>
    /// <param name="username"></param>
    /// <exception cref="UserFriendlyException"></exception>
    public void SetUserName(string username)
    {
        // 判斷使用者名稱是否符合要求
        if (username.IsNullOrWhiteSpace())
        {
            throw new UserFriendlyException("使用者名稱不能為空");
        }

        if (username.Length < 5)
        {
            throw new UserFriendlyException("使用者名稱長度不能小於5位");
        }

        Username = username;
    }

    /// <summary>
    /// 修改密碼
    /// </summary>
    /// <param name="password"></param>
    /// <exception cref="UserFriendlyException"></exception>
    public void UpdatePassword(string password)
    {
        // 判斷密碼是否符合要求
        if (password.IsNullOrWhiteSpace())
        {
            throw new UserFriendlyException("密碼不能為空");
        }

        if (!IsComplexPassword(password))
        {
            throw new UserFriendlyException("密碼過於簡單");
        }

        Password = password;
    }

    /// <summary>
    /// 修改郵箱
    /// </summary>
    /// <param name="email"></param>
    /// <exception cref="UserFriendlyException"></exception>
    public void UpdateEmail(string email)
    {
        if (email.IsNullOrWhiteSpace())
        {
            throw new UserFriendlyException("郵箱不能為空");
        }

        if (!IsValidEmail(email))
        {
            throw new UserFriendlyException("郵箱校驗失敗");
        }

        Email = email;
    }

    public static bool IsValidEmail(string email)
    {
        // 正規表示式模式
        string pattern = @"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$";

        // 使用正規表示式進行匹配
        Match match = Regex.Match(email, pattern);

        // 如果匹配成功,則為有效郵箱
        return match.Success;
    }
    public static bool IsComplexPassword(string password)
    {
        bool hasUpperCase = password.Any(char.IsUpper);
        bool hasLowerCase = password.Any(char.IsLower);
        bool hasDigit = password.Any(char.IsDigit);
        bool hasSpecialChar = password.Any(ch => !char.IsLetterOrDigit(ch));

        return password.Length >= 8 && hasUpperCase && hasLowerCase && hasDigit && hasSpecialChar;
    }
}

Roles設計


public class Roles : FullAggregateRoot<int, long>
{
    /// <summary>
    /// 角色排序
    /// </summary>
    public int sort;

    /// <summary>
    /// 角色名稱
    /// </summary>
    public string name;

    /// <summary>
    /// 角色描述
    /// </summary>
    public string description;

    /// <summary>
    /// 預設角色不允許刪除
    /// </summary>
    public bool isDefault;

    /// <summary>
    /// 是否正常使用的
    /// </summary>
    public bool isActive;
    /// <summary>
    /// 角色排序
    /// </summary>
    public int Sort { get => sort; set => sort = value; }

    /// <summary>
    /// 角色名稱
    /// </summary>
    public string Name { get => name; set => name = value; }

    /// <summary>
    /// 角色描述
    /// </summary>
    public string Description { get => description; set => description = value; }

    /// <summary>
    /// 預設角色不允許刪除
    /// </summary>
    public bool IsDefault { get => isDefault; private set => isDefault = value; }

    /// <summary>
    /// 是否正常使用的
    /// </summary>
    public bool IsActive { get => isActive; private set => isActive = value; }

    public Roles()
    {
    }

    public Roles(int sort, string name, string description, bool isDefault)
    {
        UpdateName(name);
        Sort = sort;
        Description = description;
        IsDefault = isDefault;
        IsActive = true;
    }

    public void UpdateName(string name)
    {
        if (name.IsNullOrWhiteSpace())
        {
            throw new UserFriendlyException("角色名稱不能為空");
        }

        Name = name;
    }
}

RoleUsers設計

public class RoleUsers : Entity<long>
{
    /// <summary>
    /// 使用者id
    /// </summary>
    public long UserId { get; set; }

    /// <summary>
    /// 角色id
    /// </summary>
    public long RoleId { get; set; }
}

VideoComments設計


public class VideoComments : Entity<long>, IAuditEntity<long>
{
    public long videoId;

    public string comment;

    public long? parentId;

    /// <summary>
    /// 影片Id
    /// </summary>
    public long VideoId { get => videoId; private set => videoId = value; }

    /// <summary>
    /// 評論內容
    /// </summary>
    public string Comment { get => comment; private set => comment = value; }

    /// <summary>
    /// 父級id如果為空則是頂層
    /// </summary>
    public long? ParentId { get => parentId; private set => parentId = value; }

    public long Creator { get; private set; }
    public DateTime CreationTime { get; private set; }
    public long Modifier { get; private set; }
    public DateTime ModificationTime { get; private set; }

    protected VideoComments()
    {
    }

    public VideoComments(long videoId, string comment, long? parentId)
    {
        UpdateVideoId(videoId);
        UpdateComment(comment);
        VideoId = videoId;
        ParentId = parentId;
    }

    public void UpdateVideoId(long videoId)
    {
        if (videoId == null)
        {
            throw new UserFriendlyException("您的影片id為空!");
        }

        VideoId = videoId;
    }

    public void UpdateComment(string comment)
    {
        if (comment.IsNullOrWhiteSpace())
        {
            throw new UserFriendlyException("您的評論為空");
        }

        Comment = comment;
    }
}

VideoLikes設計

public class VideoLikes{
    
    public long Id { get; set; }

    /// <summary>
    /// 影片id
    /// </summary>
    public long VideoId { get; set; }

    /// <summary>
    /// 點贊使用者id
    /// </summary>
    public long UserId { get; set; }
}

VideoCategories設計


public class VideoCategories : Entity<int>
{
    public string name;

    public string description;

    /// <summary>
    /// 分類名稱
    /// </summary>
    public string Name { get => name; private set => name = value; }

    /// <summary>
    /// 分類描述
    /// </summary>
    public string Description { get => description; private set => description = value; }

    protected VideoCategories()
    {

    }

    public VideoCategories(string name, string description)
    {
        UpdateName(name);
        UpdateDescription(description);
    }

    public void UpdateName(string name)
    {
        if (name.IsNullOrWhiteSpace())
        {
            throw new UserFriendlyException("分類名稱不能為空");
        }

        Name = name;
    }

    public void UpdateDescription(string description)
    {
        if (description.IsNullOrWhiteSpace())
        {
            throw new UserFriendlyException("分類描述不能為空");
        }

        Description = description;
    }
}

VideoTags設計

public class VideoTags : Entity<int>
{
    public string name;

    public string description;

    /// <summary>
    /// 標籤名稱
    /// </summary>
    public string Name { get => name; private set => name = value; }

    /// <summary>
    /// 標籤描述
    /// </summary>
    public string Description { get => description; private set => description = value; }

    protected VideoTags()
    {

    }

    public VideoTags(string name, string description)
    {
        UpdateName(name);
        UpdateDescription(description);
    }

    public void UpdateName(string name)
    {
        if (name.IsNullOrWhiteSpace())
        {
            throw new UserFriendlyException("分類名稱不能為空");
        }

        Name = name;
    }

    public void UpdateDescription(string description)
    {
        if (description.IsNullOrWhiteSpace())
        {
            throw new UserFriendlyException("分類描述不能為空");
        }

        Description = description;
    }
}

UserFollows設計

public class UserFollows : Entity<long>
{
    /// <summary>
    /// 關注者id
    /// </summary>
    public long FollowerId { get; set; }

    /// <summary>
    /// 被關注者id
    /// </summary>
    public long FollowedId { get; set; }
}

VideoPlayRecords設計

public class VideoPlayRecords : Entity<long>, IAuditEntity<long>
{
    private long videoId;

    private DateTime playTime;

    /// <summary>
    /// 影片id
    /// </summary>
    public long VideoId { get => videoId; private set => videoId = value; }

    /// <summary>
    /// 播放時間
    /// </summary>
    public DateTime PlayTime { get => playTime; private set => playTime = value; }

    public long Creator { get; private set; }

    public DateTime CreationTime { get; private set; }

    public long Modifier { get; private set; }

    public DateTime ModificationTime { get; private set; }

    public VideoPlayRecords()
    {
    }

    public VideoPlayRecords(long videoId, DateTime playTime)
    {
        VideoId = videoId;
        PlayTime = playTime;
    }
}

FileStorage設計


public class FileStorage : FullAggregateRoot<long, long>
{
    /// <summary>
    /// 檔名
    /// </summary>
    public string name;

    /// <summary>
    /// 檔案路徑
    /// </summary>
    public string path;

    public long size;

    public FileType type;

    /// <summary>
    /// 檔名
    /// </summary>
    public string Name { get => name; set => name = value; }

    /// <summary>
    /// 檔案路徑
    /// </summary>
    public string Path { get => path; set => path = value; }

    /// <summary>
    /// 檔案大小
    /// </summary>
    public long Size { get => size; set => size = value; }

    /// <summary>
    /// 檔案型別
    /// </summary>
    public FileType Type { get => type; private set => type = value; }

    protected FileStorage()
    {

    }

    public FileStorage(string name, string path, long size, FileType type)
    {
        UpdateName(name);
        UpdatePath(path);
        Size = size;
        Type = type;
    }

    public void UpdateName(string name)
    {
        if (name.IsNullOrWhiteSpace())
        {
            throw new UserFriendlyException("檔名稱不能為空");
        }

        Name = name;
    }

    public void UpdatePath(string path)
    {
        if (path.IsNullOrWhiteSpace())
        {
            throw new UserFriendlyException("檔案地址不能為空");
        }
        Path = path;
    }
}

// 檔案類別
public enum FileType
{
    /// <summary>
    /// 檔案
    /// </summary>
    File,

    /// <summary>
    /// 圖片
    /// </summary>
    Image,

    /// <summary>
    /// 影片
    /// </summary>
    Video,

    /// <summary>
    /// 音訊
    /// </summary>
    Audio
}

Auditlog設計


/// <summary>
/// 審計模型
/// </summary>
public class Auditlog : FullAggregateRoot<long, long>
{

    /// <summary>
    /// 請求路由
    /// </summary>
    private string requestRoute;

    /// <summary>
    /// 請求路由
    /// </summary>
    public string RequestRoute
    {
        get { return requestRoute; }
        private set { requestRoute = value; }
    }

    /// <summary>
    /// 請求Query引數
    /// </summary>
    private string requestQuery;

    /// <summary>
    ///請求Query引數
    /// </summary>
    public string RequestQuery
    {
        get { return requestQuery; }
        private set { requestQuery = value; }
    }

    /// <summary>
    /// 請求方式
    /// </summary>
    private string requestMethod;

    /// <summary>
    /// 請求方式
    /// </summary>
    public string RequestMethod
    {
        get { return requestMethod; }
        private set { requestMethod = value; }
    }

    /// <summary>
    /// 請求客戶端標識
    /// </summary>
    private string clientIdentifier;

    /// <summary>
    /// 請求客戶端標識
    /// </summary>
    public string ClientIdentifier
    {
        get { return clientIdentifier; }
        private set { clientIdentifier = value; }
    }

    /// <summary>
    /// 響應狀態
    /// </summary>
    private int responseStatus;

    /// <summary>
    /// 響應狀態
    /// </summary>
    public int ResponseStatus
    {
        get { return responseStatus; }
        private set { responseStatus = value; }
    }

    /// <summary>
    /// 請求ip
    /// </summary>
    private string requestIp;

    /// <summary>
    /// 請求ip
    /// </summary>
    public string RequestIp
    {
        get { return requestIp; }
        private set { requestIp = value; }
    }

    /// <summary>
    /// 擴充套件引數
    /// </summary>
    private Dictionary<string, string> extendedParameters;

    /// <summary>
    /// 擴充套件引數
    /// </summary>
    public Dictionary<string, string> ExtendedParameters
    {
        get { return extendedParameters; }
        private set { extendedParameters = value; }
    }

    /// <summary>
    /// 請求耗時(ms)
    /// </summary>
    private int requestDuration;

    /// <summary>
    /// 請求耗時(ms)
    /// </summary>
    public int RequestDuration
    {
        get => requestDuration;
        private set => requestDuration = value;
    }

    /// <summary>
    /// 應用環境
    /// </summary>
    private string applicationEnvironment;

    /// <summary>
    /// 應用環境
    /// </summary>
    public string ApplicationEnvironment
    {
        get => applicationEnvironment;
        private set => applicationEnvironment = value;
    }

    protected Auditlog()
    {

    }

    public Auditlog(string requestRoute, string requestQuery, string requestMethod, string clientIdentifier, int responseStatus, string requestIp, Dictionary<string, string> extendedParameters, int requestDuration, string applicationEnvironment)
    {
        RequestRoute = requestRoute;
        RequestQuery = requestQuery;
        RequestMethod = requestMethod;
        ClientIdentifier = clientIdentifier;
        ResponseStatus = responseStatus;
        RequestIp = requestIp;
        ExtendedParameters = extendedParameters;
        RequestDuration = requestDuration;
        ApplicationEnvironment = applicationEnvironment;
    }
}

SettingManager設計

public class SettingManager : Entity<long>
{
    private string name;

    private string value;

    /// <summary>
    /// 擴充套件引數
    /// </summary>
    public string Name { get => name; private set => name = value; }

    /// <summary>
    /// 請求耗時(ms)
    /// </summary>
    public string Value { get => value; private set => this.value = value; }

    protected SettingManager()
    {

    }

    public SettingManager(string name, string value)
    {
        Name = name;
        Value = value;
    }
}

技術交流

qq群:737776595

線上文件地址:https://docs.chat.tokengo.top/docs/video/Service/Domain_Design

相關文章