添加项目文件。
This commit is contained in:
30
Controllers/BaseController.cs
Normal file
30
Controllers/BaseController.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using AcdiuTools.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace AcdiuTools.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// 基础控制器
|
||||
/// 所有需要主题功能的控制器应继承此类
|
||||
/// </summary>
|
||||
public class BaseController(IThemeService themeService) : Controller
|
||||
{
|
||||
private readonly IThemeService _themeService = themeService;
|
||||
|
||||
/// <summary>
|
||||
/// 在执行 Action 之前加载主题配置并注入 ViewBag
|
||||
/// </summary>
|
||||
public override async void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
base.OnActionExecuting(context);
|
||||
|
||||
// 异步操作在 OnActionExecuting 中处理需小心,通常建议在 Action 内部或中间件中处理
|
||||
// 这里为了演示简单,使用同步等待或改为中间件方案更佳
|
||||
// 更好的方式:使用 ViewComponent 或 TagHelper
|
||||
|
||||
var theme = await _themeService.GetUserThemeAsync();
|
||||
ViewBag.CurrentTheme = theme;
|
||||
}
|
||||
}
|
||||
}
|
||||
84
Controllers/HomeController.cs
Normal file
84
Controllers/HomeController.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using AcdiuTools.Models;
|
||||
using AcdiuTools.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace AcdiuTools.Controllers
|
||||
{
|
||||
public class HomeController(IThemeService themeService) : BaseController(themeService)
|
||||
{
|
||||
private readonly IThemeService _themeService = themeService;
|
||||
|
||||
[Route("")]
|
||||
public IActionResult Index()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
[Route("privacy")]
|
||||
public IActionResult Privacy()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
[Route("err")]
|
||||
[Route("error")]
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
public IActionResult Error()
|
||||
{
|
||||
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// API 端点:用于前端 AJAX 调用以切换主题
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> SetTheme([FromBody] ThemeRequest model)
|
||||
{
|
||||
// 获取用户 ID
|
||||
string? claimUserId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value
|
||||
?? User.FindFirst("sub")?.Value;
|
||||
|
||||
string userId;
|
||||
|
||||
if (!string.IsNullOrEmpty(claimUserId))
|
||||
{
|
||||
// 已登录用户
|
||||
userId = claimUserId;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 匿名用户:尝试使用 Session ID
|
||||
// 注意:访问 HttpContext.Session 会触发 Session 创建/加载
|
||||
try
|
||||
{
|
||||
userId = HttpContext.Session.Id;
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
// 如果 Session 未配置(防御性编程),回退到匿名标识
|
||||
userId = "anonymous_" + HttpContext.Connection.RemoteIpAddress?.ToString()?.Replace(".", "_") ?? "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
await _themeService.SaveUserThemeAsync(userId, model.Theme);
|
||||
|
||||
return Json(new { success = true, theme = model.Theme });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 主题请求模型
|
||||
/// </summary>
|
||||
public class ThemeRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 主题名称
|
||||
/// 修复 CS8618: 使用 required 修饰符,确保反序列化时必须存在该字段
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required string Theme { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user