using AgoraIO.Media;
using Hangfire.MemoryStorage.Database;
using Mapster;
using Masuit.Tools;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Microsoft.IdentityModel.Tokens;
using SqlSugar;
using SqlSugar.Extensions;
using WGShare.API.Controllers.Basic;
using WGShare.API.Helpers;
using WGShare.API.Hubs;
using WGShare.Domain.Constant;
using WGShare.Domain.DTOs.File;
using WGShare.Domain.DTOs.Room;
using WGShare.Domain.DTOs.User;
using WGShare.Domain.Entities;
using WGShare.Domain.FriendlyException;
using WGShare.Domain.GeneralModel;
using Yitter.IdGenerator;
namespace WGShare.API.Controllers.Frontend
{
///
/// 会议室接口
///
[ApiExplorerSettings(GroupName = "frontend")]
[Route("room")]
public class RoomController : BasicController
{
private readonly ISqlSugarClient _sqlSugar;
private readonly IConfiguration _configuration;
private readonly OssHelper _ossHelper;
private readonly AgoraHelper _agoraHelper;
private readonly IHubContext _hubContext;
private readonly ILogger _logger;
public RoomController(ISqlSugarClient sqlSugar,
IConfiguration configuration,
OssHelper ossHelper,
AgoraHelper agoraHelper,
IHubContext hubContext,
ILogger logger)
{
this._sqlSugar = sqlSugar;
this._configuration = configuration;
this._ossHelper = ossHelper;
this._agoraHelper = agoraHelper;
this._hubContext = hubContext;
this._logger = logger;
}
/////
///// 获取会议室管理员
/////
/////
//[HttpGet("manager")]
//public async Task> GetRoomManager([FromQuery] string roomId)
//{
// return await _sqlSugar.Queryable()
// .Where(x => x.RoomId == roomId)
// .Select(x => x.UserId)
// .ToListAsync();
//}
///
/// 设置房间管理员
///
///
[HttpPost("manager")]
public async Task SetRoomManager([FromQuery] string roomId, [FromBody] List userIds)
{
var entities = userIds.ConvertAll(x => new RoomManager
{
RoomId = roomId,
UserId = x
});
return await _sqlSugar.Insertable(entities).ExecuteCommandAsync() > 0;
}
///
/// 取消房间管理员
///
///
[HttpDelete("manager")]
public async Task DelRoomManager([FromQuery] string roomId, [FromBody] List userIds)
{
return await _sqlSugar.Deleteable()
.Where(x => x.RoomId == roomId && userIds.Contains(x.UserId))
.ExecuteCommandAsync() > 0;
}
///
/// 查询用户信息
///
///
[HttpGet("user")]
public async Task> GetUsers([FromQuery] string roomNum)
{
var channelUsers = RedisHelper.Instance.HVals(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum));
if (channelUsers.IsNullOrEmpty())
{
return new List();
}
var uids = channelUsers.Select(x => x.UID);
var users = await _sqlSugar.Queryable()
.Where(x => uids.Contains(x.Id))
.ToListAsync();
var managerIds = await _sqlSugar.Queryable()
.InnerJoin((rm, r) => r.Id == rm.RoomId)
.Where((rm, r) => r.RoomNum == roomNum)
.Select((rm, r) => rm.UserId)
.ToListAsync();
var result = users.Adapt>();
result.ForEach(x =>
{
x.IsManager = managerIds.Contains(x.Id);
var info = channelUsers.FirstOrDefault(q => q.UID == x.Id);
if (info != null)
{
x.EnableMicr = info.EnableMicr;
x.EnableCamera = info.EnableCamera;
}
});
return result;
#region 暂时不用声网获取用户列表
//var data = await _agoraHelper.GetChannelUserList(roomNum);
//if (data == null)
//{
// throw Oops.Oh("请求失败");
//}
//if (!data.channel_exist)
//{
// throw Oops.Oh("频道不存在");
//}
//if (data.broadcasters.IsNullOrEmpty())
//{
// return new List();
//}
//var accounts = data.broadcasters.ConvertAll(x => x.ToString());
//var users = await _sqlSugar.Queryable()
// .Where(x => accounts.Contains(x.Account))
// .ToListAsync();
//var managerIds = await _sqlSugar.Queryable()
// .InnerJoin((rm, r) => r.Id == rm.RoomId)
// .Where((rm, r) => r.RoomNum == roomNum)
// .Select((rm, r) => rm.UserId)
// .ToListAsync();
//var result = users.Adapt>();
//result.ForEach(x => x.IsManager = managerIds.Contains(x.Id));
//return result;
#endregion
}
///
/// 检验房间是否存在
///
///
[HttpGet("checkout"), AllowAnonymous]
public async Task ExistsRoom([FromQuery] string roomNum)
{
return await _sqlSugar.Queryable().AnyAsync(x => x.RoomNum == roomNum && x.IsDelete == false);
}
///
/// 获取单个会议室信息
///
///
[HttpGet("{roomNum}")]
public async Task GetRoom([FromRoute] string roomNum)
{
var room = await _sqlSugar.Queryable().FirstAsync(x => x.RoomNum == roomNum && x.IsDelete == false);
if (room == null)
{
throw Oops.Oh("会议号无效");
}
return room.Adapt();
}
///
/// 获取房间rtc token
///
///
[HttpGet("tk/rtc")]
public async Task GetRTCToken([FromQuery] string roomNum)
{
//var privilegeExpiredTs = _configuration["Agora:tokenExpireTimeInSecond"].ToInt32() + Utils.getTimestamp();
return new RtcTokenBuilder2().buildTokenWithUserAccount(
_configuration["Agora:appId"],
_configuration["Agora:appSecret"],
roomNum,
Account,
RtcTokenBuilder2.Role.ROLE_PUBLISHER,
_configuration["Agora:tokenExpireTimeInSecond"].ToInt32(),
_configuration["Agora:tokenExpireTimeInSecond"].ToInt32());
}
///
/// 邀请用户
///
///
[HttpPost("invite")]
public async Task InviteUser([FromQuery] string roomId, [FromBody] string[] inviteeUids)
{
var room = await _sqlSugar.Queryable().FirstAsync(x => x.Id == roomId);
var connectIds = RedisHelper.Instance.HMGet(RedisKeyConstant.SessionManage.GetOnlineUserKey(TenantId), inviteeUids);
connectIds.RemoveWhere(x => string.IsNullOrWhiteSpace(x));
await _hubContext.Clients.Clients(connectIds).Invitation(room.RoomNum, room.RoomName, UserName);
}
///
/// 踢出房间
///
///
[HttpGet("kickout")]
public async Task KickOut([FromQuery] string roomNum, [FromQuery] string kickUid)
{
var connectId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetOnlineUserKey(TenantId), kickUid);
if (!string.IsNullOrWhiteSpace(connectId))
{
await _hubContext.Clients.Client(connectId).ForceExitRoom(roomNum);
}
}
///
/// 开闭麦
///
///
[HttpGet("oper-micr")]
public async Task Mute([FromQuery] string roomNum, [FromQuery] bool enableMicr, [FromQuery] string? uid, [FromQuery] bool? isAll = false)
{
if (isAll.HasValue && isAll.Value)
{
// 全员静音
var allUsers = RedisHelper.Instance.HGetAll(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum));
if (!allUsers.Any())
{
return;
}
allUsers.ForEach(x => x.Value.EnableMicr = enableMicr);
RedisHelper.Instance.HMSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), allUsers);
await _hubContext.Clients.Group(roomNum).OperMicr(enableMicr);
await _hubContext.Clients.Group(roomNum).RefreshUserList();
return;
}
var userInfo = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), uid);
if (userInfo == null || string.IsNullOrWhiteSpace(userInfo.ConnectId))
{
_logger.LogError($"闭麦操作,用户不存在频道!rediskey:{RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum)} uid:" + uid);
return;
}
userInfo.EnableMicr = enableMicr;
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), uid, userInfo);
await _hubContext.Clients.Clients(userInfo.ConnectId).OperMicr(enableMicr);
await _hubContext.Clients.Group(roomNum).RefreshUserList();
}
///
/// 开关闭摄像头
///
///
[HttpGet("oper-camera")]
public async Task CloseCamera([FromQuery] string roomNum, [FromQuery] bool enableCamera, [FromQuery] string? uid, [FromQuery] bool? isAll = false)
{
if (isAll.HasValue && isAll.Value)
{
var allUsers = RedisHelper.Instance.HGetAll(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum));
if (!allUsers.Any())
{
return;
}
allUsers.ForEach(x => x.Value.EnableCamera = enableCamera);
RedisHelper.Instance.HMSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), allUsers);
// 全员开关闭摄像头
await _hubContext.Clients.Group(roomNum).OperCamera(enableCamera);
await _hubContext.Clients.Group(roomNum).RefreshUserList();
return;
}
var userInfo = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), uid);
if (userInfo == null || string.IsNullOrWhiteSpace(userInfo.ConnectId))
{
_logger.LogError($"关闭摄像头操作,用户不存在频道!rediskey:{RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum)} uid:" + uid);
return;
}
userInfo.EnableCamera = enableCamera;
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), uid, userInfo);
await _hubContext.Clients.Clients(userInfo.ConnectId).OperCamera(enableCamera);
await _hubContext.Clients.Group(roomNum).RefreshUserList();
}
#region 文件分享
///
/// 分享上传文件
///
///
///
[HttpPost("file")]
public async Task AddFile([FromBody] ShareFileInputDTO inputDTO)
{
var entity = inputDTO.Adapt();
entity.Id = YitIdHelper.NextId().ToString();
entity.UserId = UId;
return await _sqlSugar.Insertable(entity).ExecuteCommandAsync() > 0;
}
///
/// 删除文件
///
///
[HttpDelete("file")]
public async Task DeleteFile([FromBody] List ids)
{
return await _sqlSugar.Updateable()
.SetColumns(x => x.IsDelete == true)
.Where(x => ids.Contains(x.Id))
.ExecuteCommandHasChangeAsync();
}
///
/// 获取分享文件列表
///
/// 房间Id
///
///
[HttpGet("file")]
public async Task> GetFilesList([FromQuery] string roomId, [FromQuery] string? keyword, [FromQuery] PagedBaseDto pagedBaseDto)
{
RefAsync total = 0;
var list = await _sqlSugar.Queryable()
.LeftJoin((sf, u) => sf.UserId == u.Id)
.Where((sf, u) => sf.IsDelete == false && sf.RoomId == roomId)
.WhereIF(!string.IsNullOrWhiteSpace(keyword), (sf, u) => sf.FileName.Contains(keyword))
.Select((sf, u) => new ShareFileOutputDTO
{
Id = sf.Id,
UserId = u.Id,
UserName = u.UserName,
FileName = sf.FileName,
FileUrl = sf.FileUrl,
RoomId = sf.RoomId,
Size = sf.Size,
ModifyTime = sf.ModifyTime,
DownloadCount = sf.DownloadCount,
}).ToPageListAsync(pagedBaseDto.PageIndex, pagedBaseDto.PageSize, total);
return PagedResult.Create(list, total.Value);
}
///
/// 获取文件上传url
///
///
[HttpGet("up-fileurl")]
public async Task GetUploadUrl([FromQuery] string roomNum, [FromQuery] string fileSuffix)
{
return Ok(_ossHelper.GetUploadUrl($@"share_file/{TenantId}/{roomNum}", Guid.NewGuid().ToString("N") + "." + fileSuffix));
}
///
/// 获取文件下载地址
///
///
/// 文件Id
///
[HttpGet("file-dw-url")]
public async Task GetDownloadUrl([FromQuery] string fileUrl, [FromQuery] string fileId)
{
await _sqlSugar.Updateable()
.SetColumns(x => x.DownloadCount == x.DownloadCount + 1)
.Where(x => x.Id == fileId).ExecuteCommandAsync();
return _ossHelper.GetAccessFileUrl(fileUrl);
}
#endregion
}
}