parent
dac6eee091
commit
9d7edad80a
|
|
@ -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
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用该属性,接口对结果原样输出,不做包装
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = false)]
|
||||||
|
public class ResultIgnore : Attribute { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// http接口日志启用
|
||||||
|
/// </summary>
|
||||||
|
public class HttpLogEnable : Attribute { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Http请求过滤器
|
||||||
|
/// </summary>
|
||||||
|
public class HttpLogAttribute : ActionFilterAttribute, IAsyncExceptionFilter
|
||||||
|
{
|
||||||
|
readonly Stopwatch _stopwatch;//统计程序耗时
|
||||||
|
|
||||||
|
public HttpLogAttribute()
|
||||||
|
{
|
||||||
|
_stopwatch = Stopwatch.StartNew();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 执行接口前文件做缓存处理
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
/// <exception cref="CustomException"></exception>
|
||||||
|
public void ExecutingFileCached(ActionExecutingContext context)
|
||||||
|
{
|
||||||
|
//特殊处理:ResultIgnore,不进行返回结果包装,原样输出
|
||||||
|
var endpoint = context.HttpContext.GetEndpoint();
|
||||||
|
// 直接返回原始结果,不封装
|
||||||
|
if (endpoint?.Metadata.GetMetadata<HttpLogEnable>() == 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 执行接口前400 处理
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
/// <exception cref="CustomException"></exception>
|
||||||
|
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<T>(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;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 接口结果格式化
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
public BaseReturn<object>? ApiResultFormatting(ActionExecutedContext context)
|
||||||
|
{
|
||||||
|
//特殊处理:ResultIgnore,不进行返回结果包装,原样输出
|
||||||
|
if (HasAttribute<ResultIgnore>(context))
|
||||||
|
{
|
||||||
|
base.OnActionExecuted(context);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 返回结果为JsonResult的请求进行Result包装
|
||||||
|
if (context.Exception != null)
|
||||||
|
throw context.Exception;
|
||||||
|
if (context.Result != null)
|
||||||
|
{
|
||||||
|
object? resData = null;
|
||||||
|
if (context.Result is ObjectResult objectResult)
|
||||||
|
resData = objectResult.Value;
|
||||||
|
else if (context.Result is ContentResult contentRes)
|
||||||
|
resData = contentRes.Content;
|
||||||
|
else if (context.Result is JsonResult resJ)
|
||||||
|
resData = resJ.Value;
|
||||||
|
else if (context.Result is FileResult)
|
||||||
|
return null;
|
||||||
|
var code = (context?.Result as IStatusCodeActionResult)?.StatusCode ?? 200;
|
||||||
|
var res = new BaseReturn<object>()
|
||||||
|
{
|
||||||
|
Code = code,
|
||||||
|
Data = resData,
|
||||||
|
Message = "SUCCESS"
|
||||||
|
};
|
||||||
|
//不对返回结果结果做修改
|
||||||
|
//context.Result = new JsonResult(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 添加http日志信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
/// <param name="result"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task AddHttpLogAsync(HttpContext context, BaseReturn<object>? result = null, Exception? e = null)
|
||||||
|
{
|
||||||
|
//特殊处理:ResultIgnore,不进行返回结果包装,原样输出
|
||||||
|
var endpoint = context.GetEndpoint();
|
||||||
|
// 所有请求都记录
|
||||||
|
//if (endpoint?.Metadata.GetMetadata<HttpLogEnable>() == null&& e is null) return;
|
||||||
|
|
||||||
|
string request = null;
|
||||||
|
var logId = Yitter.IdGenerator.YitIdHelper.NextId();
|
||||||
|
if (!context.Request.Method.Equals("GET", StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
//记录请求参数
|
||||||
|
if (context.Request.Body.CanSeek)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var fileArr = context.Items.ContainsKey("FileCached") ? context.Items["FileCached"] as (IFormFile file, MemoryStream stream)[] : null;
|
||||||
|
if (context.Request.HasFormContentType && fileArr != null)
|
||||||
|
{
|
||||||
|
// 设置保存目录(例如:项目根目录下的Uploads文件夹)
|
||||||
|
string uploadsFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UploadLogs", logId.ToString());
|
||||||
|
// 创建目录(如果不存在)
|
||||||
|
if (!Directory.Exists(uploadsFolder))
|
||||||
|
Directory.CreateDirectory(uploadsFolder);
|
||||||
|
foreach (var fileInfo in fileArr)
|
||||||
|
{
|
||||||
|
// 生成安全文件名(防止路径遍历攻击)
|
||||||
|
string uniqueFileName = Guid.NewGuid().ToString().Substring(0, 5) + "_" + Path.GetFileName(fileInfo.file.FileName);
|
||||||
|
// 保存文件
|
||||||
|
using var stream = new FileStream(Path.Combine(uploadsFolder, uniqueFileName), FileMode.Create, FileAccess.Write);
|
||||||
|
fileInfo.stream.Position = 0;
|
||||||
|
await fileInfo.stream.CopyToAsync(stream);
|
||||||
|
fileInfo.stream.Dispose();
|
||||||
|
}
|
||||||
|
request = $"请求体包含{context.Request.Form.Files.Count()}个文件 目录 {uploadsFolder}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.Request.Body.Position = 0;
|
||||||
|
using var sr = new System.IO.StreamReader(context.Request.Body);
|
||||||
|
request = await sr.ReadToEndAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
request = "处理请求入参时发生了错误 \r\n" + ex.ToString() + "\r\n 原有请求数据 " + request;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//写入队列
|
||||||
|
await DbScoped.Sugar.CopyNew()
|
||||||
|
.Insertable<HttpLog>(new HttpLog
|
||||||
|
{
|
||||||
|
Id = logId,
|
||||||
|
Url = context.Request.Path + context.Request.QueryString,
|
||||||
|
Method = context.Request.Method,
|
||||||
|
Request = request,
|
||||||
|
IP = $"{context.Connection?.RemoteIpAddress?.ToString()}",
|
||||||
|
ResponseCode = result?.Code ?? -1,
|
||||||
|
Response = (result != null ? JsonSerializer.Serialize(result) : null) ,
|
||||||
|
Authorization = context.Request.Headers.ContainsKey("Authorization")
|
||||||
|
? context.Request.Headers["Authorization"].ToString()
|
||||||
|
: string.Empty,
|
||||||
|
Exception = e?.ToString(),
|
||||||
|
ExceptionMessage = e?.Message,
|
||||||
|
AdminId = 0,
|
||||||
|
TotalMilliseconds = (double)_stopwatch.Elapsed.TotalMilliseconds
|
||||||
|
}).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override async void OnActionExecuting(ActionExecutingContext context)
|
||||||
|
{
|
||||||
|
// 过期的
|
||||||
|
//if (context.HttpContext.GetEndpoint()?
|
||||||
|
// .Metadata.GetMetadata<IAllowAnonymous>() is null)
|
||||||
|
//{
|
||||||
|
// context.Result = new UnauthorizedResult();
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
Executing400(context);
|
||||||
|
ExecutingFileCached(context);
|
||||||
|
base.OnActionExecuting(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在Controller的Action执行后执行
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
public override async void OnActionExecuted(ActionExecutedContext context)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
BaseReturn<object>? res = ApiResultFormatting(context);
|
||||||
|
await AddHttpLogAsync(context.HttpContext, res);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnActionExecuted(context);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 执行错误时
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task OnExceptionAsync(ExceptionContext context)
|
||||||
|
{
|
||||||
|
var code = -1;
|
||||||
|
var msg = context.Exception.Message;
|
||||||
|
if (context.Exception is OhException exception)
|
||||||
|
code = exception.Code;
|
||||||
|
var result = new BaseReturn()
|
||||||
|
{
|
||||||
|
Code = code,
|
||||||
|
Message = context.Exception.Message
|
||||||
|
};
|
||||||
|
context.Result = new JsonResult(result);
|
||||||
|
await AddHttpLogAsync(context.HttpContext, null, context.Exception);
|
||||||
|
if (code == 401 || code == 403)
|
||||||
|
context.HttpContext.Response.StatusCode = code;
|
||||||
|
context.ExceptionHandled = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,9 @@
|
||||||
using Learn.VideoAnalysis.API.Expand;
|
using Learn.VideoAnalysis.API.Expand;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Unicode;
|
||||||
using VideoAnalysisCore.AICore.FFMPGE;
|
using VideoAnalysisCore.AICore.FFMPGE;
|
||||||
using VideoAnalysisCore.AICore.GPT.DeepSeek;
|
using VideoAnalysisCore.AICore.GPT.DeepSeek;
|
||||||
using VideoAnalysisCore.AICore.SherpaOnnx;
|
using VideoAnalysisCore.AICore.SherpaOnnx;
|
||||||
|
|
@ -18,8 +21,17 @@ namespace Learn.VideoAnalysis.API
|
||||||
|
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
|
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers(options =>
|
||||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
{
|
||||||
|
// 全局模型赋值默认值 和 统一返回格式处理
|
||||||
|
options.Filters.Add<HttpLogAttribute>();
|
||||||
|
}).AddJsonOptions(options =>
|
||||||
|
{
|
||||||
|
|
||||||
|
options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);//中文转换时不使用Unicode
|
||||||
|
//options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;// 默认小驼峰 null 大驼峰
|
||||||
|
});
|
||||||
|
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddSwaggerGen(c =>
|
builder.Services.AddSwaggerGen(c =>
|
||||||
{
|
{
|
||||||
|
|
@ -42,10 +54,8 @@ namespace Learn.VideoAnalysis.API
|
||||||
|
|
||||||
builder.Services.AddCoravel();
|
builder.Services.AddCoravel();
|
||||||
builder.Services.AddCorsExpand();
|
builder.Services.AddCorsExpand();
|
||||||
builder.Services.AddDownloadFileExpand();
|
|
||||||
builder.Services.AddFFMPGEExpand();
|
|
||||||
builder.Services.AddSenseVoiceExpand();
|
|
||||||
builder.Services.AddHttpContextAccessor();
|
|
||||||
builder.Services.AddControllersWithViews(options =>
|
builder.Services.AddControllersWithViews(options =>
|
||||||
{
|
{
|
||||||
options.Filters.Add(typeof(ExceptionFilter));
|
options.Filters.Add(typeof(ExceptionFilter));
|
||||||
|
|
@ -62,7 +72,6 @@ namespace Learn.VideoAnalysis.API
|
||||||
|
|
||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
|
|
||||||
app.UseAuthorization();
|
|
||||||
|
|
||||||
|
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ using Microsoft.Extensions.DependencyInjection;
|
||||||
using VideoAnalysisCore.AICore.GPT.ChatGPT;
|
using VideoAnalysisCore.AICore.GPT.ChatGPT;
|
||||||
using VideoAnalysisCore.AICore.GPT.DeepSeek;
|
using VideoAnalysisCore.AICore.GPT.DeepSeek;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
using VideoAnalysisCore.AICore.GPT.Gemini;
|
||||||
|
|
||||||
namespace VideoAnalysisCore.AICore.GPT
|
namespace VideoAnalysisCore.AICore.GPT
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,10 @@ using System.Net.Http;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Net.Http.Json;
|
using System.Net.Http.Json;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using VideoAnalysisCore.AICore.GPT.DeepSeek;
|
|
||||||
using VideoAnalysisCore.AICore.GPT;
|
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
|
|
||||||
namespace VideoAnalysisCore.AICore.GPT.ChatGPT
|
namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
||||||
{
|
{
|
||||||
|
|
||||||
public class DeepSeekGPTClient : GPTClient
|
public class DeepSeekGPTClient : GPTClient
|
||||||
|
|
@ -24,7 +22,7 @@ namespace VideoAnalysisCore.AICore.GPT.ChatGPT
|
||||||
private readonly RedisManager redisManager;
|
private readonly RedisManager redisManager;
|
||||||
|
|
||||||
public DeepSeekGPTClient(IHttpClientFactory httpClientFactory, RedisManager redisManager)
|
public DeepSeekGPTClient(IHttpClientFactory httpClientFactory, RedisManager redisManager)
|
||||||
:base(httpClientFactory, redisManager)
|
: base(httpClientFactory, redisManager)
|
||||||
{
|
{
|
||||||
_httpClientFactory = httpClientFactory;
|
_httpClientFactory = httpClientFactory;
|
||||||
this.redisManager = redisManager;
|
this.redisManager = redisManager;
|
||||||
|
|
@ -48,7 +46,7 @@ namespace VideoAnalysisCore.AICore.GPT.ChatGPT
|
||||||
new Message(postMessages,"user"),
|
new Message(postMessages,"user"),
|
||||||
];
|
];
|
||||||
messageArr = messageArr.Where(s => s != null).ToArray();
|
messageArr = messageArr.Where(s => s != null).ToArray();
|
||||||
if (max_tokens > 8000 &&(model is null || model == ChatGPTType.Deepseek_Chat))
|
if (max_tokens > 8000 && (model is null || model == ChatGPTType.Deepseek_Chat))
|
||||||
max_tokens = 8000;
|
max_tokens = 8000;
|
||||||
var chatReq = new ChatRequest
|
var chatReq = new ChatRequest
|
||||||
{
|
{
|
||||||
|
|
@ -59,7 +57,7 @@ namespace VideoAnalysisCore.AICore.GPT.ChatGPT
|
||||||
stream = true,
|
stream = true,
|
||||||
messages = messageArr
|
messages = messageArr
|
||||||
};
|
};
|
||||||
return await base.ChatAsync<T>(chatReq);
|
return await ChatAsync<T>(chatReq);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,15 @@ using System.Text.RegularExpressions;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using Dm.util;
|
using Dm.util;
|
||||||
using static System.Net.Mime.MediaTypeNames;
|
using static System.Net.Mime.MediaTypeNames;
|
||||||
|
using VideoAnalysisCore.AICore.GPT.DeepSeek;
|
||||||
|
using VideoAnalysisCore.AICore.GPT.Gemini;
|
||||||
|
|
||||||
namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
namespace VideoAnalysisCore.AICore.GPT
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 视频分析工作流1
|
/// 视频分析工作流1
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GTP_Analysis_1 : IBserGPTWorkflow
|
public class GTP_Analysis_1 : IBserGPTWorkflow
|
||||||
{
|
{
|
||||||
private readonly GeminiGPTClient geminiClient;
|
private readonly GeminiGPTClient geminiClient;
|
||||||
private readonly DeepSeekGPTClient deepSeekClient;
|
private readonly DeepSeekGPTClient deepSeekClient;
|
||||||
|
|
@ -134,7 +136,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
||||||
.SelectMany(
|
.SelectMany(
|
||||||
s =>
|
s =>
|
||||||
{
|
{
|
||||||
var StageId = Yitter.IdGenerator.YitIdHelper.NextId();
|
var StageId = YitIdHelper.NextId();
|
||||||
return s.KnowPoints.Where(x => knowDic.ContainsKey(x.KnowPoint))
|
return s.KnowPoints.Where(x => knowDic.ContainsKey(x.KnowPoint))
|
||||||
.Select(x => new VideoKonwPoint()
|
.Select(x => new VideoKonwPoint()
|
||||||
{
|
{
|
||||||
|
|
@ -173,7 +175,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
||||||
|| s.Depth == 2))
|
|| s.Depth == 2))
|
||||||
.Select(s => s.Name).ToArrayAsync();
|
.Select(s => s.Name).ToArrayAsync();
|
||||||
var captionsArr = JsonSerializer.Deserialize<SenseVoiceRes[]>(taskInfo.Captions);
|
var captionsArr = JsonSerializer.Deserialize<SenseVoiceRes[]>(taskInfo.Captions);
|
||||||
|
|
||||||
var fileNameResFormat = "{授课章节: string|null}";
|
var fileNameResFormat = "{授课章节: string|null}";
|
||||||
var rCaptionArr = string.Join(',', captionsArr
|
var rCaptionArr = string.Join(',', captionsArr
|
||||||
.Where((s, i) => i % 3 == 0)
|
.Where((s, i) => i % 3 == 0)
|
||||||
|
|
@ -300,11 +302,11 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
||||||
|
|
||||||
Func<string, Task<List<SenseVoiceInput>>>[] chatClentArr =
|
Func<string, Task<List<SenseVoiceInput>>>[] chatClentArr =
|
||||||
[
|
[
|
||||||
async (string m)=>await deepSeekClient
|
async (m)=>await deepSeekClient
|
||||||
.ChatAsync<List<SenseVoiceInput>>(taskInfo.Id.ToString(), m, "优化字幕",ChatGPTType.Deepseek_Chat,8_000),
|
.ChatAsync<List<SenseVoiceInput>>(taskInfo.Id.ToString(), m, "优化字幕",ChatGPTType.Deepseek_Chat,8_000),
|
||||||
async (string m)=>await chatGPTClient
|
async (m)=>await chatGPTClient
|
||||||
.ChatAsync<List<SenseVoiceInput>>(taskInfo.Id.ToString(), m, "优化字幕",ChatGPTType.GPT5,16_000),
|
.ChatAsync<List<SenseVoiceInput>>(taskInfo.Id.ToString(), m, "优化字幕",ChatGPTType.GPT5,16_000),
|
||||||
async (string m)=>await geminiClient
|
async (m)=>await geminiClient
|
||||||
.ChatAsync<List<SenseVoiceInput>>(taskInfo.Id.ToString(), m, "优化字幕",ChatGPTType.Gemini_3_Chat,16_000), ];
|
.ChatAsync<List<SenseVoiceInput>>(taskInfo.Id.ToString(), m, "优化字幕",ChatGPTType.Gemini_3_Chat,16_000), ];
|
||||||
await Parallel.ForAsync(0, totalCount,
|
await Parallel.ForAsync(0, totalCount,
|
||||||
new ParallelOptions()
|
new ParallelOptions()
|
||||||
|
|
@ -499,8 +501,8 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (ordered.Any(s =>
|
if (ordered.Any(s =>
|
||||||
(!string.IsNullOrWhiteSpace(s.Stage) && s.Stage.Contains("作业")) ||
|
!string.IsNullOrWhiteSpace(s.Stage) && s.Stage.Contains("作业") ||
|
||||||
(!string.IsNullOrWhiteSpace(s.Theme) && s.Theme.Contains("作业"))))
|
!string.IsNullOrWhiteSpace(s.Theme) && s.Theme.Contains("作业")))
|
||||||
return ordered.ToArray();
|
return ordered.ToArray();
|
||||||
|
|
||||||
var end = homeworkStage.EndTime ?? maxVideoTime;
|
var end = homeworkStage.EndTime ?? maxVideoTime;
|
||||||
|
|
@ -804,11 +806,11 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
||||||
VideoTaskId = taskInfo.Id,
|
VideoTaskId = taskInfo.Id,
|
||||||
CourseLevel = taskInfo.CourseLevel,
|
CourseLevel = taskInfo.CourseLevel,
|
||||||
TextBookVersionId = taskInfo.TextBookVersionId,
|
TextBookVersionId = taskInfo.TextBookVersionId,
|
||||||
GradeSemester= taskInfo.GradeSemester,
|
GradeSemester = taskInfo.GradeSemester,
|
||||||
GradeId = taskInfo.GradeId,
|
GradeId = taskInfo.GradeId,
|
||||||
}).ToList();
|
}).ToList();
|
||||||
//尝试追加 作业布置分段
|
//尝试追加 作业布置分段
|
||||||
if (homework != null && (!questionRes.Any(s => s.Stage == StageEnum.作业布置.ToString())))
|
if (homework != null && !questionRes.Any(s => s.Stage == StageEnum.作业布置.ToString()))
|
||||||
tStage.Add(homework.Adapt<VideoTaskStage>());
|
tStage.Add(homework.Adapt<VideoTaskStage>());
|
||||||
await videoTaskStageDB.InsertRangeAsync(tStage);
|
await videoTaskStageDB.InsertRangeAsync(tStage);
|
||||||
await videoKonwPointDB.InsertRangeAsync(insertData);
|
await videoKonwPointDB.InsertRangeAsync(insertData);
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,10 @@ using Newtonsoft.Json;
|
||||||
using System.Net.Http.Json;
|
using System.Net.Http.Json;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using VideoAnalysisCore.AICore.GPT.DeepSeek;
|
using VideoAnalysisCore.AICore.GPT.DeepSeek;
|
||||||
using VideoAnalysisCore.AICore.GPT;
|
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
|
|
||||||
namespace VideoAnalysisCore.AICore.GPT.ChatGPT
|
namespace VideoAnalysisCore.AICore.GPT.Gemini
|
||||||
{
|
{
|
||||||
|
|
||||||
public class GeminiGPTClient : GPTClient
|
public class GeminiGPTClient : GPTClient
|
||||||
|
|
@ -52,19 +51,19 @@ namespace VideoAnalysisCore.AICore.GPT.ChatGPT
|
||||||
var chatReq = new ChatRequest
|
var chatReq = new ChatRequest
|
||||||
{
|
{
|
||||||
taskId = task,
|
taskId = task,
|
||||||
title=title,
|
title = title,
|
||||||
model = model,
|
model = model,
|
||||||
max_tokens = max_tokens,
|
max_tokens = max_tokens,
|
||||||
stream = true,
|
stream = true,
|
||||||
messages = messageArr,
|
messages = messageArr,
|
||||||
max_completion_tokens= 12288,
|
max_completion_tokens = 12288,
|
||||||
};
|
};
|
||||||
|
|
||||||
chatReq.modalities = null;
|
chatReq.modalities = null;
|
||||||
chatReq.max_tokens = null;
|
chatReq.max_tokens = null;
|
||||||
chatReq.top_p = null;
|
chatReq.top_p = null;
|
||||||
|
|
||||||
return await base.ChatAsync<T>(chatReq);
|
return await ChatAsync<T>(chatReq);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VideoAnalysisCore.Common.Dto
|
||||||
|
{
|
||||||
|
public class BaseReturn
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 消息码
|
||||||
|
/// </summary>
|
||||||
|
public int Code { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 消息
|
||||||
|
/// </summary>
|
||||||
|
public string? Message { get; set; }
|
||||||
|
}
|
||||||
|
public class BaseReturn<T>
|
||||||
|
{
|
||||||
|
public T? Data { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 消息码
|
||||||
|
/// </summary>
|
||||||
|
public int Code { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 消息
|
||||||
|
/// </summary>
|
||||||
|
public string? Message { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VideoAnalysisCore.Common.Dto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 公共返回实体
|
||||||
|
/// </summary>
|
||||||
|
public class ComboModel
|
||||||
|
{
|
||||||
|
public ComboModel(string t, object v)
|
||||||
|
{
|
||||||
|
Text = t;
|
||||||
|
Value = v;
|
||||||
|
}
|
||||||
|
public ComboModel()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public object Value { get; set; }
|
||||||
|
public string Text { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace VideoAnalysisCore.Common.Dto
|
||||||
|
{
|
||||||
|
public class PageResult<T>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 数据
|
||||||
|
/// </summary>
|
||||||
|
public List<T> Data { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 总条数
|
||||||
|
/// </summary>
|
||||||
|
public int Total { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VideoAnalysisCore.Common
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 异常抛出的拓展类
|
||||||
|
/// </summary>
|
||||||
|
public class Oh
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 抛出 异常
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
/// <param name="code"></param>
|
||||||
|
/// <exception cref="OhException"></exception>
|
||||||
|
public static void Error(string message, int code = 500)
|
||||||
|
{
|
||||||
|
throw new OhException(message, code);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 抛出 异常
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
/// <param name="code"></param>
|
||||||
|
/// <exception cref="OhException"></exception>
|
||||||
|
public static T Error<T>(string message, int code = 500)
|
||||||
|
{
|
||||||
|
throw new OhException(message, code);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 抛出 模型校验异常
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
/// <param name="code"></param>
|
||||||
|
/// <exception cref="OhException"></exception>
|
||||||
|
public static void ModelError(string message, int code = 400)
|
||||||
|
{
|
||||||
|
throw new OhException(message, code);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 抛出 模型校验异常
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
/// <param name="code"></param>
|
||||||
|
/// <exception cref="OhException"></exception>
|
||||||
|
public static void ToeknError(string message, int code = 401)
|
||||||
|
{
|
||||||
|
throw new OhException(message, code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class OhException : Exception
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 错误码
|
||||||
|
/// </summary>
|
||||||
|
public virtual int Code { get; }
|
||||||
|
public OhException(string message, int code = -1) : base(message)
|
||||||
|
{
|
||||||
|
Code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -67,7 +67,7 @@ namespace VideoAnalysisCore.Controllers
|
||||||
[HttpPost(Name = "NodePackage")]
|
[HttpPost(Name = "NodePackage")]
|
||||||
public async Task<IActionResult> NodePackage(NodePackageReq[] reqArr)
|
public async Task<IActionResult> NodePackage(NodePackageReq[] reqArr)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{DateTime.Now} 文件包订阅请求 req=" + reqArr.ToJson());
|
Console.WriteLine($"{DateTime.Now} 文件包订阅请求数量 req=" + reqArr.Count());
|
||||||
if (reqArr is null || reqArr.Count() == 0)
|
if (reqArr is null || reqArr.Count() == 0)
|
||||||
return BadRequest("无效视频列表数据");
|
return BadRequest("无效视频列表数据");
|
||||||
var videos = new List<VideoTask>(reqArr.Count());
|
var videos = new List<VideoTask>(reqArr.Count());
|
||||||
|
|
@ -77,7 +77,16 @@ namespace VideoAnalysisCore.Controllers
|
||||||
//系统可接收任务的学科
|
//系统可接收任务的学科
|
||||||
var subjectArr = new List<SubjectEnum?>
|
var subjectArr = new List<SubjectEnum?>
|
||||||
{
|
{
|
||||||
SubjectEnum.数学
|
SubjectEnum.语文,
|
||||||
|
SubjectEnum.数学,
|
||||||
|
SubjectEnum.英语,
|
||||||
|
SubjectEnum.物理,
|
||||||
|
SubjectEnum.化学,
|
||||||
|
SubjectEnum.生物,
|
||||||
|
SubjectEnum.政治,
|
||||||
|
SubjectEnum.历史,
|
||||||
|
SubjectEnum.地理,
|
||||||
|
|
||||||
};
|
};
|
||||||
var courseTypeArr = new List<AttachmentsInfoType?>
|
var courseTypeArr = new List<AttachmentsInfoType?>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
using SqlSugar;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection.Metadata.Ecma335;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UserCenter.Model;
|
||||||
|
using VideoAnalysisCore.Model.Interface;
|
||||||
|
|
||||||
|
namespace VideoAnalysisCore.Model
|
||||||
|
{
|
||||||
|
///<summary>
|
||||||
|
/// 请求日志表
|
||||||
|
///</summary>
|
||||||
|
[SugarTable("httplog")]
|
||||||
|
public partial class HttpLog : EntityBaseId, IDB
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 创建时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime CreateTime { get; set; } = DateTime.Now;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 路由
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(Length = 500)]
|
||||||
|
public string Url { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 请求方法类型
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(Length = 10)]
|
||||||
|
public string Method { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 请求来自哪个ip
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true, Length = 30)]
|
||||||
|
public string IP { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 请求参数
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true, ColumnDataType = "longtext")]
|
||||||
|
public string? Request { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 请求返回参数
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true, ColumnDataType = "longtext")]
|
||||||
|
public string? Response { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 响应状态码
|
||||||
|
/// </summary>
|
||||||
|
public int ResponseCode { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 授权信息
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true, Length = 500)]
|
||||||
|
public string? Authorization { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 异常完整信息
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true, ColumnDataType = "text")]
|
||||||
|
public string Exception { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 异常信息
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true, ColumnDataType = "text")]
|
||||||
|
public string? ExceptionMessage { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 管理员ID
|
||||||
|
/// </summary>
|
||||||
|
public long AdminId { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 总耗时(秒)
|
||||||
|
/// </summary>
|
||||||
|
public double TotalMilliseconds { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue