🍓 feat(Http): 新增客户端名称和接口描述字段

This commit is contained in:
喵你个汪呀 2025-08-20 19:52:07 +08:00
parent 2c0067d563
commit 064d91e4ce
8 changed files with 91 additions and 3 deletions

View File

@ -0,0 +1,25 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 远程请求接口特性
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class HttpRemoteApiAttribute : Attribute
{
/// <summary>
/// 编码
/// </summary>
[Required]
public string Code { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Desc { get; set; }
}

View File

@ -36,4 +36,15 @@ public class CommonConst
/// 事件-发送异常邮件
/// </summary>
public const string SendErrorMail = "Send:ErrorMail";
/// <summary>
/// 远程请求配置客户端名称键名
/// </summary>
public const string HttpRemoteClientName = "__HTTP_CLIENT_NAME__";
/// <summary>
/// 远程请求请求头接口描述键值
/// </summary>
public const string HttpRemoteApiDescHeaderName = "__HTTP_CLIENT_API_DESC__";
}

View File

@ -16,6 +16,20 @@ namespace Admin.NET.Core;
[LogTable]
public partial class SysLogHttp : EntityBaseId
{
/// <summary>
/// 客户端名称
/// </summary>
[SugarColumn(ColumnDescription = "客户端名称", Length = 32)]
[MaxLength(32)]
public string? HttpClientName { get; set; }
/// <summary>
/// 接口描述
/// </summary>
[SugarColumn(ColumnDescription = "接口描述", Length = 32)]
[MaxLength(32)]
public string? HttpApiDesc { get; set; }
/// <summary>
/// 请求方式
/// </summary>

View File

@ -11,7 +11,6 @@ namespace Admin.NET.Core;
/// </summary>
public class HttpLoggingHandler : DelegatingHandler, ITransient
{
private const string HttpName = "__HTTP_CLIENT_NAME__";
private readonly Dictionary<string, bool> _enabledLogMap;
private readonly SysConfigService _sysConfigService;
private readonly IEventPublisher _eventPublisher;
@ -35,11 +34,17 @@ public class HttpLoggingHandler : DelegatingHandler, ITransient
if (!enabledLog) return await base.SendAsync(request, cancellationToken);
// 判断当前配置日志开关
request.Options.TryGetValue<string>(HttpName, out var clientName);
request.Options.TryGetValue<string>(CommonConst.HttpRemoteClientName, out var clientName);
if (!string.IsNullOrWhiteSpace(clientName)) enabledLog = _enabledLogMap.GetOrDefault(clientName);
if (!enabledLog) return await base.SendAsync(request, cancellationToken);
var sysLogHttp = new SysLogHttp();
sysLogHttp.HttpClientName = clientName;
// 获取接口描述,并移除
sysLogHttp.HttpApiDesc = request.Headers.FirstOrDefault(u => u.Key == CommonConst.HttpRemoteApiDescHeaderName).Value?.FirstOrDefault();
request.Headers.Remove(CommonConst.HttpRemoteApiDescHeaderName);
sysLogHttp.HttpMethod = request.Method.Method;
sysLogHttp.RequestUrl = request.RequestUri?.ToString();
sysLogHttp.RequestHeaders = request.Headers.ToDictionary(u => u.Key, u => u.Value.Join(";")).ToJson();

View File

@ -87,6 +87,16 @@ public class PageLogHttpInput : BasePageInput
/// </summary>
public string SearchKey { get; set; }
/// <summary>
/// 客户端名称
/// </summary>
public string HttpClientName { get; set; }
/// <summary>
/// 请求接口描述
/// </summary>
public string HttpApiDesc { get; set; }
/// <summary>
/// 请求方式
/// </summary>

View File

@ -32,7 +32,9 @@ public class SysLogHttpService : IDynamicApiController, ITransient
{
input.Keyword = input.Keyword?.Trim();
var query = _sysLogHttpRep.AsQueryable()
.WhereIF(!string.IsNullOrWhiteSpace(input.Keyword), u => u.RequestUrl.Contains(input.Keyword) || u.RequestBody.Contains(input.Keyword) || u.ResponseBody.Contains(input.Keyword) || u.Exception.Contains(input.Keyword))
.WhereIF(!string.IsNullOrWhiteSpace(input.Keyword), u => u.HttpClientName.Contains(input.Keyword) || u.HttpApiDesc.Contains(input.Keyword) || u.RequestUrl.Contains(input.Keyword) || u.RequestBody.Contains(input.Keyword) || u.ResponseBody.Contains(input.Keyword) || u.Exception.Contains(input.Keyword))
.WhereIF(!string.IsNullOrWhiteSpace(input.HttpClientName), u => u.HttpClientName.Contains(input.HttpClientName.Trim()))
.WhereIF(!string.IsNullOrWhiteSpace(input.HttpApiDesc), u => u.HttpApiDesc.Contains(input.HttpApiDesc.Trim()))
.WhereIF(!string.IsNullOrWhiteSpace(input.RequestUrl), u => u.RequestUrl.Contains(input.RequestUrl.Trim()))
.WhereIF(!string.IsNullOrWhiteSpace(input.RequestBody), u => u.RequestBody.Contains(input.RequestBody.Trim()))
.WhereIF(!string.IsNullOrWhiteSpace(input.ResponseBody), u => u.ResponseBody.Contains(input.ResponseBody.Trim()))
@ -55,6 +57,9 @@ public class SysLogHttpService : IDynamicApiController, ITransient
public async Task<List<SysLogHttp>> GetList([FromQuery] PageLogHttpInput input)
{
return await _sysLogHttpRep.AsQueryable()
.WhereIF(!string.IsNullOrWhiteSpace(input.Keyword), u => u.HttpClientName.Contains(input.Keyword) || u.HttpApiDesc.Contains(input.Keyword) || u.RequestUrl.Contains(input.Keyword) || u.RequestBody.Contains(input.Keyword) || u.ResponseBody.Contains(input.Keyword) || u.Exception.Contains(input.Keyword))
.WhereIF(!string.IsNullOrWhiteSpace(input.HttpClientName), u => u.HttpClientName.Contains(input.HttpClientName.Trim()))
.WhereIF(!string.IsNullOrWhiteSpace(input.HttpApiDesc), u => u.HttpApiDesc.Contains(input.HttpApiDesc.Trim()))
.WhereIF(!string.IsNullOrWhiteSpace(input.RequestUrl?.Trim()), u => u.RequestUrl.Contains(input.RequestUrl.Trim()))
.WhereIF(!string.IsNullOrWhiteSpace(input.RequestBody?.Trim()), u => u.RequestBody.Contains(input.RequestBody.Trim()))
.WhereIF(!string.IsNullOrWhiteSpace(input.ResponseBody?.Trim()), u => u.ResponseBody.Contains(input.ResponseBody.Trim()))

View File

@ -10,6 +10,12 @@
<el-form :model="data" label-width="auto">
<el-tabs v-model="state.selectedTabName">
<el-tab-pane label="请求信息">
<el-form-item label="客户端">
{{ data.httpClientName }}
</el-form-item>
<el-form-item label="接口描述">
{{ data.httpApiDesc }}
</el-form-item>
<el-form-item label="请求地址">
{{ data.requestUrl?.indexOf('?') == -1 ? data.requestUrl : data.requestUrl?.substring(0, data.requestUrl.indexOf('?')) }}
</el-form-item>

View File

@ -6,6 +6,16 @@
<el-card shadow="hover" :body-style="{ padding: '5px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
<el-form :model="state.queryParams" ref="queryForm" :show-message="false" :inlineMessage="true" label-width="auto" style="flex: 1 1 0%">
<el-row :gutter="10">
<el-col class="mb5" :sm="12" :md="8" :lg="6" :xl="6">
<el-form-item label="客户端" prop="httpClientName">
<el-input v-model="state.queryParams.httpClientName" placeholder="请输入客户端" clearable @keyup.enter.native="handleQuery(true)" />
</el-form-item>
</el-col>
<el-col class="mb5" :sm="12" :md="8" :lg="6" :xl="6">
<el-form-item label="接口描述" prop="httpApiDesc">
<el-input v-model="state.queryParams.httpApiDesc" placeholder="请输入接口描述" clearable @keyup.enter.native="handleQuery(true)" />
</el-form-item>
</el-col>
<el-col class="mb5" :sm="12" :md="8" :lg="6" :xl="6">
<el-form-item label="请求方式" prop="httpMethod">
<el-input v-model="state.queryParams.httpMethod" placeholder="请输入请求方式" clearable @keyup.enter.native="handleQuery(true)" />
@ -144,8 +154,10 @@ const options = useVxeTable<PageLogHttpOutput>(
// { type: 'checkbox', width: 40, fixed: 'left' },
{ field: 'seq', type: 'seq', title: '序号', width: 60, fixed: 'left' },
{ field: 'createTime', title: '创建时间', minWidth: 150, showOverflow: 'tooltip' },
{ field: 'httpClientName', title: '客户端', minWidth: 110, showOverflow: 'tooltip' },
{ field: 'httpMethod', title: '请求方式', minWidth: 60, showOverflow: 'tooltip' },
{ field: 'isSuccessStatusCode', title: '是否成功', minWidth: 60, showOverflow: 'tooltip', slots: { default: 'row_isSuccessStatusCode' } },
{ field: 'httpApiDesc', title: '接口描述', minWidth: 150, showOverflow: 'tooltip' },
{ field: 'requestUrl', title: '请求地址', minWidth: 150, align: 'left', showOverflow: 'tooltip', slots: { default: 'row_requestUrl' } },
{ field: 'requestHeaders', title: '请求头', minWidth: 150, showOverflow: 'tooltip' },
{ field: 'requestBody', title: '请求体', minWidth: 150, showOverflow: 'tooltip', slots: { default: 'row_requestBody' } },