using MiAssessment.Admin.Business.Attributes; using MiAssessment.Admin.Business.Models; using MiAssessment.Admin.Business.Models.Common; using MiAssessment.Admin.Business.Models.Content; using MiAssessment.Admin.Business.Services.Interfaces; using Microsoft.AspNetCore.Mvc; namespace MiAssessment.Admin.Business.Controllers; /// /// 内容管理控制器 /// [Route("api/admin/content")] public class ContentController : BusinessControllerBase { private readonly IContentService _contentService; /// /// 构造函数 /// /// 内容服务 public ContentController(IContentService contentService) { _contentService = contentService; } #region Banner 轮播图接口 /// /// 获取轮播图列表 /// /// 查询参数 /// 分页轮播图列表 [HttpGet("banner/getList")] [BusinessPermission("content:view")] public async Task GetBannerList([FromQuery] BannerQueryRequest request) { try { var result = await _contentService.GetBannerListAsync(request); return Ok(result); } catch (BusinessException ex) { return Error(ex.Code, ex.Message); } catch (Exception) { return Error(ErrorCodes.SystemError, "获取轮播图列表失败"); } } /// /// 创建轮播图 /// /// 创建请求 /// 新创建的轮播图ID [HttpPost("banner/create")] [BusinessPermission("content:create")] public async Task CreateBanner([FromBody] CreateBannerRequest request) { // 参数验证 if (string.IsNullOrWhiteSpace(request.ImageUrl)) { return ValidationError("图片URL不能为空"); } // LinkType 验证 var linkValidationError = ValidateBannerLinkType(request.LinkType, request.LinkUrl, request.AppId); if (!string.IsNullOrEmpty(linkValidationError)) { return ValidationError(linkValidationError); } try { var id = await _contentService.CreateBannerAsync(request); return Ok(id); } catch (BusinessException ex) { return Error(ex.Code, ex.Message); } catch (Exception) { return Error(ErrorCodes.SystemError, "创建轮播图失败"); } } /// /// 更新轮播图 /// /// 更新请求 /// 更新结果 [HttpPost("banner/update")] [BusinessPermission("content:update")] public async Task UpdateBanner([FromBody] UpdateBannerRequest request) { // 参数验证 if (request.Id <= 0) { return ValidationError("轮播图ID无效"); } if (string.IsNullOrWhiteSpace(request.ImageUrl)) { return ValidationError("图片URL不能为空"); } // LinkType 验证 var linkValidationError = ValidateBannerLinkType(request.LinkType, request.LinkUrl, request.AppId); if (!string.IsNullOrEmpty(linkValidationError)) { return ValidationError(linkValidationError); } try { var result = await _contentService.UpdateBannerAsync(request); return Ok(result); } catch (BusinessException ex) { return Error(ex.Code, ex.Message); } catch (Exception) { return Error(ErrorCodes.SystemError, "更新轮播图失败"); } } /// /// 删除轮播图(软删除) /// /// 删除请求 /// 删除结果 [HttpPost("banner/delete")] [BusinessPermission("content:delete")] public async Task DeleteBanner([FromBody] DeleteRequest request) { if (request.Id <= 0) { return ValidationError("轮播图ID无效"); } try { var result = await _contentService.DeleteBannerAsync(request.Id); return Ok(result); } catch (BusinessException ex) { return Error(ex.Code, ex.Message); } catch (Exception) { return Error(ErrorCodes.SystemError, "删除轮播图失败"); } } /// /// 更新轮播图状态 /// /// 状态更新请求 /// 更新结果 [HttpPost("banner/updateStatus")] [BusinessPermission("content:update")] public async Task UpdateBannerStatus([FromBody] UpdateStatusRequest request) { if (request.Id <= 0) { return ValidationError("轮播图ID无效"); } if (request.Status < 0 || request.Status > 1) { return ValidationError("状态值无效,只能为0(禁用)或1(启用)"); } try { var result = await _contentService.UpdateBannerStatusAsync(request.Id, request.Status); return Ok(result); } catch (BusinessException ex) { return Error(ex.Code, ex.Message); } catch (Exception) { return Error(ErrorCodes.SystemError, "更新轮播图状态失败"); } } /// /// 批量更新轮播图排序 /// /// 排序更新请求 /// 更新结果 [HttpPost("banner/updateSort")] [BusinessPermission("content:update")] public async Task UpdateBannerSort([FromBody] UpdateSortRequest request) { if (request.Items == null || request.Items.Count == 0) { return ValidationError("排序项列表不能为空"); } // 验证每个排序项 foreach (var item in request.Items) { if (item.Id <= 0) { return ValidationError($"排序项ID无效: {item.Id}"); } } try { var result = await _contentService.UpdateBannerSortAsync(request.Items); return Ok(result); } catch (BusinessException ex) { return Error(ex.Code, ex.Message); } catch (Exception) { return Error(ErrorCodes.SystemError, "更新轮播图排序失败"); } } #endregion #region Promotion 宣传图接口 /// /// 获取宣传图列表 /// /// 查询参数 /// 分页宣传图列表 [HttpGet("promotion/getList")] [BusinessPermission("content:view")] public async Task GetPromotionList([FromQuery] PromotionQueryRequest request) { try { var result = await _contentService.GetPromotionListAsync(request); return Ok(result); } catch (BusinessException ex) { return Error(ex.Code, ex.Message); } catch (Exception) { return Error(ErrorCodes.SystemError, "获取宣传图列表失败"); } } /// /// 创建宣传图 /// /// 创建请求 /// 新创建的宣传图ID [HttpPost("promotion/create")] [BusinessPermission("content:create")] public async Task CreatePromotion([FromBody] CreatePromotionRequest request) { // 参数验证 if (string.IsNullOrWhiteSpace(request.ImageUrl)) { return ValidationError("图片URL不能为空"); } // Position 验证 if (request.Position != 1 && request.Position != 2) { return ValidationError("位置值无效,只能为1(首页底部)或2(产品页)"); } try { var id = await _contentService.CreatePromotionAsync(request); return Ok(id); } catch (BusinessException ex) { return Error(ex.Code, ex.Message); } catch (Exception) { return Error(ErrorCodes.SystemError, "创建宣传图失败"); } } /// /// 更新宣传图 /// /// 更新请求 /// 更新结果 [HttpPost("promotion/update")] [BusinessPermission("content:update")] public async Task UpdatePromotion([FromBody] UpdatePromotionRequest request) { // 参数验证 if (request.Id <= 0) { return ValidationError("宣传图ID无效"); } if (string.IsNullOrWhiteSpace(request.ImageUrl)) { return ValidationError("图片URL不能为空"); } // Position 验证 if (request.Position != 1 && request.Position != 2) { return ValidationError("位置值无效,只能为1(首页底部)或2(产品页)"); } try { var result = await _contentService.UpdatePromotionAsync(request); return Ok(result); } catch (BusinessException ex) { return Error(ex.Code, ex.Message); } catch (Exception) { return Error(ErrorCodes.SystemError, "更新宣传图失败"); } } /// /// 删除宣传图(软删除) /// /// 删除请求 /// 删除结果 [HttpPost("promotion/delete")] [BusinessPermission("content:delete")] public async Task DeletePromotion([FromBody] DeleteRequest request) { if (request.Id <= 0) { return ValidationError("宣传图ID无效"); } try { var result = await _contentService.DeletePromotionAsync(request.Id); return Ok(result); } catch (BusinessException ex) { return Error(ex.Code, ex.Message); } catch (Exception) { return Error(ErrorCodes.SystemError, "删除宣传图失败"); } } /// /// 更新宣传图状态 /// /// 状态更新请求 /// 更新结果 [HttpPost("promotion/updateStatus")] [BusinessPermission("content:update")] public async Task UpdatePromotionStatus([FromBody] UpdateStatusRequest request) { if (request.Id <= 0) { return ValidationError("宣传图ID无效"); } if (request.Status < 0 || request.Status > 1) { return ValidationError("状态值无效,只能为0(禁用)或1(启用)"); } try { var result = await _contentService.UpdatePromotionStatusAsync(request.Id, request.Status); return Ok(result); } catch (BusinessException ex) { return Error(ex.Code, ex.Message); } catch (Exception) { return Error(ErrorCodes.SystemError, "更新宣传图状态失败"); } } #endregion #region HomeNavigation 首页导航接口 /// /// 获取首页导航列表 /// /// 查询参数 /// 分页首页导航列表 [HttpGet("navigation/getList")] [BusinessPermission("content:view")] public async Task GetNavigationList([FromQuery] HomeNavigationQueryRequest request) { try { var result = await _contentService.GetNavigationListAsync(request); return Ok(result); } catch (BusinessException ex) { return Error(ex.Code, ex.Message); } catch (Exception) { return Error(ErrorCodes.SystemError, "获取首页导航列表失败"); } } /// /// 创建首页导航 /// /// 创建请求 /// 新创建的导航ID [HttpPost("navigation/create")] [BusinessPermission("content:create")] public async Task CreateNavigation([FromBody] CreateHomeNavigationRequest request) { if (string.IsNullOrWhiteSpace(request.Name)) { return ValidationError("导航名称不能为空"); } // ActionType=1(跳转页面)时 LinkUrl 必填 if (request.ActionType == 1 && string.IsNullOrWhiteSpace(request.LinkUrl)) { return Error(ErrorCodes.ParamError, "跳转链接不能为空"); } try { var id = await _contentService.CreateNavigationAsync(request); return Ok(id); } catch (BusinessException ex) { return Error(ex.Code, ex.Message); } catch (Exception) { return Error(ErrorCodes.SystemError, "创建首页导航失败"); } } /// /// 更新首页导航 /// /// 更新请求 /// 更新结果 [HttpPost("navigation/update")] [BusinessPermission("content:update")] public async Task UpdateNavigation([FromBody] UpdateHomeNavigationRequest request) { if (request.Id <= 0) { return ValidationError("导航ID无效"); } if (string.IsNullOrWhiteSpace(request.Name)) { return ValidationError("导航名称不能为空"); } // ActionType=1(跳转页面)时 LinkUrl 必填 if (request.ActionType == 1 && string.IsNullOrWhiteSpace(request.LinkUrl)) { return Error(ErrorCodes.ParamError, "跳转链接不能为空"); } try { var result = await _contentService.UpdateNavigationAsync(request); return Ok(result); } catch (BusinessException ex) { return Error(ex.Code, ex.Message); } catch (Exception) { return Error(ErrorCodes.SystemError, "更新首页导航失败"); } } /// /// 删除首页导航(软删除) /// /// 删除请求 /// 删除结果 [HttpPost("navigation/delete")] [BusinessPermission("content:delete")] public async Task DeleteNavigation([FromBody] DeleteRequest request) { if (request.Id <= 0) { return ValidationError("导航ID无效"); } try { var result = await _contentService.DeleteNavigationAsync(request.Id); return Ok(result); } catch (BusinessException ex) { return Error(ex.Code, ex.Message); } catch (Exception) { return Error(ErrorCodes.SystemError, "删除首页导航失败"); } } /// /// 更新首页导航状态 /// /// 状态更新请求 /// 更新结果 [HttpPost("navigation/updateStatus")] [BusinessPermission("content:update")] public async Task UpdateNavigationStatus([FromBody] UpdateStatusRequest request) { if (request.Id <= 0) { return ValidationError("导航ID无效"); } if (request.Status != 0 && request.Status != 1) { return Error(ErrorCodes.ParamError, "状态值无效"); } try { var result = await _contentService.UpdateNavigationStatusAsync(request.Id, request.Status); return Ok(result); } catch (BusinessException ex) { return Error(ex.Code, ex.Message); } catch (Exception) { return Error(ErrorCodes.SystemError, "更新首页导航状态失败"); } } #endregion #region 私有方法 /// /// 验证轮播图跳转类型 /// /// 跳转类型 /// 跳转地址 /// 小程序AppId /// 验证错误信息,为空表示验证通过 private static string? ValidateBannerLinkType(int linkType, string? linkUrl, string? appId) { // LinkType: 0无 1内部页面 2外部链接 3小程序 switch (linkType) { case 0: // 无跳转,不需要验证 break; case 1: case 2: // 内部页面或外部链接,需要 LinkUrl if (string.IsNullOrWhiteSpace(linkUrl)) { return "跳转地址不能为空"; } break; case 3: // 小程序,需要 LinkUrl 和 AppId if (string.IsNullOrWhiteSpace(linkUrl)) { return "跳转地址不能为空"; } if (string.IsNullOrWhiteSpace(appId)) { return "小程序AppId不能为空"; } break; default: return "跳转类型无效"; } return null; } #endregion }