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#

// ============================================================================
// 【文件说明】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));
}
}