diff --git a/AI.Api.sln b/AI.Api.sln
new file mode 100644
index 0000000..833e965
--- /dev/null
+++ b/AI.Api.sln
@@ -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
diff --git a/AI.Api/AI.Api.csproj b/AI.Api/AI.Api.csproj
new file mode 100644
index 0000000..74074d8
--- /dev/null
+++ b/AI.Api/AI.Api.csproj
@@ -0,0 +1,19 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AI.Api/Controllers/AuthController.cs b/AI.Api/Controllers/AuthController.cs
new file mode 100644
index 0000000..1e1d5a5
--- /dev/null
+++ b/AI.Api/Controllers/AuthController.cs
@@ -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 LoginAsync([FromBody] LoginDto loginDto)
+ {
+ return Ok(await _authService.LoginAsync(loginDto));
+ }
+ }
+}
diff --git a/AI.Api/Controllers/BaseController.cs b/AI.Api/Controllers/BaseController.cs
new file mode 100644
index 0000000..76200f1
--- /dev/null
+++ b/AI.Api/Controllers/BaseController.cs
@@ -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);
+ }
+ }
+ }
+}
diff --git a/AI.Api/Controllers/PromptController.cs b/AI.Api/Controllers/PromptController.cs
new file mode 100644
index 0000000..ab2f2a6
--- /dev/null
+++ b/AI.Api/Controllers/PromptController.cs
@@ -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> GetListAsync()
+ {
+ return await _promptService.GetListAsync();
+ }
+ }
+}
diff --git a/AI.Api/Controllers/QuestLogController.cs b/AI.Api/Controllers/QuestLogController.cs
new file mode 100644
index 0000000..74466dd
--- /dev/null
+++ b/AI.Api/Controllers/QuestLogController.cs
@@ -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 RecordAsync([FromBody] QuestionLogDto questionLogDto)
+ {
+ var entity = questionLogDto.Adapt();
+ entity.Uid = UId;
+
+ return await _questionLogService.RecordAsync(entity);
+ }
+ }
+}
diff --git a/AI.Api/Program.cs b/AI.Api/Program.cs
new file mode 100644
index 0000000..e0f6f27
--- /dev/null
+++ b/AI.Api/Program.cs
@@ -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();
+ // ȫģֵĬֵ ͳһظʽ
+ options.Filters.Add();
+ });
+ // 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();
+ builder.Services.AddScoped();
+ builder.Services.AddScoped();
+
+
+ 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();
+ }
+ }
+}
diff --git a/AI.Api/Properties/launchSettings.json b/AI.Api/Properties/launchSettings.json
new file mode 100644
index 0000000..8c2e3cd
--- /dev/null
+++ b/AI.Api/Properties/launchSettings.json
@@ -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"
+ }
+ }
+ }
+}
diff --git a/AI.Api/WebCore/AuthenticationServiceExtensions.cs b/AI.Api/WebCore/AuthenticationServiceExtensions.cs
new file mode 100644
index 0000000..ccfd4af
--- /dev/null
+++ b/AI.Api/WebCore/AuthenticationServiceExtensions.cs
@@ -0,0 +1,47 @@
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.IdentityModel.Tokens;
+using System.Text;
+
+namespace AI.Api.WebCore
+{
+ public static class AuthenticationServiceExtensions
+ {
+ ///
+ /// 添加认证和授权
+ ///
+ /// 服务集合
+ ///
+ 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));
+ //});
+ }
+ }
+}
diff --git a/AI.Api/WebCore/GlobalExceptionFilter.cs b/AI.Api/WebCore/GlobalExceptionFilter.cs
new file mode 100644
index 0000000..ee682b8
--- /dev/null
+++ b/AI.Api/WebCore/GlobalExceptionFilter.cs
@@ -0,0 +1,66 @@
+using AI.Common;
+using Masuit.Tools;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Filters;
+
+namespace AI.Api.WebCore
+{
+ ///
+ /// 全局异常捕获
+ ///
+ public class GlobalExceptionFilter : IAsyncExceptionFilter
+ {
+ private readonly ILogger _logger;
+
+ public GlobalExceptionFilter(ILogger logger)
+ {
+ _logger = logger; //在构造函数中注入日志处理实例
+ }
+
+ public async Task OnExceptionAsync(ExceptionContext context)
+ {
+ // 如果异常没有被处理则进行处理
+ if (context.ExceptionHandled == false)
+ {
+ // 定义返回类型
+ UniformResult