From 9d7edad80a7da6337038b3621aac583193c4a780 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=B0=8F=E8=82=A5=E7=BE=8A?= <1048382248@qq.com>
Date: Thu, 12 Feb 2026 10:30:34 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20API=E6=9C=8D=E5=8A=A1?=
=?UTF-8?q?=E7=9A=84=E9=83=A8=E5=88=86=E6=B5=81=E7=A8=8B=E9=97=AE=E9=A2=98?=
=?UTF-8?q?=20=E6=96=B0=E5=A2=9E=20API=E6=9C=8D=E5=8A=A1=E7=9A=84=E6=97=A5?=
=?UTF-8?q?=E5=BF=97=E8=AF=B7=E6=B1=82=E5=86=99=E5=85=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Learn.VideoAnalysis.API/Expand/HttpFilter.cs | 279 ++++++++++++++++++
Learn.VideoAnalysis.API/Program.cs | 23 +-
VideoAnalysisCore/AICore/GPT/BserGPT.cs | 1 +
.../AICore/GPT/DeepSeek/DeepSeekGPTClient.cs | 10 +-
.../AICore/GPT/GTP_Analysis_1.cs | 24 +-
.../AICore/GPT/Gemini/GeminiGPTClient.cs | 9 +-
VideoAnalysisCore/Common/Dto/BaseReturn.cs | 34 +++
VideoAnalysisCore/Common/Dto/ComboModel.cs | 26 ++
VideoAnalysisCore/Common/Dto/PageResult.cs | 16 +
VideoAnalysisCore/Common/OhException.cs | 67 +++++
.../Controllers/LJZK_Controller.cs | 13 +-
VideoAnalysisCore/Model/HttpLog.cs | 79 +++++
12 files changed, 550 insertions(+), 31 deletions(-)
create mode 100644 Learn.VideoAnalysis.API/Expand/HttpFilter.cs
create mode 100644 VideoAnalysisCore/Common/Dto/BaseReturn.cs
create mode 100644 VideoAnalysisCore/Common/Dto/ComboModel.cs
create mode 100644 VideoAnalysisCore/Common/Dto/PageResult.cs
create mode 100644 VideoAnalysisCore/Common/OhException.cs
create mode 100644 VideoAnalysisCore/Model/HttpLog.cs
diff --git a/Learn.VideoAnalysis.API/Expand/HttpFilter.cs b/Learn.VideoAnalysis.API/Expand/HttpFilter.cs
new file mode 100644
index 0000000..ade2cd9
--- /dev/null
+++ b/Learn.VideoAnalysis.API/Expand/HttpFilter.cs
@@ -0,0 +1,279 @@
+using Microsoft.AspNetCore.Mvc.Controllers;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Filters;
+using System;
+using System.Linq;
+using Microsoft.AspNetCore.Http;
+using SqlSugar;
+using Microsoft.AspNetCore.Mvc.Infrastructure;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+using System.Diagnostics;
+using System.Text.Json;
+using System.Collections.Generic;
+using System.Data;
+using Microsoft.Extensions.Hosting;
+using System.IO;
+using Microsoft.AspNetCore.Hosting;
+using SqlSugar.IOC;
+using Microsoft.AspNetCore.Authorization;
+using VideoAnalysisCore.Common.Dto;
+using VideoAnalysisCore.Common;
+using VideoAnalysisCore.Model;
+
+namespace Learn.VideoAnalysis.API.Expand
+{
+
+ ///
+ /// 使用该属性,接口对结果原样输出,不做包装
+ ///
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = false)]
+ public class ResultIgnore : Attribute { }
+
+ ///
+ /// http接口日志启用
+ ///
+ public class HttpLogEnable : Attribute { }
+
+ ///
+ /// Http请求过滤器
+ ///
+ public class HttpLogAttribute : ActionFilterAttribute, IAsyncExceptionFilter
+ {
+ readonly Stopwatch _stopwatch;//统计程序耗时
+
+ public HttpLogAttribute()
+ {
+ _stopwatch = Stopwatch.StartNew();
+ }
+
+ ///
+ /// 执行接口前文件做缓存处理
+ ///
+ ///
+ ///
+ public void ExecutingFileCached(ActionExecutingContext context)
+ {
+ //特殊处理:ResultIgnore,不进行返回结果包装,原样输出
+ var endpoint = context.HttpContext.GetEndpoint();
+ // 直接返回原始结果,不封装
+ if (endpoint?.Metadata.GetMetadata() == null) return;
+ if (context.HttpContext.Request.HasFormContentType &&
+ context.HttpContext.Request.Form.Files != null &&
+ context.HttpContext.Request.Form.Files.Count() > 0)
+ {
+ context.HttpContext.Items["FileCached"]=
+ context.HttpContext.Request.Form.Files.Select(s =>
+ {
+ var stream = new MemoryStream();
+ s.CopyTo(stream);
+ stream.Position = 0;
+ return (s, stream);
+ }).ToArray();
+ }
+
+ }
+ ///
+ /// 执行接口前400 处理
+ ///
+ ///
+ ///
+ public void Executing400(ActionExecutingContext context)
+ {
+ if (!context.ModelState.IsValid)
+ {
+ var errMsg = string.Join(',', context.ModelState.Values.SelectMany(s => s.Errors.Select(e => e.ErrorMessage)));
+ Oh.ModelError(errMsg);
+ }
+ }
+ private bool HasAttribute(ActionExecutedContext context) where T : Attribute
+ {
+ if (context.ActionDescriptor is ControllerActionDescriptor descriptor)
+ {
+ // 检查方法上是否有 SkipApiResultAttribute
+ if (descriptor.MethodInfo.GetCustomAttributes(typeof(T), false).Any())
+ return true;
+ // 检查控制器上是否有 SkipApiResultAttribute
+ if (descriptor.ControllerTypeInfo.GetCustomAttributes(typeof(T), false).Any())
+ return true;
+ }
+ return false;
+ }
+ ///
+ /// 接口结果格式化
+ ///
+ ///
+ public BaseReturn