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.

316 lines
12 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.

// ============================================================================
// 【文件说明】HwPortalController.cs - 门户主控制器
// ============================================================================
// 这是门户模块的主控制器,提供官网前台所需的各种数据查询接口。
//
// 【业务场景】
// 官网前台需要展示:
// - 首页配置:轮播图、核心优势、合作伙伴等
// - 产品中心:产品列表、产品详情
// - 案例中心:案例列表、案例详情
// - 联系我们:用户留言提交
// - 关于我们:公司介绍
//
// 【与 Java Spring Boot 的对比】
// Java Spring Boot:
// @RestController
// @RequestMapping("/portal/portal")
// public class HwPortalController { ... }
//
// ASP.NET Core:
// [ApiController]
// [Route("portal/portal")]
// public class HwPortalController : ControllerBase { ... }
// ============================================================================
namespace Admin.NET.Plugin.HwPortal;
/// <summary>
/// 门户主控制器。
/// <para>
/// 【控制器职责】
/// 这个控制器是官网前台的"数据入口",提供:
/// 1. 配置数据查询:首页配置、配置类型
/// 2. 产品数据查询:产品列表、产品详情
/// 3. 案例数据查询:案例列表、案例详情
/// 4. 用户留言提交:联系我们表单
/// 5. 公司信息查询:关于我们
///
/// 所有接口都是 [AllowAnonymous],因为官网前台用户不需要登录。
/// </para>
/// <para>
/// 【多服务依赖】
/// 这个控制器注入了 8 个服务,这是"服务聚合"模式:
/// - 控制器协调多个服务完成复杂业务
/// - 每个服务专注一个领域
/// - 控制器不包含业务逻辑,只做服务调用和结果组装
///
/// 对比 Java Spring Boot
/// Java 的写法完全一样,只是注解不同:
/// @Autowired private HwPortalConfigService configService;
/// @Autowired private HwProductInfoService productInfoService;
/// ...
/// </para>
/// </summary>
[AllowAnonymous]
[Route("portal/portal")]
public class HwPortalController : HwPortalControllerBase
{
/// <summary>
/// 门户配置服务。
/// </summary>
private readonly HwPortalConfigService _configService;
/// <summary>
/// 配置类型服务。
/// </summary>
private readonly HwPortalConfigTypeService _configTypeService;
/// <summary>
/// 案例信息服务。
/// </summary>
private readonly HwProductCaseInfoService _caseInfoService;
/// <summary>
/// 联系我们信息服务。
/// </summary>
private readonly HwContactUsInfoService _contactUsInfoService;
/// <summary>
/// 产品信息服务。
/// </summary>
private readonly HwProductInfoService _productInfoService;
/// <summary>
/// 产品明细服务。
/// </summary>
private readonly HwProductInfoDetailService _productInfoDetailService;
/// <summary>
/// 关于我们信息服务。
/// </summary>
private readonly HwAboutUsInfoService _aboutUsInfoService;
/// <summary>
/// 关于我们明细服务。
/// </summary>
private readonly HwAboutUsInfoDetailService _aboutUsInfoDetailService;
/// <summary>
/// 构造函数(依赖注入)。
/// <para>
/// 【构造函数注入的优势】
/// 1. 依赖关系明确:看构造函数就知道需要哪些服务
/// 2. 便于测试:可以传入 mock 对象
/// 3. 不可变readonly 字段保证服务实例不被替换
///
/// 对比 Java Spring
/// Java 推荐的写法也是构造函数注入:
/// @Autowired
/// public HwPortalController(
/// HwPortalConfigService configService,
/// HwPortalConfigTypeService configTypeService,
/// ...
/// ) {
/// this.configService = configService;
/// ...
/// }
///
/// C# 和 Java 的最佳实践是一致的。
/// </para>
/// </summary>
public HwPortalController(
HwPortalConfigService configService,
HwPortalConfigTypeService configTypeService,
HwProductCaseInfoService caseInfoService,
HwContactUsInfoService contactUsInfoService,
HwProductInfoService productInfoService,
HwProductInfoDetailService productInfoDetailService,
HwAboutUsInfoService aboutUsInfoService,
HwAboutUsInfoDetailService aboutUsInfoDetailService)
{
_configService = configService;
_configTypeService = configTypeService;
_caseInfoService = caseInfoService;
_contactUsInfoService = contactUsInfoService;
_productInfoService = productInfoService;
_productInfoDetailService = productInfoDetailService;
_aboutUsInfoService = aboutUsInfoService;
_aboutUsInfoDetailService = aboutUsInfoDetailService;
}
/// <summary>
/// 查询门户配置列表(分页)。
/// </summary>
/// <param name="input">查询条件</param>
/// <returns>分页数据</returns>
[HttpGet("getPortalConfigList")]
public async Task<HwPortalTableDataInfo<HwPortalConfig>> GetPortalConfigList([FromQuery] HwPortalConfig input)
{
// [FromQuery] 表示从 URL 查询字符串绑定参数。
// 例如GET portal/portal/getPortalConfigList?portalConfigType=2
// 框架会自动把 portalConfigType=2 绑定到 input.PortalConfigType。
return GetDataTable(await _configService.SelectHwPortalConfigList(input));
}
/// <summary>
/// 查询配置类型列表(不分页)。
/// </summary>
/// <param name="input">查询条件</param>
/// <returns>配置类型列表</returns>
[HttpGet("getPortalConfigTypeList")]
public async Task<HwPortalTableDataInfo<HwPortalConfigType>> GetPortalConfigTypeList([FromQuery] HwPortalConfigType input)
{
// GetDataTableWithoutPaging 是基类方法,返回全部数据不做分页。
return GetDataTableWithoutPaging(await _configTypeService.SelectHwPortalConfigTypeList(input));
}
/// <summary>
/// 查询配置类型列表(另一种查询)。
/// </summary>
/// <param name="input">查询条件</param>
/// <returns>配置类型列表</returns>
[HttpGet("selectConfigTypeList")]
public async Task<HwPortalTableDataInfo<HwPortalConfigType>> SelectConfigTypeList([FromQuery] HwPortalConfigType input)
{
return GetDataTableWithoutPaging(await _configTypeService.SelectConfigTypeList(input));
}
/// <summary>
/// 查询首页案例标题列表。
/// </summary>
/// <param name="input">查询条件</param>
/// <returns>案例标题列表</returns>
[HttpGet("getHomeCaseTitleList")]
public async Task<HwPortalTableDataInfo<HwPortalConfigType>> GetHomeCaseTitleList([FromQuery] HwPortalConfigType input)
{
return GetDataTable(await _configTypeService.SelectHwPortalConfigTypeList(input));
}
/// <summary>
/// 查询首页典型案例信息。
/// </summary>
/// <param name="input">查询条件</param>
/// <returns>典型案例信息</returns>
[HttpGet("getTypicalHomeCaseInfo")]
public async Task<HwPortalAjaxResult> GetTypicalHomeCaseInfo([FromQuery] HwProductCaseInfo input)
{
return Success(await _caseInfoService.GetTypicalHomeCaseInfo(input));
}
/// <summary>
/// 提交联系我们信息(用户留言)。
/// <para>
/// 【业务场景】
/// 用户在官网"联系我们"页面填写表单,提交留言。
/// 系统记录用户信息、留言内容、IP 地址等。
/// </para>
/// </summary>
/// <param name="input">联系我们信息</param>
/// <returns>操作结果</returns>
[HttpPost("addContactUsInfo")]
[Idempotent]
public async Task<HwPortalAjaxResult> AddContactUsInfo([FromBody] HwContactUsInfo input)
{
// 【获取客户端 IP】
// HwPortalContextHelper.CurrentRequestIp(HttpContext) 获取请求的客户端 IP。
// HttpContext 包含当前 HTTP 请求的所有信息:
// - Request请求对象Headers、Query、Body 等)
// - Response响应对象
// - User当前登录用户如果有
// - Connection连接信息IP、端口等
//
// 对比 Java Spring
// Java 通常通过注入 HttpServletRequest 获取 IP
// @Autowired private HttpServletRequest request;
// String ip = request.getRemoteAddr();
//
// C# 通过 HttpContext 直接访问,更简洁。
input.UserIp = HwPortalContextHelper.CurrentRequestIp(HttpContext);
return ToAjax(await _contactUsInfoService.InsertHwContactUsInfo(input));
}
/// <summary>
/// 查询产品中心产品列表(含明细)。
/// </summary>
/// <param name="input">查询条件</param>
/// <returns>产品列表(含明细)</returns>
[HttpGet("getProductCenterProductInfos")]
public async Task<HwPortalAjaxResult> GetProductCenterProductInfos([FromQuery] HwProductInfo input)
{
// SelectHwProductInfoJoinDetailList 返回产品及其明细列表。
// 这是一个复杂的关联查询,在 Service 层处理。
return Success(await _productInfoService.SelectHwProductInfoJoinDetailList(input));
}
/// <summary>
/// 查询产品明细列表。
/// </summary>
/// <param name="input">查询条件</param>
/// <returns>产品明细列表</returns>
[HttpGet("getProductCenterProductDetailInfos")]
public async Task<HwPortalAjaxResult> GetProductCenterProductDetailInfos([FromQuery] HwProductInfoDetail input)
{
return Success(await _productInfoDetailService.SelectHwProductInfoDetailList(input));
}
/// <summary>
/// 查询案例中心案例列表。
/// </summary>
/// <param name="input">查询条件</param>
/// <returns>案例列表</returns>
[HttpGet("getCaseCenterCaseInfos")]
public async Task<HwPortalAjaxResult> GetCaseCenterCaseInfos([FromQuery] HwProductCaseInfo input)
{
return Success(await _caseInfoService.SelectHwProductCaseInfoList(input));
}
/// <summary>
/// 查询案例详情。
/// <para>
/// 【路由参数】
/// [HttpGet("getCaseCenterCaseInfo/{caseInfoId:long}")] 中的 {caseInfoId:long} 是路由参数。
/// :long 是路由约束,确保 caseInfoId 是长整型。
///
/// 调用示例GET portal/portal/getCaseCenterCaseInfo/123
/// 框架会把 123 绑定到 caseInfoId 参数。
///
/// 对比 Java Spring Boot
/// Java: @GetMapping("/getCaseCenterCaseInfo/{caseInfoId}")
/// public Result getCaseCenterCaseInfo(@PathVariable Long caseInfoId)
///
/// C# 的路由约束更强大,可以在路由模板中定义类型验证。
/// </para>
/// </summary>
/// <param name="caseInfoId">案例ID</param>
/// <returns>案例详情</returns>
[HttpGet("getCaseCenterCaseInfo/{caseInfoId:long}")]
public async Task<HwPortalAjaxResult> GetCaseCenterCaseInfo(long caseInfoId)
{
return Success(await _caseInfoService.SelectHwProductCaseInfoByCaseInfoId(caseInfoId));
}
/// <summary>
/// 查询关于我们信息。
/// </summary>
/// <param name="input">查询条件</param>
/// <returns>关于我们信息</returns>
[HttpGet("getAboutUsInfo")]
public async Task<HwPortalAjaxResult> GetAboutUsInfo([FromQuery] HwAboutUsInfo input)
{
return Success(await _aboutUsInfoService.SelectHwAboutUsInfoList(input));
}
/// <summary>
/// 查询关于我们明细列表。
/// </summary>
/// <param name="input">查询条件</param>
/// <returns>关于我们明细列表</returns>
[HttpGet("getAboutUsInfoDetails")]
public async Task<HwPortalAjaxResult> GetAboutUsInfoDetails([FromQuery] HwAboutUsInfoDetail input)
{
return Success(await _aboutUsInfoDetailService.SelectHwAboutUsInfoDetailList(input));
}
}