Compare commits
48 Commits
feature-考勤
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
c65e6673e0 | |
|
|
d66fec6b66 | |
|
|
7c31c67f9d | |
|
|
c33c06176b | |
|
|
505dd42294 | |
|
|
7a75025880 | |
|
|
484ab104ab | |
|
|
806d585717 | |
|
|
ebfd8b9fb7 | |
|
|
40bf8cc5ba | |
|
|
6106f06f8a | |
|
|
9a7c0c61d0 | |
|
|
ac22e5097c | |
|
|
e29665cd90 | |
|
|
df9fbe55c4 | |
|
|
03fba8c5e9 | |
|
|
bc901d928f | |
|
|
ea382b1aa1 | |
|
|
33b238b156 | |
|
|
9dbbcc98dd | |
|
|
e3a3201a06 | |
|
|
82aede3b9d | |
|
|
e55edf4c63 | |
|
|
3401856281 | |
|
|
204d6edc78 | |
|
|
3a529cb55f | |
|
|
4a08c56042 | |
|
|
519c3949b5 | |
|
|
c3b32f4a5c | |
|
|
32374a9cd4 | |
|
|
481009985e | |
|
|
4824180441 | |
|
|
d28791558d | |
|
|
c09017455a | |
|
|
28b47ed440 | |
|
|
1f0c002ca4 | |
|
|
975297a6aa | |
|
|
70cb4ca524 | |
|
|
23856bf617 | |
|
|
520aaac302 | |
|
|
e897520326 | |
|
|
dd115afdfc | |
|
|
80595e250c | |
|
|
4588536363 | |
|
|
5aaea0e252 | |
|
|
e36fd1d1df | |
|
|
e17ab68abd | |
|
|
a048ffd787 |
|
|
@ -24,13 +24,23 @@
|
||||||
"LinuxServerList": [
|
"LinuxServerList": [
|
||||||
{
|
{
|
||||||
"UserName": "marking",
|
"UserName": "marking",
|
||||||
"Pwd": "0610DBF49053E6779393A74BE1ED4FD2",
|
"Pwd": "CE09921E2AD09E56095579DF1F7C614B",
|
||||||
"Host": "47.109.67.254:10022",
|
"Host": "47.109.67.254:10022",
|
||||||
"NickName": "marking001",
|
"NickName": "marking001",
|
||||||
"IIsFireUrl": null,
|
"IIsFireUrl": null,
|
||||||
"DockerFireUrl": "",
|
"DockerFireUrl": "",
|
||||||
"WindowsServiceFireUrl": null,
|
"WindowsServiceFireUrl": null,
|
||||||
"LinuxServiceFireUrl": null
|
"LinuxServiceFireUrl": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"UserName": "marking",
|
||||||
|
"Pwd": "CE09921E2AD09E56095579DF1F7C614B",
|
||||||
|
"Host": "47.109.193.53:10022",
|
||||||
|
"NickName": "meeting",
|
||||||
|
"IIsFireUrl": null,
|
||||||
|
"DockerFireUrl": "",
|
||||||
|
"WindowsServiceFireUrl": null,
|
||||||
|
"LinuxServiceFireUrl": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"IgnoreList": [],
|
"IgnoreList": [],
|
||||||
|
|
@ -115,11 +125,11 @@
|
||||||
"DockerConfig": {
|
"DockerConfig": {
|
||||||
"Prot": "5192:5192",
|
"Prot": "5192:5192",
|
||||||
"AspNetCoreEnv": "",
|
"AspNetCoreEnv": "",
|
||||||
"LastEnvName": "29dev",
|
"LastEnvName": "marking001",
|
||||||
"RemoveDaysFromPublished": "10",
|
"RemoveDaysFromPublished": "10",
|
||||||
"WorkDir": "",
|
"WorkDir": "",
|
||||||
"Volume": "",
|
"Volume": "",
|
||||||
"Other": "--name wgshare-api -e ASPNETCORE_ENVIRONMENT=Development -e TZ=Asia/Shanghai",
|
"Other": "--name wgshare-api -e ASPNETCORE_ENVIRONMENT=Production -e TZ=Asia/Shanghai",
|
||||||
"EnvPairList": [
|
"EnvPairList": [
|
||||||
{
|
{
|
||||||
"EnvName": "29dev",
|
"EnvName": "29dev",
|
||||||
|
|
|
||||||
|
|
@ -32,10 +32,10 @@ namespace WGShare.API.BackgroudServices
|
||||||
// 离开频道消息订阅
|
// 离开频道消息订阅
|
||||||
using (RedisHelper.Instance.SubscribeList(RedisKeyConstant.PubSub.MeetingRecord, async (message) =>
|
using (RedisHelper.Instance.SubscribeList(RedisKeyConstant.PubSub.MeetingRecord, async (message) =>
|
||||||
{
|
{
|
||||||
_logger.LogDebug($"接受消息: {message}");
|
|
||||||
if (message == null) return;
|
if (message == null) return;
|
||||||
|
|
||||||
|
|
||||||
|
_logger.LogDebug($"接受消息: {message}");
|
||||||
var body = message.ToString().FromJson<EventBody>();
|
var body = message.ToString().FromJson<EventBody>();
|
||||||
if (body == null)
|
if (body == null)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ using WGShare.API.Hubs;
|
||||||
using WGShare.Domain.Constant;
|
using WGShare.Domain.Constant;
|
||||||
using WGShare.Domain.DTOs.Login;
|
using WGShare.Domain.DTOs.Login;
|
||||||
using WGShare.Domain.Entities;
|
using WGShare.Domain.Entities;
|
||||||
|
using WGShare.Domain.Enums;
|
||||||
using WGShare.Domain.FriendlyException;
|
using WGShare.Domain.FriendlyException;
|
||||||
using WGShare.Domain.FriendlyException.Exceptions;
|
using WGShare.Domain.FriendlyException.Exceptions;
|
||||||
|
|
||||||
|
|
@ -47,7 +48,28 @@ namespace WGShare.API.Controllers
|
||||||
[HttpGet("check-user"), AllowAnonymous]
|
[HttpGet("check-user"), AllowAnonymous]
|
||||||
public async Task<bool> CheckUser([FromQuery] string account)
|
public async Task<bool> CheckUser([FromQuery] string account)
|
||||||
{
|
{
|
||||||
return await _sqlSugar.Queryable<User>().AnyAsync(x => x.IsDelete == false && x.Account == account);
|
return await _sqlSugar.Queryable<User>().AnyAsync(x => x.IsDelete == false && x.Account == account && x.IsAnonymous == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查用户是否在线
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="account"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("check-online"), AllowAnonymous]
|
||||||
|
public async Task<bool> CheckUserOnline([FromQuery] string account)
|
||||||
|
{
|
||||||
|
var user = await _sqlSugar.Queryable<User>().FirstAsync(x => x.IsDelete == false && x.Account == account && x.IsAnonymous == false);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var connectId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetOnlineUserKey(user.TenantId), user.Id);
|
||||||
|
if (!string.IsNullOrWhiteSpace(connectId))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -58,7 +80,7 @@ namespace WGShare.API.Controllers
|
||||||
public async Task<IActionResult> Login([FromBody] UserLoginDTO loginDTO)
|
public async Task<IActionResult> Login([FromBody] UserLoginDTO loginDTO)
|
||||||
{
|
{
|
||||||
var user = await _sqlSugar.Queryable<User>()
|
var user = await _sqlSugar.Queryable<User>()
|
||||||
.FirstAsync(x => x.Account == loginDTO.Account && x.IsDelete == false && x.Pwd == loginDTO.Pwd);
|
.FirstAsync(x => x.Account == loginDTO.Account && x.IsDelete == false && x.Pwd == loginDTO.Pwd && x.IsAnonymous == false);
|
||||||
if (user == null)
|
if (user == null)
|
||||||
{
|
{
|
||||||
throw Oops.Oh("用户名或密码不正确!");
|
throw Oops.Oh("用户名或密码不正确!");
|
||||||
|
|
@ -91,6 +113,9 @@ namespace WGShare.API.Controllers
|
||||||
btnAutn.Add(new Claim("account", user.Account));
|
btnAutn.Add(new Claim("account", user.Account));
|
||||||
btnAutn.Add(new Claim("uname", user.UserName));
|
btnAutn.Add(new Claim("uname", user.UserName));
|
||||||
btnAutn.Add(new Claim("ssid", user.ScreenShareId));
|
btnAutn.Add(new Claim("ssid", user.ScreenShareId));
|
||||||
|
btnAutn.Add(new Claim("year", user.Year.ToString()));
|
||||||
|
btnAutn.Add(new Claim("subject", ((int)user.Subject).ToString()));
|
||||||
|
btnAutn.Add(new Claim("anonymous", user.IsAnonymous ? "1" : "0"));
|
||||||
|
|
||||||
// 获取已登录的token
|
// 获取已登录的token
|
||||||
var tokens = RedisHelper.Instance.Get<AccessAndRefreshToken>(RedisKeyConstant.Data.GetAccessTokenKey(user.Id));
|
var tokens = RedisHelper.Instance.Get<AccessAndRefreshToken>(RedisKeyConstant.Data.GetAccessTokenKey(user.Id));
|
||||||
|
|
@ -104,7 +129,7 @@ namespace WGShare.API.Controllers
|
||||||
pipe.Del(RedisKeyConstant.Data.GetRefreshTokenKey(tokens.RefreshToken));
|
pipe.Del(RedisKeyConstant.Data.GetRefreshTokenKey(tokens.RefreshToken));
|
||||||
}
|
}
|
||||||
// 设置新的刷新token
|
// 设置新的刷新token
|
||||||
pipe.Set(RedisKeyConstant.Data.GetRefreshTokenKey(refreshToken), user, TimeSpan.FromDays(7).TotalSeconds.ToInt32());
|
pipe.Set(RedisKeyConstant.Data.GetRefreshTokenKey(refreshToken), user, TimeSpan.FromDays(360).TotalSeconds.ToInt32());
|
||||||
// 记录accessToken
|
// 记录accessToken
|
||||||
pipe.Set(RedisKeyConstant.Data.GetAccessTokenKey(user.Id), new AccessAndRefreshToken
|
pipe.Set(RedisKeyConstant.Data.GetAccessTokenKey(user.Id), new AccessAndRefreshToken
|
||||||
{
|
{
|
||||||
|
|
@ -138,7 +163,8 @@ namespace WGShare.API.Controllers
|
||||||
expire = _configuration["Jwt:Expires"].ToInt32(),
|
expire = _configuration["Jwt:Expires"].ToInt32(),
|
||||||
account = user.Account,
|
account = user.Account,
|
||||||
uid = user.Id,
|
uid = user.Id,
|
||||||
screenShareId = user.ScreenShareId
|
screenShareId = user.ScreenShareId,
|
||||||
|
isAnonymous = false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,13 +189,16 @@ namespace WGShare.API.Controllers
|
||||||
btnAutn.Add(new Claim("account", user.Account));
|
btnAutn.Add(new Claim("account", user.Account));
|
||||||
btnAutn.Add(new Claim("uname", user.UserName));
|
btnAutn.Add(new Claim("uname", user.UserName));
|
||||||
btnAutn.Add(new Claim("ssid", user.ScreenShareId));
|
btnAutn.Add(new Claim("ssid", user.ScreenShareId));
|
||||||
|
btnAutn.Add(new Claim("year", user.Year.ToString()));
|
||||||
|
btnAutn.Add(new Claim("subject", ((int)user.Subject).ToString()));
|
||||||
|
btnAutn.Add(new Claim("anonymous", user.IsAnonymous ? "1" : "0"));
|
||||||
|
|
||||||
var accessToken = _jwtHelper.CreateToken(user.Id, btnAutn);
|
var accessToken = _jwtHelper.CreateToken(user.Id, btnAutn);
|
||||||
var refreshTokenNew = Guid.NewGuid().ToString();
|
var refreshTokenNew = Guid.NewGuid().ToString();
|
||||||
using (var pipe = RedisHelper.Instance.StartPipe())
|
using (var pipe = RedisHelper.Instance.StartPipe())
|
||||||
{
|
{
|
||||||
pipe.Del(RedisKeyConstant.Data.GetRefreshTokenKey(refreshToken));
|
pipe.Del(RedisKeyConstant.Data.GetRefreshTokenKey(refreshToken));
|
||||||
pipe.Set(RedisKeyConstant.Data.GetRefreshTokenKey(refreshTokenNew), user, TimeSpan.FromDays(7).TotalSeconds.ToInt32());
|
pipe.Set(RedisKeyConstant.Data.GetRefreshTokenKey(refreshTokenNew), user, TimeSpan.FromDays(360).TotalSeconds.ToInt32());
|
||||||
pipe.Set(RedisKeyConstant.Data.GetAccessTokenKey(user.Id), new AccessAndRefreshToken
|
pipe.Set(RedisKeyConstant.Data.GetAccessTokenKey(user.Id), new AccessAndRefreshToken
|
||||||
{
|
{
|
||||||
AccessToken = accessToken,
|
AccessToken = accessToken,
|
||||||
|
|
@ -190,7 +219,8 @@ namespace WGShare.API.Controllers
|
||||||
expire = _configuration["Jwt:Expires"].ToInt32(),
|
expire = _configuration["Jwt:Expires"].ToInt32(),
|
||||||
account = user.Account,
|
account = user.Account,
|
||||||
uid = user.Id,
|
uid = user.Id,
|
||||||
screenShareId = user.ScreenShareId
|
screenShareId = user.ScreenShareId,
|
||||||
|
isAnonymous = false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,6 +235,76 @@ namespace WGShare.API.Controllers
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 匿名登录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="loginDTO"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("anon-login"), AllowAnonymous]
|
||||||
|
public async Task<IActionResult> AnonymousLogin([FromBody] AnonymousUserLoginDTO loginDTO)
|
||||||
|
{
|
||||||
|
var room = await _sqlSugar.Queryable<Room>().Where(x => x.RoomNum == loginDTO.RoomNum && x.IsDelete == false).FirstAsync();
|
||||||
|
if (room == null)
|
||||||
|
{
|
||||||
|
throw Oops.Oh("房间不存在!");
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = await _sqlSugar.Queryable<User>().Where(x => x.Account == loginDTO.DeviceId).FirstAsync();
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
// 用户不存在,创建
|
||||||
|
user = new User
|
||||||
|
{
|
||||||
|
Account = loginDTO.DeviceId,
|
||||||
|
IsDelete = false,
|
||||||
|
IsAnonymous = true,
|
||||||
|
Pwd = "123456",
|
||||||
|
RoleId = "2",
|
||||||
|
UserName = loginDTO.NickName,
|
||||||
|
ScreenShareId = UserShareIdHelper.GenerateUnique8DigitNumber(),
|
||||||
|
TenantId = "123456",
|
||||||
|
};
|
||||||
|
user.Id = (await _sqlSugar.Insertable(user).ExecuteReturnIdentityAsync()).ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (user.IsDelete)
|
||||||
|
{
|
||||||
|
throw Oops.Oh("该设备已禁止登录!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改用户名
|
||||||
|
await _sqlSugar.Updateable<User>()
|
||||||
|
.SetColumns(x => x.UserName == loginDTO.NickName)
|
||||||
|
.Where(x => x.Id == user.Id)
|
||||||
|
.ExecuteCommandHasChangeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
var btnAutn = new List<Claim>();
|
||||||
|
btnAutn.Add(new Claim("perm", "0"));
|
||||||
|
btnAutn.Add(new Claim("roleid", "2"));
|
||||||
|
btnAutn.Add(new Claim("tenant", room.TenantId));
|
||||||
|
btnAutn.Add(new Claim("account", user.Account));
|
||||||
|
btnAutn.Add(new Claim("uname", loginDTO.NickName));
|
||||||
|
btnAutn.Add(new Claim("ssid", user.ScreenShareId));
|
||||||
|
btnAutn.Add(new Claim("anonymous", user.IsAnonymous ? "1" : "0"));
|
||||||
|
|
||||||
|
var accessToken = _jwtHelper.CreateToken(user.Id, btnAutn);
|
||||||
|
return Ok(new
|
||||||
|
{
|
||||||
|
perms = 0,
|
||||||
|
token = accessToken,
|
||||||
|
refresh_token = "",
|
||||||
|
roleId = user.RoleId,
|
||||||
|
userName = loginDTO.NickName,
|
||||||
|
tenantName = "匿名用户区域",
|
||||||
|
expire = _configuration["Jwt:Expires"].ToInt32(),
|
||||||
|
account = user.Account,
|
||||||
|
uid = user.Id,
|
||||||
|
screenShareId = user.ScreenShareId,
|
||||||
|
isAnonymous = true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#region 后台管理员登录接口
|
#region 后台管理员登录接口
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ using WGShare.API.Controllers.Basic;
|
||||||
using WGShare.API.Helpers;
|
using WGShare.API.Helpers;
|
||||||
using WGShare.Domain.DTOs.User;
|
using WGShare.Domain.DTOs.User;
|
||||||
using WGShare.Domain.Entities;
|
using WGShare.Domain.Entities;
|
||||||
|
using WGShare.Domain.Enums;
|
||||||
using WGShare.Domain.FriendlyException;
|
using WGShare.Domain.FriendlyException;
|
||||||
using WGShare.Domain.GeneralModel;
|
using WGShare.Domain.GeneralModel;
|
||||||
using Yitter.IdGenerator;
|
using Yitter.IdGenerator;
|
||||||
|
|
@ -71,7 +72,7 @@ namespace WGShare.API.Controllers.Backend
|
||||||
var entity = userInput.Adapt<User>();
|
var entity = userInput.Adapt<User>();
|
||||||
entity.ScreenShareId = UserShareIdHelper.GenerateUnique8DigitNumber();
|
entity.ScreenShareId = UserShareIdHelper.GenerateUnique8DigitNumber();
|
||||||
|
|
||||||
if (await _sqlSugar.Queryable<User>().AnyAsync(x => x.Account == entity.Account))
|
if (await _sqlSugar.Queryable<User>().AnyAsync(x => x.Account == entity.Account && x.IsDelete == false))
|
||||||
{
|
{
|
||||||
throw Oops.Oh("账号已存在!");
|
throw Oops.Oh("账号已存在!");
|
||||||
}
|
}
|
||||||
|
|
@ -84,7 +85,7 @@ namespace WGShare.API.Controllers.Backend
|
||||||
{
|
{
|
||||||
var entity = inputDTO.Adapt<User>();
|
var entity = inputDTO.Adapt<User>();
|
||||||
|
|
||||||
if (await _sqlSugar.Queryable<User>().AnyAsync(x => x.Account == entity.Account && x.Id != inputDTO.Id))
|
if (await _sqlSugar.Queryable<User>().AnyAsync(x => x.Account == entity.Account && x.Id != inputDTO.Id && x.IsDelete == false))
|
||||||
{
|
{
|
||||||
throw Oops.Oh("账号已存在!");
|
throw Oops.Oh("账号已存在!");
|
||||||
}
|
}
|
||||||
|
|
@ -152,7 +153,7 @@ namespace WGShare.API.Controllers.Backend
|
||||||
|
|
||||||
// 数据库重复账号检查
|
// 数据库重复账号检查
|
||||||
var existsAccount = await _sqlSugar.Queryable<User>()
|
var existsAccount = await _sqlSugar.Queryable<User>()
|
||||||
.Where(x => distinctAccount.Contains(x.Account))
|
.Where(x => distinctAccount.Contains(x.Account) && x.IsDelete == false)
|
||||||
.Select(x => x.Account)
|
.Select(x => x.Account)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
if (!existsAccount.IsNullOrEmpty())
|
if (!existsAccount.IsNullOrEmpty())
|
||||||
|
|
@ -193,7 +194,18 @@ namespace WGShare.API.Controllers.Backend
|
||||||
x.Pwd = x.Pwd.MDString();
|
x.Pwd = x.Pwd.MDString();
|
||||||
x.ScreenShareId = UserShareIdHelper.GenerateUnique8DigitNumber();
|
x.ScreenShareId = UserShareIdHelper.GenerateUnique8DigitNumber();
|
||||||
x.TenantId = tenantId;
|
x.TenantId = tenantId;
|
||||||
x.RoleId = x.RoleId == "管理员" ? "1" : "2";
|
|
||||||
|
var roleId = "2";
|
||||||
|
if (x.RoleId == "管理员")
|
||||||
|
roleId = "1";
|
||||||
|
else if (x.RoleId == "房间管理员")
|
||||||
|
roleId = "3";
|
||||||
|
x.RoleId = roleId;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(x.SubjectName))
|
||||||
|
x.Subject = SubjectType.All;
|
||||||
|
else
|
||||||
|
x.Subject = x.SubjectName.GetEnumValueFromDescription<SubjectType>();
|
||||||
});
|
});
|
||||||
|
|
||||||
await _sqlSugar.Insertable(users).ExecuteCommandAsync();
|
await _sqlSugar.Insertable(users).ExecuteCommandAsync();
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ namespace WGShare.API.Controllers.Basic
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var roleId = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "roleid").Value;
|
var roleId = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "roleid")?.Value;
|
||||||
if (string.IsNullOrWhiteSpace(roleId) || !int.TryParse(roleId, out int role) || role == 0)
|
if (string.IsNullOrWhiteSpace(roleId) || !int.TryParse(roleId, out int role) || role == 0)
|
||||||
{
|
{
|
||||||
throw Oops.Oh("用户信息有误,请重新登录");
|
throw Oops.Oh("用户信息有误,请重新登录");
|
||||||
|
|
@ -72,7 +72,7 @@ namespace WGShare.API.Controllers.Basic
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var tenant = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "tenant").Value;
|
var tenant = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "tenant")?.Value;
|
||||||
if (string.IsNullOrWhiteSpace(tenant))
|
if (string.IsNullOrWhiteSpace(tenant))
|
||||||
{
|
{
|
||||||
throw Oops.Oh("用户信息有误,请重新登录");
|
throw Oops.Oh("用户信息有误,请重新登录");
|
||||||
|
|
@ -85,7 +85,7 @@ namespace WGShare.API.Controllers.Basic
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var ssId = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "ssid").Value;
|
var ssId = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "ssid")?.Value;
|
||||||
if (string.IsNullOrWhiteSpace(ssId))
|
if (string.IsNullOrWhiteSpace(ssId))
|
||||||
{
|
{
|
||||||
throw Oops.Oh("用户信息有误,请重新登录");
|
throw Oops.Oh("用户信息有误,请重新登录");
|
||||||
|
|
@ -111,6 +111,63 @@ namespace WGShare.API.Controllers.Basic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int year = -1;
|
||||||
|
public int Year
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (year >= 0)
|
||||||
|
{
|
||||||
|
return year;
|
||||||
|
}
|
||||||
|
|
||||||
|
var year_str = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "year")?.Value;
|
||||||
|
if (string.IsNullOrWhiteSpace(year_str) || !int.TryParse(year_str, out year))
|
||||||
|
{
|
||||||
|
throw Oops.Oh("用户信息有误,请重新登录");
|
||||||
|
}
|
||||||
|
return year;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int subject = -1;
|
||||||
|
public SubjectType Subject
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (subject >= 0)
|
||||||
|
{
|
||||||
|
return (SubjectType)subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
var subject_str = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "subject")?.Value;
|
||||||
|
if (string.IsNullOrWhiteSpace(subject_str) || !int.TryParse(subject_str, out subject))
|
||||||
|
{
|
||||||
|
throw Oops.Oh("用户信息有误,请重新登录");
|
||||||
|
}
|
||||||
|
return (SubjectType)subject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 匿名用户
|
||||||
|
/// </summary>
|
||||||
|
public bool IsAnonymous
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!HttpContext.User.Identity.IsAuthenticated)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var anonymous_str = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "anonymous")?.Value;
|
||||||
|
if (string.IsNullOrWhiteSpace(anonymous_str) || !int.TryParse(anonymous_str, out int anonymous))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return anonymous == 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using SharpCompress;
|
using SharpCompress;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using WGShare.API.Controllers.Basic;
|
using WGShare.API.Controllers.Basic;
|
||||||
|
|
@ -32,15 +33,21 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
private readonly ILogger<AgoraCallbackController> _logger;
|
private readonly ILogger<AgoraCallbackController> _logger;
|
||||||
private readonly AgoraHelper _agoraHelper;
|
private readonly AgoraHelper _agoraHelper;
|
||||||
private readonly IConfiguration _configuration;
|
private readonly IConfiguration _configuration;
|
||||||
|
private readonly ISqlSugarClient _sqlSugarClient;
|
||||||
|
private readonly IHostEnvironment _hostEnvironment;
|
||||||
|
|
||||||
public AgoraCallbackController(
|
public AgoraCallbackController(
|
||||||
ILogger<AgoraCallbackController> logger,
|
ILogger<AgoraCallbackController> logger,
|
||||||
AgoraHelper agoraHelper,
|
AgoraHelper agoraHelper,
|
||||||
IConfiguration configuration)
|
IConfiguration configuration,
|
||||||
|
ISqlSugarClient sqlSugarClient,
|
||||||
|
IHostEnvironment hostEnvironment)
|
||||||
{
|
{
|
||||||
this._logger = logger;
|
this._logger = logger;
|
||||||
this._agoraHelper = agoraHelper;
|
this._agoraHelper = agoraHelper;
|
||||||
this._configuration = configuration;
|
this._configuration = configuration;
|
||||||
|
this._sqlSugarClient = sqlSugarClient;
|
||||||
|
this._hostEnvironment = hostEnvironment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -84,12 +91,14 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
switch (body.eventType)
|
switch (body.eventType)
|
||||||
{
|
{
|
||||||
case Domain.Enums.EventType.channel_create:
|
case Domain.Enums.EventType.channel_create:
|
||||||
|
await CreateChannel(body);
|
||||||
break;
|
break;
|
||||||
case Domain.Enums.EventType.channel_destroy:
|
case Domain.Enums.EventType.channel_destroy:
|
||||||
|
await DestroyChannel(body);
|
||||||
break;
|
break;
|
||||||
case Domain.Enums.EventType.broadcaster_join_channel:
|
case Domain.Enums.EventType.broadcaster_join_channel:
|
||||||
case Domain.Enums.EventType.audience_join_channel:
|
case Domain.Enums.EventType.audience_join_channel:
|
||||||
JoinChannelEvent(bodyString);
|
JoinChannelEvent(bodyString, body);
|
||||||
break;
|
break;
|
||||||
case Domain.Enums.EventType.broadcaster_leave_channel:
|
case Domain.Enums.EventType.broadcaster_leave_channel:
|
||||||
case Domain.Enums.EventType.audience_leave_channel:
|
case Domain.Enums.EventType.audience_leave_channel:
|
||||||
|
|
@ -111,10 +120,9 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
/// 加入频道
|
/// 加入频道
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[NonAction]
|
[NonAction]
|
||||||
private void JoinChannelEvent(string bodyString)
|
private void JoinChannelEvent(string bodyString, EventBody eventBody)
|
||||||
{
|
{
|
||||||
_logger.LogDebug($"Agora回调内容 加入频道:{bodyString}");
|
_logger.LogDebug($"Agora回调内容 加入频道:{bodyString}");
|
||||||
|
|
||||||
RedisHelper.Instance.LPush(RedisKeyConstant.PubSub.MeetingRecord, bodyString);
|
RedisHelper.Instance.LPush(RedisKeyConstant.PubSub.MeetingRecord, bodyString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,6 +139,61 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static List<string> excludeChannel = new();
|
||||||
|
static ConcurrentDictionary<string, int> existsChannel = new();
|
||||||
|
/// <summary>
|
||||||
|
/// 创建频道
|
||||||
|
/// </summary>
|
||||||
|
[NonAction]
|
||||||
|
private async Task CreateChannel(EventBody eventBody)
|
||||||
|
{
|
||||||
|
if (_hostEnvironment.IsDevelopment())
|
||||||
|
{
|
||||||
|
_logger.LogDebug($"测试环境不通知创建频道");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (excludeChannel.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
// 缓存测试区域房间
|
||||||
|
excludeChannel = await _sqlSugarClient.Queryable<Room>().Where(x => x.TenantId == "559167236182085")
|
||||||
|
.Select(x => x.RoomNum).ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (excludeChannel.Any(x => x == eventBody.payload.channelName))
|
||||||
|
{
|
||||||
|
_logger.LogDebug($"正式环境的测试区域不通知创建频道");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existsChannel.TryAdd(eventBody.payload.channelName, 0))
|
||||||
|
{
|
||||||
|
var roomInfo = await _sqlSugarClient.Queryable<Room>()
|
||||||
|
.LeftJoin<Tenant>((r, t) => r.TenantId == t.Id)
|
||||||
|
.Where((r, t) => r.RoomNum == eventBody.payload.channelName)
|
||||||
|
.Select((r, t) => new Room
|
||||||
|
{
|
||||||
|
Id = r.Id.SelectAll(),
|
||||||
|
TenantName = t.TenantName
|
||||||
|
})
|
||||||
|
.FirstAsync();
|
||||||
|
ExceptionNotice.JoinAsync(eventBody, roomInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 销毁频道
|
||||||
|
/// </summary>
|
||||||
|
[NonAction]
|
||||||
|
private async Task DestroyChannel(EventBody eventBody)
|
||||||
|
{
|
||||||
|
if (_hostEnvironment.IsDevelopment())
|
||||||
|
return;
|
||||||
|
existsChannel.TryRemove(eventBody.payload.channelName, out _);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,22 @@
|
||||||
using AgoraIO.Media;
|
using AgoraIO.Media;
|
||||||
using AgoraIO.Rtm;
|
using AgoraIO.Rtm;
|
||||||
|
using Azure;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
using Masuit.Tools;
|
using Masuit.Tools;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using MiniExcelLibs;
|
using MiniExcelLibs;
|
||||||
|
using MiniExcelLibs.Attributes;
|
||||||
|
using MiniExcelLibs.OpenXml;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
|
using SqlSugar.Extensions;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using WGShare.API.Controllers.Basic;
|
using WGShare.API.Controllers.Basic;
|
||||||
using WGShare.API.Helpers;
|
using WGShare.API.Helpers;
|
||||||
using WGShare.Domain.Constant;
|
using WGShare.Domain.Constant;
|
||||||
|
using WGShare.Domain.DTOs.Home;
|
||||||
|
using WGShare.Domain.DTOs.MiniProgram;
|
||||||
using WGShare.Domain.DTOs.Room;
|
using WGShare.Domain.DTOs.Room;
|
||||||
using WGShare.Domain.Entities;
|
using WGShare.Domain.Entities;
|
||||||
using WGShare.Domain.Enums;
|
using WGShare.Domain.Enums;
|
||||||
|
|
@ -33,6 +40,7 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
private readonly AgoraHelper _agoraHelper;
|
private readonly AgoraHelper _agoraHelper;
|
||||||
private readonly ILogger<HomeController> _logger;
|
private readonly ILogger<HomeController> _logger;
|
||||||
private readonly OssHelper _ossHelper;
|
private readonly OssHelper _ossHelper;
|
||||||
|
private readonly MiniProgramHelper _miniProgramHelper;
|
||||||
|
|
||||||
public HomeController(
|
public HomeController(
|
||||||
ISqlSugarClient sqlSugar,
|
ISqlSugarClient sqlSugar,
|
||||||
|
|
@ -40,7 +48,8 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
IHttpClientFactory httpClientFactory,
|
IHttpClientFactory httpClientFactory,
|
||||||
AgoraHelper agoraHelper,
|
AgoraHelper agoraHelper,
|
||||||
ILogger<HomeController> logger,
|
ILogger<HomeController> logger,
|
||||||
OssHelper ossHelper)
|
OssHelper ossHelper,
|
||||||
|
MiniProgramHelper miniProgramHelper)
|
||||||
{
|
{
|
||||||
_sqlSugar = sqlSugar;
|
_sqlSugar = sqlSugar;
|
||||||
this._configuration = configuration;
|
this._configuration = configuration;
|
||||||
|
|
@ -48,6 +57,7 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
this._agoraHelper = agoraHelper;
|
this._agoraHelper = agoraHelper;
|
||||||
this._logger = logger;
|
this._logger = logger;
|
||||||
this._ossHelper = ossHelper;
|
this._ossHelper = ossHelper;
|
||||||
|
this._miniProgramHelper = miniProgramHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -63,6 +73,8 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
|
|
||||||
var list = await _sqlSugar.Queryable<Room>()
|
var list = await _sqlSugar.Queryable<Room>()
|
||||||
.Where(x => x.TenantId == TenantId && x.IsDelete == false)
|
.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)
|
.OrderBy(x => x.Id, OrderByType.Desc)
|
||||||
.ToPageListAsync(dto.PageIndex, dto.PageSize, total);
|
.ToPageListAsync(dto.PageIndex, dto.PageSize, total);
|
||||||
|
|
||||||
|
|
@ -79,7 +91,7 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PagedResult<RoomOutputDTO>.Create(result, total.Value);
|
return PagedResult<RoomOutputDTO>.Create(result, total.Value, dto.PageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -99,7 +111,9 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
entity.Id = YitIdHelper.NextId().ToString();
|
entity.Id = YitIdHelper.NextId().ToString();
|
||||||
entity.TenantId = TenantId;
|
entity.TenantId = TenantId;
|
||||||
|
|
||||||
if (await _sqlSugar.Queryable<Room>().AnyAsync(x => x.RoomNum == inputDTO.RoomNum))
|
|
||||||
|
var room = await _sqlSugar.Queryable<Room>().FirstAsync(x => x.RoomNum == inputDTO.RoomNum);
|
||||||
|
if (room != null)
|
||||||
{
|
{
|
||||||
throw Oops.Oh("无效会议号,请重新输入");
|
throw Oops.Oh("无效会议号,请重新输入");
|
||||||
}
|
}
|
||||||
|
|
@ -107,6 +121,19 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
return await _sqlSugar.Insertable(entity).ExecuteCommandAsync() > 0;
|
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, x.RoomName, x.AllowAnonymous })
|
||||||
|
.ExecuteCommandHasChangeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 删除会议室
|
/// 删除会议室
|
||||||
|
|
@ -188,15 +215,19 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
|
|
||||||
var groupByUser = recordList.GroupBy(x => x.uid).ToList();
|
var groupByUser = recordList.GroupBy(x => x.uid).ToList();
|
||||||
|
|
||||||
|
var beginDatetime = DateTimeUtils.FromJavaScriptTimestampToLocal(beginTimestamp);
|
||||||
|
var endDaetime = DateTimeUtils.FromJavaScriptTimestampToLocal(endTimestamp);
|
||||||
var value = new RoomMettingRecordExportDTO
|
var value = new RoomMettingRecordExportDTO
|
||||||
{
|
{
|
||||||
RoomName = room.RoomName,
|
RoomName = room.RoomName,
|
||||||
RoomNum = room.RoomNum,
|
RoomNum = room.RoomNum,
|
||||||
BeginTime = DateTimeUtils.FromJavaScriptTimestampToLocal(beginTimestamp).ToString("yyyy-MM-dd HH:mm:ss"),
|
BeginTime = beginDatetime.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||||
EndTime = DateTimeUtils.FromJavaScriptTimestampToLocal(endTimestamp).ToString("yyyy-MM-dd HH:mm:ss"),
|
EndTime = endDaetime.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||||
Users = new List<UserBehavior>()
|
Users = new List<UserBehavior>(),
|
||||||
|
Signin = new List<SignInListRecordExcelDto>()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#region 计算入会次数、累计参会时长
|
||||||
foreach (var userRecord in groupByUser)
|
foreach (var userRecord in groupByUser)
|
||||||
{
|
{
|
||||||
if (userRecord.IsNullOrEmpty())
|
if (userRecord.IsNullOrEmpty())
|
||||||
|
|
@ -207,14 +238,25 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
var orderedRecord = userRecord.OrderBy(x => x.ts).ToList();
|
var orderedRecord = userRecord.OrderBy(x => x.ts).ToList();
|
||||||
|
|
||||||
// 获取第一次进入房间的事件记录
|
// 获取第一次进入房间的事件记录
|
||||||
var firstJoinTime = orderedRecord
|
var firstJoinTimeRecord = orderedRecord
|
||||||
.FirstOrDefault(x => x.EventType == EventType.broadcaster_join_channel
|
.FirstOrDefault(x => x.EventType == EventType.broadcaster_join_channel
|
||||||
|| x.EventType == EventType.audience_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 lastLeaveTime = orderedRecord
|
var lastLeaveTimeRecord = orderedRecord
|
||||||
.LastOrDefault(x => x.EventType == EventType.broadcaster_leave_channel
|
.LastOrDefault(x => x.EventType == EventType.broadcaster_leave_channel
|
||||||
|| x.EventType == EventType.audience_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
|
var joinCount = orderedRecord.Count(x => x.EventType == EventType.broadcaster_join_channel
|
||||||
|
|
@ -226,22 +268,120 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
value.Users.Add(new UserBehavior
|
value.Users.Add(new UserBehavior
|
||||||
{
|
{
|
||||||
Account = userRecord.FirstOrDefault().UserAccount,
|
Account = userRecord.FirstOrDefault().UserAccount,
|
||||||
FirstJoinTime = DateTimeUtils.FromJavaScriptTimestampToLocal(firstJoinTime.ts).ToString("yyyy-MM-dd HH:mm:ss"),
|
FirstJoinTime = firstJoinTime,
|
||||||
LastExitTime = DateTimeUtils.FromJavaScriptTimestampToLocal(lastLeaveTime.ts).ToString("yyyy-MM-dd HH:mm:ss"),
|
LastExitTime = lastLeaveTime,
|
||||||
JoinCount = joinCount,
|
JoinCount = joinCount,
|
||||||
Role = userRecord.FirstOrDefault().RoleName,
|
Role = userRecord.FirstOrDefault().RoleName,
|
||||||
UserName = userRecord.FirstOrDefault().userName,
|
UserName = userRecord.FirstOrDefault().userName,
|
||||||
SumTime = sumTime,
|
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();
|
using var stream = new MemoryStream();
|
||||||
|
|
||||||
await MiniExcel.SaveAsByTemplateAsync(stream, $@"{AppDomain.CurrentDomain.BaseDirectory}meetingRecordTemplate.xlsx", value);
|
await MiniExcel.SaveAsByTemplateAsync(stream, $@"{AppDomain.CurrentDomain.BaseDirectory}meetingRecordTemplate.xlsx", value);
|
||||||
stream.Seek(0, SeekOrigin.Begin);
|
stream.Seek(0, SeekOrigin.Begin);
|
||||||
var fileName = $@"excel/{room.RoomName}-参会记录.xlsx";
|
var fileName = $@"excel/{room.RoomName}-参会记录-{beginDatetime.ToString("yyyyMMddHHmmss")}至{endDaetime.ToString("yyyyMMddHHmmss")}.xlsx";
|
||||||
_ossHelper.UploadWithExpireTime(fileName, stream, 10);
|
_ossHelper.UploadWithExpireTime(fileName, stream, 10);
|
||||||
return _ossHelper.GetAccessFileUrl(fileName, 5);
|
return _ossHelper.GetAccessFileUrl(fileName, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取房间二维码(缓存10mins)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="roomNum"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("r-qrcode")]
|
||||||
|
public async Task<string> GetMiniProgramQrCode([FromQuery] string roomNum, [FromQuery] string env = "release")
|
||||||
|
{
|
||||||
|
var img = RedisHelper.Instance.Get(RedisKeyConstant.WxMiniProgram.GetRoomQrCode(roomNum, env));
|
||||||
|
if (!string.IsNullOrWhiteSpace(img))
|
||||||
|
{
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
var httpClient = _httpClientFactory.CreateClient();
|
||||||
|
var accessToken = await _miniProgramHelper.GetAccessToken();
|
||||||
|
|
||||||
|
var result = await httpClient.PostAsync($@"https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={accessToken}", new StringContent(new wxacodeunlimitBody
|
||||||
|
{
|
||||||
|
page = "pages/form/index",
|
||||||
|
scene = ("r=" + roomNum),
|
||||||
|
check_path = true,
|
||||||
|
env_version = env,
|
||||||
|
width = 280
|
||||||
|
}.ToJsonString()));
|
||||||
|
if (result == null || !result.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
_logger.LogError($@"二维码生成失败,statusCode:{(int)result.StatusCode},content:{await result.Content.ReadAsStringAsync()}");
|
||||||
|
throw Oops.Oh("二维码生成失败!");
|
||||||
|
}
|
||||||
|
var contentType = result.Content.Headers.ContentType?.MediaType;
|
||||||
|
// 如果是图片类型
|
||||||
|
if (contentType != null && contentType.StartsWith("image/"))
|
||||||
|
{
|
||||||
|
// 处理图片数据
|
||||||
|
var imageArr = await result.Content.ReadAsByteArrayAsync();
|
||||||
|
var imgStr = Convert.ToBase64String(imageArr);
|
||||||
|
|
||||||
|
imgStr = QrCodeOptimizerHelper.CompressImage(imgStr, 50);
|
||||||
|
RedisHelper.Instance.Set(RedisKeyConstant.WxMiniProgram.GetRoomQrCode(roomNum, env), imgStr, TimeSpan.FromDays(1));
|
||||||
|
return imgStr;
|
||||||
|
}
|
||||||
|
else if (contentType != null && contentType.Contains("json"))
|
||||||
|
{
|
||||||
|
var apiResult = await result.Content.ReadFromJsonAsync<WxMiniProgramBaseApiResult>();
|
||||||
|
if (apiResult != null)
|
||||||
|
{
|
||||||
|
_logger.LogError($"二维码生成失败,errorCode:{apiResult.errorcode},errmsg:{apiResult.errmsg}");
|
||||||
|
throw Oops.Oh("二维码生成失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_logger.LogError("返回 ContentType 未命中");
|
||||||
|
throw Oops.Oh("二维码生成失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反馈打分
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("feedback")]
|
||||||
|
public async Task FeedbackScoring([FromBody] FeedBackRequset requset)
|
||||||
|
{
|
||||||
|
var entity = requset.Adapt<FeedbackIssue>();
|
||||||
|
entity.UID = UId.ToInt64();
|
||||||
|
entity.Types = string.Join(",", requset.Types);
|
||||||
|
|
||||||
|
await _sqlSugar.Insertable(entity).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录用户当前用户版本
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("ver-log")]
|
||||||
|
public async Task RecordVersionLog([FromBody] UserVersionLogDto userVersionLog)
|
||||||
|
{
|
||||||
|
var uvl = userVersionLog.Adapt<UserVersionLog>();
|
||||||
|
uvl.UserId = UId.ToInt64();
|
||||||
|
await _sqlSugar.Insertable(uvl).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using Hangfire.MemoryStorage.Database;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
using Masuit.Tools;
|
using Masuit.Tools;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Components.Forms;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
|
@ -62,10 +63,11 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
[HttpPost("manager")]
|
[HttpPost("manager")]
|
||||||
public async Task SetRoomManager([FromBody] RoomManagerInputDTO inputDTO)
|
public async Task SetRoomManager([FromBody] RoomManagerInputDTO inputDTO)
|
||||||
{
|
{
|
||||||
|
inputDTO.SettingUserId = UId;
|
||||||
var users = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum));
|
var users = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum));
|
||||||
if (users.Count(x => x.IsRoomManager || x.RoleId == ((int)RoleEnums.Admin).ToString() || x.RoleId == ((int)RoleEnums.RoomManager).ToString()) >= 12)
|
if (users.Count(x => x.IsRoomManager || x.RoleId == ((int)RoleEnums.Admin).ToString() || x.RoleId == ((int)RoleEnums.RoomManager).ToString()) >= 20)
|
||||||
{
|
{
|
||||||
throw Oops.Oh("房间已达到12个发言人限制。请移除一位发言人");
|
throw Oops.Oh("当前房间已达最大发言人数!");
|
||||||
}
|
}
|
||||||
var user = users.FirstOrDefault(x => x.UID == inputDTO.UserId);
|
var user = users.FirstOrDefault(x => x.UID == inputDTO.UserId);
|
||||||
if (user == null)
|
if (user == null)
|
||||||
|
|
@ -73,11 +75,13 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
throw Oops.Oh("用户已不在房间内!");
|
throw Oops.Oh("用户已不在房间内!");
|
||||||
}
|
}
|
||||||
|
|
||||||
user.IsRoomManager = true;
|
await _hubContext.Clients.User(inputDTO.UserId).SetSpeaker(inputDTO);
|
||||||
|
|
||||||
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum), inputDTO.UserId, user);
|
//user.IsRoomManager = true;
|
||||||
|
|
||||||
await _hubContext.Clients.Group(inputDTO.RoomNum).ManagerRefresh(user, UId);
|
//RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum), inputDTO.UserId, user);
|
||||||
|
|
||||||
|
//await _hubContext.Clients.Group(inputDTO.RoomNum).ManagerRefresh(user, UId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -95,21 +99,35 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
}
|
}
|
||||||
|
|
||||||
user.IsRoomManager = false;
|
user.IsRoomManager = false;
|
||||||
|
user.EnableCamera = false;
|
||||||
|
user.EnableMicr = false;
|
||||||
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum), inputDTO.UserId, user);
|
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum), inputDTO.UserId, user);
|
||||||
|
|
||||||
// 判断是否显示用户
|
// 判断是否显示用户
|
||||||
var showUserId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), inputDTO.RoomNum);
|
var showUserId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), inputDTO.RoomNum);
|
||||||
if (showUserId == inputDTO.UserId)
|
if (showUserId == inputDTO.UserId || showUserId == user.ScreenShareId)
|
||||||
{
|
{
|
||||||
// 取消显示用户,设置显示管理员
|
if (UId == inputDTO.UserId)
|
||||||
var users = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum));
|
|
||||||
var showUser = users.FirstOrDefault(x => x.RoleId == ((int)RoleEnums.Admin).ToString() || x.IsRoomManager || x.RoleId == ((int)RoleEnums.RoomManager).ToString());
|
|
||||||
if (showUser != null)
|
|
||||||
{
|
{
|
||||||
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), inputDTO.RoomNum, showUser.UID);
|
// 表示自己取消自己的发言权限
|
||||||
await _hubContext.Clients.Group(inputDTO.RoomNum).ShowUser(showUser.UID, showUser.UserName, string.Empty, string.Empty);
|
var users = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum));
|
||||||
|
var showUser = users.FirstOrDefault(x => x.RoleId == ((int)RoleEnums.Admin).ToString() || x.IsRoomManager || x.RoleId == ((int)RoleEnums.RoomManager).ToString());
|
||||||
|
if (showUser != null)
|
||||||
|
{
|
||||||
|
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), inputDTO.RoomNum, showUser.UID);
|
||||||
|
await _hubContext.Clients.Group(inputDTO.RoomNum).ShowUser(showUser.UID, showUser.UserName, string.Empty, string.Empty);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), inputDTO.RoomNum, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 取消显示用户,设置显示当前操作的管理员
|
||||||
|
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), inputDTO.RoomNum, UId);
|
||||||
|
await _hubContext.Clients.Group(inputDTO.RoomNum).ShowUser(UId, UserName, string.Empty, string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await _hubContext.Clients.Group(inputDTO.RoomNum).ManagerRefresh(user, UId);
|
await _hubContext.Clients.Group(inputDTO.RoomNum).ManagerRefresh(user, UId);
|
||||||
|
|
@ -188,7 +206,34 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
[HttpGet("checkout"), AllowAnonymous]
|
[HttpGet("checkout"), AllowAnonymous]
|
||||||
public async Task<bool> ExistsRoom([FromQuery] string roomNum)
|
public async Task<bool> ExistsRoom([FromQuery] string roomNum)
|
||||||
{
|
{
|
||||||
return await _sqlSugar.Queryable<Room>().AnyAsync(x => x.RoomNum == roomNum && x.IsDelete == false);
|
if (IsAnonymous)
|
||||||
|
{
|
||||||
|
// 匿名用户
|
||||||
|
var room = await _sqlSugar.Queryable<Room>().FirstAsync(x => x.RoomNum == roomNum && x.IsDelete == false);
|
||||||
|
if (room == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!room.AllowAnonymous)
|
||||||
|
{
|
||||||
|
throw Oops.Oh("房间不允许匿名用户进入");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 非匿名用户
|
||||||
|
var room = await _sqlSugar.Queryable<Room>()
|
||||||
|
.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)
|
||||||
|
.FirstAsync(x => x.RoomNum == roomNum && x.IsDelete == false);
|
||||||
|
if (room == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -297,7 +342,7 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
userInfo.EnableMicr = enableMicr;
|
userInfo.EnableMicr = enableMicr;
|
||||||
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), uid, userInfo);
|
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), uid, userInfo);
|
||||||
|
|
||||||
_logger.LogInformation($@"开闭麦克分,推送一次,roomNum:{roomNum},enableMicr:{enableMicr},uid:{uid}");
|
//_logger.LogInformation($@"开闭麦克分,推送一次,roomNum:{roomNum},enableMicr:{enableMicr},uid:{uid}");
|
||||||
// 通知所有人该用户麦克风状态
|
// 通知所有人该用户麦克风状态
|
||||||
await _hubContext.Clients.Group(roomNum).OperMicr(userInfo, UId);
|
await _hubContext.Clients.Group(roomNum).OperMicr(userInfo, UId);
|
||||||
}
|
}
|
||||||
|
|
@ -338,13 +383,25 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取全部用户
|
// 获取全部用户
|
||||||
var uids = RedisHelper.Instance.HKeys(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum));
|
var userInfos = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum));
|
||||||
if (uids.IsNullOrEmpty())
|
if (userInfos.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
throw Oops.Oh("无效会议号!");
|
throw Oops.Oh("无效会议号!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return uids.FirstOrDefault();
|
var managers = userInfos.Where(x => x.RoleId == ((int)RoleEnums.Admin).ToString() || x.IsRoomManager || x.RoleId == ((int)RoleEnums.RoomManager).ToString());
|
||||||
|
if (managers.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
return userInfos.FirstOrDefault().UID;
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = managers.FirstOrDefault(x => x.EnableCamera = true);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return managers.FirstOrDefault().UID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return user.UID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -354,6 +411,13 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
[HttpPost("show-user")]
|
[HttpPost("show-user")]
|
||||||
public async Task SetShowUser([FromQuery] string roomNum, [FromQuery] string uid, [FromQuery] string uname)
|
public async Task SetShowUser([FromQuery] string roomNum, [FromQuery] string uid, [FromQuery] string uname)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum) == uid)
|
||||||
|
{
|
||||||
|
// 如果已经是全员观看他了, 直接通知其他房间用户
|
||||||
|
await _hubContext.Clients.Group(roomNum).ShowUser(uid, uname, UId, UserName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
// 设置房间全员观看用户
|
// 设置房间全员观看用户
|
||||||
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum, uid);
|
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum, uid);
|
||||||
|
|
||||||
|
|
@ -373,9 +437,10 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
/// <param name="enableMicr"></param>
|
/// <param name="enableMicr"></param>
|
||||||
/// <param name="enableCamera"></param>
|
/// <param name="enableCamera"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("join")]
|
[HttpGet("join"), Obsolete("废弃,请使用Socker接口 JoinChannel")]
|
||||||
public async Task JoinChannel([FromQuery] string roomNum, [FromQuery] bool enableMicr = false, [FromQuery] bool enableCamera = false)
|
public async Task JoinChannel([FromQuery] string roomNum, [FromQuery] bool enableMicr = false, [FromQuery] bool enableCamera = false)
|
||||||
{
|
{
|
||||||
|
//throw Oops.("接口已废弃");
|
||||||
//var isRoomManager = await _sqlSugar.Queryable<RoomManager>()
|
//var isRoomManager = await _sqlSugar.Queryable<RoomManager>()
|
||||||
// .InnerJoin<Room>((rm, r) => r.Id == rm.RoomId)
|
// .InnerJoin<Room>((rm, r) => r.Id == rm.RoomId)
|
||||||
// .Where((rm, r) => r.RoomNum == roomNum && rm.UserId == UId)
|
// .Where((rm, r) => r.RoomNum == roomNum && rm.UserId == UId)
|
||||||
|
|
@ -433,9 +498,10 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="roomNum"></param>
|
/// <param name="roomNum"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("leave")]
|
[HttpGet("leave"), Obsolete("废弃,请使用Socker接口 leavelChannel")]
|
||||||
public async Task LevelChannel([FromQuery] string roomNum)
|
public async Task LevelChannel([FromQuery] string roomNum)
|
||||||
{
|
{
|
||||||
|
|
||||||
using (var pipe = RedisHelper.Instance.StartPipe())
|
using (var pipe = RedisHelper.Instance.StartPipe())
|
||||||
{
|
{
|
||||||
// 判断,如果有全员看ta,则删除
|
// 判断,如果有全员看ta,则删除
|
||||||
|
|
@ -562,10 +628,78 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
|
|
||||||
if (connectionIds.Any())
|
if (connectionIds.Any())
|
||||||
{
|
{
|
||||||
await _hubContext.Clients.Clients(connectionIds).ApplyToSpeak(UId, UserName);
|
var userInfo = RedisHelper.Instance.HGet<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), UId);
|
||||||
|
var userName = UserName;
|
||||||
|
if (userInfo != null)
|
||||||
|
{
|
||||||
|
userName = userInfo.UserName;
|
||||||
|
}
|
||||||
|
await _hubContext.Clients.Clients(connectionIds).ApplyToSpeak(UId, userName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取共享屏幕
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("shared-screen")]
|
||||||
|
public async Task<string> GetSharedScreen([FromQuery] string roomNum)
|
||||||
|
{
|
||||||
|
var showUserId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum);
|
||||||
|
if (!string.IsNullOrWhiteSpace(showUserId) && showUserId.Length == 9)
|
||||||
|
{
|
||||||
|
// 全员观看userid =9 表示共享屏幕
|
||||||
|
return showUserId;
|
||||||
|
}
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置共享屏幕
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("shared-screen")]
|
||||||
|
public async Task SharedScreen([FromQuery] string roomNum)
|
||||||
|
{
|
||||||
|
//var showUserId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum);
|
||||||
|
//if (showUserId.Length == 9)
|
||||||
|
//{
|
||||||
|
// var user = await _sqlSugar.Queryable<User>().FirstAsync(x => x.ScreenShareId == showUserId);
|
||||||
|
// if (user != null)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// await _hubContext.Clients.User(user.Id).ExitSharedScreen();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
var connectId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetOnlineUserKey(TenantId), UId);
|
||||||
|
// 通知其他所有共享屏幕用户退出
|
||||||
|
await _hubContext.Clients.GroupExcept(roomNum, connectId).ExitSharedScreen();
|
||||||
|
|
||||||
|
// 设置新的共享屏幕
|
||||||
|
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum, ScreenShareId);
|
||||||
|
// 通知全员观看新的共享屏幕
|
||||||
|
await _hubContext.Clients.Group(roomNum).ShowUser(UId, UserName, string.Empty, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 共享人取消共享屏幕
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("stop-shared-screen")]
|
||||||
|
public async Task StopedSharedScreen([FromQuery] string roomNum)
|
||||||
|
{
|
||||||
|
if (RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum) != ScreenShareId)
|
||||||
|
{
|
||||||
|
// 不是共享屏幕的人,不做处理
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置新的共享屏幕
|
||||||
|
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), roomNum, UId);
|
||||||
|
|
||||||
|
await _hubContext.Clients.Group(roomNum).StopedSharedScreen(ScreenShareId);
|
||||||
|
}
|
||||||
|
|
||||||
#region 文件分享
|
#region 文件分享
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -654,5 +788,49 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
return _ossHelper.GetAccessFileUrl(fileUrl);
|
return _ossHelper.GetAccessFileUrl(fileUrl);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取签到列表
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("sign-in")]
|
||||||
|
public async Task<List<UserSignInListDto>> GetSignInList()
|
||||||
|
{
|
||||||
|
var list = await _sqlSugar.Queryable<UserSignInList>()
|
||||||
|
.Where(x => x.UId == UId)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return list.Adapt<List<UserSignInListDto>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 提交签到
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="list"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("sign-in")]
|
||||||
|
public async Task SignIn([FromBody] List<UserSignInRecordDto> list)
|
||||||
|
{
|
||||||
|
var entitys = list.Adapt<List<UserSignInRecord>>();
|
||||||
|
entitys.ForEach(x => x.UId = UId);
|
||||||
|
|
||||||
|
await _sqlSugar.Insertable(entitys).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改昵称
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPut("alter-uname")]
|
||||||
|
public async Task ModifyNickName([FromBody] UserModifyNickNameDto dto)
|
||||||
|
{
|
||||||
|
var user = RedisHelper.Instance.HGet<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, dto.RoomNum), dto.UId.ToString());
|
||||||
|
user.UserName = dto.NickName;
|
||||||
|
|
||||||
|
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, dto.RoomNum), dto.UId.ToString(), user);
|
||||||
|
|
||||||
|
await _hubContext.Clients.Group(dto.RoomNum).ModifyNickName(dto.UId, dto.NickName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,9 @@ using WGShare.Domain.Entities;
|
||||||
using WGShare.Domain.FriendlyException;
|
using WGShare.Domain.FriendlyException;
|
||||||
using WGShare.Domain.GeneralModel;
|
using WGShare.Domain.GeneralModel;
|
||||||
using Yitter.IdGenerator;
|
using Yitter.IdGenerator;
|
||||||
|
using WGShare.Domain.Enums;
|
||||||
|
using Microsoft.AspNetCore.Routing.Template;
|
||||||
|
using MiniExcelLibs.OpenXml;
|
||||||
|
|
||||||
namespace WGShare.API.Controllers.Frontend
|
namespace WGShare.API.Controllers.Frontend
|
||||||
{
|
{
|
||||||
|
|
@ -49,7 +52,7 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
|
|
||||||
var list = await _sqlSugar.Queryable<User>()
|
var list = await _sqlSugar.Queryable<User>()
|
||||||
.InnerJoin<Role>((u, r) => u.RoleId == r.Id)
|
.InnerJoin<Role>((u, r) => u.RoleId == r.Id)
|
||||||
.Where((u, r) => u.IsDelete == false && u.TenantId == TenantId)
|
.Where((u, r) => u.IsDelete == false && u.TenantId == TenantId && u.IsAnonymous == false)
|
||||||
.WhereIF(!string.IsNullOrWhiteSpace(searchKeywod), (u, r) => u.UserName.Contains(searchKeywod) || u.Account.Contains(searchKeywod))
|
.WhereIF(!string.IsNullOrWhiteSpace(searchKeywod), (u, r) => u.UserName.Contains(searchKeywod) || u.Account.Contains(searchKeywod))
|
||||||
.WhereIF(isOnline.HasValue && isOnline.Value == true, (u, r) => onlineUid.Contains(u.Id))
|
.WhereIF(isOnline.HasValue && isOnline.Value == true, (u, r) => onlineUid.Contains(u.Id))
|
||||||
.WhereIF(isOnline.HasValue && isOnline.Value == false, (u, r) => !onlineUid.Contains(u.Id))
|
.WhereIF(isOnline.HasValue && isOnline.Value == false, (u, r) => !onlineUid.Contains(u.Id))
|
||||||
|
|
@ -61,7 +64,9 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
Account = u.Account,
|
Account = u.Account,
|
||||||
RoleId = r.Id,
|
RoleId = r.Id,
|
||||||
RoleName = r.RoleName,
|
RoleName = r.RoleName,
|
||||||
ScreenShareId = u.ScreenShareId
|
ScreenShareId = u.ScreenShareId,
|
||||||
|
Subject = u.Subject,
|
||||||
|
Year = u.Year,
|
||||||
})
|
})
|
||||||
.ToPageListAsync(pagedBaseDto.PageIndex, pagedBaseDto.PageSize, total);
|
.ToPageListAsync(pagedBaseDto.PageIndex, pagedBaseDto.PageSize, total);
|
||||||
|
|
||||||
|
|
@ -85,7 +90,7 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
user.TenantId = TenantId;
|
user.TenantId = TenantId;
|
||||||
user.ScreenShareId = UserShareIdHelper.GenerateUnique8DigitNumber();
|
user.ScreenShareId = UserShareIdHelper.GenerateUnique8DigitNumber();
|
||||||
|
|
||||||
if (await _sqlSugar.Queryable<User>().AnyAsync(x => x.Account == user.Account))
|
if (await _sqlSugar.Queryable<User>().AnyAsync(x => x.Account == user.Account && x.IsDelete == false))
|
||||||
{
|
{
|
||||||
throw Oops.Oh("账号已存在!");
|
throw Oops.Oh("账号已存在!");
|
||||||
}
|
}
|
||||||
|
|
@ -103,13 +108,52 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
{
|
{
|
||||||
var entity = inputDTO.Adapt<User>();
|
var entity = inputDTO.Adapt<User>();
|
||||||
|
|
||||||
if (await _sqlSugar.Queryable<User>().AnyAsync(x => x.Account == entity.Account && x.Id != inputDTO.Id))
|
if (await _sqlSugar.Queryable<User>().AnyAsync(x => x.Account == entity.Account && x.Id != inputDTO.Id && x.IsDelete == false))
|
||||||
{
|
{
|
||||||
throw Oops.Oh("账号已存在!");
|
throw Oops.Oh("账号已存在!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return await _sqlSugar.Updateable(entity)
|
return await _sqlSugar.Updateable(entity)
|
||||||
.UpdateColumns(x => new { x.Account, x.UserName, x.RoleId }).ExecuteCommandAsync() > 0;
|
.UpdateColumns(x => new { x.Account, x.UserName, x.RoleId, x.Year, x.Subject }).ExecuteCommandAsync() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取用户签到名单列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uid"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("signs")]
|
||||||
|
public async Task<List<UserSignInListDto>> GetUserSignInList([FromQuery] string uid)
|
||||||
|
{
|
||||||
|
var list = await _sqlSugar.Queryable<UserSignInList>().Where(x => x.UId == uid)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return list.Adapt<List<UserSignInListDto>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改用户签到列表
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPut("signs")]
|
||||||
|
public async Task ModifySignList([FromQuery] string uid, [FromBody] List<UserSignInListDto> signInList)
|
||||||
|
{
|
||||||
|
var entities = signInList.Adapt<List<UserSignInList>>();
|
||||||
|
|
||||||
|
using (var tran = _sqlSugar.AsTenant().UseTran())
|
||||||
|
{
|
||||||
|
await _sqlSugar.Deleteable<UserSignInList>().Where(x => x.UId == uid).ExecuteCommandAsync();
|
||||||
|
|
||||||
|
if (!entities.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
var stor = await _sqlSugar.Storageable(entities).ToStorageAsync();
|
||||||
|
await stor.AsInsertable.ExecuteCommandAsync(); //不存在插入
|
||||||
|
await stor.AsUpdateable.UpdateColumns(x => x.SignInName).ExecuteCommandAsync(); //存在更新
|
||||||
|
}
|
||||||
|
tran.CommitTran();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -126,6 +170,21 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
.UpdateColumns(x => new { x.Pwd }).ExecuteCommandAsync() > 0;
|
.UpdateColumns(x => new { x.Pwd }).ExecuteCommandAsync() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量修改用户信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inputDTO"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPut("bth")]
|
||||||
|
public async Task<bool> BatchModifyUsers([FromBody] List<UserBatchUpdateDTO> updateDTOs)
|
||||||
|
{
|
||||||
|
var entity = updateDTOs.Adapt<List<User>>();
|
||||||
|
|
||||||
|
return await _sqlSugar.Updateable(entity)
|
||||||
|
.UpdateColumns(x => new { x.Subject, x.Year }).ExecuteCommandAsync() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 删除用户
|
/// 删除用户
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -165,7 +224,7 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
|
|
||||||
// 数据库重复账号检查
|
// 数据库重复账号检查
|
||||||
var existsAccount = await _sqlSugar.Queryable<User>()
|
var existsAccount = await _sqlSugar.Queryable<User>()
|
||||||
.Where(x => distinctAccount.Contains(x.Account))
|
.Where(x => distinctAccount.Contains(x.Account) && x.IsDelete == false)
|
||||||
.Select(x => x.Account)
|
.Select(x => x.Account)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
if (!existsAccount.IsNullOrEmpty())
|
if (!existsAccount.IsNullOrEmpty())
|
||||||
|
|
@ -214,6 +273,11 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
roleId = "3";
|
roleId = "3";
|
||||||
x.RoleId = roleId;
|
x.RoleId = roleId;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(x.SubjectName))
|
||||||
|
x.Subject = SubjectType.All;
|
||||||
|
else
|
||||||
|
x.Subject = x.SubjectName.GetEnumValueFromDescription<SubjectType>();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await _sqlSugar.Insertable(users).ExecuteCommandAsync();
|
await _sqlSugar.Insertable(users).ExecuteCommandAsync();
|
||||||
|
|
@ -221,5 +285,80 @@ namespace WGShare.API.Controllers.Frontend
|
||||||
return Ok((isSuccess: true, url: "", msg: "导入成功"));
|
return Ok((isSuccess: true, url: "", msg: "导入成功"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取签到绑定列表
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("signin-list")]
|
||||||
|
public async Task<string> GetSignInBinding()
|
||||||
|
{
|
||||||
|
var userWithSign = await _sqlSugar.Queryable<User>()
|
||||||
|
.InnerJoin<Role>((u, r) => u.RoleId == r.Id)
|
||||||
|
.LeftJoin<UserSignInList>((u, r, s) => u.Id == s.UId)
|
||||||
|
.Where((u, r, s) => u.IsDelete == false && TenantId == u.TenantId)
|
||||||
|
.Select((u, r, s) => new SignInListExcelDto
|
||||||
|
{
|
||||||
|
UId = u.Id,
|
||||||
|
Account = u.Account,
|
||||||
|
RoleId = u.RoleId,
|
||||||
|
RoleName = r.RoleName,
|
||||||
|
SignInName = s.SignInName,
|
||||||
|
UserName = u.UserName,
|
||||||
|
}).ToListAsync();
|
||||||
|
|
||||||
|
var value = new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
["Users"] = userWithSign
|
||||||
|
};
|
||||||
|
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
await MiniExcel.SaveAsByTemplateAsync(stream, $@"{AppDomain.CurrentDomain.BaseDirectory}signInListImportTemplate.xlsx", value);
|
||||||
|
stream.Seek(0, SeekOrigin.Begin);
|
||||||
|
var fileName = $@"excel/签到绑定导入-{DateTime.Now.ToString("MMddHHmmss")}.xlsx";
|
||||||
|
_ossHelper.UploadWithExpireTime(fileName, stream, 10);
|
||||||
|
return _ossHelper.GetAccessFileUrl(fileName, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost("import/signin-list")]
|
||||||
|
public async Task<IActionResult> ImportSigninList([FromForm] IFormFile file)
|
||||||
|
{
|
||||||
|
using var stream = file.OpenReadStream();
|
||||||
|
var rows = stream.Query<SignInListExcelDto>().ToList();
|
||||||
|
rows.RemoveAll(x => x == null || string.IsNullOrWhiteSpace(x.Account) || string.IsNullOrWhiteSpace(x.UId));
|
||||||
|
if (rows.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
throw Oops.Oh("无有效数据,请检查文件数据!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取已存在用户Id
|
||||||
|
var existsUIds = await _sqlSugar.Queryable<User>()
|
||||||
|
.Where(x => x.IsDelete == false).Select(x => x.Id).ToListAsync();
|
||||||
|
// 去除不存在用户Id
|
||||||
|
rows.RemoveAll(x => !existsUIds.Contains(x.UId));
|
||||||
|
|
||||||
|
var delUids = rows.Select(x => x.UId).Distinct().ToList();
|
||||||
|
|
||||||
|
|
||||||
|
var entities = rows.Where(x => !string.IsNullOrWhiteSpace(x.SignInName)).Adapt<List<UserSignInList>>();
|
||||||
|
|
||||||
|
using (var tran = _sqlSugar.AsTenant().UseTran())
|
||||||
|
{
|
||||||
|
await _sqlSugar.Deleteable<UserSignInList>().Where(x => delUids.Contains(x.UId)).ExecuteCommandAsync();
|
||||||
|
|
||||||
|
var store = await _sqlSugar.Storageable(entities)
|
||||||
|
.WhereColumns(x => new { x.UId, x.SignInName })
|
||||||
|
.ToStorageAsync();
|
||||||
|
|
||||||
|
|
||||||
|
await store.AsInsertable.ExecuteCommandAsync();
|
||||||
|
await store.AsUpdateable.UpdateColumns(x => x.SignInName).ExecuteCommandHasChangeAsync();
|
||||||
|
|
||||||
|
tran.CommitTran();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok((isSuccess: true, url: "", msg: "导入成功"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,18 @@ using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using MiniExcelLibs;
|
using MiniExcelLibs;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Configuration;
|
using System.Configuration;
|
||||||
|
using System.Reflection;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using WGShare.API.Controllers.Basic;
|
using WGShare.API.Controllers.Basic;
|
||||||
using WGShare.API.Helpers;
|
using WGShare.API.Helpers;
|
||||||
using WGShare.Domain.DTOs.Login;
|
using WGShare.Domain.DTOs.Login;
|
||||||
|
using WGShare.Domain.DTOs.MiniProgram;
|
||||||
using WGShare.Domain.DTOs.User;
|
using WGShare.Domain.DTOs.User;
|
||||||
using WGShare.Domain.Entities;
|
using WGShare.Domain.Entities;
|
||||||
|
using WGShare.Domain.Enums;
|
||||||
using WGShare.Domain.FriendlyException;
|
using WGShare.Domain.FriendlyException;
|
||||||
|
|
||||||
namespace WGShare.API.Controllers
|
namespace WGShare.API.Controllers
|
||||||
|
|
@ -23,10 +27,19 @@ namespace WGShare.API.Controllers
|
||||||
public class PublicController : BasicController
|
public class PublicController : BasicController
|
||||||
{
|
{
|
||||||
private readonly ISqlSugarClient _sqlSugar;
|
private readonly ISqlSugarClient _sqlSugar;
|
||||||
|
private readonly IHttpClientFactory _httpClientFactory;
|
||||||
|
private readonly Microsoft.Extensions.Configuration.IConfiguration _configuration;
|
||||||
|
private readonly ILogger<PublicController> _logger;
|
||||||
|
|
||||||
public PublicController(ISqlSugarClient sqlSugar)
|
public PublicController(ISqlSugarClient sqlSugar,
|
||||||
|
IHttpClientFactory httpClientFactory,
|
||||||
|
Microsoft.Extensions.Configuration.IConfiguration configuration,
|
||||||
|
ILogger<PublicController> logger)
|
||||||
{
|
{
|
||||||
_sqlSugar = sqlSugar;
|
_sqlSugar = sqlSugar;
|
||||||
|
this._httpClientFactory = httpClientFactory;
|
||||||
|
this._configuration = configuration;
|
||||||
|
this._logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -38,5 +51,54 @@ namespace WGShare.API.Controllers
|
||||||
{
|
{
|
||||||
return await _sqlSugar.Queryable<Role>().Where(x => x.IsDelete == false).ToListAsync();
|
return await _sqlSugar.Queryable<Role>().Where(x => x.IsDelete == false).ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 科目列表下拉框
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("sub-dp-list"), AllowAnonymous]
|
||||||
|
public async Task<List<SubjectInfo>> GetSubjectDropDownList()
|
||||||
|
{
|
||||||
|
var list = new List<SubjectInfo>();
|
||||||
|
foreach (SubjectType subject in Enum.GetValues(typeof(SubjectType)))
|
||||||
|
{
|
||||||
|
var description = GetEnumDescription(subject);
|
||||||
|
list.Add(new SubjectInfo { Value = (int)subject, Name = description });
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
[NonAction]
|
||||||
|
private string GetEnumDescription(Enum value)
|
||||||
|
{
|
||||||
|
FieldInfo fi = value.GetType().GetField(value.ToString());
|
||||||
|
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
|
||||||
|
|
||||||
|
if (attributes != null && attributes.Length > 0)
|
||||||
|
return attributes[0].Description;
|
||||||
|
else
|
||||||
|
return value.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取小程序openid
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("mini-openid"), AllowAnonymous]
|
||||||
|
public async Task<string> GetOpenId(string js_code)
|
||||||
|
{
|
||||||
|
var queryString = $@"appid={_configuration["miniProgram:appId"]}&secret={_configuration["miniProgram:appSecret"]}&js_code={js_code}&grant_type=authorization_code";
|
||||||
|
|
||||||
|
var httpclient = _httpClientFactory.CreateClient();
|
||||||
|
var result = await httpclient.GetFromJsonAsync<JsCode2SessionApiResult>($@"https://api.weixin.qq.com/sns/jscode2session?{queryString}");
|
||||||
|
if (result == null || result.errorcode != 0 || string.IsNullOrWhiteSpace(result.openid))
|
||||||
|
{
|
||||||
|
_logger.LogError($"获取openid失败,错误码:{result?.errorcode},错误信息:{result?.errmsg}");
|
||||||
|
|
||||||
|
throw Oops.Oh("小程序登录失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.openid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Reflection;
|
||||||
|
using WGShare.Domain.DTOs.User;
|
||||||
|
using WGShare.Domain.Enums;
|
||||||
|
|
||||||
namespace WGShare.API.Helpers
|
namespace WGShare.API.Helpers
|
||||||
{
|
{
|
||||||
|
|
@ -10,5 +13,38 @@ namespace WGShare.API.Helpers
|
||||||
var customAttribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute));
|
var customAttribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute));
|
||||||
return customAttribute == null ? val.ToString() : ((DescriptionAttribute)customAttribute).Description;
|
return customAttribute == null ? val.ToString() : ((DescriptionAttribute)customAttribute).Description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据描述获取枚举
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="description"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="ArgumentException"></exception>
|
||||||
|
public static T GetEnumValueFromDescription<T>(this string description) where T : Enum
|
||||||
|
{
|
||||||
|
description = description.Trim();
|
||||||
|
foreach (var field in typeof(T).GetFields())
|
||||||
|
{
|
||||||
|
if (Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) is DescriptionAttribute attribute)
|
||||||
|
{
|
||||||
|
if (attribute.Description == description)
|
||||||
|
{
|
||||||
|
return (T)field.GetValue(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (field.Name == description)
|
||||||
|
{
|
||||||
|
return (T)field.GetValue(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ArgumentException($"No matching enum value found for description: {description}", nameof(description));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
using WGShare.Domain.Constant;
|
||||||
|
using WGShare.Domain.DTOs.MiniProgram;
|
||||||
|
using WGShare.Domain.FriendlyException;
|
||||||
|
|
||||||
|
namespace WGShare.API.Helpers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 小程序帮助类
|
||||||
|
/// </summary>
|
||||||
|
public class MiniProgramHelper
|
||||||
|
{
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
|
||||||
|
public MiniProgramHelper(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
this._configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取access_token
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<string> GetAccessToken()
|
||||||
|
{
|
||||||
|
var accessToken = RedisHelper.Instance.Get<string>(RedisKeyConstant.WxMiniProgram.AccessTokenKey);
|
||||||
|
if (!string.IsNullOrWhiteSpace(accessToken) )
|
||||||
|
{
|
||||||
|
return accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
var appId = _configuration["miniProgram:appId"];
|
||||||
|
var secret = _configuration["miniProgram:appSecret"];
|
||||||
|
|
||||||
|
using var httpClient = new HttpClient();
|
||||||
|
|
||||||
|
var result = await httpClient.GetAsync($@"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appId}&secret={secret}");
|
||||||
|
if (result == null || !result.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
Console.WriteLine($@"微信服务器授权失败,{result.StatusCode},{await result.Content.ReadAsStringAsync()}");
|
||||||
|
throw Oops.Oh("微信服务器授权失败");
|
||||||
|
}
|
||||||
|
var apiResult = await result.Content.ReadFromJsonAsync<AccessTokenApiResult>();
|
||||||
|
if (apiResult == null)
|
||||||
|
{
|
||||||
|
Console.WriteLine($@"微信服务器授权失败,接口返回数据解析失败");
|
||||||
|
throw Oops.Oh("微信服务器授权失败");
|
||||||
|
}
|
||||||
|
if (apiResult.errorcode != 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine($@"微信服务器授权失败,errorCode:{apiResult.errorcode},errmsg:{apiResult.errmsg}");
|
||||||
|
throw Oops.Oh("微信服务器授权失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
RedisHelper.Instance.Set(RedisKeyConstant.WxMiniProgram.AccessTokenKey, apiResult.access_token, TimeSpan.FromSeconds(apiResult.expires_in - 60));
|
||||||
|
return apiResult.access_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
using SixLabors.ImageSharp;
|
||||||
|
using SixLabors.ImageSharp.Formats.Jpeg;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
|
||||||
|
namespace WGShare.API.Helpers
|
||||||
|
{
|
||||||
|
public class QrCodeOptimizerHelper
|
||||||
|
{
|
||||||
|
public static string CompressImage(string base64String, int quality)
|
||||||
|
{
|
||||||
|
// 将 Base64 字符串转换为字节数组
|
||||||
|
byte[] imageBytes = Convert.FromBase64String(base64String);
|
||||||
|
|
||||||
|
// 使用 ImageSharp 加载图像
|
||||||
|
using (Image image = Image.Load(imageBytes))
|
||||||
|
{
|
||||||
|
// 设置压缩参数
|
||||||
|
JpegEncoder jpegEncoder = new JpegEncoder
|
||||||
|
{
|
||||||
|
Quality = quality
|
||||||
|
};
|
||||||
|
|
||||||
|
// 创建一个新的内存流来保存压缩后的图像
|
||||||
|
using (MemoryStream compressedMs = new MemoryStream())
|
||||||
|
{
|
||||||
|
image.Save(compressedMs, jpegEncoder);
|
||||||
|
|
||||||
|
// 将压缩后的图像转换回 Base64 字符串
|
||||||
|
byte[] compressedImageBytes = compressedMs.ToArray();
|
||||||
|
return Convert.ToBase64String(compressedImageBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using WGShare.Domain.DTOs.User;
|
using SignalRSwaggerGen.Attributes;
|
||||||
|
using WGShare.Domain.DTOs.Room;
|
||||||
|
using WGShare.Domain.DTOs.User;
|
||||||
using WGShare.Domain.Entities;
|
using WGShare.Domain.Entities;
|
||||||
|
|
||||||
namespace WGShare.API.Hubs
|
namespace WGShare.API.Hubs
|
||||||
|
|
@ -6,6 +8,7 @@ namespace WGShare.API.Hubs
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 客户端消息
|
/// 客户端消息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[SignalRHub]
|
||||||
public interface IMessageClient
|
public interface IMessageClient
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -44,7 +47,7 @@ namespace WGShare.API.Hubs
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="type"></param>
|
/// <param name="type"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task Operation(int type);
|
Task Operation(string contentString);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更新视图
|
/// 更新视图
|
||||||
|
|
@ -58,6 +61,12 @@ namespace WGShare.API.Hubs
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task ShowUser(string uid, string uname, string operUid, string operUserName);
|
Task ShowUser(string uid, string uname, string operUid, string operUserName);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 共享人取消共享屏幕
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task StopedSharedScreen(string ScreenShareId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用户加入频道回调
|
/// 用户加入频道回调
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -144,5 +153,37 @@ namespace WGShare.API.Hubs
|
||||||
/// <param name="driversJsonString"></param>
|
/// <param name="driversJsonString"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task ShowDriverList(string driversJsonString);
|
Task ShowDriverList(string driversJsonString);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改昵称
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="UId"></param>
|
||||||
|
/// <param name="NickName"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task ModifyNickName(long UId, string NickName);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 退出共享屏幕
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task ExitSharedScreen();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加入频道回调
|
||||||
|
/// </summary>
|
||||||
|
Task JoinChannelCallback(bool isSuccess);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送设置发言人指令
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task SetSpeaker(RoomManagerInputDTO inputDTO);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 客户端接收到消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="contentString"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task ReceivedOperation(string contentString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,22 @@
|
||||||
using Masuit.Tools.DateTimeExt;
|
using Masuit.Tools.DateTimeExt;
|
||||||
using Masuit.Tools.Maths;
|
using Masuit.Tools.Maths;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Components.Forms;
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
|
using SqlSugar.Extensions;
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using WGShare.API.Helpers;
|
using WGShare.API.Helpers;
|
||||||
using WGShare.Domain.Constant;
|
using WGShare.Domain.Constant;
|
||||||
|
using WGShare.Domain.DTOs.Room;
|
||||||
using WGShare.Domain.Entities;
|
using WGShare.Domain.Entities;
|
||||||
using WGShare.Domain.Enums;
|
using WGShare.Domain.Enums;
|
||||||
|
using WGShare.Domain.FriendlyException;
|
||||||
using ZstdSharp.Unsafe;
|
using ZstdSharp.Unsafe;
|
||||||
|
|
||||||
namespace WGShare.API.Hubs
|
namespace WGShare.API.Hubs
|
||||||
|
|
@ -29,13 +35,22 @@ namespace WGShare.API.Hubs
|
||||||
public async override Task OnConnectedAsync()
|
public async override Task OnConnectedAsync()
|
||||||
{
|
{
|
||||||
var tenant = Context.User?.Claims.FirstOrDefault(x => x.Type == "tenant")?.Value;
|
var tenant = Context.User?.Claims.FirstOrDefault(x => x.Type == "tenant")?.Value;
|
||||||
var uid = Context.User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier)?.Value;
|
var uid = Context.User?.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier)?.Value;
|
||||||
var account = Context.User?.Claims.FirstOrDefault(x => x.Type == "account")?.Value;
|
var account = Context.User?.Claims.FirstOrDefault(x => x.Type == "account")?.Value;
|
||||||
var ssid = Context.User?.Claims.FirstOrDefault(x => x.Type == "ssid")?.Value;
|
var ssid = Context.User?.Claims.FirstOrDefault(x => x.Type == "ssid")?.Value;
|
||||||
|
var uname = Context.User?.Claims.FirstOrDefault(x => x.Type == "uname")?.Value;
|
||||||
|
var roleId = Context.User?.Claims.FirstOrDefault(x => x.Type == "roleid")?.Value;
|
||||||
|
|
||||||
Console.WriteLine($"{DateTime.Now}连接成功 当前租户:{tenant} account:{account} uid:{uid} connectId:{Context.ConnectionId}");
|
Context.Items.Add("tenant", tenant);
|
||||||
|
Context.Items.Add("uid", uid);
|
||||||
|
Context.Items.Add("account", account);
|
||||||
|
Context.Items.Add("ssid", ssid);
|
||||||
|
Context.Items.Add("uname", uname);
|
||||||
|
Context.Items.Add("roleid", roleId);
|
||||||
|
|
||||||
await ClearUserChannel(uid, tenant, account, ssid, false);
|
_logger.LogInformation($"{DateTime.Now}连接成功 当前租户:{tenant} account:{account} uid:{uid} connectId:{Context.ConnectionId}");
|
||||||
|
|
||||||
|
//await ClearUserChannel(uid, tenant, account, ssid, false);
|
||||||
// 存储在线信息
|
// 存储在线信息
|
||||||
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetOnlineUserKey(tenant), uid, Context.ConnectionId);
|
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetOnlineUserKey(tenant), uid, Context.ConnectionId);
|
||||||
}
|
}
|
||||||
|
|
@ -48,11 +63,11 @@ namespace WGShare.API.Hubs
|
||||||
var ssid = Context.User?.Claims.FirstOrDefault(x => x.Type == "ssid")?.Value;
|
var ssid = Context.User?.Claims.FirstOrDefault(x => x.Type == "ssid")?.Value;
|
||||||
|
|
||||||
|
|
||||||
Console.WriteLine($"{DateTime.Now}断开连接 当前租户:{tenant} account:{account} uid:{uid} connectId:{Context.ConnectionId} exception:{exception?.Message} ");
|
_logger.LogInformation($"{DateTime.Now}断开连接 当前租户:{tenant} account:{account} uid:{uid} connectId:{Context.ConnectionId} exception:{exception?.Message} ");
|
||||||
|
|
||||||
if (Context.ConnectionId == RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetOnlineUserKey(tenant), uid))
|
if (Context.ConnectionId == RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetOnlineUserKey(tenant), uid))
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{DateTime.Now}断开连接 未重连,开始删除用户频道信息");
|
_logger.LogInformation($"{DateTime.Now}断开连接 未重连,开始删除用户频道信息");
|
||||||
// 断开后未重连则清退频道
|
// 断开后未重连则清退频道
|
||||||
await ClearUserChannel(uid, tenant, account, ssid, true);
|
await ClearUserChannel(uid, tenant, account, ssid, true);
|
||||||
|
|
||||||
|
|
@ -62,17 +77,14 @@ namespace WGShare.API.Hubs
|
||||||
|
|
||||||
private async Task ClearUserChannel(string uid, string tenant, string account, string ssid, bool isclose)
|
private async Task ClearUserChannel(string uid, string tenant, string account, string ssid, bool isclose)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{DateTime.Now} 执行删除开始");
|
_logger.LogInformation($"{DateTime.Now} 执行删除开始");
|
||||||
// 获取用户参加得频道
|
// 获取用户参加得频道
|
||||||
var roomNum = RedisHelper.Instance.Get(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(uid));
|
var roomNum = RedisHelper.Instance.Get(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(uid));
|
||||||
using (var pipe = RedisHelper.Instance.StartPipe())
|
using (var pipe = RedisHelper.Instance.StartPipe())
|
||||||
{
|
{
|
||||||
Console.WriteLine($@"{DateTime.Now} account:{account} 退出以下频道:{string.Join(',', roomNum)}");
|
_logger.LogInformation($@"{DateTime.Now} account:{account} 退出以下频道:{string.Join(',', roomNum)}");
|
||||||
if (!string.IsNullOrEmpty(roomNum))
|
if (!string.IsNullOrEmpty(roomNum))
|
||||||
{
|
{
|
||||||
// 所有房间移除该用户
|
|
||||||
pipe.HDel(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum), uid);
|
|
||||||
|
|
||||||
// 判断是否全员看他,是则移除
|
// 判断是否全员看他,是则移除
|
||||||
var script = $@"local value = redis.call('HGET', KEYS[1], ARGV[1])
|
var script = $@"local value = redis.call('HGET', KEYS[1], ARGV[1])
|
||||||
if value == ARGV[2] or value == ARGV[3] then
|
if value == ARGV[2] or value == ARGV[3] then
|
||||||
|
|
@ -80,6 +92,9 @@ namespace WGShare.API.Hubs
|
||||||
else return -1 end";
|
else return -1 end";
|
||||||
// 执行 eval 命令
|
// 执行 eval 命令
|
||||||
pipe.Eval(script, [RedisKeyConstant.SessionManage.GetChannelShowUserKey(tenant)], roomNum, uid, ssid);
|
pipe.Eval(script, [RedisKeyConstant.SessionManage.GetChannelShowUserKey(tenant)], roomNum, uid, ssid);
|
||||||
|
|
||||||
|
// 房间移除该用户
|
||||||
|
pipe.HDel(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum), uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除用户在线状态
|
// 删除用户在线状态
|
||||||
|
|
@ -88,14 +103,31 @@ namespace WGShare.API.Hubs
|
||||||
// 删除用户已加入频道信息
|
// 删除用户已加入频道信息
|
||||||
pipe.Del(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(uid));
|
pipe.Del(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(uid));
|
||||||
|
|
||||||
pipe.EndPipe();
|
var result = pipe.EndPipe();
|
||||||
|
|
||||||
|
if (!result.IsNullOrEmpty() && result[0].ObjToInt() != -1)
|
||||||
|
{
|
||||||
|
// 如果离开的是全员看ta,则重新设置管理员为全员看ta
|
||||||
|
var users = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum));
|
||||||
|
var showUsers = users.Where(x => x.RoleId == ((int)RoleEnums.Admin).ToString() || x.IsRoomManager || x.RoleId == ((int)RoleEnums.RoomManager).ToString()).ToList();
|
||||||
|
if (!showUsers.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
var showUser = showUsers.FirstOrDefault(x => x.EnableCamera == true);
|
||||||
|
if (showUser == null)
|
||||||
|
{
|
||||||
|
showUser = showUsers.FirstOrDefault();
|
||||||
|
}
|
||||||
|
// 通知全员看ta
|
||||||
|
await Clients.Group(roomNum).ShowUser(showUser.UID, showUser.UserName, string.Empty, string.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(roomNum))
|
if (!string.IsNullOrEmpty(roomNum))
|
||||||
// 通知房间其他用户,该用户退出
|
// 通知房间其他用户,该用户退出
|
||||||
await Clients.Group(roomNum).UserLeave(uid);
|
await Clients.Group(roomNum).UserLeave(uid);
|
||||||
|
|
||||||
Console.WriteLine($"{DateTime.Now} 执行删除完成");
|
_logger.LogInformation($"{DateTime.Now} 执行删除完成");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -104,8 +136,8 @@ namespace WGShare.API.Hubs
|
||||||
/// <param name="roomNum"></param>
|
/// <param name="roomNum"></param>
|
||||||
/// <param name="enableMicr">是否关闭麦克风,默认是</param>
|
/// <param name="enableMicr">是否关闭麦克风,默认是</param>
|
||||||
/// <param name="enableCamera">是否关闭摄像头,默认是</param>
|
/// <param name="enableCamera">是否关闭摄像头,默认是</param>
|
||||||
[HubMethodName("joinChannel"), Obsolete("废弃,请使用Api接口 JoinChannel")]
|
[HubMethodName("joinChannel")]
|
||||||
public async Task JoinChannel(string roomNum, bool enableMicr = true, bool enableCamera = true)
|
public async Task JoinChannel(string roomNum, bool enableMicr = false, bool enableCamera = false, bool isRoomManager = false)
|
||||||
{
|
{
|
||||||
var tenant = Context.User?.Claims.FirstOrDefault(x => x.Type == "tenant")?.Value;
|
var tenant = Context.User?.Claims.FirstOrDefault(x => x.Type == "tenant")?.Value;
|
||||||
var uid = Context.User?.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier)?.Value;
|
var uid = Context.User?.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier)?.Value;
|
||||||
|
|
@ -113,18 +145,74 @@ namespace WGShare.API.Hubs
|
||||||
var ssid = Context.User?.Claims.FirstOrDefault(x => x.Type == "ssid")?.Value;
|
var ssid = Context.User?.Claims.FirstOrDefault(x => x.Type == "ssid")?.Value;
|
||||||
var uname = Context.User?.Claims.FirstOrDefault(x => x.Type == "uname")?.Value;
|
var uname = Context.User?.Claims.FirstOrDefault(x => x.Type == "uname")?.Value;
|
||||||
var roleId = Context.User?.Claims.FirstOrDefault(x => x.Type == "roleid")?.Value;
|
var roleId = Context.User?.Claims.FirstOrDefault(x => x.Type == "roleid")?.Value;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_logger.LogInformation($"{DateTime.Now}加入频道 会议号:" + roomNum);
|
||||||
|
_logger.LogInformation($"{DateTime.Now}加入频道 account:" + account);
|
||||||
|
_logger.LogInformation($"{DateTime.Now}加入频道 tenant:" + tenant);
|
||||||
|
|
||||||
|
var userInfo = new ChannelUserInfo
|
||||||
|
{
|
||||||
|
UID = uid,
|
||||||
|
UserName = uname,
|
||||||
|
EnableCamera = enableCamera,
|
||||||
|
EnableMicr = enableMicr,
|
||||||
|
ConnectId = Context.ConnectionId,
|
||||||
|
Account = account,
|
||||||
|
ScreenShareId = ssid,
|
||||||
|
RoleId = roleId,
|
||||||
|
RoleName = ((RoleEnums)roleId.ToInt32()).GetDescription(),
|
||||||
|
IsRoomManager = isRoomManager
|
||||||
|
};
|
||||||
|
using (var pipe = RedisHelper.Instance.StartPipe())
|
||||||
|
{
|
||||||
|
|
||||||
Console.WriteLine($"{DateTime.Now}加入频道 会议号:" + roomNum);
|
if (((RoleEnums)roleId.ToInt32()) == RoleEnums.Admin || ((RoleEnums)roleId.ToInt32()) == RoleEnums.RoomManager)
|
||||||
Console.WriteLine($"{DateTime.Now}加入频道 account:" + account);
|
{
|
||||||
Console.WriteLine($"{DateTime.Now}加入频道 tenant:" + tenant);
|
// 管理员进房,如果没有全员看ta,则设置
|
||||||
|
var script = @"local hashKey = KEYS[1]
|
||||||
|
local field = ARGV[1]
|
||||||
|
local value = ARGV[2]
|
||||||
|
|
||||||
|
if redis.call('HEXISTS', hashKey, field) == 0 then
|
||||||
|
redis.call('HSET', hashKey, field, value)
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end";
|
||||||
|
pipe.Eval(script, [RedisKeyConstant.SessionManage.GetChannelShowUserKey(tenant)], roomNum, uid);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 记录频道得用户信息
|
||||||
|
pipe.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum), uid, userInfo);
|
||||||
|
// 记录用户已参与频道
|
||||||
|
pipe.Set(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(uid), roomNum);
|
||||||
|
var results = pipe.EndPipe();
|
||||||
|
|
||||||
|
// 判断,如果有全员看ta,则通知
|
||||||
|
if ((((RoleEnums)roleId.ToInt32()) == RoleEnums.Admin || ((RoleEnums)roleId.ToInt32()) == RoleEnums.RoomManager) && !results.IsNullOrEmpty() && results[0].ObjToInt() == 1)
|
||||||
|
await Clients.Group(roomNum).ShowUser(uid, uname, string.Empty, string.Empty);
|
||||||
|
}
|
||||||
|
await Groups.AddToGroupAsync(Context.ConnectionId, roomNum);
|
||||||
|
await Clients.GroupExcept(roomNum, Context.ConnectionId).UserJoined(userInfo);
|
||||||
|
|
||||||
|
await Clients.Caller.JoinChannelCallback(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
|
||||||
|
await Clients.Caller.JoinChannelCallback(false);
|
||||||
|
_logger.LogError(ex, $@"加入频道异常,tenant:{tenant},uid:{uid},ssid:{ssid},uname:{uname} {Environment.NewLine}{ex.Message}");
|
||||||
|
await ExceptionNotice.SendAsync(ex, $@"加入频道异常,tenant:{tenant},uid:{uid},ssid:{ssid},uname:{uname} ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 离开频道
|
/// 离开频道
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="roomNum"></param>
|
/// <param name="roomNum"></param>
|
||||||
[HubMethodName("levelChannel"), Obsolete("废弃,请使用Api接口 LevelChannel")]
|
[HubMethodName("levelChannel")]
|
||||||
public async Task LevelChannel(string roomNum)
|
public async Task LevelChannel(string roomNum)
|
||||||
{
|
{
|
||||||
var tenant = Context.User?.Claims.FirstOrDefault(x => x.Type == "tenant")?.Value;
|
var tenant = Context.User?.Claims.FirstOrDefault(x => x.Type == "tenant")?.Value;
|
||||||
|
|
@ -135,9 +223,45 @@ namespace WGShare.API.Hubs
|
||||||
var roleId = Context.User?.Claims.FirstOrDefault(x => x.Type == "roleid")?.Value;
|
var roleId = Context.User?.Claims.FirstOrDefault(x => x.Type == "roleid")?.Value;
|
||||||
|
|
||||||
|
|
||||||
Console.WriteLine($" {DateTime.Now}离开频道 会议号:" + roomNum);
|
_logger.LogInformation($" {DateTime.Now}离开频道 会议号:" + roomNum);
|
||||||
Console.WriteLine($" {DateTime.Now}离开频道 account:" + account);
|
_logger.LogInformation($" {DateTime.Now}离开频道 account:" + account);
|
||||||
Console.WriteLine($" {DateTime.Now}离开频道 tenant:" + tenant);
|
_logger.LogInformation($" {DateTime.Now}离开频道 tenant:" + tenant);
|
||||||
|
|
||||||
|
using (var pipe = RedisHelper.Instance.StartPipe())
|
||||||
|
{
|
||||||
|
// 判断,如果有全员看ta,则删除
|
||||||
|
var script = $@"local value = redis.call('HGET', KEYS[1], ARGV[1])
|
||||||
|
if value == ARGV[2] or value == ARGV[3] then
|
||||||
|
return redis.call('HDEL', KEYS[1], ARGV[1])
|
||||||
|
else return -1 end";
|
||||||
|
// 执行 eval 命令
|
||||||
|
pipe.Eval(script, [RedisKeyConstant.SessionManage.GetChannelShowUserKey(tenant)], roomNum, uid, ssid);
|
||||||
|
// 删除频道中得该用户
|
||||||
|
pipe.HDel(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum), uid);
|
||||||
|
// 删除用户已参与频道
|
||||||
|
pipe.Del(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(uid));
|
||||||
|
var result = pipe.EndPipe();
|
||||||
|
if (!result.IsNullOrEmpty() && result[0].ObjToInt() != -1)
|
||||||
|
{
|
||||||
|
// 如果离开的是全员看ta,则重新设置管理员为全员看ta
|
||||||
|
var users = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, roomNum));
|
||||||
|
var showUsers = users.Where(x => x.RoleId == ((int)RoleEnums.Admin).ToString() || x.IsRoomManager || x.RoleId == ((int)RoleEnums.RoomManager).ToString()).ToList();
|
||||||
|
if (!showUsers.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
var showUser = showUsers.FirstOrDefault(x => x.EnableCamera == true);
|
||||||
|
if (showUser == null)
|
||||||
|
{
|
||||||
|
showUser = showUsers.FirstOrDefault();
|
||||||
|
}
|
||||||
|
// 通知全员看ta
|
||||||
|
await Clients.Group(roomNum).ShowUser(showUser.UID, showUser.UserName, string.Empty, string.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Clients.GroupExcept(roomNum, Context.ConnectionId).UserLeave(uid);
|
||||||
|
await Groups.RemoveFromGroupAsync(Context.ConnectionId, roomNum);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -150,12 +274,18 @@ namespace WGShare.API.Hubs
|
||||||
{
|
{
|
||||||
var uname = Context.User?.Claims.FirstOrDefault(x => x.Type == "uname")?.Value;
|
var uname = Context.User?.Claims.FirstOrDefault(x => x.Type == "uname")?.Value;
|
||||||
var uid = Context.User?.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier)?.Value;
|
var uid = Context.User?.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier)?.Value;
|
||||||
|
var tenant = Context.Items["tenant"].ToString();
|
||||||
|
|
||||||
Console.WriteLine($" {DateTime.Now}发送消息 uname:" + uname);
|
_logger.LogInformation($" {DateTime.Now} 发送消息 uname:{uname} roomNum:{rooNum} msg:{msg}");
|
||||||
Console.WriteLine($" {DateTime.Now}发送消息 roomNum:" + rooNum);
|
|
||||||
Console.WriteLine($" {DateTime.Now}发送消息 msg:" + msg);
|
|
||||||
|
|
||||||
await Clients.OthersInGroup(rooNum).ReceiveMessage(uid, uname, msg, DateTime.Now.GetTotalMilliseconds()); //await Clients.GroupExcept(rooNum, Context.ConnectionId).ReceiveMessage(uid, uname, msg);
|
var userInfo = RedisHelper.Instance.HGet<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(tenant, rooNum), uid);
|
||||||
|
var userName = uname;
|
||||||
|
if (userInfo != null)
|
||||||
|
{
|
||||||
|
userName = userInfo.UserName;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Clients.OthersInGroup(rooNum).ReceiveMessage(uid, userName, msg, DateTime.Now.GetTotalMilliseconds()); //await Clients.GroupExcept(rooNum, Context.ConnectionId).ReceiveMessage(uid, uname, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -163,9 +293,21 @@ namespace WGShare.API.Hubs
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HubMethodName("sendOper")]
|
[HubMethodName("sendOper")]
|
||||||
public async Task SendOperation(string roomNum, int type)
|
public async Task SendOperation(string roomNum, string contentString)
|
||||||
{
|
{
|
||||||
await Clients.Group(roomNum).Operation(type);
|
await Clients.Group(roomNum).Operation(contentString);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送客户端指令到指定用户
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uid"></param>
|
||||||
|
/// <param name="contentString"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HubMethodName("sendOper2User")]
|
||||||
|
public async Task SendOperationToUser(string uid, string contentString)
|
||||||
|
{
|
||||||
|
await Clients.User(uid).ReceivedOperation(contentString);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -203,5 +345,32 @@ namespace WGShare.API.Hubs
|
||||||
{
|
{
|
||||||
await Clients.User(uid).SaveDriver(driversJsonString);
|
await Clients.User(uid).SaveDriver(driversJsonString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发言人设置成功回调
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inputDTO"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HubMethodName("setSpeakerCallback")]
|
||||||
|
public async Task SetSpeakerCallback(RoomManagerInputDTO inputDTO)
|
||||||
|
{
|
||||||
|
var tenantId = Context.Items["tenant"].ToString();
|
||||||
|
|
||||||
|
var users = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(tenantId, inputDTO.RoomNum));
|
||||||
|
//if (users.Count(x => x.IsRoomManager || x.RoleId == ((int)RoleEnums.Admin).ToString() || x.RoleId == ((int)RoleEnums.RoomManager).ToString()) >= 20)
|
||||||
|
//{
|
||||||
|
// throw Oops.Oh("房间已达到20个发言人限制。请移除一位发言人");
|
||||||
|
//}
|
||||||
|
var user = users.FirstOrDefault(x => x.UID == inputDTO.UserId);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
throw Oops.Oh("用户已不在房间内!");
|
||||||
|
}
|
||||||
|
user.IsRoomManager = true;
|
||||||
|
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(tenantId, inputDTO.RoomNum), inputDTO.UserId, user);
|
||||||
|
|
||||||
|
await Clients.Group(inputDTO.RoomNum).ManagerRefresh(user, inputDTO.SettingUserId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ namespace WGShare.API
|
||||||
builder.Services.ConfigureHangfire();
|
builder.Services.ConfigureHangfire();
|
||||||
builder.Services.AddSingleton(new JwtHelper(configuration));
|
builder.Services.AddSingleton(new JwtHelper(configuration));
|
||||||
builder.Services.AddSingleton(new AgoraHelper(configuration));
|
builder.Services.AddSingleton(new AgoraHelper(configuration));
|
||||||
|
builder.Services.AddSingleton(new MiniProgramHelper(configuration));
|
||||||
builder.Services.AddSingleton(new OssHelper(configuration));
|
builder.Services.AddSingleton(new OssHelper(configuration));
|
||||||
builder.Services.AddHostedService<AgoraCallbackComsuerService>();
|
builder.Services.AddHostedService<AgoraCallbackComsuerService>();
|
||||||
builder.Services.AddAuth(configuration["Jwt:Issuer"],
|
builder.Services.AddAuth(configuration["Jwt:Issuer"],
|
||||||
|
|
@ -98,7 +99,6 @@ namespace WGShare.API
|
||||||
options.SwaggerEndpoint($"/swagger/frontend/swagger.json", "ǰ¶Ë");
|
options.SwaggerEndpoint($"/swagger/frontend/swagger.json", "ǰ¶Ë");
|
||||||
options.SwaggerEndpoint($"/swagger/backend/swagger.json", "ºó¶Ë");
|
options.SwaggerEndpoint($"/swagger/backend/swagger.json", "ºó¶Ë");
|
||||||
options.SwaggerEndpoint($"/swagger/public/swagger.json", "¹«¹²½Ó¿Ú");
|
options.SwaggerEndpoint($"/swagger/public/swagger.json", "¹«¹²½Ó¿Ú");
|
||||||
|
|
||||||
});
|
});
|
||||||
app.UseCustomCors();
|
app.UseCustomCors();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ namespace WGShare.API.ServiceConfigs
|
||||||
{
|
{
|
||||||
services.AddSwaggerGen(w =>
|
services.AddSwaggerGen(w =>
|
||||||
{
|
{
|
||||||
|
w.AddSignalRSwaggerGen();
|
||||||
w.SwaggerDoc("frontend", new OpenApiInfo { Title = "前端", Version = "frontend" });
|
w.SwaggerDoc("frontend", new OpenApiInfo { Title = "前端", Version = "frontend" });
|
||||||
w.SwaggerDoc("backend", new OpenApiInfo { Title = "后端", Version = "backend" });
|
w.SwaggerDoc("backend", new OpenApiInfo { Title = "后端", Version = "backend" });
|
||||||
w.SwaggerDoc("public", new OpenApiInfo { Title = "公共接口", Version = "public" });
|
w.SwaggerDoc("public", new OpenApiInfo { Title = "公共接口", Version = "public" });
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.14" />
|
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.14" />
|
||||||
<PackageReference Include="Hangfire.Core" Version="1.8.14" />
|
<PackageReference Include="Hangfire.Core" Version="1.8.14" />
|
||||||
<PackageReference Include="Hangfire.MemoryStorage" Version="1.8.1.1" />
|
<PackageReference Include="Hangfire.MemoryStorage" Version="1.8.1.1" />
|
||||||
|
<PackageReference Include="SignalRSwaggerGen" Version="4.7.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
@ -35,6 +36,9 @@
|
||||||
<None Update="Reference\AgoraIO.dll">
|
<None Update="Reference\AgoraIO.dll">
|
||||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Update="signInListImportTemplate.xlsx">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<None Update="WGShare.API.xml">
|
<None Update="WGShare.API.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,13 @@
|
||||||
<param name="account"></param>
|
<param name="account"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.AuthController.CheckUserOnline(System.String)">
|
||||||
|
<summary>
|
||||||
|
检查用户是否在线
|
||||||
|
</summary>
|
||||||
|
<param name="account"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:WGShare.API.Controllers.AuthController.Login(WGShare.Domain.DTOs.Login.UserLoginDTO)">
|
<member name="M:WGShare.API.Controllers.AuthController.Login(WGShare.Domain.DTOs.Login.UserLoginDTO)">
|
||||||
<summary>
|
<summary>
|
||||||
正常账号登录
|
正常账号登录
|
||||||
|
|
@ -30,6 +37,13 @@
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.AuthController.AnonymousLogin(WGShare.Domain.DTOs.Login.AnonymousUserLoginDTO)">
|
||||||
|
<summary>
|
||||||
|
匿名登录
|
||||||
|
</summary>
|
||||||
|
<param name="loginDTO"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:WGShare.API.Controllers.AuthController.LoginForAdmin(WGShare.Domain.DTOs.Login.UserLoginDTO)">
|
<member name="M:WGShare.API.Controllers.AuthController.LoginForAdmin(WGShare.Domain.DTOs.Login.UserLoginDTO)">
|
||||||
<summary>
|
<summary>
|
||||||
管理员登录
|
管理员登录
|
||||||
|
|
@ -61,12 +75,17 @@
|
||||||
<param name="file"></param>
|
<param name="file"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="P:WGShare.API.Controllers.Basic.BasicController.IsAnonymous">
|
||||||
|
<summary>
|
||||||
|
匿名用户
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="T:WGShare.API.Controllers.Frontend.AgoraCallbackController">
|
<member name="T:WGShare.API.Controllers.Frontend.AgoraCallbackController">
|
||||||
<summary>
|
<summary>
|
||||||
Agora接口
|
Agora接口
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:WGShare.API.Controllers.Frontend.AgoraCallbackController.JoinChannelEvent(System.String)">
|
<member name="M:WGShare.API.Controllers.Frontend.AgoraCallbackController.JoinChannelEvent(System.String,WGShare.Domain.DTOs.AgoraCallback.EventBody)">
|
||||||
<summary>
|
<summary>
|
||||||
加入频道
|
加入频道
|
||||||
</summary>
|
</summary>
|
||||||
|
|
@ -76,6 +95,16 @@
|
||||||
离开频道
|
离开频道
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.Frontend.AgoraCallbackController.CreateChannel(WGShare.Domain.DTOs.AgoraCallback.EventBody)">
|
||||||
|
<summary>
|
||||||
|
创建频道
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.Frontend.AgoraCallbackController.DestroyChannel(WGShare.Domain.DTOs.AgoraCallback.EventBody)">
|
||||||
|
<summary>
|
||||||
|
销毁频道
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="T:WGShare.API.Controllers.Frontend.HomeController">
|
<member name="T:WGShare.API.Controllers.Frontend.HomeController">
|
||||||
<summary>
|
<summary>
|
||||||
首页接口
|
首页接口
|
||||||
|
|
@ -95,6 +124,13 @@
|
||||||
<param name="inputDTO"></param>
|
<param name="inputDTO"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.Frontend.HomeController.ModifyRoom(WGShare.Domain.DTOs.Room.RoomInfoInputDTO)">
|
||||||
|
<summary>
|
||||||
|
更新会议室信息
|
||||||
|
</summary>
|
||||||
|
<param name="inputDTO"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:WGShare.API.Controllers.Frontend.HomeController.DeleteRoom(System.String)">
|
<member name="M:WGShare.API.Controllers.Frontend.HomeController.DeleteRoom(System.String)">
|
||||||
<summary>
|
<summary>
|
||||||
删除会议室
|
删除会议室
|
||||||
|
|
@ -120,6 +156,25 @@
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.Frontend.HomeController.GetMiniProgramQrCode(System.String,System.String)">
|
||||||
|
<summary>
|
||||||
|
获取房间二维码(缓存10mins)
|
||||||
|
</summary>
|
||||||
|
<param name="roomNum"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.Frontend.HomeController.FeedbackScoring(WGShare.Domain.DTOs.Home.FeedBackRequset)">
|
||||||
|
<summary>
|
||||||
|
反馈打分
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.Frontend.HomeController.RecordVersionLog(WGShare.Domain.DTOs.Home.UserVersionLogDto)">
|
||||||
|
<summary>
|
||||||
|
记录用户当前用户版本
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="T:WGShare.API.Controllers.Frontend.RoomController">
|
<member name="T:WGShare.API.Controllers.Frontend.RoomController">
|
||||||
<summary>
|
<summary>
|
||||||
会议室接口
|
会议室接口
|
||||||
|
|
@ -244,6 +299,24 @@
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.Frontend.RoomController.GetSharedScreen(System.String)">
|
||||||
|
<summary>
|
||||||
|
获取共享屏幕
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.Frontend.RoomController.SharedScreen(System.String)">
|
||||||
|
<summary>
|
||||||
|
设置共享屏幕
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.Frontend.RoomController.StopedSharedScreen(System.String)">
|
||||||
|
<summary>
|
||||||
|
共享人取消共享屏幕
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:WGShare.API.Controllers.Frontend.RoomController.AddFile(WGShare.Domain.DTOs.File.ShareFileInputDTO)">
|
<member name="M:WGShare.API.Controllers.Frontend.RoomController.AddFile(WGShare.Domain.DTOs.File.ShareFileInputDTO)">
|
||||||
<summary>
|
<summary>
|
||||||
分享上传文件
|
分享上传文件
|
||||||
|
|
@ -279,6 +352,26 @@
|
||||||
<param name="fileId">文件Id</param>
|
<param name="fileId">文件Id</param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.Frontend.RoomController.GetSignInList">
|
||||||
|
<summary>
|
||||||
|
获取签到列表
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.Frontend.RoomController.SignIn(System.Collections.Generic.List{WGShare.Domain.DTOs.User.UserSignInRecordDto})">
|
||||||
|
<summary>
|
||||||
|
提交签到
|
||||||
|
</summary>
|
||||||
|
<param name="list"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.Frontend.RoomController.ModifyNickName(WGShare.Domain.DTOs.User.UserModifyNickNameDto)">
|
||||||
|
<summary>
|
||||||
|
修改昵称
|
||||||
|
</summary>
|
||||||
|
<param name="dto"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:WGShare.API.Controllers.Frontend.UserController.GetUserList(System.String,System.Nullable{System.Boolean},WGShare.Domain.GeneralModel.PagedBaseDto)">
|
<member name="M:WGShare.API.Controllers.Frontend.UserController.GetUserList(System.String,System.Nullable{System.Boolean},WGShare.Domain.GeneralModel.PagedBaseDto)">
|
||||||
<summary>
|
<summary>
|
||||||
获取用户列表
|
获取用户列表
|
||||||
|
|
@ -301,6 +394,19 @@
|
||||||
<param name="inputDTO"></param>
|
<param name="inputDTO"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.Frontend.UserController.GetUserSignInList(System.String)">
|
||||||
|
<summary>
|
||||||
|
获取用户签到名单列表
|
||||||
|
</summary>
|
||||||
|
<param name="uid"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.Frontend.UserController.ModifySignList(System.String,System.Collections.Generic.List{WGShare.Domain.DTOs.User.UserSignInListDto})">
|
||||||
|
<summary>
|
||||||
|
修改用户签到列表
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:WGShare.API.Controllers.Frontend.UserController.ModifyPassword(WGShare.Domain.DTOs.User.UserChangePwdDTO)">
|
<member name="M:WGShare.API.Controllers.Frontend.UserController.ModifyPassword(WGShare.Domain.DTOs.User.UserChangePwdDTO)">
|
||||||
<summary>
|
<summary>
|
||||||
更改密码
|
更改密码
|
||||||
|
|
@ -308,6 +414,13 @@
|
||||||
<param name="inputDTO"></param>
|
<param name="inputDTO"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.Frontend.UserController.BatchModifyUsers(System.Collections.Generic.List{WGShare.Domain.DTOs.User.UserBatchUpdateDTO})">
|
||||||
|
<summary>
|
||||||
|
批量修改用户信息
|
||||||
|
</summary>
|
||||||
|
<param name="inputDTO"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:WGShare.API.Controllers.Frontend.UserController.Delete(System.String[])">
|
<member name="M:WGShare.API.Controllers.Frontend.UserController.Delete(System.String[])">
|
||||||
<summary>
|
<summary>
|
||||||
删除用户
|
删除用户
|
||||||
|
|
@ -322,6 +435,12 @@
|
||||||
<param name="file"></param>
|
<param name="file"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.Frontend.UserController.GetSignInBinding">
|
||||||
|
<summary>
|
||||||
|
获取签到绑定列表
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="T:WGShare.API.Controllers.PublicController">
|
<member name="T:WGShare.API.Controllers.PublicController">
|
||||||
<summary>
|
<summary>
|
||||||
前后端共用接口
|
前后端共用接口
|
||||||
|
|
@ -333,6 +452,18 @@
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.PublicController.GetSubjectDropDownList">
|
||||||
|
<summary>
|
||||||
|
科目列表下拉框
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:WGShare.API.Controllers.PublicController.GetOpenId(System.String)">
|
||||||
|
<summary>
|
||||||
|
获取小程序openid
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="F:WGShare.API.Helpers.AgoraHelper.Constant.REDIS_CHANNEL_USERCOUNT">
|
<member name="F:WGShare.API.Helpers.AgoraHelper.Constant.REDIS_CHANNEL_USERCOUNT">
|
||||||
<summary>
|
<summary>
|
||||||
Redis 键,hash ,每个频道用户数量
|
Redis 键,hash ,每个频道用户数量
|
||||||
|
|
@ -387,6 +518,26 @@
|
||||||
<param name="jsTimestamp">JavaScript 时间戳(以秒为单位)。</param>
|
<param name="jsTimestamp">JavaScript 时间戳(以秒为单位)。</param>
|
||||||
<returns>对应的本地时间的 DateTime 对象。</returns>
|
<returns>对应的本地时间的 DateTime 对象。</returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:WGShare.API.Helpers.EnumExtensions.GetEnumValueFromDescription``1(System.String)">
|
||||||
|
<summary>
|
||||||
|
根据描述获取枚举
|
||||||
|
</summary>
|
||||||
|
<typeparam name="T"></typeparam>
|
||||||
|
<param name="description"></param>
|
||||||
|
<returns></returns>
|
||||||
|
<exception cref="T:System.ArgumentException"></exception>
|
||||||
|
</member>
|
||||||
|
<member name="T:WGShare.API.Helpers.MiniProgramHelper">
|
||||||
|
<summary>
|
||||||
|
小程序帮助类
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:WGShare.API.Helpers.MiniProgramHelper.GetAccessToken">
|
||||||
|
<summary>
|
||||||
|
获取access_token
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:WGShare.API.Helpers.OssHelper.GetUploadUrl(System.String,System.String,System.UInt32)">
|
<member name="M:WGShare.API.Helpers.OssHelper.GetUploadUrl(System.String,System.String,System.UInt32)">
|
||||||
<summary>
|
<summary>
|
||||||
获取上传url
|
获取上传url
|
||||||
|
|
@ -468,7 +619,7 @@
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:WGShare.API.Hubs.IMessageClient.Operation(System.Int32)">
|
<member name="M:WGShare.API.Hubs.IMessageClient.Operation(System.String)">
|
||||||
<summary>
|
<summary>
|
||||||
客户端操作
|
客户端操作
|
||||||
</summary>
|
</summary>
|
||||||
|
|
@ -487,6 +638,12 @@
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:WGShare.API.Hubs.IMessageClient.StopedSharedScreen(System.String)">
|
||||||
|
<summary>
|
||||||
|
共享人取消共享屏幕
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:WGShare.API.Hubs.IMessageClient.UserJoined(WGShare.Domain.Entities.ChannelUserInfo)">
|
<member name="M:WGShare.API.Hubs.IMessageClient.UserJoined(WGShare.Domain.Entities.ChannelUserInfo)">
|
||||||
<summary>
|
<summary>
|
||||||
用户加入频道回调
|
用户加入频道回调
|
||||||
|
|
@ -574,7 +731,39 @@
|
||||||
<param name="driversJsonString"></param>
|
<param name="driversJsonString"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:WGShare.API.Hubs.SessionManageHub.JoinChannel(System.String,System.Boolean,System.Boolean)">
|
<member name="M:WGShare.API.Hubs.IMessageClient.ModifyNickName(System.Int64,System.String)">
|
||||||
|
<summary>
|
||||||
|
修改昵称
|
||||||
|
</summary>
|
||||||
|
<param name="UId"></param>
|
||||||
|
<param name="NickName"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:WGShare.API.Hubs.IMessageClient.ExitSharedScreen">
|
||||||
|
<summary>
|
||||||
|
退出共享屏幕
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:WGShare.API.Hubs.IMessageClient.JoinChannelCallback(System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
加入频道回调
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:WGShare.API.Hubs.IMessageClient.SetSpeaker(WGShare.Domain.DTOs.Room.RoomManagerInputDTO)">
|
||||||
|
<summary>
|
||||||
|
发送设置发言人指令
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:WGShare.API.Hubs.IMessageClient.ReceivedOperation(System.String)">
|
||||||
|
<summary>
|
||||||
|
客户端接收到消息
|
||||||
|
</summary>
|
||||||
|
<param name="contentString"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:WGShare.API.Hubs.SessionManageHub.JoinChannel(System.String,System.Boolean,System.Boolean,System.Boolean)">
|
||||||
<summary>
|
<summary>
|
||||||
加入频道
|
加入频道
|
||||||
</summary>
|
</summary>
|
||||||
|
|
@ -595,12 +784,20 @@
|
||||||
<param name="rooNum"></param>
|
<param name="rooNum"></param>
|
||||||
<param name="msg"></param>
|
<param name="msg"></param>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:WGShare.API.Hubs.SessionManageHub.SendOperation(System.String,System.Int32)">
|
<member name="M:WGShare.API.Hubs.SessionManageHub.SendOperation(System.String,System.String)">
|
||||||
<summary>
|
<summary>
|
||||||
发送客户端指令
|
发送客户端指令
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:WGShare.API.Hubs.SessionManageHub.SendOperationToUser(System.String,System.String)">
|
||||||
|
<summary>
|
||||||
|
发送客户端指令到指定用户
|
||||||
|
</summary>
|
||||||
|
<param name="uid"></param>
|
||||||
|
<param name="contentString"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:WGShare.API.Hubs.SessionManageHub.GetDriversList(System.String)">
|
<member name="M:WGShare.API.Hubs.SessionManageHub.GetDriversList(System.String)">
|
||||||
<summary>
|
<summary>
|
||||||
获取设备列表
|
获取设备列表
|
||||||
|
|
@ -623,6 +820,13 @@
|
||||||
<param name="driversJsonString"></param>
|
<param name="driversJsonString"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:WGShare.API.Hubs.SessionManageHub.SetSpeakerCallback(WGShare.Domain.DTOs.Room.RoomManagerInputDTO)">
|
||||||
|
<summary>
|
||||||
|
发言人设置成功回调
|
||||||
|
</summary>
|
||||||
|
<param name="inputDTO"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:WGShare.API.Program.ResetRedisKey">
|
<member name="M:WGShare.API.Program.ResetRedisKey">
|
||||||
<summary>
|
<summary>
|
||||||
程序启动前,删除redis中得数据
|
程序启动前,删除redis中得数据
|
||||||
|
|
|
||||||
|
|
@ -36,12 +36,12 @@
|
||||||
"Issuer": "WGshareApi",
|
"Issuer": "WGshareApi",
|
||||||
"Audience": "WGshareClient",
|
"Audience": "WGshareClient",
|
||||||
// 过期 秒
|
// 过期 秒
|
||||||
"Expires": 86400
|
"Expires": 600000
|
||||||
},
|
},
|
||||||
"Agora": {
|
"Agora": {
|
||||||
"appId": "4a4f7be64fa1404ebda74784fe9ac381",
|
"appId": "4a4f7be64fa1404ebda74784fe9ac381",
|
||||||
"appSecret": "255e05d96c794251b282a0de84242355",
|
"appSecret": "255e05d96c794251b282a0de84242355",
|
||||||
"tokenExpireTimeInSecond": 7200,
|
"tokenExpireTimeInSecond": 86400,
|
||||||
"apiPrefix": "https://api.sd-rtn.com/",
|
"apiPrefix": "https://api.sd-rtn.com/",
|
||||||
"clientId": "80cdc24f7dfa4497a37d98da95a3c4a4",
|
"clientId": "80cdc24f7dfa4497a37d98da95a3c4a4",
|
||||||
"clientSecret": "8323581d4d464114b1f324b26cc62e09",
|
"clientSecret": "8323581d4d464114b1f324b26cc62e09",
|
||||||
|
|
|
||||||
|
|
@ -10,33 +10,37 @@
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"Jwt": {
|
"Jwt": {
|
||||||
"SecretKey": "apDbztyqjSNuvWnezhbdUxduhDidZbF897t2uTJs53RMdY9Cai7eexavBhka3HN6mcTe9oohjFg6bNffRRkcfMqnVKNBnmyPzkRgNopHGJAL7KMwkeZdZ7BaWnT57jCi",
|
"SecretKey": "apDbztyqjSNuvWnezhbdUxduhDidZbF897t2uTJs53RMdY9Cai7eexavBhka3HN6mcTe9oohjFg6bNffRRkcfMqnVKNBnmyPzkRgNopHGJAL7KMwkeZdZ7BaWnT57jCi11",
|
||||||
"Issuer": "WGshareApi",
|
"Issuer": "WGshareApi",
|
||||||
"Audience": "WGshareClient",
|
"Audience": "WGshareClient",
|
||||||
// 过期 秒
|
// 过期 秒 360 天
|
||||||
"Expires": 86400
|
"Expires": 31104000
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"metting": "Database=metting;Server=rds-proxy-internal.rwlb.cn-chengdu.rds.aliyuncs.com;Port=3306;Uid=marking;Pwd=poiuytPOIUYT098765)(*&^%;AllowZeroDateTime=True;ConvertZeroDateTime=True;",
|
"metting": "Database=metting;Server=rds-external.23544.com;Port=3306;Uid=marking;Pwd=poiuytPOIUYT098765)(*&^%;AllowZeroDateTime=True;ConvertZeroDateTime=True;",
|
||||||
"usercenter": "Database=usercenter;Server=rds-proxy-internal.rwlb.cn-chengdu.rds.aliyuncs.com;Port=3306;Uid=marking;Pwd=poiuytPOIUYT098765)(*&^%;AllowZeroDateTime=True;ConvertZeroDateTime=True;"
|
"usercenter": "Database=usercenter;Server=rds-external.23544.com;Port=3306;Uid=marking;Pwd=poiuytPOIUYT098765)(*&^%;AllowZeroDateTime=True;ConvertZeroDateTime=True;"
|
||||||
},
|
},
|
||||||
"Redis": {
|
"Redis": {
|
||||||
"master": "172.29.33.83:16379,password=poiuyt)(*&^%,defaultDatabase=6,prefix=wgshare:"
|
"master": "redis-internal.23544.com:16379,password=poiuyt)(*&^%,defaultDatabase=6,prefix=wgshare:"
|
||||||
},
|
},
|
||||||
"Agora": {
|
"Agora": {
|
||||||
"appId": "dcfc466a6ecb4a1f972630065dfb1e75",
|
"appId": "dcfc466a6ecb4a1f972630065dfb1e75",
|
||||||
"appSecret": "fc77000e329b4be7a0e26fa789e20d00",
|
"appSecret": "fc77000e329b4be7a0e26fa789e20d00",
|
||||||
"tokenExpireTimeInSecond": 7200,
|
"tokenExpireTimeInSecond": 72000,
|
||||||
"apiPrefix": "https://api.sd-rtn.com/",
|
"apiPrefix": "https://api.sd-rtn.com/",
|
||||||
"clientId": "80cdc24f7dfa4497a37d98da95a3c4a4",
|
"clientId": "80cdc24f7dfa4497a37d98da95a3c4a4",
|
||||||
"clientSecret": "8323581d4d464114b1f324b26cc62e09"
|
"clientSecret": "8323581d4d464114b1f324b26cc62e09",
|
||||||
|
"eventSecret": "dgi7oUiuT"
|
||||||
},
|
},
|
||||||
"OSS": {
|
"OSS": {
|
||||||
"AccessKeyID": "LTAI5tQYVQHkkXxXTmjwiSDv",
|
"AccessKeyID": "LTAI5tQYVQHkkXxXTmjwiSDv",
|
||||||
"AccessKeySecret": "FKFNYRdS53FwA5ME2wM1585qX5eVEd",
|
"AccessKeySecret": "FKFNYRdS53FwA5ME2wM1585qX5eVEd",
|
||||||
"Endpoint": "oss-cn-chengdu.aliyuncs.com",
|
"Endpoint": "oss-cn-chengdu.aliyuncs.com",
|
||||||
"Host": "https://wgshare.oss-cn-chengdu.aliyuncs.com/",
|
"Host": "https://wgshare.oss-cn-chengdu.aliyuncs.com/",
|
||||||
"BucketName": "wgshare",
|
"BucketName": "wgshare"
|
||||||
"eventSecret": ""
|
},
|
||||||
|
"miniProgram": {
|
||||||
|
"appId": "wx99885b1c181cda72",
|
||||||
|
"appSecret": "edd9cdb04c3f59fe70f2a70c396e5b0d"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -86,5 +86,12 @@ namespace WGShare.Domain.Constant
|
||||||
{
|
{
|
||||||
public static string MeetingRecord => "meeting_record";
|
public static string MeetingRecord => "meeting_record";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class WxMiniProgram
|
||||||
|
{
|
||||||
|
public static string AccessTokenKey => $@"wx_mini_program:accessToken";
|
||||||
|
|
||||||
|
public static string GetRoomQrCode(string roomNum, string env) => $@"wx_mini_program:room_qrcode:{env}:{roomNum}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using WGShare.Domain.Enums;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.DTOs.Home
|
||||||
|
{
|
||||||
|
public class FeedBackRequset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 分值
|
||||||
|
/// </summary>
|
||||||
|
public double Score { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反馈内容
|
||||||
|
/// </summary>
|
||||||
|
public string OtherContent { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反馈类型
|
||||||
|
/// </summary>
|
||||||
|
public List<int> Types { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
using SqlSugar;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Yitter.IdGenerator;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.DTOs.Home
|
||||||
|
{
|
||||||
|
public class UserVersionLogDto
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用版本
|
||||||
|
///</summary>
|
||||||
|
public string Version { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 平台类型 1:PC 2:微信小程序
|
||||||
|
///</summary>
|
||||||
|
public int PlatformType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 房间号
|
||||||
|
///</summary>
|
||||||
|
public string RoomNum { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.DTOs.Login
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 匿名用户登录
|
||||||
|
/// </summary>
|
||||||
|
public class AnonymousUserLoginDTO
|
||||||
|
{
|
||||||
|
public string DeviceId { get; set; }
|
||||||
|
|
||||||
|
public string NickName { get; set; }
|
||||||
|
|
||||||
|
public string RoomNum { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.DTOs.MiniProgram
|
||||||
|
{
|
||||||
|
public class AccessTokenApiResult : WxMiniProgramBaseApiResult
|
||||||
|
{
|
||||||
|
public string access_token { get; set; }
|
||||||
|
public int expires_in { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.DTOs.MiniProgram
|
||||||
|
{
|
||||||
|
public class JsCode2SessionApiResult
|
||||||
|
{
|
||||||
|
public string openid { get; set; }
|
||||||
|
public string seesionkey { get; set; }
|
||||||
|
public string unionid { get; set; }
|
||||||
|
public int errorcode { get; set; }
|
||||||
|
public string errmsg { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.DTOs.MiniProgram
|
||||||
|
{
|
||||||
|
public class WxMiniProgramBaseApiResult
|
||||||
|
{
|
||||||
|
public int errorcode { get; set; }
|
||||||
|
public string errmsg { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.DTOs.MiniProgram
|
||||||
|
{
|
||||||
|
public class wxacodeunlimitBody
|
||||||
|
{
|
||||||
|
public string scene { get; set; }
|
||||||
|
public string page { get; set; }
|
||||||
|
public bool check_path { get; set; }
|
||||||
|
public string env_version { get; set; }
|
||||||
|
public int width { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,21 +4,54 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using WGShare.Domain.Enums;
|
||||||
using Yitter.IdGenerator;
|
using Yitter.IdGenerator;
|
||||||
|
|
||||||
namespace WGShare.Domain.DTOs.Room
|
namespace WGShare.Domain.DTOs.Room
|
||||||
{
|
{
|
||||||
public class RoomInputDTO
|
public class RoomInputDTO : RoomInfoInputDTO
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 会议室名称
|
/// 会议室名称
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarColumn(ColumnName = "room_name")]
|
|
||||||
public string RoomName { get; set; }
|
public string RoomName { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 会议号
|
/// 会议号
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarColumn(ColumnName = "room_num")]
|
|
||||||
public string RoomNum { get; set; }
|
public string RoomNum { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 届
|
||||||
|
///</summary>
|
||||||
|
public int Year { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 科目
|
||||||
|
///</summary>
|
||||||
|
public SubjectType Subject { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class RoomInfoInputDTO
|
||||||
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 届
|
||||||
|
///</summary>
|
||||||
|
public int Year { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 科目
|
||||||
|
///</summary>
|
||||||
|
public SubjectType Subject { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 会议室名称
|
||||||
|
/// </summary>
|
||||||
|
public string RoomName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否允许匿名
|
||||||
|
/// </summary>
|
||||||
|
public bool AllowAnonymous { get; set; } = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,5 +12,9 @@ namespace WGShare.Domain.DTOs.Room
|
||||||
public string RoomId { get; set; }
|
public string RoomId { get; set; }
|
||||||
public string RoomNum { get; set; }
|
public string RoomNum { get; set; }
|
||||||
public string UserId { get; set; }
|
public string UserId { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 设置人Id
|
||||||
|
/// </summary>
|
||||||
|
public string SettingUserId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using MiniExcelLibs.Attributes;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
@ -15,6 +16,8 @@ namespace WGShare.Domain.DTOs.Room
|
||||||
public string EndTime { get; set; }
|
public string EndTime { get; set; }
|
||||||
|
|
||||||
public List<UserBehavior> Users { get; set; }
|
public List<UserBehavior> Users { get; set; }
|
||||||
|
|
||||||
|
public List<SignInListRecordExcelDto> Signin { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UserBehavior
|
public class UserBehavior
|
||||||
|
|
@ -27,4 +30,15 @@ namespace WGShare.Domain.DTOs.Room
|
||||||
public int JoinCount { get; set; }
|
public int JoinCount { get; set; }
|
||||||
public int SumTime { get; set; }
|
public int SumTime { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SignInListRecordExcelDto
|
||||||
|
{
|
||||||
|
|
||||||
|
public string Account { get; set; }
|
||||||
|
|
||||||
|
public string UserName { get; set; }
|
||||||
|
|
||||||
|
public string SignInTime { get; set; }
|
||||||
|
public string SignInName { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using WGShare.Domain.Enums;
|
||||||
using Yitter.IdGenerator;
|
using Yitter.IdGenerator;
|
||||||
|
|
||||||
namespace WGShare.Domain.DTOs.Room
|
namespace WGShare.Domain.DTOs.Room
|
||||||
|
|
@ -24,5 +25,16 @@ namespace WGShare.Domain.DTOs.Room
|
||||||
/// 在线人数
|
/// 在线人数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long OnlineUserCount { get; set; }
|
public long OnlineUserCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 届
|
||||||
|
///</summary>
|
||||||
|
public int Year { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 科目
|
||||||
|
///</summary>
|
||||||
|
public SubjectType Subject { get; set; }
|
||||||
|
|
||||||
|
public bool AllowAnonymous { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
using MiniExcelLibs.Attributes;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.DTOs.User
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 导出账号签到用户列表
|
||||||
|
/// </summary>
|
||||||
|
public class SignInListExcelDto
|
||||||
|
{
|
||||||
|
|
||||||
|
[ExcelColumnName("UId")]
|
||||||
|
public string UId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
[ExcelColumnName("账号")]
|
||||||
|
public string Account { get; set; }
|
||||||
|
|
||||||
|
[ExcelColumnName("账号名称")]
|
||||||
|
public string UserName{ get; set; }
|
||||||
|
|
||||||
|
public string RoleId { get; set; }
|
||||||
|
[ExcelColumnName("角色")]
|
||||||
|
public string RoleName { get; set; }
|
||||||
|
[ExcelColumnName("绑定签到人姓名")]
|
||||||
|
|
||||||
|
public string SignInName { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.DTOs.User
|
||||||
|
{
|
||||||
|
public class SubjectInfo
|
||||||
|
{
|
||||||
|
public int Value { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using WGShare.Domain.Entities;
|
||||||
|
using WGShare.Domain.Enums;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.DTOs.User
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 用户批量修改信息
|
||||||
|
/// </summary>
|
||||||
|
public class UserBatchUpdateDTO
|
||||||
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
public int Year { get; set; }
|
||||||
|
public SubjectType Subject { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -29,6 +29,16 @@ namespace WGShare.Domain.DTOs.User
|
||||||
///</summary>
|
///</summary>
|
||||||
[ExcelColumnName("角色")]
|
[ExcelColumnName("角色")]
|
||||||
public string RoleId{ get; set; }
|
public string RoleId{ get; set; }
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
///</summary>
|
||||||
|
[ExcelColumnName("届")]
|
||||||
|
public int Year { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
///</summary>
|
||||||
|
[ExcelColumnName("科目")]
|
||||||
|
public string SubjectName { get; set; }
|
||||||
|
|
||||||
|
|
||||||
[ExcelColumnName("导入结果")]
|
[ExcelColumnName("导入结果")]
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using WGShare.Domain.Enums;
|
||||||
|
|
||||||
namespace WGShare.Domain.DTOs.User
|
namespace WGShare.Domain.DTOs.User
|
||||||
{
|
{
|
||||||
|
|
@ -31,5 +32,15 @@ namespace WGShare.Domain.DTOs.User
|
||||||
/// 租户id
|
/// 租户id
|
||||||
///</summary>
|
///</summary>
|
||||||
public string? TenantId { get; set; }
|
public string? TenantId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 届
|
||||||
|
/// </summary>
|
||||||
|
public int Year { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 科目
|
||||||
|
/// </summary>
|
||||||
|
public SubjectType Subject { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.DTOs.User
|
||||||
|
{
|
||||||
|
public class UserModifyNickNameDto
|
||||||
|
{
|
||||||
|
public string RoomNum { get; set; }
|
||||||
|
public string NickName { get; set; }
|
||||||
|
public long UId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using WGShare.Domain.Enums;
|
||||||
|
|
||||||
namespace WGShare.Domain.DTOs.User
|
namespace WGShare.Domain.DTOs.User
|
||||||
{
|
{
|
||||||
|
|
@ -29,5 +30,15 @@ namespace WGShare.Domain.DTOs.User
|
||||||
/// 共享屏幕ID
|
/// 共享屏幕ID
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ScreenShareId { get; set; }
|
public string ScreenShareId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 届
|
||||||
|
/// </summary>
|
||||||
|
public int Year { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 科目
|
||||||
|
/// </summary>
|
||||||
|
public SubjectType Subject { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
using MiniExcelLibs.Attributes;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.DTOs.User
|
||||||
|
{
|
||||||
|
public class UserSignInListDto
|
||||||
|
{
|
||||||
|
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
public string UId { get; set; }
|
||||||
|
|
||||||
|
public string SignInName { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
using SqlSugar;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.DTOs.User
|
||||||
|
{
|
||||||
|
public class UserSignInRecordDto
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public string SignInName { get; set; }
|
||||||
|
|
||||||
|
public string RoomNum { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using SqlSugar;
|
||||||
|
using WGShare.Domain.Enums;
|
||||||
|
using Yitter.IdGenerator;
|
||||||
|
namespace WGShare.Domain.Entities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 反馈问题表
|
||||||
|
///</summary>
|
||||||
|
[SugarTable("feedback_issue")]
|
||||||
|
public class FeedbackIssue
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "id", IsPrimaryKey = true)]
|
||||||
|
public string Id { get; set; } = YitIdHelper.NextId().ToString();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建时间
|
||||||
|
/// 默认值: CURRENT_TIMESTAMP
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "create_time", IsOnlyIgnoreInsert = true, IsOnlyIgnoreUpdate = true)]
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户id
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "uid")]
|
||||||
|
public long UID { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分值
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "score")]
|
||||||
|
public double Score { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反馈其他
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "other_content")]
|
||||||
|
public string OtherContent { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反馈其他
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "types")]
|
||||||
|
public string Types { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
|
using WGShare.Domain.Enums;
|
||||||
using Yitter.IdGenerator;
|
using Yitter.IdGenerator;
|
||||||
namespace WGShare.Domain.Entities
|
namespace WGShare.Domain.Entities
|
||||||
{
|
{
|
||||||
|
|
@ -49,5 +50,30 @@ namespace WGShare.Domain.Entities
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarColumn(ColumnName = "room_num")]
|
[SugarColumn(ColumnName = "room_num")]
|
||||||
public string RoomNum { get; set; }
|
public string RoomNum { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 届
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "year")]
|
||||||
|
public int Year { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 科目
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "subject")]
|
||||||
|
public SubjectType Subject { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否允许匿名
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "allow_anonymous")]
|
||||||
|
public bool AllowAnonymous { get; set; } = true;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租户名称
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsIgnore = true)]
|
||||||
|
public string TenantName { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
|
using WGShare.Domain.Enums;
|
||||||
using Yitter.IdGenerator;
|
using Yitter.IdGenerator;
|
||||||
namespace WGShare.Domain.Entities
|
namespace WGShare.Domain.Entities
|
||||||
{
|
{
|
||||||
|
|
@ -59,11 +60,32 @@ namespace WGShare.Domain.Entities
|
||||||
[SugarColumn(ColumnName = "tenant_id")]
|
[SugarColumn(ColumnName = "tenant_id")]
|
||||||
public string TenantId { get; set; }
|
public string TenantId { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// 是否匿名登录用户
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "is_anonymous")]
|
||||||
|
public bool IsAnonymous { get; set; }
|
||||||
|
/// <summary>
|
||||||
/// 共享屏幕Id
|
/// 共享屏幕Id
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarColumn(ColumnName = "screen_share_id", IsOnlyIgnoreUpdate = true)]
|
[SugarColumn(ColumnName = "screen_share_id", IsOnlyIgnoreUpdate = true)]
|
||||||
public string ScreenShareId { get; set; }
|
public string ScreenShareId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 届
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "year")]
|
||||||
|
public int Year { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 科目
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "subject")]
|
||||||
|
public SubjectType Subject { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 科目名称
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(IsIgnore = true)]
|
||||||
|
public string SubjectName { get; set; }
|
||||||
|
|
||||||
[SugarColumn(IsIgnore = true)]
|
[SugarColumn(IsIgnore = true)]
|
||||||
public string RoleName { get; set; }
|
public string RoleName { get; set; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
using AngleSharp.Text;
|
||||||
|
using SqlSugar;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.Entities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 签到名单
|
||||||
|
///</summary>
|
||||||
|
[SugarTable("user_signin_list")]
|
||||||
|
public class UserSignInList
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsIdentity = true)]
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "uid")]
|
||||||
|
public string UId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
[SugarColumn(ColumnName = "signin_name")]
|
||||||
|
public string SignInName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建时间
|
||||||
|
/// 默认值: CURRENT_TIMESTAMP
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "create_time", IsOnlyIgnoreInsert = true, IsOnlyIgnoreUpdate = true)]
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改时间
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "modify_time", IsOnlyIgnoreInsert = true, IsOnlyIgnoreUpdate = true)]
|
||||||
|
public DateTime ModifyTime { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
using AngleSharp.Text;
|
||||||
|
using SqlSugar;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.Entities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 签到名单记录
|
||||||
|
///</summary>
|
||||||
|
[SugarTable("user_signin_record")]
|
||||||
|
public class UserSignInRecord
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsIdentity = true)]
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "uid")]
|
||||||
|
public string UId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
[SugarColumn(ColumnName = "signin_name")]
|
||||||
|
public string SignInName { get; set; }
|
||||||
|
|
||||||
|
[SugarColumn(ColumnName = "room_num")]
|
||||||
|
public string RoomNum { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 创建时间
|
||||||
|
/// 默认值: CURRENT_TIMESTAMP
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "create_time", IsOnlyIgnoreInsert = true, IsOnlyIgnoreUpdate = true)]
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
using SqlSugar;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Principal;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Yitter.IdGenerator;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.Entities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 用户版本记录表
|
||||||
|
/// </summary>
|
||||||
|
[SugarTable("user_version_log")]
|
||||||
|
public class UserVersionLog
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsIdentity = true)]
|
||||||
|
public string Id { get; set; } = YitIdHelper.NextId().ToString();
|
||||||
|
/// <summary>
|
||||||
|
/// 用户Id
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "user_id")]
|
||||||
|
public long UserId { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 使用版本
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "version")]
|
||||||
|
public string Version { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 平台类型
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "platform_type")]
|
||||||
|
public int PlatformType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 房间号
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "room_num")]
|
||||||
|
public string RoomNum { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 进房时间
|
||||||
|
///</summary>
|
||||||
|
[SugarColumn(ColumnName = "join_time", IsOnlyIgnoreInsert = true, IsOnlyIgnoreUpdate = true)]
|
||||||
|
public DateTime JoinTime { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.Enums
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 反馈问题枚举
|
||||||
|
/// </summary>
|
||||||
|
public enum FeedbackIssueEnums
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 其他
|
||||||
|
/// </summary>
|
||||||
|
Other = 1,
|
||||||
|
/// <summary>
|
||||||
|
/// 软件卡顿
|
||||||
|
/// </summary>
|
||||||
|
SoftwareLag = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设计不合理
|
||||||
|
/// </summary>
|
||||||
|
UnreasonableDesign = 3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 功能太少
|
||||||
|
/// </summary>
|
||||||
|
TooLittleFeatures = 4,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 通话不流畅
|
||||||
|
/// </summary>
|
||||||
|
CallIsNotSmooth = 5,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 视频卡顿
|
||||||
|
/// </summary>
|
||||||
|
VideoLag = 6,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 操作麻烦
|
||||||
|
/// </summary>
|
||||||
|
OperationTrouble
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WGShare.Domain.Enums
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public enum SubjectType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 全部科目
|
||||||
|
/// </summary>
|
||||||
|
[Description("全部科目")]
|
||||||
|
All = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// 语文
|
||||||
|
/// </summary>
|
||||||
|
[Description("语文")]
|
||||||
|
Chinese = 1,
|
||||||
|
/// <summary>
|
||||||
|
/// 数学
|
||||||
|
/// </summary>
|
||||||
|
[Description("数学")]
|
||||||
|
Math = 2,
|
||||||
|
/// <summary>
|
||||||
|
/// 英语
|
||||||
|
/// </summary>
|
||||||
|
[Description("英语")]
|
||||||
|
English = 3,
|
||||||
|
/// <summary>
|
||||||
|
/// 物理
|
||||||
|
/// </summary>
|
||||||
|
[Description("物理")]
|
||||||
|
Physical = 4,
|
||||||
|
/// <summary>
|
||||||
|
/// 化学
|
||||||
|
/// </summary>
|
||||||
|
[Description("化学")]
|
||||||
|
Chemical = 5,
|
||||||
|
/// <summary>
|
||||||
|
/// 生物
|
||||||
|
/// </summary>
|
||||||
|
[Description("生物")]
|
||||||
|
Biological = 6,
|
||||||
|
/// <summary>
|
||||||
|
/// 政治
|
||||||
|
/// </summary>
|
||||||
|
[Description("政治")]
|
||||||
|
Political = 7,
|
||||||
|
/// <summary>
|
||||||
|
/// 历史
|
||||||
|
/// </summary>
|
||||||
|
[Description("历史")]
|
||||||
|
History = 8,
|
||||||
|
/// <summary>
|
||||||
|
/// 地理
|
||||||
|
/// </summary>
|
||||||
|
[Description("地理")]
|
||||||
|
Geographic = 9
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using System.Net.Http.Json;
|
using System.Net.Http.Json;
|
||||||
|
using WGShare.Domain.DTOs.AgoraCallback;
|
||||||
|
using WGShare.Domain.Entities;
|
||||||
|
|
||||||
namespace WGShare.Domain.FriendlyException
|
namespace WGShare.Domain.FriendlyException
|
||||||
{
|
{
|
||||||
|
|
@ -39,6 +41,39 @@ namespace WGShare.Domain.FriendlyException
|
||||||
return reponse.IsSuccessStatusCode;
|
return reponse.IsSuccessStatusCode;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task JoinAsync(EventBody eventBody, Room roomInfo)
|
||||||
|
{
|
||||||
|
// 获取当前的日期
|
||||||
|
DateTime today = DateTime.Today;
|
||||||
|
|
||||||
|
// 定义东八区的时区信息
|
||||||
|
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time");
|
||||||
|
|
||||||
|
// 创建东八区今天00:00:01的DateTime对象
|
||||||
|
DateTime startOfDayLocal = new DateTime(today.Year, today.Month, today.Day, 0, 0, 1, DateTimeKind.Unspecified);
|
||||||
|
|
||||||
|
// 创建东八区今天23:59:00的DateTime对象
|
||||||
|
DateTime endOfDayLocal = new DateTime(today.Year, today.Month, today.Day, 23, 59, 0, DateTimeKind.Unspecified);
|
||||||
|
|
||||||
|
// 将时间转换为UTC
|
||||||
|
DateTimeOffset startOfDayUtc = TimeZoneInfo.ConvertTimeToUtc(startOfDayLocal, timeZoneInfo);
|
||||||
|
DateTimeOffset endOfDayUtc = TimeZoneInfo.ConvertTimeToUtc(endOfDayLocal, timeZoneInfo);
|
||||||
|
|
||||||
|
// 获取Unix时间戳(秒)
|
||||||
|
long startTimestamp = startOfDayUtc.ToUnixTimeSeconds();
|
||||||
|
long endTimestamp = endOfDayUtc.ToUnixTimeSeconds();
|
||||||
|
|
||||||
|
var reponse = await httpClient.PostAsync(string.Empty, JsonContent.Create(new
|
||||||
|
{
|
||||||
|
msgtype = "markdown",
|
||||||
|
markdown = new
|
||||||
|
{
|
||||||
|
title = "有人入会通知",
|
||||||
|
text = $"有人进入会议室了,学校:{roomInfo.TenantName},会议室名称:{roomInfo.RoomName},会议号:{eventBody.payload.channelName}. \r\n 点击查看:https://analytics-lab.agora.io/analytics/call/search?projectId=0tOpVUrmf&fromTs={startTimestamp}&toTs={endTimestamp}"
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ namespace WGShare.Domain.GeneralModel
|
||||||
public class PagedResult<TEntity>
|
public class PagedResult<TEntity>
|
||||||
{
|
{
|
||||||
public PagedResult() { }
|
public PagedResult() { }
|
||||||
public PagedResult(IEnumerable<TEntity> list, int total)
|
public PagedResult(IEnumerable<TEntity> list, int total, int pageSize = 10)
|
||||||
{
|
{
|
||||||
Total = total;
|
Total = total;
|
||||||
Items = list;
|
Items = list;
|
||||||
|
|
@ -20,9 +20,19 @@ namespace WGShare.Domain.GeneralModel
|
||||||
public int Total { get; set; }
|
public int Total { get; set; }
|
||||||
public IEnumerable<TEntity> Items { get; private set; }
|
public IEnumerable<TEntity> Items { get; private set; }
|
||||||
|
|
||||||
public static PagedResult<TEntity> Create(IEnumerable<TEntity> list, int total)
|
private int pageSize = 10;
|
||||||
|
|
||||||
|
public int TotalPage
|
||||||
{
|
{
|
||||||
return new PagedResult<TEntity>(list, total);
|
get
|
||||||
|
{
|
||||||
|
return (int)Math.Ceiling(Total / (double)pageSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PagedResult<TEntity> Create(IEnumerable<TEntity> list, int total, int pageSize = 10)
|
||||||
|
{
|
||||||
|
return new PagedResult<TEntity>(list, total, pageSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue