Files
f9-web-ai-test/backend/F9WebAiTest.Api/Controllers/Notice/NotificationControllers.cs
T
2026-10-08 10:43:59 +08:00

192 lines
8.1 KiB
C#

using F9WebAiTest.Application.Common;
using F9WebAiTest.Application.Dtos;
using F9WebAiTest.Application.Dtos.Notice;
using F9WebAiTest.Application.Services;
using F9WebAiTest.Application.Services.Auth;
using F9WebAiTest.Application.Services.Notice;
using F9WebAiTest.Domain.Entities;
using F9WebAiTest.Domain.Entities.Notice;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace F9WebAiTest.Api.Controllers.Notice;
// ==================== 消息类型管理(管理员) ====================
[ApiController]
[Route("api/notification/type")]
[Authorize]
public class NotificationTypeController : ControllerBase
{
private readonly INotificationService _svc;
public NotificationTypeController(INotificationService svc) => _svc = svc;
[HttpGet]
public async Task<IActionResult> GetList()
=> Ok(ApiResult<List<NotificationTypeDto>>.Ok(await _svc.GetTypeListAsync()));
[HttpPost]
public async Task<IActionResult> Create([FromBody] NotificationTypeCreateDto dto)
{
try { return Ok(ApiResult<NotificationTypeDto>.Ok(await _svc.CreateTypeAsync(dto, GetUserId()), "创建成功")); }
catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult<object>.Fail(ex.Message, ex.Code)); }
}
[HttpPut("{id}")]
public async Task<IActionResult> Update(long id, [FromBody] NotificationTypeCreateDto dto)
{
try { return Ok(ApiResult<NotificationTypeDto>.Ok(await _svc.UpdateTypeAsync(id, dto), "更新成功")); }
catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult<object>.Fail(ex.Message, ex.Code)); }
}
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(long id)
{
try { await _svc.DeleteTypeAsync(id); return Ok(ApiResult<object>.Ok(null, "删除成功")); }
catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult<object>.Fail(ex.Message, ex.Code)); }
}
private long GetUserId() => long.Parse(User.FindFirst("id")!.Value);
}
// ==================== 用户端:订阅 + 消息 ====================
[ApiController]
[Route("api/notification")]
[Authorize]
public class NotificationController : ControllerBase
{
private readonly INotificationService _svc;
private readonly IMediator _mediator;
private readonly IAuthService _authService;
public NotificationController(INotificationService svc, IMediator mediator, IAuthService authService)
{
_svc = svc;
_mediator = mediator;
_authService = authService;
}
// 可订阅的消息类型列表(有权限的才可见/可订阅)
[HttpGet("subscribe")]
public async Task<IActionResult> GetSubscribeList()
=> Ok(ApiResult<List<NotificationTypeDto>>.Ok(await _svc.GetSubscribeListAsync(GetUserId())));
// 订阅 / 取消订阅
[HttpPost("subscribe")]
public async Task<IActionResult> Subscribe([FromBody] SubscribeDto dto)
{
try
{
await _svc.SubscribeAsync(GetUserId(), dto.NotificationTypeId, dto.Subscribe);
return Ok(ApiResult<object>.Ok(null, dto.Subscribe ? "订阅成功" : "已取消订阅"));
}
catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult<object>.Fail(ex.Message, ex.Code)); }
}
// 我的消息列表(readStatus: 0未读 1已读;category: 0通知 1待办 2公告)
[HttpGet("messages")]
public async Task<IActionResult> GetMyMessages([FromQuery] int pageIndex = 1, [FromQuery] int pageSize = 20, [FromQuery] int? readStatus = null, [FromQuery] int? category = null)
=> Ok(ApiResult<PageResult<NotificationMessageDto>>.Ok(await _svc.GetMyMessagesAsync(GetUserId(), pageIndex, pageSize, readStatus, category)));
// 我的待办列表
[HttpGet("todos")]
public async Task<IActionResult> GetMyTodos([FromQuery] int? status = null)
=> Ok(ApiResult<List<TodoItemDto>>.Ok(await _svc.GetMyTodosAsync(GetUserId(), status)));
// 完成待办
[HttpPost("todos/{id}/complete")]
public async Task<IActionResult> CompleteTodo(long id, [FromBody] CompleteTodoDto dto)
{
try { await _svc.CompleteTodoAsync(GetUserId(), id, dto.HandleResult); return Ok(ApiResult<object>.Ok(null, "已完成")); }
catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult<object>.Fail(ex.Message, ex.Code)); }
}
// 标记已读
[HttpPut("messages/{id}/read")]
public async Task<IActionResult> MarkRead(long id)
{
try { await _svc.MarkReadAsync(GetUserId(), id); return Ok(ApiResult<object>.Ok(null)); }
catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult<object>.Fail(ex.Message, ex.Code)); }
}
// 全部已读
[HttpPut("messages/read-all")]
public async Task<IActionResult> MarkAllRead()
{
await _svc.MarkAllReadAsync(GetUserId());
return Ok(ApiResult<object>.Ok(null));
}
// 未读数量
[HttpGet("unread-count")]
public async Task<IActionResult> GetUnreadCount()
=> Ok(ApiResult<UnreadCountDto>.Ok(new UnreadCountDto { Count = await _svc.GetUnreadCountAsync(GetUserId()) }));
// 触发一条消息(模拟业务系统触发,用于演示/测试)
[HttpPost("trigger")]
public async Task<IActionResult> Trigger([FromBody] TriggerDto dto)
{
try
{
var msgId = await _mediator.Send(new CreateNotificationCommand
{
NotificationTypeCode = dto.Code,
BusinessType = dto.BusinessType ?? "Manual",
BusinessId = dto.BusinessId ?? Guid.NewGuid().ToString("N"),
Title = dto.Title ?? "测试消息",
Content = dto.Content ?? "这是一条测试消息",
Priority = dto.Priority ?? NotificationPriority.Normal,
RoutePath = dto.RoutePath ?? "",
ForceReceivers = dto.AssigneeIds ?? new List<long>(),
AssigneeIds = dto.AssigneeIds ?? new List<long>(),
CreatorId = GetUserId(),
CreatorName = User.FindFirst("realName")?.Value ?? "系统"
});
return Ok(ApiResult<object>.Ok(new { id = msgId }, "消息已创建并即时推送给在线接收人"));
}
catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult<object>.Fail(ex.Message, ex.Code)); }
}
// 发送广播通知(拥有通知广播权限的用户可发送,空接收人 = 订阅广播)
[HttpPost("broadcast")]
public async Task<IActionResult> Broadcast([FromBody] BroadcastNotificationDto dto)
{
try
{
var userId = GetUserId();
var perms = await _authService.GetUserPermissionsAsync(userId);
if (!perms.Contains("notification:broadcast"))
return StatusCode(403, ApiResult<object>.Fail("您没有发送广播通知的权限", 403));
var msgId = await _mediator.Send(new CreateNotificationCommand
{
NotificationTypeCode = "Broadcast",
BusinessType = "Broadcast",
BusinessId = Guid.NewGuid().ToString("N"),
Title = dto.Title,
Content = dto.Content,
Priority = dto.Priority ?? NotificationPriority.Normal,
RoutePath = dto.RoutePath ?? "",
ForceReceivers = new List<long>(),
CreatorId = userId,
CreatorName = User.FindFirst("realName")?.Value ?? "系统"
});
return Ok(ApiResult<object>.Ok(new { id = msgId }, "广播消息已创建"));
}
catch (ServiceException ex) { return StatusCode(ex.Code, ApiResult<object>.Fail(ex.Message, ex.Code)); }
}
private long GetUserId() => long.Parse(User.FindFirst("id")!.Value);
}
public class TriggerDto
{
public string Code { get; set; } = "TeyeFound";
public string Title { get; set; }
public string Content { get; set; }
public string BusinessType { get; set; }
public string BusinessId { get; set; }
public NotificationPriority? Priority { get; set; }
public string RoutePath { get; set; }
public List<long> AssigneeIds { get; set; }
}