WGShare.API/WGShare.API/Controllers/Frontend/HomeController.cs

296 lines
12 KiB
C#

using AgoraIO.Media;
using AgoraIO.Rtm;
using Mapster;
using Masuit.Tools;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
using MiniExcelLibs.Attributes;
using MiniExcelLibs.OpenXml;
using SqlSugar;
using System.IO;
using System.Text.RegularExpressions;
using WGShare.API.Controllers.Basic;
using WGShare.API.Helpers;
using WGShare.Domain.Constant;
using WGShare.Domain.DTOs.Room;
using WGShare.Domain.Entities;
using WGShare.Domain.Enums;
using WGShare.Domain.FriendlyException;
using WGShare.Domain.GeneralModel;
using Yitter.IdGenerator;
using IConfiguration = Microsoft.Extensions.Configuration.IConfiguration;
namespace WGShare.API.Controllers.Frontend
{
/// <summary>
/// 首页接口
/// </summary>
[ApiExplorerSettings(GroupName = "frontend")]
[Route("home")]
public class HomeController : BasicController
{
private readonly ISqlSugarClient _sqlSugar;
private readonly IConfiguration _configuration;
private readonly IHttpClientFactory _httpClientFactory;
private readonly AgoraHelper _agoraHelper;
private readonly ILogger<HomeController> _logger;
private readonly OssHelper _ossHelper;
public HomeController(
ISqlSugarClient sqlSugar,
IConfiguration configuration,
IHttpClientFactory httpClientFactory,
AgoraHelper agoraHelper,
ILogger<HomeController> logger,
OssHelper ossHelper)
{
_sqlSugar = sqlSugar;
this._configuration = configuration;
this._httpClientFactory = httpClientFactory;
this._agoraHelper = agoraHelper;
this._logger = logger;
this._ossHelper = ossHelper;
}
/// <summary>
/// 获取会议室列表
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpGet("room")]
public async Task<PagedResult<RoomOutputDTO>> GetRooms([FromQuery] PagedBaseDto dto)
{
RefAsync<int> total = 0;
var list = await _sqlSugar.Queryable<Room>()
.Where(x => x.TenantId == TenantId && x.IsDelete == false)
.WhereIF(Year > 0 && RoleId == RoleEnums.User, x => x.Year == Year || x.Year == 0)
.WhereIF(Subject > 0 && RoleId == RoleEnums.User, x => x.Subject == Subject || x.Subject == 0)
.OrderBy(x => x.Id, OrderByType.Desc)
.ToPageListAsync(dto.PageIndex, dto.PageSize, total);
var result = list.Adapt<List<RoomOutputDTO>>();
if (!result.IsNullOrEmpty())
{
// 从Redis获取缓存在线人数 拼装数据
result.ForEach(x => x.OnlineUserCount = RedisHelper.Instance.HLen(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, x.RoomNum)));
//var userCounts = RedisHelper.Instance.HMGet<int>(RedisKeyConstant.SessionManage.GetChannelUserCountKey(TenantId),
// result.Select(x => x.RoomNum).ToArray());
//for (int i = 0; i < userCounts.Length; i++)
//{
// result[i].OnlineUserCount = userCounts[i];
//}
}
return PagedResult<RoomOutputDTO>.Create(result, total.Value);
}
/// <summary>
/// 创建会议室
/// </summary>
/// <param name="inputDTO"></param>
/// <returns></returns>
[HttpPost("room")]
public async Task<bool> CreateRoom([FromBody] RoomInputDTO inputDTO)
{
if (inputDTO.RoomNum.Length != 8 || !int.TryParse(inputDTO.RoomNum, out _))
{
throw Oops.Oh("会议号必须为8位数字");
}
var entity = inputDTO.Adapt<Room>();
entity.Id = YitIdHelper.NextId().ToString();
entity.TenantId = TenantId;
if (await _sqlSugar.Queryable<Room>().AnyAsync(x => x.RoomNum == inputDTO.RoomNum))
{
throw Oops.Oh("无效会议号,请重新输入");
}
return await _sqlSugar.Insertable(entity).ExecuteCommandAsync() > 0;
}
/// <summary>
/// 更新会议室信息
/// </summary>
/// <param name="inputDTO"></param>
/// <returns></returns>
[HttpPut("room-info")]
public async Task<bool> ModifyRoom([FromBody] RoomInfoInputDTO inputDTO)
{
var entity = inputDTO.Adapt<Room>();
return await _sqlSugar.Updateable(entity)
.UpdateColumns(x => new { x.Year, x.Subject })
.ExecuteCommandHasChangeAsync();
}
/// <summary>
/// 删除会议室
/// </summary>
/// <param name="inputDTO"></param>
/// <returns></returns>
[HttpDelete("room")]
public async Task<bool> DeleteRoom([FromQuery] string roomId)
{
return await _sqlSugar.Updateable<Room>()
.SetColumns(x => x.IsDelete == true)
.Where(x => x.Id == roomId).ExecuteCommandAsync() > 0;
}
/// <summary>
/// 获取 rtm token
/// </summary>
/// <returns></returns>
[HttpGet("tk/rtm"), Obsolete]
public async Task<string> GetRTMToken()
{
uint privilegeExpiredTs = (uint)_configuration["tokenExpireTimeInSecond"].ToInt32() + (uint)Utils.getTimestamp();
return RtmTokenBuilder.buildToken(_configuration["Agora:appId"],
_configuration["Agora:appSecret"],
UId,
privilegeExpiredTs);
}
/// <summary>
/// 获取Agora配置
/// </summary>
/// <returns></returns>
[HttpGet("agora-conf")]
public string GetAgoraConfig()
{
return _configuration["Agora:appId"].ToString();
}
/// <summary>
/// 获取会议记录
/// </summary>
/// <returns></returns>
[HttpGet("record")]
public async Task<string> GetMeetingRecord([FromQuery] long beginTimestamp, [FromQuery] long endTimestamp, [FromQuery] string roomNum)
{
var room = await _sqlSugar.Queryable<Room>().Where(x => x.RoomNum == roomNum && x.IsDelete == false).FirstAsync();
if (room == null)
{
throw Oops.Oh("该会议室不存在!");
}
var recordList = await _sqlSugar.Queryable<MeetingRecord>()
.InnerJoin<User>((mr, u) => mr.uid == u.Id)
.InnerJoin<Role>((mr, u, r) => u.RoleId == r.Id)
.Where((mr, u, r) => mr.channelName == roomNum && mr.ts >= beginTimestamp && mr.ts <= endTimestamp)
.Select((mr, u, r) => new MeetingRecord
{
Id = mr.Id,
uid = u.Id,
ts = mr.ts,
account = mr.account,
channelName = mr.channelName,
clientSeq = mr.clientSeq,
CreateTime = mr.CreateTime,
duration = mr.duration,
EventType = mr.EventType,
platform = mr.platform,
reason = mr.reason,
userName = u.UserName,
UserAccount = u.Account,
RoleName = r.RoleName,
}).ToListAsync();
if (recordList.IsNullOrEmpty())
{
throw Oops.Oh("该时间段内没有记录!");
}
var groupByUser = recordList.GroupBy(x => x.uid).ToList();
var beginDatetime = DateTimeUtils.FromJavaScriptTimestampToLocal(beginTimestamp);
var endDaetime = DateTimeUtils.FromJavaScriptTimestampToLocal(endTimestamp);
var value = new RoomMettingRecordExportDTO
{
RoomName = room.RoomName,
RoomNum = room.RoomNum,
BeginTime = beginDatetime.ToString("yyyy-MM-dd HH:mm:ss"),
EndTime = endDaetime.ToString("yyyy-MM-dd HH:mm:ss"),
Users = new List<UserBehavior>(),
Signin = new List<SignInListRecordExcelDto>()
};
#region
foreach (var userRecord in groupByUser)
{
if (userRecord.IsNullOrEmpty())
{
continue;
}
// 按时间排序
var orderedRecord = userRecord.OrderBy(x => x.ts).ToList();
// 获取第一次进入房间的事件记录
var firstJoinTimeRecord = orderedRecord
.FirstOrDefault(x => x.EventType == EventType.broadcaster_join_channel
|| x.EventType == EventType.audience_join_channel);
string firstJoinTime = "暂无记录";
if (firstJoinTimeRecord != null)
{
firstJoinTime = DateTimeUtils.FromJavaScriptTimestampToLocal(firstJoinTimeRecord.ts).ToString("yyyy-MM-dd HH:mm:ss");
}
// 获取最后一次离开房间的事件记录
var lastLeaveTimeRecord = orderedRecord
.LastOrDefault(x => x.EventType == EventType.broadcaster_leave_channel
|| x.EventType == EventType.audience_leave_channel);
string lastLeaveTime = "暂无记录";
if (lastLeaveTimeRecord != null)
{
lastLeaveTime = DateTimeUtils.FromJavaScriptTimestampToLocal(lastLeaveTimeRecord.ts).ToString("yyyy-MM-dd HH:mm:ss");
}
// 计算入会次数
var joinCount = orderedRecord.Count(x => x.EventType == EventType.broadcaster_join_channel
|| x.EventType == EventType.audience_join_channel);
// 累计参会时长
var sumTime = orderedRecord.Sum(x => x.duration);
value.Users.Add(new UserBehavior
{
Account = userRecord.FirstOrDefault().UserAccount,
FirstJoinTime = firstJoinTime,
LastExitTime = lastLeaveTime,
JoinCount = joinCount,
Role = userRecord.FirstOrDefault().RoleName,
UserName = userRecord.FirstOrDefault().userName,
SumTime = sumTime,
});
}
#endregion
#region
var signins = await _sqlSugar.Queryable<UserSignInRecord>()
.InnerJoin<User>((u, us) => u.UId == us.Id)
.Where((u, us) => u.RoomNum == roomNum && u.CreateTime >= beginDatetime && u.CreateTime <= endDaetime)
.Select((u, us) => new SignInListRecordExcelDto
{
Account = us.Account,
SignInTime = u.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"),
UserName = us.UserName,
SignInName = u.SignInName
})
.ToListAsync();
value.Signin.AddRange(signins);
#endregion
using var stream = new MemoryStream();
await MiniExcel.SaveAsByTemplateAsync(stream, $@"{AppDomain.CurrentDomain.BaseDirectory}meetingRecordTemplate.xlsx", value);
stream.Seek(0, SeekOrigin.Begin);
var fileName = $@"excel/{room.RoomName}-参会记录-{beginDatetime.ToString("yyyyMMddHHmmss")}至{endDaetime.ToString("yyyyMMddHHmmss")}.xlsx";
_ossHelper.UploadWithExpireTime(fileName, stream, 10);
return _ossHelper.GetAccessFileUrl(fileName, 5);
}
}
}