using Dpz.Core.Public.ViewModel.Request;
using Dpz.Core.Public.ViewModel.Response;

namespace Dpz.Core.WebApi.Controllers;

/// <summary>
/// 录音
/// </summary>
[Route("api/[controller]")]
[ApiController]
public class AudioController(
    IAudioService audioService,
    IObjectStorageOperation objectStorageService,
    IHttpCurrentUserService currentUserService
) : ControllerBase
{
    /// <summary>
    /// 获取录音
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    [Authorize(Policy = "System")]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType<List<AudioResponse>>(StatusCodes.Status200OK)]
    public async Task<IActionResult> GetAudio([FromQuery] QueryDtoBase parameter)
    {
        var list = await audioService.GetPagesAsync(parameter.PageIndex, parameter.PageSize);
        list.AddPaginationMetadata(Response.Headers);
        return Ok(list);
    }

    /// <summary>
    /// 获取我的录音
    /// </summary>
    /// <param name="parameter"></param>
    /// <returns></returns>
    [HttpGet("my"), Authorize]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType<List<AudioResponse>>(StatusCodes.Status200OK)]
    public async Task<IActionResult> GetMyAudio([FromQuery] QueryDtoBase parameter)
    {
        var userInfo = await currentUserService.GetRequiredUserInfoAsync();
        var list = await audioService.GetPagesAsync(
            parameter.PageIndex,
            parameter.PageSize,
            userInfo
        );
        list.AddPaginationMetadata(Response.Headers);
        return Ok(list);
    }

    /// <summary>
    /// 上传录音
    /// </summary>
    /// <param name="audio"></param>
    /// <returns></returns>
    [HttpPost, Authorize]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    public async Task<IActionResult> Upload([Required] IFormFile audio)
    {
        // var webHost = _configuration.GetSection("WebHost").Get<string>();
        // var audioInfo = await _audioService.UploadAsync(audio, User.GetIdentity());
        // return Created($"{webHost}/Audio/Result/{audioInfo.Id}", audioInfo);
        var stream = audio.OpenReadStream();
        var result = await objectStorageService.UploadAsync(
            stream,
            ["audio", DateTime.Now.ToString("yyyy-MM-dd")],
            $"{ObjectId.GenerateNewId()}.wav"
        );
        var user = await currentUserService.GetRequiredUserInfoAsync();
        var request = new CreateAudioRequest
        {
            AccessUrl = result.Url,
            Duration = TimeSpan.Zero,
            Size = stream.Length,
            Uploader = user,
            UploadTime = DateTime.Now,
        };

        await audioService.AddAsync(request);
        return NoContent();
    }

    /// <summary>
    /// 获取录音
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpGet("{id}")]
    [ProducesResponseType<AudioResponse>(StatusCodes.Status200OK)]
    public async Task<ActionResult<AudioResponse>> GetAudio(string id)
    {
        var audio = await audioService.FindAsync(id);
        return Ok(audio);
    }

    /// <summary>
    /// 删除录音
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpDelete("{id}"), Authorize(Policy = "System")]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    public async Task<IActionResult> Delete(string id)
    {
        var audio = await audioService.FindAsync(id);
        if (audio == null)
        {
            return NotFound();
        }
        await audioService.DeleteAsync(id);
        if (!string.IsNullOrWhiteSpace(audio.AccessUrl))
        {
            await objectStorageService.DeleteAsync(audio.AccessUrl);
        }
        return NoContent();
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

代码解释

这是一个 ASP.NET Core WebAPI 控制器,用于处理音频录音相关的业务操作。

整体结构

控制器名称: AudioController
路由前缀: api/[controller] (即 api/audio)
依赖注入: 使用主构造函数注入了三个服务:

  • IAudioService: 音频业务逻辑服务
  • IObjectStorageOperation: 对象存储服务(用于文件上传/删除)
  • IHttpCurrentUserService: 当前用户信息服务

API 端点详解

1. GetAudio - 获取录音列表(管理员)

[HttpGet]
[Authorize(Policy = "System")]
  • 权限: 需要 "System" 策略授权(管理员)
  • 功能: 分页获取所有录音
  • 返回: 录音列表,并将分页元数据添加到响应头

2. GetMyAudio - 获取我的录音

[HttpGet("my"), Authorize]
  • 路由: api/audio/my
  • 权限: 需要登录
  • 功能: 获取当前登录用户的录音列表
  • 返回: 当前用户的录音,带分页信息

3. Upload - 上传录音

[HttpPost, Authorize]
  • 权限: 需要登录
  • 功能:
    1. 接收音频文件上传
    2. 将文件存储到对象存储(按日期分目录,使用 ObjectId 生成唯一文件名)
    3. 创建音频记录保存到数据库
  • 参数: IFormFile audio (必填)
  • 返回: 204 NoContent

4. GetAudio(id) - 获取单个录音

[HttpGet("{id}")]
  • 权限: 无需授权
  • 功能: 根据 ID 查询单个录音详情
  • 返回: 录音详细信息

5. Delete - 删除录音

[HttpDelete("{id}"), Authorize(Policy = "System")]
  • 权限: 需要 "System" 策略授权(管理员)
  • 功能:
    1. 查找录音记录
    2. 删除数据库记录
    3. 删除对象存储中的文件
  • 返回: 204 NoContent 或 404 NotFound

技术特点

  1. RESTful 设计: 遵循 REST 规范,使用标准 HTTP 方法
  2. 权限控制: 使用 [Authorize] 特性实现细粒度权限控制
  3. 依赖注入: 通过构造函数注入实现松耦合
  4. 异步操作: 所有方法均为异步,提高并发性能
  5. 分页支持: 使用扩展方法将分页元数据添加到响应头
  6. 文件存储: 集成对象存储服务,按日期组织文件
评论加载中...