XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEExtension.NetCore.ServerInteractive

[DLL] Server interaction extension, including user identity verification and querying in conjunction with AutoConfig

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Net;
using System.Text;
using System.Text.Json;
using XFEExtension.NetCore.DelegateExtension;
using XFEExtension.NetCore.ServerInteractive.Interfaces.Requester;
using XFEExtension.NetCore.ServerInteractive.Models;
using XFEExtension.NetCore.ServerInteractive.Models.RequesterModels;
using XFEExtension.NetCore.ServerInteractive.Utilities.Helpers;
using XFEExtension.NetCore.StringExtension.Json;

namespace XFEExtension.NetCore.ServerInteractive.Utilities.Requester;

/// <summary>
/// 表格请求器
/// </summary>
public class TableRequester : IRequesterBase
{
    /// <summary>
    /// 请求地址
    /// </summary>
    public string RequestAddress { get; set; } = string.Empty;
    /// <summary>
    /// 电脑信息
    /// </summary>
    public string DeviceInfo { get; set; } = string.Empty;
    /// <summary>
    /// 用户登录Session
    /// </summary>
    public string Session { get; set; } = string.Empty;
    /// <summary>
    /// Json序列化选项
    /// </summary>
    public JsonSerializerOptions? JsonSerializerOptions { get; set; }
    /// <summary>
    /// 请求消息返回事件
    /// </summary>
    public event XFEEventHandler<object?, ServerInteractiveEventArgs>? MessageReceived;

    private static string GetRequestName<T>() => $"{typeof(T).Name[0]}".ToLower() + typeof(T).Name[1..];

    /// <summary>
    /// 获取Table列表(分页)
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    /// <param name="tableName">表名称</param>
    /// <param name="pageSize">每页个数</param>
    /// <param name="page">当前页面</param>
    /// <returns>表内容</returns>
    public Task<TableRequestResult<T>> Get<T>(string tableName, int pageSize, int page) where T : IIdModel
        => GetAsync<T>(tableName, pageSize, page, CancellationToken.None);

    /// <summary>获取 Table 列表(分页、支持取消)。</summary>
    public async Task<TableRequestResult<T>> GetAsync<T>(string tableName, int pageSize, int page, CancellationToken cancellationToken) where T : IIdModel
    {
        try
        {
            if (pageSize != -1 && (pageSize is < 1 or > 1000 || page < 1))
                throw new ArgumentOutOfRangeException(nameof(pageSize), "pageSize 必须介于 1 和 1000 之间,page 必须大于等于 1");
            var requestUri = BuildTableUri("get", tableName);
            var (response, code) = await InteractiveHelper.GetServerResponse(requestUri, new
            {
                pageSize,
                page,
                session = Session,
                deviceInfo = DeviceInfo
            }, JsonSerializerOptions ?? new(), cancellationToken);
            if (code == HttpStatusCode.OK)
            {
                NotifyMessageReceived(new ServerInteractiveEventArgsImpl("Success", code));
                var result = JsonSerializer.Deserialize<TableRequestResult<T>>(response, JsonSerializerOptions);
                return result ?? new();
            }

            NotifyMessageReceived(new ServerInteractiveEventArgsImpl(response, code));
            return new();
        }
        catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
        {
            throw;
        }
        catch (Exception ex)
        {
            NotifyMessageReceived(new ServerInteractiveEventArgsImpl(ex.Message, HttpStatusCode.InternalServerError));
            return new();
        }
    }

    /// <summary>
    /// 获取Table列表(分页)
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    /// <returns>表内容</returns>
    public Task<TableRequestResult<T>> Get<T>(int pageSize, int page) where T : IIdModel => Get<T>(GetRequestName<T>(), pageSize, page);

    /// <summary>获取默认名称的 Table 列表(分页、支持取消)。</summary>
    public Task<TableRequestResult<T>> GetAsync<T>(int pageSize, int page, CancellationToken cancellationToken) where T : IIdModel
        => GetAsync<T>(GetRequestName<T>(), pageSize, page, cancellationToken);

    /// <summary>
    /// 获取Table列表
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    /// <returns>表内容</returns>
    public Task<TableRequestResult<T>> Get<T>() where T : IIdModel => Get<T>(-1, -1);

    /// <summary>
    /// 向表中添加一个数据
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    /// <param name="tableName">表名称</param>
    /// <param name="data">数据</param>
    /// <returns>是否添加成功</returns>
    public Task<bool> Add<T>(string tableName, T data) where T : IIdModel
        => AddAsync(tableName, data, CancellationToken.None);

    /// <summary>向 Table 添加数据(支持取消)。</summary>
    public async Task<bool> AddAsync<T>(string tableName, T data, CancellationToken cancellationToken) where T : IIdModel
    {
        try
        {
            var (response, code) = await InteractiveHelper.GetServerResponse(BuildTableUri("add", tableName), new
            {
                data = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(data, JsonSerializerOptions))),
                session = Session,
                deviceInfo = DeviceInfo
            }, JsonSerializerOptions ?? new(), cancellationToken);
            if ((int)code is >= 200 and < 300)
            {
                NotifyMessageReceived(new ServerInteractiveEventArgsImpl("Success", code));
                return true;
            }

            NotifyMessageReceived(new ServerInteractiveEventArgsImpl(response, code));
            return false;
        }
        catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
        {
            throw;
        }
        catch (Exception ex)
        {
            NotifyMessageReceived(new ServerInteractiveEventArgsImpl(ex.Message, HttpStatusCode.InternalServerError));
            return false;
        }
    }

    /// <summary>
    /// 向表中添加一个数据
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    /// <param name="data">数据</param>
    /// <returns>是否添加成功</returns>
    public Task<bool> Add<T>(T data) where T : IIdModel => Add(GetRequestName<T>(), data);

    /// <summary>向默认名称的 Table 添加数据(支持取消)。</summary>
    public Task<bool> AddAsync<T>(T data, CancellationToken cancellationToken) where T : IIdModel
        => AddAsync(GetRequestName<T>(), data, cancellationToken);

    /// <summary>
    /// 从表中删除一个数据
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    /// <param name="tableName">表名称</param>
    /// <param name="id">元素的ID</param>
    /// <returns>是否删除成功</returns>
    public Task<bool> Remove<T>(string tableName, string id) where T : IIdModel
        => RemoveAsync<T>(tableName, id, CancellationToken.None);

    /// <summary>从 Table 删除数据(支持取消)。</summary>
    public async Task<bool> RemoveAsync<T>(string tableName, string id, CancellationToken cancellationToken) where T : IIdModel
    {
        try
        {
            var (response, code) = await InteractiveHelper.GetServerResponse(BuildTableUri("remove", tableName), new
            {
                id,
                session = Session,
                deviceInfo = DeviceInfo
            }, JsonSerializerOptions ?? new(), cancellationToken);
            if ((int)code is >= 200 and < 300)
            {
                NotifyMessageReceived(new ServerInteractiveEventArgsImpl("Success", code));
                return true;
            }

            NotifyMessageReceived(new ServerInteractiveEventArgsImpl(response, code));
            return false;
        }
        catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
        {
            throw;
        }
        catch (Exception ex)
        {
            NotifyMessageReceived(new ServerInteractiveEventArgsImpl(ex.Message, HttpStatusCode.InternalServerError));
            return false;
        }
    }

    /// <summary>
    /// 从表中删除一个数据
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    /// <param name="id">元素的ID</param>
    /// <returns>是否删除成功</returns>
    public Task<bool> Remove<T>(string id) where T : IIdModel => Remove<T>(GetRequestName<T>(), id);

    /// <summary>从默认名称的 Table 删除数据(支持取消)。</summary>
    public Task<bool> RemoveAsync<T>(string id, CancellationToken cancellationToken) where T : IIdModel
        => RemoveAsync<T>(GetRequestName<T>(), id, cancellationToken);

    /// <summary>
    /// 更改表中的数据
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    /// <param name="tableName">表名称</param>
    /// <param name="data">数据</param>
    /// <returns></returns>
    public Task<bool> Change<T>(string tableName, T data) where T : IIdModel
        => ChangeAsync(tableName, data, CancellationToken.None);

    /// <summary>更改 Table 数据(支持取消)。</summary>
    public async Task<bool> ChangeAsync<T>(string tableName, T data, CancellationToken cancellationToken) where T : IIdModel
    {
        try
        {
            var (response, code) = await InteractiveHelper.GetServerResponse(BuildTableUri("change", tableName), new
            {
                data = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(data, JsonSerializerOptions))),
                session = Session,
                deviceInfo = DeviceInfo
            }, JsonSerializerOptions ?? new(), cancellationToken);
            if ((int)code is >= 200 and < 300)
            {
                NotifyMessageReceived(new ServerInteractiveEventArgsImpl("Success", code));
                return true;
            }

            NotifyMessageReceived(new ServerInteractiveEventArgsImpl(response, code));
            return false;
        }
        catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
        {
            throw;
        }
        catch (Exception ex)
        {
            NotifyMessageReceived(new ServerInteractiveEventArgsImpl(ex.Message, HttpStatusCode.InternalServerError));
            return false;
        }
    }

    /// <summary>
    /// 更改表中的数据
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    /// <param name="data">数据</param>
    /// <returns>是否修改成功</returns>
    public Task<bool> Change<T>(T data) where T : IIdModel => Change(GetRequestName<T>(), data);

    /// <summary>更改默认名称的 Table 数据(支持取消)。</summary>
    public Task<bool> ChangeAsync<T>(T data, CancellationToken cancellationToken) where T : IIdModel
        => ChangeAsync(GetRequestName<T>(), data, cancellationToken);

    private Uri BuildTableUri(string operation, string tableName) =>
        InteractiveHelper.BuildRequestUri(RequestAddress, $"table/{operation}/{Uri.EscapeDataString(tableName)}");

    private void NotifyMessageReceived(ServerInteractiveEventArgs args)
    {
        try { MessageReceived?.Invoke(this, args); } catch (Exception) { }
    }
}