网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using AutoMapper;
using Dpz.Core.EnumLibrary;
using Dpz.Core.Infrastructure;
using Dpz.Core.Public.Entity;

namespace Dpz.Core.Public.ViewModel;

/// <summary>
/// 评论 出参
/// </summary>
public class CommentViewModel : IHaveCustomMapping
{
    public string Id { get; set; }

    /// <summary>
    /// 评论类型
    /// </summary>
    public CommentNode Node { get; set; }

    /// <summary>
    /// 关联
    /// </summary>
    public string Relation { get; set; }

    /// <summary>
    /// 回复时间
    /// </summary>
    public DateTime PublishTime { get; set; }

    /// <summary>
    /// 评论人 (多态)分为匿名评论和成员评论
    /// </summary>
    [JsonConverter(typeof(CommenterConverter))]
    public VmCommenter Commenter { get; set; }

    /// <summary>
    /// 回复内容
    /// </summary>
    public string CommentText { get; set; }

    /// <summary>
    /// 回复ID
    /// </summary>
    public List<string> Replies { get; set; }

    /// <summary>
    /// 是否删除
    /// </summary>
    public bool? IsDelete { get; set; }

    /// <summary>
    /// 回复
    /// </summary>
    public List<CommentChildren> Children { get; set; }

    private IMapper _mapper = new Mapper(new MapperConfiguration(x =>
    {
        x.CreateMap<MembleCommenter, VmMemberCommenter>();
        x.CreateMap<GuestCommenter, VmGuestCommenter>();
    }));

    public void CreateMappings(MapperConfigurationExpression cfg)
    {
        cfg.CreateMap<Comment, CommentViewModel>().ConvertUsing((entity, _) =>
        {
            if (entity.IsDelete == true)
            {
                entity.Commenter = new GuestCommenter
                {
                    Email = "",
                    NickName = "该用户发言已被删除",
                    Site = ""
                };
                entity.CommentText = "该用户发言因某些原因已被删除";
            }

            var viewModel = new CommentViewModel
            {
                Id = entity.Id.ToString(),
                Node = entity.Node,
                Relation = entity.Relation,
                PublishTime = entity.PublishTime.ToLocalTime(),
                CommentText = entity.CommentText,
                Replies = entity.Replies == null
                    ? new List<string>()
                    : entity.Replies.Select(x => x.ToString()).ToList(),
                IsDelete = entity.IsDelete,
                Children = new List<CommentChildren>(),
                Commenter = entity.Commenter switch
                {
                    MembleCommenter membleCommenter => _mapper.Map<VmMemberCommenter>(membleCommenter),
                    GuestCommenter guestCommenter => _mapper.Map<VmGuestCommenter>(guestCommenter),
                    _ => null
                }
            };

            return viewModel;
        });
    }
}

public class CommentChildren : IHaveCustomMapping
{
    public string Id { get; set; }

    /// <summary>
    /// 回复时间
    /// </summary>
    public DateTime PublishTime { get; set; }

    /// <summary>
    /// 评论人
    /// </summary>
    [JsonConverter(typeof(CommenterConverter))]
    public VmCommenter Commenter { get; set; }

    /// <summary>
    /// 回复内容
    /// </summary>
    public string CommentText { get; set; }

    /// <summary>
    /// 回复ID
    /// </summary>
    public List<string> Replies { get; set; }

    /// <summary>
    /// 是否删除
    /// </summary>
    public bool? IsDelete { get; set; }

    private IMapper _mapper = new Mapper(new MapperConfiguration(x =>
    {
        x.CreateMap<MembleCommenter, VmMemberCommenter>();
        x.CreateMap<GuestCommenter, VmGuestCommenter>();
    }));

    public void CreateMappings(MapperConfigurationExpression cfg)
    {
        cfg.CreateMap<Comment, CommentChildren>().ConvertUsing((entity, _) =>
        {
            if (entity.IsDelete == true)
            {
                entity.Commenter = new GuestCommenter
                {
                    Email = "",
                    NickName = "该用户发言已被删除",
                    Site = ""
                };
                entity.CommentText = "该用户发言因某些原因已被删除";
            }

            var viewModel = new CommentChildren
            {
                Id = entity.Id.ToString(),
                PublishTime = entity.PublishTime.ToLocalTime(),
                CommentText = entity.CommentText,
                Replies = entity.Replies.Select(x => x.ToString()).ToList(),
                IsDelete = entity.IsDelete,
                Commenter = entity.Commenter switch
                {
                    MembleCommenter membleCommenter => _mapper.Map<VmMemberCommenter>(membleCommenter),
                    GuestCommenter guestCommenter => _mapper.Map<VmGuestCommenter>(guestCommenter),
                    _ => null
                }
            };
            return viewModel;
        });
    }
}

public abstract class VmCommenter
{
    /// <summary>
    /// 昵称
    /// </summary>
    public string NickName { get; set; }
}

/// <summary>
/// 登录会员评论
/// </summary>
public class VmMemberCommenter : VmCommenter, IMapFrom<MembleCommenter>
{
    /// <summary>
    /// 头像
    /// </summary>
    public string Avatar { get; set; }

    /// <summary>
    /// 身份标识
    /// </summary>
    public string Identity { get; set; }
}

/// <summary>
/// 匿名评论
/// </summary>
public class VmGuestCommenter : VmCommenter, IMapFrom<GuestCommenter>
{
    /// <summary>
    /// 邮箱
    /// </summary>
    public string Email { get; set; } = "";

    /// <summary>
    /// 网站
    /// </summary>
    public string Site { get; set; }

    public string EmailMd5 { get; private set; }

    public void GenerateEmailMd5()
    {
        EmailMd5 = Email.GenerateHashMd5();
        Email = "";
    }
}

public class CommenterConverter : JsonConverter<VmCommenter>
{
    public override VmCommenter Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.Null) return null;

        if (reader.TokenType != JsonTokenType.StartObject)
            throw new JsonException("JsonTokenType.StartObject not found.");

        if (!reader.Read() || reader.TokenType != JsonTokenType.PropertyName
                           || reader.GetString() != "$type")
            throw new JsonException("Property $type not found.");

        if (!reader.Read() || reader.TokenType != JsonTokenType.String)
            throw new JsonException("Value at $type is invalid.");

        var typeStr = reader.GetString();
        var type = typeStr switch
        {
            "GuestCommenter" => typeof(VmGuestCommenter),
            "MemberCommenter" => typeof(VmMemberCommenter),
            _ => typeof(Commenter)
        };
        using var output = new MemoryStream();
        ReadObject(ref reader, output, options);
        var result = JsonSerializer.Deserialize(output.ToArray(), type, options);
        return result as VmCommenter;
    }
    
    private void ReadObject(ref Utf8JsonReader reader, Stream output, JsonSerializerOptions options)
    {
        using var writer = new Utf8JsonWriter(output, new JsonWriterOptions
        {
            Encoder = options.Encoder,
            Indented = options.WriteIndented
        });
        writer.WriteStartObject();
        var objectIntend = 0;

        while (reader.Read())
        {
            switch (reader.TokenType)
            {
                case JsonTokenType.None:
                case JsonTokenType.Null:
                    writer.WriteNullValue();
                    break;
                case JsonTokenType.StartObject:
                    writer.WriteStartObject();
                    objectIntend++;
                    break;
                case JsonTokenType.EndObject:
                    writer.WriteEndObject();
                    if (objectIntend == 0)
                    {
                        writer.Flush();
                        return;
                    }
                    objectIntend--;
                    break;
                case JsonTokenType.StartArray:
                    writer.WriteStartArray();
                    break;
                case JsonTokenType.EndArray:
                    writer.WriteEndArray();
                    break;
                case JsonTokenType.PropertyName:
                    writer.WritePropertyName(reader.GetString() ?? "");
                    break;
                case JsonTokenType.Comment:
                    writer.WriteCommentValue(reader.GetComment());
                    break;
                case JsonTokenType.String:
                    writer.WriteStringValue(reader.GetString());
                    break;
                case JsonTokenType.Number:
                    writer.WriteNumberValue(reader.GetInt32());
                    break;
                case JsonTokenType.True:
                case JsonTokenType.False:
                    writer.WriteBooleanValue(reader.GetBoolean());
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
    }

    public override void Write(Utf8JsonWriter writer, VmCommenter value, JsonSerializerOptions options)
    {
        writer.WriteStartObject();
        var valueType = value.GetType();
        //var valueAssemblyName = valueType.Assembly.GetName();
        writer.WriteString("$type", $"{valueType.Name.Replace("Vm", "")}");

        var json = JsonSerializer.Serialize(value, value.GetType(), options);
        using (var document = JsonDocument.Parse(json, new JsonDocumentOptions
        {
            AllowTrailingCommas = options.AllowTrailingCommas,
            MaxDepth = options.MaxDepth
        }))
        {
            foreach (var jsonProperty in document.RootElement.EnumerateObject())
                jsonProperty.WriteTo(writer);
        }

        writer.WriteEndObject();
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

上述代码定义了一个用于处理评论的视图模型(ViewModel)及其相关类,主要用于将评论数据从实体模型转换为适合前端展示的格式。以下是代码的主要功能和结构的详细解释:

1. CommentViewModel

  • 功能: 该类表示评论的视图模型,包含了评论的各种属性和相关信息。

  • 属性:

    • Id: 评论的唯一标识符。
    • Node: 评论的类型(使用 CommentNode 枚举)。
    • Relation: 评论关联的对象(如文章、帖子等)。
    • PublishTime: 评论的发布时间。
    • Commenter: 评论者的信息,使用多态处理(可以是匿名评论或会员评论)。
    • CommentText: 评论的内容。
    • Replies: 评论的回复ID列表。
    • IsDelete: 评论是否被删除的标志。
    • Children: 评论的子评论(回复)。
  • 映射: 使用 AutoMapper 将 Comment 实体映射到 CommentViewModel。在映射过程中,如果评论被标记为删除,则会用默认的删除信息替代评论者和评论内容。

2. CommentChildren

  • 功能: 该类表示评论的子评论(回复),结构与 CommentViewModel 类似。
  • 属性: 包含与 CommentViewModel 类似的属性,如 Id, PublishTime, Commenter, CommentText, Replies, IsDelete
  • 映射: 也使用 AutoMapper 将 Comment 实体映射到 CommentChildren

3. VmCommenter 抽象类

  • 功能: 该类是评论者的基类,包含评论者的基本信息。
  • 属性: 包含 NickName 属性。

4. VmMemberCommenterVmGuestCommenter

  • 功能: 这两个类分别表示会员评论者和匿名评论者,继承自 VmCommenter
  • 属性:
    • VmMemberCommenter 还包含 AvatarIdentity 属性。
    • VmGuestCommenter 包含 EmailSite 属性,并提供了一个方法 GenerateEmailMd5 用于生成邮箱的 MD5 哈希值。

5. CommenterConverter

  • 功能: 自定义 JSON 转换器,用于在序列化和反序列化过程中处理 VmCommenter 类型的对象。
  • 方法:
    • Read: 从 JSON 中读取评论者信息,并根据 $type 属性确定具体的评论者类型(会员或匿名)。
    • Write: 将 VmCommenter 对象序列化为 JSON,包含 $type 属性以指示具体类型。

总结

整体上,这段代码的目的是将评论数据从后端实体模型转换为适合前端展示的视图模型,支持多态处理评论者类型,并提供了自定义的 JSON 序列化和反序列化逻辑。通过使用 AutoMapper 和自定义 JSON 转换器,代码实现了灵活且可扩展的评论处理机制。

loading