垃圾Bug终于让我给修好了。

更新JWT角色声明名称并优化字典控制器文档和方法注释
This commit is contained in:
罗澜大帅哥 2025-07-16 00:42:30 +08:00
parent 7ae98dedfb
commit f7dd631f47
5 changed files with 148 additions and 24 deletions

View File

@ -136,7 +136,7 @@ namespace AGSS.Areas.Identity.Pages.Account
var roles = await _userManager.GetRolesAsync(user);
foreach (string role in roles)
{
claims.Add(new Claim("role", role));
claims.Add(new Claim(ClaimTypes.Role, role));
}
string jwtToken = _jwt.BuildToken(claims, jwtOptions.Value);

View File

@ -148,7 +148,7 @@ namespace AGSS.Areas.Identity.Pages.Account
var roles = await _userManager.GetRolesAsync(user);
foreach (string role in roles)
{
claims.Add(new Claim("role", role));
claims.Add(new Claim(ClaimTypes.Role, role));
}
string jwtToken = _jwt.BuildToken(claims, jwtOptions.Value);
var frontendCallback = $"{Request.Query["frontendCallback"]}?token={jwtToken}";

View File

@ -10,10 +10,12 @@ namespace AGSS.Controllers.Dict
// [Produces("application/json")]
public class DictController : ControllerBase
{
private readonly DictService _dictService;
private readonly ILogger<DictController> _logger;
private readonly DictService _dictService;
public DictController(DictService dictService, ILogger<DictController> logger)
private readonly ILogger<DictController> _logger;
public DictController(DictService dictService, ILogger<DictController> logger)
{
_dictService = dictService;
_logger = logger;
@ -21,7 +23,7 @@ namespace AGSS.Controllers.Dict
// 1. 获取父级列表
[HttpGet("parents")]
[HttpGet("parents")]
public async Task<ActionResult> GetParents([FromQuery] string? label)
{
try
@ -38,27 +40,32 @@ namespace AGSS.Controllers.Dict
// 2. 创建父级项
// [Authorize(Roles = "Admin")]
/// <summary>
/// 创建一个新的父级项。
/// </summary>
/// <param name="request">包含创建父级所需信息的请求对象。</param>
/// <returns>返回一个ActionResult表示操作结果。成功时返回状态码200及新创建的父级项失败时返回错误信息和相应的状态码。</returns>
[HttpPost("parents")]
public async Task<ActionResult> CreateParent([FromBody] CreateParentRequest request)
{
try
{
var result = await _dictService.CreateParentAsync(request.Label, request.Value);
return Ok(new ReturnTemplate(200, "创建成功啦!", result));
}
catch (Exception ex)
{
return Ok(new ReturnTemplate(500, "错误", ex.Message));
}
}
// 请求模型
public class CreateParentRequest
public class CreateParentRequest
{
[Required(ErrorMessage = "字典标签不能为空")]
[Required(ErrorMessage = "字典标签不能为空")]
[StringLength(100, ErrorMessage = "标签长度不能超过100字符")]
public string Label { get; set; } = null!;
/// <summary>
/// Represents the value of a dictionary item. This property is required and must not exceed 50 characters in length.
/// </summary>
/// <remarks>Ensure that the value provided is unique within its context to avoid conflicts.</remarks>
[Required(ErrorMessage = "字典值不能为空")]
[StringLength(50, ErrorMessage = "值长度不能超过50字符")]
public string Value { get; set; } = null!;
@ -83,8 +90,16 @@ namespace AGSS.Controllers.Dict
}
}
/// <summary>
/// Represents the data contract for updating a parent dictionary item.
/// This class is used to pass updated details of a parent dictionary item through HTTP requests.
/// </summary>
public class UpdateParentRequest
{
/// <summary>
/// Represents the label of a dictionary item. This property is used to uniquely identify or name the item within its context.
/// It is required and must not be null, with a maximum length of 100 characters. The label plays a crucial role in both creating and updating dictionary items, serving as a key identifier for operations performed on the dictionary structure.
/// </summary>
[Required(ErrorMessage = "字典标签不能为空")]
[StringLength(100, ErrorMessage = "标签长度不能超过100字符")]
public string Label { get; set; } = null!;
@ -92,7 +107,12 @@ namespace AGSS.Controllers.Dict
// 3. 删除父级项
[Authorize(Roles = "Admin")]
/// <summary>
/// Deletes a parent dictionary entry by its unique identifier.
/// </summary>
/// <param name="uuid">The unique identifier (UUID) of the parent dictionary entry to be deleted.</param>
/// <returns>An action result indicating the success or failure of the deletion operation. On success, returns a 200 status code with a confirmation message. In case of an exception, it returns a 200 status code with an error message and exception details.</returns>
[Authorize(Roles = "Admin")]
[HttpDelete("parents/{uuid}")]
public async Task<ActionResult> DeleteParent([FromRoute] Guid uuid)
{
@ -109,6 +129,11 @@ namespace AGSS.Controllers.Dict
// 4. 创建子项
/// <summary>
/// 创建一个新的子项。
/// </summary>
/// <param name="request">包含创建子项所需信息的请求对象。</param>
/// <returns>如果创建成功,则返回一个包含成功消息和新创建子项数据的结果;如果失败,则返回一个错误消息。</returns>
[HttpPost("children")]
public async Task<ActionResult> CreateChild([FromBody] CreateChildRequest request)
{
@ -131,23 +156,57 @@ namespace AGSS.Controllers.Dict
}
}
/// <summary>
/// Represents the request model used for creating a child item in the dictionary.
/// This model contains the necessary properties to define a new child entry, including
/// its relationship to a parent, and additional metadata such as labels and values.
/// </summary>
public class CreateChildRequest
{
/// <summary>
/// Represents the unique identifier of the parent dictionary item to which a child dictionary item is associated.
/// This property is required and must be provided when creating or updating a child dictionary item.
/// </summary>
/// <remarks>
/// The value of this property should correspond to an existing dictionary item that is not a child itself (i.e., it does not have its own ParentId).
/// </remarks>
[Required(ErrorMessage = "父级ID不能为空")] public Guid ParentId { get; set; }
[Required(ErrorMessage = "父级值不能为空")] public string ParentValue { get; set; } = null!;
/// <summary>
/// Represents the label of a dictionary item. This property is required and must not be empty, as it uniquely identifies the dictionary entry within its parent context. It is used in both creation and update operations for dictionary items.
/// </summary>
/// <remarks>
/// The label should be descriptive and meaningful to easily identify the purpose or content of the dictionary item. It plays a crucial role in the user interface and backend logic, serving as a key identifier for related operations.
/// </remarks>
[Required(ErrorMessage = "字典标签不能为空")] public string Label { get; set; } = null!;
[Required(ErrorMessage = "字典值不能为空")] public string Value { get; set; } = null!;
/// <summary>
/// Represents the English label for a dictionary item. This property is optional and can be used to store an English translation or equivalent of the main label.
/// </summary>
/// <remarks>
/// This property is part of the request model for creating or updating a child dictionary item. It allows for the inclusion of an English label, enhancing multilingual support within the application.
/// </remarks>
public string? LabelEn { get; set; }
public string? Remark { get; set; }
/// <summary>
/// Represents an optional tag or identifier for a dictionary item. This property can be used to categorize or label the item in a way that is meaningful within the context of its usage, such as for filtering or searching purposes.
/// </summary>
public string? Tag { get; set; }
}
// 4.1 更新子项
[HttpPut("children/{uuid}")]
/// <summary>
/// Updates the details of a child dictionary item.
/// </summary>
/// <param name="uuid">The unique identifier of the child dictionary item to update.</param>
/// <param name="request">The request object containing the new values for the child dictionary item.</param>
/// <returns>An action result indicating the success or failure of the operation, including a message and an optional data payload.</returns>
[HttpPut("children/{uuid}")]
public async Task<ActionResult> UpdateChild(
[FromRoute] Guid uuid,
[FromBody] UpdateChildRequest request)
@ -170,19 +229,58 @@ namespace AGSS.Controllers.Dict
}
}
/// <summary>
/// Represents the request model used for updating a child item in the dictionary.
/// This class is utilized by the API endpoint responsible for modifying an existing child entry,
/// allowing changes to its label, value, and optional attributes such as English label, remarks, and tags.
/// </summary>
public class UpdateChildRequest
{
/// <summary>
/// Represents the label of a dictionary item. This property is required and must not be empty, as it uniquely identifies the dictionary item in a human-readable format.
/// </summary>
/// <remarks>
/// The Label is used to provide a meaningful name for the dictionary item that can be displayed in user interfaces or referenced in other parts of the application. It is crucial for the identification and management of dictionary items within the system.
/// </remarks>
[Required(ErrorMessage = "字典标签不能为空")] public string Label { get; set; } = null!;
/// <summary>
/// Represents the value of a dictionary item. This property is required and must be provided when updating or creating a dictionary child item.
/// </summary>
/// <remarks>
/// The value is a unique identifier for the dictionary item within its parent context. It should be meaningful and reflect the nature of the item it represents.
/// </remarks>
[Required(ErrorMessage = "字典值不能为空")] public string Value { get; set; } = null!;
/// <summary>
/// Represents the English label for a dictionary item. This property can be used to store an English translation or alternative name for the dictionary entry, facilitating internationalization and localization efforts.
/// </summary>
/// <remarks>
/// This is an optional field; if not provided, it defaults to null, indicating no specific English label is set for the dictionary item.
/// </remarks>
public string? LabelEn { get; set; }
/// <summary>
/// Gets or sets the remark for the dictionary item. This property is optional and can be used to store additional information or comments about the dictionary item.
/// </summary>
public string? Remark { get; set; }
/// <summary>
/// Represents an optional tag associated with a dictionary item. This property can be used to categorize or provide additional metadata about the dictionary item.
/// </summary>
/// <remarks>
/// The Tag is not required and can be null. It serves as a flexible way to add extra information that can be used for filtering, sorting, or any other purpose as needed by the application.
/// </remarks>
public string? Tag { get; set; }
}
// 5. 删除子项
[HttpDelete("children/{uuid}")]
/// <summary>
/// Deletes a child item from the dictionary based on the provided unique identifier.
/// </summary>
/// <param name="uuid">The unique identifier (UUID) of the child item to be deleted.</param>
/// <returns>An action result indicating the success or failure of the deletion operation, encapsulated in a ReturnTemplate object which includes a status code, message, and additional data if any.</returns>
[HttpDelete("children/{uuid}")]
public async Task<ActionResult> DeleteChild([FromRoute] Guid uuid)
{
try
@ -215,14 +313,40 @@ namespace AGSS.Controllers.Dict
}
// 统一响应模型
public class ApiResponse
/// <summary>
/// Represents a response object that is returned by API endpoints.
/// This class encapsulates the status code, message, and optionally data to provide a consistent structure for API responses.
/// </summary>
public class ApiResponse
{
/// <summary>
/// Represents the status code of the API response. This property is used to indicate the outcome of an operation, such as success, error, or a specific HTTP status.
/// </summary>
/// <remarks>
/// The value of this property should be set based on the result of the operation being performed. It can be used by the client to determine the next steps or to handle the response appropriately.
/// </remarks>
public int Code { get; set; }
/// <summary>
/// Represents a message or description associated with the API response. This property is used to provide additional information about the result of an operation, such as success messages, error details, or any other relevant information that needs to be communicated back to the client.
/// </summary>
public string Message { get; set; } = null!;
}
/// <summary>
/// Represents a response from the API, containing a status code and message.
/// This class is used to provide a uniform structure for all API responses,
/// ensuring that clients can consistently handle and interpret the results of their requests.
/// </summary>
public class ApiResponse<T> : ApiResponse
{
/// <summary>
/// Represents the data payload in the ApiResponse, containing the result of an API operation.
/// This property can hold any type of object that is being returned as part of the response from the server,
/// such as a list of items, a single item, or a custom object. The actual type of the data will be determined
/// by the generic type parameter T used with ApiResponse.
/// </summary>
/// <typeparam name="T">The type of the data being carried in the response.</typeparam>
public T? Data { get; set; }
}
}

View File

@ -62,6 +62,10 @@ builder.Services.AddScoped<ICurrentUserService, CurrentUserService>();
builder.Services.Configure<JwtBearerOptions>(options =>
{
options.TokenValidationParameters.RoleClaimType = ClaimTypes.Role;
});
builder.Services.Configure<JWTOptions>(builder.Configuration.GetSection("JWT"));
@ -85,10 +89,6 @@ builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
builder.Services.AddAuthorization();
builder.Services.Configure<JwtBearerOptions>(options =>
{
options.TokenValidationParameters.RoleClaimType = "role";
});
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle

View File

@ -21,5 +21,5 @@ public class CurrentUserService : ICurrentUserService
Guid.Parse(_httpContextAccessor.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value);
public bool IsAdmin =>
_httpContextAccessor.HttpContext?.User?.IsInRole("luolan") ?? false;
_httpContextAccessor.HttpContext?.User?.IsInRole("Admin") ?? false;
}