添加项目文件。
This commit is contained in:
parent
e8e7f09210
commit
919c295b13
|
|
@ -0,0 +1,28 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.12.35506.116
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AI.Api", "AI.Api\AI.Api.csproj", "{DC60489F-F76C-47FF-8698-5EF3454FA974}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AI.Common", "AI.Common\AI.Common.csproj", "{B5A93DD0-B38E-40D4-B6A3-40BA62A2FA2D}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{DC60489F-F76C-47FF-8698-5EF3454FA974}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{DC60489F-F76C-47FF-8698-5EF3454FA974}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{DC60489F-F76C-47FF-8698-5EF3454FA974}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{DC60489F-F76C-47FF-8698-5EF3454FA974}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{B5A93DD0-B38E-40D4-B6A3-40BA62A2FA2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{B5A93DD0-B38E-40D4-B6A3-40BA62A2FA2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{B5A93DD0-B38E-40D4-B6A3-40BA62A2FA2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{B5A93DD0-B38E-40D4-B6A3-40BA62A2FA2D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.11" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\AI.Common\AI.Common.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
using AI.Common.Dtos;
|
||||||
|
using AI.Common.Services.Interface;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace AI.Api.Controllers
|
||||||
|
{
|
||||||
|
[Route("[controller]")]
|
||||||
|
public class AuthController : BaseController
|
||||||
|
{
|
||||||
|
private readonly IAuthService _authService;
|
||||||
|
|
||||||
|
public AuthController(IAuthService authService)
|
||||||
|
{
|
||||||
|
this._authService = authService;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpPost("login")]
|
||||||
|
public async Task<IActionResult> LoginAsync([FromBody] LoginDto loginDto)
|
||||||
|
{
|
||||||
|
return Ok(await _authService.LoginAsync(loginDto));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
using AI.Common.Helpers;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace AI.Api.Controllers
|
||||||
|
{
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class BaseController : ControllerBase
|
||||||
|
{
|
||||||
|
public long UId
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var uid = HttpContext.User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier).Value;
|
||||||
|
if (string.IsNullOrWhiteSpace(uid))
|
||||||
|
{
|
||||||
|
throw Oops.Oh("用户信息有误,请重新登录");
|
||||||
|
}
|
||||||
|
return long.Parse(uid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
using AI.Common.Dtos;
|
||||||
|
using AI.Common.Entities;
|
||||||
|
using AI.Common.Services.Interface;
|
||||||
|
using Mapster;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace AI.Api.Controllers
|
||||||
|
{
|
||||||
|
[Route("[controller]")]
|
||||||
|
public class PromptController : BaseController
|
||||||
|
{
|
||||||
|
private readonly IPromptService _promptService;
|
||||||
|
|
||||||
|
public PromptController(IPromptService promptService)
|
||||||
|
{
|
||||||
|
this._promptService = promptService;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("list")]
|
||||||
|
public async Task<List<PromptDto>> GetListAsync()
|
||||||
|
{
|
||||||
|
return await _promptService.GetListAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
using AI.Common.Dtos;
|
||||||
|
using AI.Common.Entities;
|
||||||
|
using AI.Common.Services.Interface;
|
||||||
|
using Mapster;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace AI.Api.Controllers
|
||||||
|
{
|
||||||
|
[Route("[controller]")]
|
||||||
|
public class QuestLogController : BaseController
|
||||||
|
{
|
||||||
|
private readonly IQuestionLogService _questionLogService;
|
||||||
|
|
||||||
|
public QuestLogController(IQuestionLogService questionLogService)
|
||||||
|
{
|
||||||
|
this._questionLogService = questionLogService;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("record")]
|
||||||
|
public async Task<long> RecordAsync([FromBody] QuestionLogDto questionLogDto)
|
||||||
|
{
|
||||||
|
var entity = questionLogDto.Adapt<QuestionLog>();
|
||||||
|
entity.Uid = UId;
|
||||||
|
|
||||||
|
return await _questionLogService.RecordAsync(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
using AI.Api.WebCore;
|
||||||
|
using AI.Common.Services;
|
||||||
|
using AI.Common.Services.Interface;
|
||||||
|
using SqlSugar;
|
||||||
|
using DbType = SqlSugar.DbType;
|
||||||
|
|
||||||
|
namespace AI.Api
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
var configuration = builder.Configuration;
|
||||||
|
// Add services to the container.
|
||||||
|
|
||||||
|
builder.Services.AddControllers(options =>
|
||||||
|
{
|
||||||
|
// 全局异常捕获,无需在代码中 写 try catch
|
||||||
|
options.Filters.Add<GlobalExceptionFilter>();
|
||||||
|
// 全局模型赋值默认值 和 统一返回格式处理
|
||||||
|
options.Filters.Add<ModelActionFilter>();
|
||||||
|
});
|
||||||
|
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||||
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
|
builder.Services.AddSwaggerGen();
|
||||||
|
builder.Services.AddSingleton(new Common.Helpers.JwtHelper(configuration));
|
||||||
|
builder.Services.AddAuth(configuration["Jwt:Issuer"],
|
||||||
|
configuration["Jwt:Audience"],
|
||||||
|
configuration["Jwt:SecretKey"]);
|
||||||
|
builder.Services.AddSqlsugar(builder.Environment.EnvironmentName, new ConnectionConfig
|
||||||
|
{
|
||||||
|
DbType = DbType.MySql,
|
||||||
|
ConfigId = "walle",
|
||||||
|
ConnectionString = configuration.GetConnectionString("walle"),
|
||||||
|
IsAutoCloseConnection = true
|
||||||
|
},
|
||||||
|
new ConnectionConfig
|
||||||
|
{
|
||||||
|
DbType = DbType.MySql,
|
||||||
|
ConfigId = "usercenter",
|
||||||
|
ConnectionString = configuration.GetConnectionString("usercenter"),
|
||||||
|
IsAutoCloseConnection = true
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Services.AddScoped<IAuthService, AuthService>();
|
||||||
|
builder.Services.AddScoped<IQuestionLogService, QuestionLogService>();
|
||||||
|
builder.Services.AddScoped<IPromptService, PromptService>();
|
||||||
|
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
//调用中间件:UseAuthentication(认证),必须在所有需要身份认证的中间件前调用,比如 UseAuthorization(授权)。
|
||||||
|
app.UseAuthentication();
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
|
app.Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:29214",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": false,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "http://localhost:5108",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace AI.Api.WebCore
|
||||||
|
{
|
||||||
|
public static class AuthenticationServiceExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 添加认证和授权
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="services">服务集合</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IServiceCollection AddAuth(this IServiceCollection services, string issuer, string audience, string secretKey)
|
||||||
|
{
|
||||||
|
services.AddAuthentication(options =>
|
||||||
|
{
|
||||||
|
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
|
}).AddJwtBearer(options =>
|
||||||
|
{
|
||||||
|
options.TokenValidationParameters = new TokenValidationParameters()
|
||||||
|
{
|
||||||
|
ValidateIssuer = true, //是否验证Issuer
|
||||||
|
ValidIssuer = issuer, //发行人Issuer
|
||||||
|
ValidateAudience = true, //是否验证Audience
|
||||||
|
ValidAudience = audience, //订阅人Audience
|
||||||
|
ValidateIssuerSigningKey = true, //是否验证SecurityKey
|
||||||
|
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)), //SecurityKey
|
||||||
|
ValidateLifetime = true, //是否验证失效时间
|
||||||
|
ClockSkew = TimeSpan.FromSeconds(30), //过期时间容错值,解决服务器端时间不同步问题(秒)
|
||||||
|
RequireExpirationTime = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return services;
|
||||||
|
//services.AddAuthorization(options =>
|
||||||
|
//{
|
||||||
|
// options.AddPolicy(Constant.Policy.FreePolicyName,
|
||||||
|
// policy => policy.RequireClaim(Constant.Auth.PermissionsKey, Constant.Auth.FreeClaimValue, Constant.Auth.VipClaimValue));
|
||||||
|
// options.AddPolicy(Constant.Policy.VipPolicyName,
|
||||||
|
// policy => policy.RequireClaim(Constant.Auth.PermissionsKey, Constant.Auth.VipClaimValue));
|
||||||
|
//});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
using AI.Common;
|
||||||
|
using Masuit.Tools;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
|
||||||
|
namespace AI.Api.WebCore
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 全局异常捕获
|
||||||
|
/// </summary>
|
||||||
|
public class GlobalExceptionFilter : IAsyncExceptionFilter
|
||||||
|
{
|
||||||
|
private readonly ILogger<GlobalExceptionFilter> _logger;
|
||||||
|
|
||||||
|
public GlobalExceptionFilter(ILogger<GlobalExceptionFilter> logger)
|
||||||
|
{
|
||||||
|
_logger = logger; //在构造函数中注入日志处理实例
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task OnExceptionAsync(ExceptionContext context)
|
||||||
|
{
|
||||||
|
// 如果异常没有被处理则进行处理
|
||||||
|
if (context.ExceptionHandled == false)
|
||||||
|
{
|
||||||
|
// 定义返回类型
|
||||||
|
UniformResult<object> result;
|
||||||
|
|
||||||
|
// 如果为业务逻辑抛出的内部异常
|
||||||
|
if (context.Exception is FriendlyInternalException ex)
|
||||||
|
{
|
||||||
|
// 企业微信异常通知
|
||||||
|
//await ExceptionNotice.SendFriendlyExceptionAsync(ex);
|
||||||
|
|
||||||
|
result = UniformResult<object>
|
||||||
|
.Create(ex.FriendlyData, ex.ErrorCode, context.Exception.Message);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 程序异常,不对外暴露程序异常细节
|
||||||
|
result = UniformResult<object>
|
||||||
|
.Create(null, 500, "程序出错啦🐞🐞🐞!");
|
||||||
|
|
||||||
|
//使用日志对象 _logger 的 LogError() 方法将异常信息写入日志文件
|
||||||
|
_logger.LogError(context.Exception, context.Exception.Message);
|
||||||
|
|
||||||
|
// 企业微信异常通知
|
||||||
|
await ExceptionNotice.SendAsync(context.Exception, "全局异常捕获");
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Result = new ContentResult
|
||||||
|
{
|
||||||
|
// 返回状态码设置为200,表示成功
|
||||||
|
StatusCode = StatusCodes.Status200OK,
|
||||||
|
// 设置返回格式
|
||||||
|
ContentType = "application/json;charset=utf-8",
|
||||||
|
Content = result.ToJsonString()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置为true,表示异常已经被处理了
|
||||||
|
context.ExceptionHandled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
using AI.Common;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
|
||||||
|
namespace AI.Api.WebCore
|
||||||
|
{
|
||||||
|
public class ModelActionFilter : ActionFilterAttribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 在Controller的Action执行后执行
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
public override void OnActionExecuted(ActionExecutedContext context)
|
||||||
|
{
|
||||||
|
//特殊处理:对有ApiResultIgnoreAttribute标签的,不进行返回结果包装,原样输出
|
||||||
|
//var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
|
||||||
|
//if (controllerActionDescriptor != null)
|
||||||
|
//{
|
||||||
|
// var isDefined = controllerActionDescriptor.EndpointMetadata.Any(a => a.GetType().Equals(typeof(ApiResultIgnoreAttribute)));
|
||||||
|
// if (isDefined)
|
||||||
|
// {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
// 返回结果为JsonResult的请求进行Result包装
|
||||||
|
if (context.Result != null)
|
||||||
|
{
|
||||||
|
switch (context.Result)
|
||||||
|
{
|
||||||
|
case ObjectResult:
|
||||||
|
{
|
||||||
|
var result = context.Result as ObjectResult;
|
||||||
|
context.Result = new JsonResult(UniformResult<object>.Create(result.Value));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EmptyResult:
|
||||||
|
context.Result = new JsonResult(UniformResult<object>.Create(null));
|
||||||
|
break;
|
||||||
|
case ContentResult:
|
||||||
|
{
|
||||||
|
var result = context.Result as ContentResult;
|
||||||
|
context.Result = new JsonResult(UniformResult<object>.Create(result.Content));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnActionExecuted(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在Controller的Action执行前执行
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
public override void OnActionExecuting(ActionExecutingContext context)
|
||||||
|
{
|
||||||
|
base.OnActionExecuting(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
using SqlSugar;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace AI.Api.WebCore
|
||||||
|
{
|
||||||
|
public static class SqlsugarServiceExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 添加SqlSugar
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="services">服务集合</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IServiceCollection AddSqlsugar(this IServiceCollection services, string env, params ConnectionConfig[] connectionConfigs)
|
||||||
|
{
|
||||||
|
SqlSugarScope sqlSugar = new SqlSugarScope(connectionConfigs.ToList(),
|
||||||
|
db =>
|
||||||
|
{
|
||||||
|
if (env == Environments.Development)
|
||||||
|
{
|
||||||
|
// 正则表达式匹配Ip
|
||||||
|
var ipMatch = Regex.Match(db.CurrentConnectionConfig.ConnectionString, @"((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))");
|
||||||
|
|
||||||
|
var connections = db.CurrentConnectionConfig.ConnectionString.Split(';');
|
||||||
|
string dbNamne = string.Empty;
|
||||||
|
foreach (var item in connections)
|
||||||
|
{
|
||||||
|
if (item.Contains("Database"))
|
||||||
|
{
|
||||||
|
dbNamne = item.Split('=')[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SQL执行前
|
||||||
|
db.Aop.OnLogExecuting = (sql, pars) =>
|
||||||
|
{
|
||||||
|
// 打印 Sql 语句
|
||||||
|
Console.WriteLine($@"{DateTime.Now.ToShortTimeString()}{new string('=', 10)}BEGIN{new string('=', 5)} DB-IP:{ipMatch.Value} {new string('=', 5)} DB-Name:{dbNamne} {new string('=', 15)}");
|
||||||
|
Console.WriteLine($"执行Sql:{Environment.NewLine}{sql}");
|
||||||
|
Console.WriteLine($"参数:{db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value))}");
|
||||||
|
};
|
||||||
|
|
||||||
|
//SQL执行完成
|
||||||
|
db.Aop.OnLogExecuted = (sql, pars) =>
|
||||||
|
{
|
||||||
|
//执行完了可以输出SQL执行时间
|
||||||
|
Console.WriteLine("Sql用时:" + db.Ado.SqlExecutionTime.ToString());
|
||||||
|
Console.WriteLine($@"{DateTime.Now.ToShortTimeString()}{new string('=', 10)}END{new string('=', 7)} DB-IP:{ipMatch.Value} {new string('=', 5)} DB-Name:{dbNamne} {new string('=', 15)}");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
services.AddSingleton<ISqlSugarClient>(sqlSugar);
|
||||||
|
StaticConfig.Check_StringIdentity = false;
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Debug",
|
||||||
|
"Microsoft.AspNetCore": "Information"
|
||||||
|
},
|
||||||
|
"Console": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Debug",
|
||||||
|
"Microsoft": "Information",
|
||||||
|
"Hangfire": "Information"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"walle": "Database=walle;Server=192.168.2.9;Port=3306;Uid=root;Pwd=qwe123!@#;AllowZeroDateTime=True;ConvertZeroDateTime=True;",
|
||||||
|
"usercenter": "Database=usercenter;Server=192.168.2.9;Port=3306;Uid=root;Pwd=qwe123!@#;AllowZeroDateTime=True;ConvertZeroDateTime=True;"
|
||||||
|
},
|
||||||
|
"Jwt": {
|
||||||
|
"SecretKey": "apDbztyqjSNuvWnezhbdUxduhDidZbF897t2uTJs53RMdY9Cai7eexavBhka3HN6mcTe9oohjFg6bNffRRkcfMqnVKNBnmyPzkRgNopHGJAL7KMwkeZdZ7BaWnT57jCi",
|
||||||
|
"Issuer": "AI.Api",
|
||||||
|
"Audience": "AIClient",
|
||||||
|
// 过期 秒
|
||||||
|
"Expires": 108000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||||
|
<PackageReference Include="Masuit.Tools.Core" Version="2024.6.0" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.11" />
|
||||||
|
<PackageReference Include="SqlSugarCore" Version="5.1.4.170" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Entities\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AI.Common.Dtos
|
||||||
|
{
|
||||||
|
public class LoginDto
|
||||||
|
{
|
||||||
|
public string Account { get; set; }
|
||||||
|
public string Password { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AI.Common.Dtos
|
||||||
|
{
|
||||||
|
public class PromptDto
|
||||||
|
{
|
||||||
|
public long Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Prompt { get; set; }
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AI.Common.Dtos
|
||||||
|
{
|
||||||
|
public class QuestionLogDto
|
||||||
|
{
|
||||||
|
public long Id { get; set; }
|
||||||
|
public string QuestionContent { get; set; }
|
||||||
|
public string? GptAnswer { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using SqlSugar;
|
||||||
|
namespace AI.Common.Entities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
///</summary>
|
||||||
|
[SugarTable("prompts")]
|
||||||
|
public class Prompts
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="id" ,IsPrimaryKey = true,IsIdentity = true) ]
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:角色名称
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="name" ) ]
|
||||||
|
public string Name { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:提示词
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="prompt" ) ]
|
||||||
|
public string Prompt { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="create_time", IsOnlyIgnoreInsert = true, IsOnlyIgnoreUpdate = true) ]
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="is_delete" ) ]
|
||||||
|
public bool IsDelete { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using SqlSugar;
|
||||||
|
namespace AI.Common.Entities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
///</summary>
|
||||||
|
[SugarTable("question_log")]
|
||||||
|
public class QuestionLog
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsIdentity = true)]
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "create_time", IsOnlyIgnoreInsert = true, IsOnlyIgnoreUpdate = true)]
|
||||||
|
public DateTime Create_time { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "uid")]
|
||||||
|
public long Uid { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:问题内容
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "question_content")]
|
||||||
|
public string? QuestionContent { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "gpt_answer")]
|
||||||
|
public string? GptAnswer { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,298 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using SqlSugar;
|
||||||
|
namespace AI.Common.Entities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 用户表【学生,教师,校职工】
|
||||||
|
///</summary>
|
||||||
|
[SugarTable("user")]
|
||||||
|
public class User
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="Id" ,IsPrimaryKey = true) ]
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:模板id
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="TemplateId" ) ]
|
||||||
|
public long TemplateId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:学校Id
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="SchoolId" ) ]
|
||||||
|
public long? SchoolId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:用户类型 1:学生 2:领导
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="UserType" ) ]
|
||||||
|
public int UserType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:账号
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="Account" ) ]
|
||||||
|
public string Account { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:学号/考号
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="StudentId" ) ]
|
||||||
|
public string StudentId { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:身份证号 18位数长度限制
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="IdCard" ) ]
|
||||||
|
public string? IdCard { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:密码
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="Password" ) ]
|
||||||
|
public string Password { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:姓名
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="RealName" ) ]
|
||||||
|
public string RealName { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:性别 0=男 1=女
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="Sex" ) ]
|
||||||
|
public int Sex { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:出生日期
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="BirthDate" ) ]
|
||||||
|
public DateTime BirthDate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:家庭户口
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="Residence" ) ]
|
||||||
|
public string Residence { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:民族
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="National" ) ]
|
||||||
|
public string National { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:头像
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="HeadImage" ) ]
|
||||||
|
public string HeadImage { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:省Id
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="Pid" ) ]
|
||||||
|
public int Pid { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="Pname" ) ]
|
||||||
|
public string Pname { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:市Id
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="Cid" ) ]
|
||||||
|
public int Cid { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="Cname" ) ]
|
||||||
|
public string Cname { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:区Id
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="Rid" ) ]
|
||||||
|
public int Rid { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="Rname" ) ]
|
||||||
|
public string Rname { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:微信号
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="Wx" ) ]
|
||||||
|
public string Wx { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:是否完善信息 0:否 1:是
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="IsPerfectInfo" ) ]
|
||||||
|
public int IsPerfectInfo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:账户状态 0禁用 1正常
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="State" ) ]
|
||||||
|
public int State { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:直播平台编号
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="LiveId" ) ]
|
||||||
|
public long LiveId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:上次登录时间
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="LastLoginTime" ) ]
|
||||||
|
public DateTime LastLoginTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:登录IP
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="LastLoginIP" ) ]
|
||||||
|
public string LastLoginIP { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:添加时间
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="CreateTime" ) ]
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:层次
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="Level" ) ]
|
||||||
|
public int Level { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:会议系统账号
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="MeetingAccount" ) ]
|
||||||
|
public string? MeetingAccount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:新高考物理化学选科
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="GLSubject" ) ]
|
||||||
|
public int? GLSubject { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:新高考,政地化生选科1
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="GSubject1" ) ]
|
||||||
|
public int? GSubject1 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:新高考,政地化生选科2
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="GSubject2" ) ]
|
||||||
|
public int? GSubject2 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:第三方id
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="ThirdPartyId" ) ]
|
||||||
|
public string? ThirdPartyId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:电话号码
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="Phone" ) ]
|
||||||
|
public string? Phone { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:点阵笔SN
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="PointPenSN" ) ]
|
||||||
|
public string? PointPenSN { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:删除状态
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="DeleteState" ) ]
|
||||||
|
public SByte DeleteState { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:互动课堂创建人Id
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="HdktCreatorId" ) ]
|
||||||
|
public long? HdktCreatorId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:用户来源
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="Source" ) ]
|
||||||
|
public int Source { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:点阵笔MAC
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="PointPenMAC" ) ]
|
||||||
|
public string? PointPenMAC { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备 注:创建人名称
|
||||||
|
/// 默认值:
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName="Creator" ) ]
|
||||||
|
public string? Creator { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
|
||||||
|
namespace AI.Common
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 异常通知
|
||||||
|
/// </summary>
|
||||||
|
public class ExceptionNotice
|
||||||
|
{
|
||||||
|
private static HttpClient httpClient = new HttpClient()
|
||||||
|
{
|
||||||
|
BaseAddress = new Uri("https://oapi.dingtalk.com/robot/send?access_token=0ba23267d03084010ee5ffae60e6f4a11e541db8e062f5cde75f3205c10c42c8"),
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送异常信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="exp">异常</param>
|
||||||
|
/// <param name="expSrc">异常来源(用于显示)</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<bool> SendAsync(Exception exp, string expSrc)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
Console.WriteLine("*************** Excpetion ***************");
|
||||||
|
Console.WriteLine(exp.Message, exp);
|
||||||
|
Console.WriteLine("*************** Excpetion ***************");
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
var reponse = await httpClient.PostAsync(string.Empty, JsonContent.Create(new
|
||||||
|
{
|
||||||
|
msgtype = "markdown",
|
||||||
|
markdown = new
|
||||||
|
{
|
||||||
|
title = "AI.Api异常",
|
||||||
|
text = $"AI.Api异常.描述:{exp.Message}\n详情:{exp}"
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
return reponse.IsSuccessStatusCode;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
namespace AI.Common
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Api内部错误(错误细节不暴露给外部)
|
||||||
|
/// </summary>
|
||||||
|
public class FriendlyInternalException : Exception
|
||||||
|
{
|
||||||
|
public int ErrorCode { get; private set; }
|
||||||
|
public object FriendlyData { get; private set; }
|
||||||
|
|
||||||
|
public FriendlyInternalException(string message, object friendlyData = null, int errorCode = 1000) : base(message)
|
||||||
|
{
|
||||||
|
ErrorCode = errorCode;
|
||||||
|
FriendlyData = friendlyData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
using Masuit.Tools;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace AI.Common.Helpers
|
||||||
|
{
|
||||||
|
public class JwtHelper
|
||||||
|
{
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
|
||||||
|
public JwtHelper(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
_configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CreateToken(string uid, List<Claim> claims = null)
|
||||||
|
{
|
||||||
|
if (claims.IsNullOrEmpty())
|
||||||
|
claims = new();
|
||||||
|
claims.AddRange(new List<Claim>
|
||||||
|
{
|
||||||
|
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
|
||||||
|
new Claim(ClaimTypes.NameIdentifier, uid),
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. 从 appsettings.json 中读取SecretKey
|
||||||
|
var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecretKey"]));
|
||||||
|
|
||||||
|
// 3. 选择加密算法
|
||||||
|
var algorithm = SecurityAlgorithms.HmacSha256;
|
||||||
|
|
||||||
|
// 4. 生成Credentials
|
||||||
|
var signingCredentials = new SigningCredentials(secretKey, algorithm);
|
||||||
|
|
||||||
|
// 5. 根据以上,生成token
|
||||||
|
var jwtSecurityToken = new JwtSecurityToken(
|
||||||
|
_configuration["Jwt:Issuer"], //Issuer
|
||||||
|
_configuration["Jwt:Audience"], //Audience
|
||||||
|
claims, //Claims,
|
||||||
|
DateTime.Now, //notBefore
|
||||||
|
DateTime.Now.AddSeconds(_configuration["Jwt:Expires"].ToDouble()), //expires
|
||||||
|
signingCredentials //Credentials
|
||||||
|
);
|
||||||
|
|
||||||
|
// 6. 将token变为string
|
||||||
|
var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
namespace AI.Common.Helpers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 异常抛出帮助类
|
||||||
|
/// </summary>
|
||||||
|
public static class Oops
|
||||||
|
{
|
||||||
|
public static FriendlyInternalException Oh(string message)
|
||||||
|
{
|
||||||
|
return new FriendlyInternalException(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除失败异常
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static FriendlyInternalException OhDeleteFailed()
|
||||||
|
{
|
||||||
|
return new FriendlyInternalException("删除失败!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 数据不存在异常
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static FriendlyInternalException OhDataNotExists()
|
||||||
|
{
|
||||||
|
return new FriendlyInternalException("数据不存在!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新失败异常
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static FriendlyInternalException OhUpdateFailed()
|
||||||
|
{
|
||||||
|
return new FriendlyInternalException("更新失败!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新增失败异常
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static FriendlyInternalException OhAddFailed()
|
||||||
|
{
|
||||||
|
return new FriendlyInternalException("新增失败!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 业务处理失败自定义消息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static FriendlyInternalException OhBusinessFailed(string msg, object data)
|
||||||
|
{
|
||||||
|
return new FriendlyInternalException(msg, data, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 操作失败
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static FriendlyInternalException OperationFailed()
|
||||||
|
{
|
||||||
|
return new FriendlyInternalException("操作失败!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
using AI.Common.Dtos;
|
||||||
|
using AI.Common.Entities;
|
||||||
|
using AI.Common.Helpers;
|
||||||
|
using AI.Common.Services.Interface;
|
||||||
|
using Masuit.Tools;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using SqlSugar;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace AI.Common.Services
|
||||||
|
{
|
||||||
|
public class AuthService : IAuthService
|
||||||
|
{
|
||||||
|
private readonly ISqlSugarClient _sqlSugarClient;
|
||||||
|
private readonly JwtHelper _jwtHelper;
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
|
||||||
|
public AuthService(ISqlSugarClient sqlSugarClient, JwtHelper jwtHelper, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
this._sqlSugarClient = sqlSugarClient.AsTenant().GetConnection("usercenter");
|
||||||
|
this._jwtHelper = jwtHelper;
|
||||||
|
this._configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<object> LoginAsync(LoginDto loginDto)
|
||||||
|
{
|
||||||
|
var user = await _sqlSugarClient.Queryable<User>()
|
||||||
|
.FirstAsync(x => x.Account == loginDto.Account && x.Password == loginDto.Password && x.DeleteState == 0);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
throw Oops.Oh("登录失败,账号或密码错误!");
|
||||||
|
}
|
||||||
|
|
||||||
|
var accessToken = _jwtHelper.CreateToken(user.Id.ToString(), new List<Claim>
|
||||||
|
{
|
||||||
|
new Claim("account",user.Account),
|
||||||
|
new Claim(ClaimTypes.Name,user.RealName),
|
||||||
|
});
|
||||||
|
|
||||||
|
return new
|
||||||
|
{
|
||||||
|
token = accessToken,
|
||||||
|
userName = user.RealName,
|
||||||
|
account = user.Account,
|
||||||
|
expire = _configuration["Jwt:Expires"].ToInt32(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
using AI.Common.Dtos;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AI.Common.Services.Interface
|
||||||
|
{
|
||||||
|
public interface IAuthService
|
||||||
|
{
|
||||||
|
Task<object> LoginAsync(LoginDto loginDto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
using AI.Common.Dtos;
|
||||||
|
using AI.Common.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AI.Common.Services.Interface
|
||||||
|
{
|
||||||
|
public interface IPromptService
|
||||||
|
{
|
||||||
|
Task AddAsync(Prompts prompts);
|
||||||
|
Task DeleteAsync(long id);
|
||||||
|
Task<List<PromptDto>> GetListAsync();
|
||||||
|
Task UpdateAsync(Prompts prompts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
using AI.Common.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AI.Common.Services.Interface
|
||||||
|
{
|
||||||
|
public interface IQuestionLogService
|
||||||
|
{
|
||||||
|
Task<long> RecordAsync(QuestionLog questionLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
using AI.Common.Dtos;
|
||||||
|
using AI.Common.Entities;
|
||||||
|
using AI.Common.Services.Interface;
|
||||||
|
using Mapster;
|
||||||
|
using SqlSugar;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AI.Common.Services
|
||||||
|
{
|
||||||
|
public class PromptService : IPromptService
|
||||||
|
{
|
||||||
|
private readonly ISqlSugarClient _sqlSugarClient;
|
||||||
|
|
||||||
|
public PromptService(ISqlSugarClient sqlSugarClient)
|
||||||
|
{
|
||||||
|
this._sqlSugarClient = sqlSugarClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<PromptDto>> GetListAsync()
|
||||||
|
{
|
||||||
|
var entities = await _sqlSugarClient.Queryable<Prompts>().ToListAsync();
|
||||||
|
return entities.Adapt<List<PromptDto>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task AddAsync(Prompts prompts)
|
||||||
|
{
|
||||||
|
await _sqlSugarClient.Insertable(prompts).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateAsync(Prompts prompts)
|
||||||
|
{
|
||||||
|
await _sqlSugarClient.Updateable(prompts)
|
||||||
|
.UpdateColumns(x => new { x.Name, x.Prompt })
|
||||||
|
.ExecuteCommandHasChangeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DeleteAsync(long id)
|
||||||
|
{
|
||||||
|
await _sqlSugarClient.Updateable<Prompts>()
|
||||||
|
.SetColumns(x => x.IsDelete == true)
|
||||||
|
.Where(x => x.Id == id).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
using AI.Common.Dtos;
|
||||||
|
using AI.Common.Entities;
|
||||||
|
using AI.Common.Services.Interface;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using SqlSugar;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AI.Common.Services
|
||||||
|
{
|
||||||
|
public class QuestionLogService : IQuestionLogService
|
||||||
|
{
|
||||||
|
private readonly ISqlSugarClient _sqlSugarClient;
|
||||||
|
|
||||||
|
public QuestionLogService(ISqlSugarClient sqlSugarClient)
|
||||||
|
{
|
||||||
|
this._sqlSugarClient = sqlSugarClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<long> RecordAsync(QuestionLog questionLog)
|
||||||
|
{
|
||||||
|
if (questionLog.Id <= 0)
|
||||||
|
{
|
||||||
|
// 新增
|
||||||
|
return await _sqlSugarClient.Insertable(questionLog).ExecuteReturnBigIdentityAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新
|
||||||
|
await _sqlSugarClient.Updateable(questionLog)
|
||||||
|
.UpdateColumns(x => new { x.QuestionContent, x.GptAnswer }).ExecuteCommandAsync();
|
||||||
|
|
||||||
|
return questionLog.Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
namespace AI.Common
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 统一返回结果模型
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
public class UniformResult<T>
|
||||||
|
{
|
||||||
|
public UniformResult(T data, int code = 200, string msg = "success")
|
||||||
|
{
|
||||||
|
this.data = data;
|
||||||
|
this.code = code;
|
||||||
|
message = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 消息
|
||||||
|
/// </summary>
|
||||||
|
public string message { get; set; } = "success";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回代码
|
||||||
|
/// </summary>
|
||||||
|
public int code { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 数据
|
||||||
|
/// </summary>
|
||||||
|
public T data { get; set; }
|
||||||
|
|
||||||
|
public static UniformResult<T> Create(T data, int code = 200, string msg = "success")
|
||||||
|
{
|
||||||
|
return new UniformResult<T>(data, code, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue