You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

53 lines
3.0 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

namespace Admin.NET.Plugin.HwPortal;
// [AllowAnonymous] 是 ASP.NET Core/Furion 里的匿名放行特性。
// 你可以把它理解成 Spring Security 里“这个接口不要求登录”的声明式配置。
// 和 Spring 常见的配置类放行不同,这里直接写在控制器上,阅读时更集中。
[AllowAnonymous]
[Route("portal/search")]
public class HwSearchController : HwPortalControllerBase
{
// readonly 字段表示“构造完成后不允许再被重新赋值”。
// 这和 Java 里把依赖字段声明成 final 的意图一致:依赖一旦注入完成,就不要在运行期乱改。
private readonly HwSearchService _service;
public HwSearchController(HwSearchService service)
{
// 这就是 C#/ASP.NET Core 最常见的“构造函数注入”。
// 对应 Java Spring 你可以理解成:
// 1. 以前常见的 @Autowired 字段注入
// 2. 更推荐的 @RequiredArgsConstructor / 构造器注入
// 这里只是 C# 没有 Lombok直接手写构造函数而已。
_service = service;
}
// [HttpGet] 表示这个方法处理 GET 请求。
// Java Spring 里对应 @GetMapping。
// 这里没有写路径,表示沿用类上的基础路由,也就是 /portal/search。
[HttpGet]
// 这是我们自定义的限流特性。
// 注意它不是“只做标记”,而是自己实现了 IAsyncActionFilter框架执行到这里会先跑限流逻辑再决定要不要进入方法体。
[HwPortalIpRateLimit("portal_search", 60, 120)]
public async Task<HwPortalAjaxResult> Search([FromQuery] string keyword, [FromQuery] int? pageNum, [FromQuery] int? pageSize)
{
// async + await 是 C# 异步编程的核心写法。
// 你可以先把它理解成“这个方法里要等待数据库/IO但等待时不想卡死线程”。
// Java 里它不等于 new Thread也不等于 CompletableFuture 全套写法,更像框架层帮你把异步 IO 写法简化了。
// [FromQuery] 表示参数从 URL 查询串里绑定,例如 ?keyword=轮胎&pageNum=1。
// Spring Boot 里通常你会写 @RequestParamASP.NET Core 则更常用 [FromQuery] 明确绑定来源。
return Success(await _service.Search(keyword, pageNum, pageSize));
}
// 这里写了 "edit",所以完整路由会变成 /portal/search/edit。
// 这和 Spring 的 @GetMapping("/edit") 完全是同一类路由声明思路。
[HttpGet("edit")]
[HwPortalIpRateLimit("portal_search_edit", 60, 120)]
public async Task<HwPortalAjaxResult> EditSearch([FromQuery] string keyword, [FromQuery] int? pageNum, [FromQuery] int? pageSize)
{
// 展示端和编辑端共用同一套搜索主逻辑,只是编辑端需要多返回 editRoute。
// 这种“控制器只做参数接线,真正差异交给 Service”的写法是为了让 API 层保持薄,不把业务判断写散。
return Success(await _service.SearchForEdit(keyword, pageNum, pageSize));
}
}