using System.Net;
using XFEToolBox.Core.Chat;
using XFEExtension.NetCore.ServerInteractive.Attributes;
namespace XFEToolBox.Server.Services.Chat;
public partial class ChatFriendService : ChatServiceBase
{
[EntryPoint("v1/chat/users/search")]
public async Task SearchUsersEntryPoint()
{
await ExecuteChatAsync(_ =>
{
var query = GetString("query") ?? throw InvalidRequest("请输入用户账号或昵称。");
if (query.Length > 80) throw InvalidRequest("搜索内容不能超过 80 个字符。");
var limit = Math.Clamp(GetInt32("limit") ?? 20, 1, 50);
var users = GetUserFunction()
.Where(user => user.Enable
&& !string.Equals(user.Id, User.Id, StringComparison.Ordinal)
&& (user.UserName.Contains(query, StringComparison.OrdinalIgnoreCase)
|| user.NickName.Contains(query, StringComparison.CurrentCultureIgnoreCase)))
.OrderBy(user => user.UserName, StringComparer.OrdinalIgnoreCase)
.Take(limit)
.Select(user => ToUserSummary(user.Id))
.ToArray();
return Task.FromResult(users);
});
}
[EntryPoint("v1/chat/friends/list")]
public async Task ListFriendsEntryPoint()
{
await ExecuteChatAsync(async repository =>
{
var friends = await repository.GetFriendsAsync(User.Id);
return friends.Select(friend => new ChatFriendInfo
{
User = ToUserSummary(friend.UserId),
FriendsSinceUtc = friend.FriendsSinceUtc,
ConversationId = friend.ConversationId
}).ToArray();
});
}
[EntryPoint("v1/chat/friends/requests")]
public async Task ListFriendRequestsEntryPoint()
{
await ExecuteChatAsync(async repository =>
{
var requests = await repository.GetFriendRequestsAsync(User.Id);
return requests.Select(ToFriendRequestInfo).ToArray();
});
}
[EntryPoint("v1/chat/friends/request")]
public async Task CreateFriendRequestEntryPoint()
{
await ExecuteChatAsync(async repository =>
{
var targetUserId = GetString("targetUserId") ?? throw InvalidRequest("缺少 targetUserId。");
if (FindUser(targetUserId) is null) throw NotFound("用户不存在。");
var request = await repository.CreateFriendRequestAsync(User.Id, targetUserId, GetString("message", allowEmpty: true));
var result = ToFriendRequestInfo(request);
await PublishToUserBestEffortAsync(targetUserId, "chat.friend.requested", result);
return result;
}, HttpStatusCode.Created);
}
[EntryPoint("v1/chat/friends/respond")]
public async Task RespondFriendRequestEntryPoint()
{
await ExecuteChatAsync(async repository =>
{
var requestId = GetString("requestId") ?? throw InvalidRequest("缺少 requestId。");
var accept = GetBoolean("accept") ?? throw InvalidRequest("accept 必须是布尔值。");
var request = await repository.RespondToFriendRequestAsync(requestId, User.Id, accept);
var result = ToFriendRequestInfo(request);
await Task.WhenAll(
PublishToUserBestEffortAsync(request.FromUserId, "chat.friend.request.updated", result),
PublishToUserBestEffortAsync(request.ToUserId, "chat.friend.request.updated", result));
return result;
});
}
[EntryPoint("v1/chat/friends/delete")]
public async Task DeleteFriendEntryPoint()
{
await ExecuteChatAsync(async repository =>
{
var friendUserId = GetString("friendUserId") ?? throw InvalidRequest("缺少 friendUserId。");
if (!await repository.DeleteFriendshipAsync(User.Id, friendUserId)) throw NotFound("好友关系不存在。");
var result = new { friendUserId, deleted = true };
await Task.WhenAll(
EndDirectCallsBestEffortAsync(friendUserId, "friendship-removed"),
PublishToUserBestEffortAsync(User.Id, "chat.friend.deleted", result),
PublishToUserBestEffortAsync(friendUserId, "chat.friend.deleted", new
{
friendUserId = User.Id,
deleted = true
}));
return result;
});
}
}
using System.Net;
using XFEToolBox.Core.Chat;
using XFEExtension.NetCore.ServerInteractive.Attributes;
namespace XFEToolBox.Server.Services.Chat;
public partial class ChatFriendService : ChatServiceBase
{
[EntryPoint("v1/chat/users/search")]
public async Task SearchUsersEntryPoint()
{
await ExecuteChatAsync(_ =>
{
var query = GetString("query") ?? throw InvalidRequest("请输入用户账号或昵称。");
if (query.Length > 80) throw InvalidRequest("搜索内容不能超过 80 个字符。");
var limit = Math.Clamp(GetInt32("limit") ?? 20, 1, 50);
var users = GetUserFunction()
.Where(user => user.Enable
&& !string.Equals(user.Id, User.Id, StringComparison.Ordinal)
&& (user.UserName.Contains(query, StringComparison.OrdinalIgnoreCase)
|| user.NickName.Contains(query, StringComparison.CurrentCultureIgnoreCase)))
.OrderBy(user => user.UserName, StringComparer.OrdinalIgnoreCase)
.Take(limit)
.Select(user => ToUserSummary(user.Id))
.ToArray();
return Task.FromResult(users);
});
}
[EntryPoint("v1/chat/friends/list")]
public async Task ListFriendsEntryPoint()
{
await ExecuteChatAsync(async repository =>
{
var friends = await repository.GetFriendsAsync(User.Id);
return friends.Select(friend => new ChatFriendInfo
{
User = ToUserSummary(friend.UserId),
FriendsSinceUtc = friend.FriendsSinceUtc,
ConversationId = friend.ConversationId
}).ToArray();
});
}
[EntryPoint("v1/chat/friends/requests")]
public async Task ListFriendRequestsEntryPoint()
{
await ExecuteChatAsync(async repository =>
{
var requests = await repository.GetFriendRequestsAsync(User.Id);
return requests.Select(ToFriendRequestInfo).ToArray();
});
}
[EntryPoint("v1/chat/friends/request")]
public async Task CreateFriendRequestEntryPoint()
{
await ExecuteChatAsync(async repository =>
{
var targetUserId = GetString("targetUserId") ?? throw InvalidRequest("缺少 targetUserId。");
if (FindUser(targetUserId) is null) throw NotFound("用户不存在。");
var request = await repository.CreateFriendRequestAsync(User.Id, targetUserId, GetString("message", allowEmpty: true));
var result = ToFriendRequestInfo(request);
await PublishToUserBestEffortAsync(targetUserId, "chat.friend.requested", result);
return result;
}, HttpStatusCode.Created);
}
[EntryPoint("v1/chat/friends/respond")]
public async Task RespondFriendRequestEntryPoint()
{
await ExecuteChatAsync(async repository =>
{
var requestId = GetString("requestId") ?? throw InvalidRequest("缺少 requestId。");
var accept = GetBoolean("accept") ?? throw InvalidRequest("accept 必须是布尔值。");
var request = await repository.RespondToFriendRequestAsync(requestId, User.Id, accept);
var result = ToFriendRequestInfo(request);
await Task.WhenAll(
PublishToUserBestEffortAsync(request.FromUserId, "chat.friend.request.updated", result),
PublishToUserBestEffortAsync(request.ToUserId, "chat.friend.request.updated", result));
return result;
});
}
[EntryPoint("v1/chat/friends/delete")]
public async Task DeleteFriendEntryPoint()
{
await ExecuteChatAsync(async repository =>
{
var friendUserId = GetString("friendUserId") ?? throw InvalidRequest("缺少 friendUserId。");
if (!await repository.DeleteFriendshipAsync(User.Id, friendUserId)) throw NotFound("好友关系不存在。");
var result = new { friendUserId, deleted = true };
await Task.WhenAll(
EndDirectCallsBestEffortAsync(friendUserId, "friendship-removed"),
PublishToUserBestEffortAsync(User.Id, "chat.friend.deleted", result),
PublishToUserBestEffortAsync(friendUserId, "chat.friend.deleted", new
{
friendUserId = User.Id,
deleted = true
}));
return result;
});
}
}