Delete relationship

This commit is contained in:
2026-01-06 22:46:21 +08:00
parent 0cc6f86f3b
commit 7a0ba166dc
2 changed files with 73 additions and 40 deletions

View File

@@ -9,7 +9,7 @@ namespace DysonNetwork.Pass.Account;
[ApiController] [ApiController]
[Route("/api/relationships")] [Route("/api/relationships")]
public class RelationshipController(AppDatabase db, RelationshipService rels) : ControllerBase public class RelationshipController(AppDatabase db, RelationshipService rls) : ControllerBase
{ {
[HttpGet] [HttpGet]
[Authorize] [Authorize]
@@ -17,11 +17,11 @@ public class RelationshipController(AppDatabase db, RelationshipService rels) :
[FromQuery] int take = 20) [FromQuery] int take = 20)
{ {
if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized(); if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized();
var userId = currentUser.Id; var accountId = currentUser.Id;
var query = db.AccountRelationships.AsQueryable() var query = db.AccountRelationships.AsQueryable()
.OrderByDescending(r => r.CreatedAt) .OrderByDescending(r => r.CreatedAt)
.Where(r => r.RelatedId == userId); .Where(r => r.RelatedId == accountId);
var totalCount = await query.CountAsync(); var totalCount = await query.CountAsync();
var relationships = await query var relationships = await query
.Include(r => r.Related) .Include(r => r.Related)
@@ -33,7 +33,7 @@ public class RelationshipController(AppDatabase db, RelationshipService rels) :
.ToListAsync(); .ToListAsync();
var statuses = await db.AccountRelationships var statuses = await db.AccountRelationships
.Where(r => r.AccountId == userId) .Where(r => r.AccountId == accountId)
.ToDictionaryAsync(r => r.RelatedId); .ToDictionaryAsync(r => r.RelatedId);
foreach (var relationship in relationships) foreach (var relationship in relationships)
relationship.Status = statuses.TryGetValue(relationship.AccountId, out var status) relationship.Status = statuses.TryGetValue(relationship.AccountId, out var status)
@@ -67,19 +67,19 @@ public class RelationshipController(AppDatabase db, RelationshipService rels) :
[Required] public RelationshipStatus Status { get; set; } [Required] public RelationshipStatus Status { get; set; }
} }
[HttpPost("{userId:guid}")] [HttpPost("{accountId:guid}")]
[Authorize] [Authorize]
public async Task<ActionResult<SnAccountRelationship>> CreateRelationship(Guid userId, public async Task<ActionResult<SnAccountRelationship>> CreateRelationship(Guid accountId,
[FromBody] RelationshipRequest request) [FromBody] RelationshipRequest request)
{ {
if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized(); if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized();
var relatedUser = await db.Accounts.FindAsync(userId); var relatedUser = await db.Accounts.FindAsync(accountId);
if (relatedUser is null) return NotFound("Account was not found."); if (relatedUser is null) return NotFound("Account was not found.");
try try
{ {
var relationship = await rels.CreateRelationship( var relationship = await rls.CreateRelationship(
currentUser, relatedUser, request.Status currentUser, relatedUser, request.Status
); );
return relationship; return relationship;
@@ -90,16 +90,16 @@ public class RelationshipController(AppDatabase db, RelationshipService rels) :
} }
} }
[HttpPatch("{userId:guid}")] [HttpPatch("{accountId:guid}")]
[Authorize] [Authorize]
public async Task<ActionResult<SnAccountRelationship>> UpdateRelationship(Guid userId, public async Task<ActionResult<SnAccountRelationship>> UpdateRelationship(Guid accountId,
[FromBody] RelationshipRequest request) [FromBody] RelationshipRequest request)
{ {
if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized(); if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized();
try try
{ {
var relationship = await rels.UpdateRelationship(currentUser.Id, userId, request.Status); var relationship = await rls.UpdateRelationship(currentUser.Id, accountId, request.Status);
return relationship; return relationship;
} }
catch (ArgumentException err) catch (ArgumentException err)
@@ -112,15 +112,36 @@ public class RelationshipController(AppDatabase db, RelationshipService rels) :
} }
} }
[HttpGet("{userId:guid}")] [HttpDelete("{accountId:guid}")]
[Authorize] [Authorize]
public async Task<ActionResult<SnAccountRelationship>> GetRelationship(Guid userId) public async Task<ActionResult<SnAccountRelationship>> DeleteRelationship(Guid accountId)
{
if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized();
try
{
var relationship = await rls.DeleteRelationship(currentUser.Id, accountId);
return Ok(relationship);
}
catch (ArgumentException err)
{
return BadRequest(err.Message);
}
catch (InvalidOperationException err)
{
return BadRequest(err.Message);
}
}
[HttpGet("{accountId:guid}")]
[Authorize]
public async Task<ActionResult<SnAccountRelationship>> GetRelationship(Guid accountId)
{ {
if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized(); if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized();
var now = Instant.FromDateTimeUtc(DateTime.UtcNow); var now = Instant.FromDateTimeUtc(DateTime.UtcNow);
var queries = db.AccountRelationships.AsQueryable() var queries = db.AccountRelationships.AsQueryable()
.Where(r => r.AccountId == currentUser.Id && r.RelatedId == userId) .Where(r => r.AccountId == currentUser.Id && r.RelatedId == accountId)
.Where(r => r.ExpiredAt == null || r.ExpiredAt > now); .Where(r => r.ExpiredAt == null || r.ExpiredAt > now);
var relationship = await queries var relationship = await queries
.Include(r => r.Related) .Include(r => r.Related)
@@ -132,23 +153,23 @@ public class RelationshipController(AppDatabase db, RelationshipService rels) :
return Ok(relationship); return Ok(relationship);
} }
[HttpPost("{userId:guid}/friends")] [HttpPost("{accountId:guid}/friends")]
[Authorize] [Authorize]
public async Task<ActionResult<SnAccountRelationship>> SendFriendRequest(Guid userId) public async Task<ActionResult<SnAccountRelationship>> SendFriendRequest(Guid accountId)
{ {
if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized(); if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized();
var relatedUser = await db.Accounts.FindAsync(userId); var relatedUser = await db.Accounts.FindAsync(accountId);
if (relatedUser is null) return NotFound("Account was not found."); if (relatedUser is null) return NotFound("Account was not found.");
var existing = await db.AccountRelationships.FirstOrDefaultAsync(r => var existing = await db.AccountRelationships.FirstOrDefaultAsync(r =>
(r.AccountId == currentUser.Id && r.RelatedId == userId) || (r.AccountId == currentUser.Id && r.RelatedId == accountId) ||
(r.AccountId == userId && r.RelatedId == currentUser.Id)); (r.AccountId == accountId && r.RelatedId == currentUser.Id));
if (existing != null) return BadRequest("Relationship already exists."); if (existing != null) return BadRequest("Relationship already exists.");
try try
{ {
var relationship = await rels.SendFriendRequest(currentUser, relatedUser); var relationship = await rls.SendFriendRequest(currentUser, relatedUser);
return relationship; return relationship;
} }
catch (InvalidOperationException err) catch (InvalidOperationException err)
@@ -157,15 +178,15 @@ public class RelationshipController(AppDatabase db, RelationshipService rels) :
} }
} }
[HttpDelete("{userId:guid}/friends")] [HttpDelete("{accountId:guid}/friends")]
[Authorize] [Authorize]
public async Task<ActionResult> DeleteFriendRequest(Guid userId) public async Task<ActionResult> DeleteFriendRequest(Guid accountId)
{ {
if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized(); if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized();
try try
{ {
await rels.DeleteFriendRequest(currentUser.Id, userId); await rls.DeleteFriendRequest(currentUser.Id, accountId);
return NoContent(); return NoContent();
} }
catch (ArgumentException err) catch (ArgumentException err)
@@ -174,18 +195,18 @@ public class RelationshipController(AppDatabase db, RelationshipService rels) :
} }
} }
[HttpPost("{userId:guid}/friends/accept")] [HttpPost("{accountId:guid}/friends/accept")]
[Authorize] [Authorize]
public async Task<ActionResult<SnAccountRelationship>> AcceptFriendRequest(Guid userId) public async Task<ActionResult<SnAccountRelationship>> AcceptFriendRequest(Guid accountId)
{ {
if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized(); if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized();
var relationship = await rels.GetRelationship(userId, currentUser.Id, RelationshipStatus.Pending); var relationship = await rls.GetRelationship(accountId, currentUser.Id, RelationshipStatus.Pending);
if (relationship is null) return NotFound("Friend request was not found."); if (relationship is null) return NotFound("Friend request was not found.");
try try
{ {
relationship = await rels.AcceptFriendRelationship(relationship); relationship = await rls.AcceptFriendRelationship(relationship);
return relationship; return relationship;
} }
catch (InvalidOperationException err) catch (InvalidOperationException err)
@@ -194,18 +215,18 @@ public class RelationshipController(AppDatabase db, RelationshipService rels) :
} }
} }
[HttpPost("{userId:guid}/friends/decline")] [HttpPost("{accountId:guid}/friends/decline")]
[Authorize] [Authorize]
public async Task<ActionResult<SnAccountRelationship>> DeclineFriendRequest(Guid userId) public async Task<ActionResult<SnAccountRelationship>> DeclineFriendRequest(Guid accountId)
{ {
if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized(); if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized();
var relationship = await rels.GetRelationship(userId, currentUser.Id, RelationshipStatus.Pending); var relationship = await rls.GetRelationship(accountId, currentUser.Id, RelationshipStatus.Pending);
if (relationship is null) return NotFound("Friend request was not found."); if (relationship is null) return NotFound("Friend request was not found.");
try try
{ {
relationship = await rels.AcceptFriendRelationship(relationship, status: RelationshipStatus.Blocked); relationship = await rls.AcceptFriendRelationship(relationship, status: RelationshipStatus.Blocked);
return relationship; return relationship;
} }
catch (InvalidOperationException err) catch (InvalidOperationException err)
@@ -214,18 +235,18 @@ public class RelationshipController(AppDatabase db, RelationshipService rels) :
} }
} }
[HttpPost("{userId:guid}/block")] [HttpPost("{accountId:guid}/block")]
[Authorize] [Authorize]
public async Task<ActionResult<SnAccountRelationship>> BlockUser(Guid userId) public async Task<ActionResult<SnAccountRelationship>> BlockUser(Guid accountId)
{ {
if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized(); if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized();
var relatedUser = await db.Accounts.FindAsync(userId); var relatedUser = await db.Accounts.FindAsync(accountId);
if (relatedUser is null) return NotFound("Account was not found."); if (relatedUser is null) return NotFound("Account was not found.");
try try
{ {
var relationship = await rels.BlockAccount(currentUser, relatedUser); var relationship = await rls.BlockAccount(currentUser, relatedUser);
return relationship; return relationship;
} }
catch (InvalidOperationException err) catch (InvalidOperationException err)
@@ -233,19 +254,19 @@ public class RelationshipController(AppDatabase db, RelationshipService rels) :
return BadRequest(err.Message); return BadRequest(err.Message);
} }
} }
[HttpDelete("{userId:guid}/block")] [HttpDelete("{accountId:guid}/block")]
[Authorize] [Authorize]
public async Task<ActionResult<SnAccountRelationship>> UnblockUser(Guid userId) public async Task<ActionResult<SnAccountRelationship>> UnblockUser(Guid accountId)
{ {
if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized(); if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized();
var relatedUser = await db.Accounts.FindAsync(userId); var relatedUser = await db.Accounts.FindAsync(accountId);
if (relatedUser is null) return NotFound("Account was not found."); if (relatedUser is null) return NotFound("Account was not found.");
try try
{ {
var relationship = await rels.UnblockAccount(currentUser, relatedUser); var relationship = await rls.UnblockAccount(currentUser, relatedUser);
return relationship; return relationship;
} }
catch (InvalidOperationException err) catch (InvalidOperationException err)

View File

@@ -192,6 +192,18 @@ public class RelationshipService(
return relationship; return relationship;
} }
public async Task<SnAccountRelationship> DeleteRelationship(Guid accountId, Guid relatedId)
{
var relationship = await GetRelationship(accountId, relatedId);
if (relationship is null) throw new ArgumentException("There is no relationship between you and the user.");
db.Remove(relationship);
await db.SaveChangesAsync();
await PurgeRelationshipCache(accountId, relatedId, relationship.Status);
return relationship;
}
public async Task<List<Guid>> ListAccountFriends(SnAccount account, bool isRelated = false) public async Task<List<Guid>> ListAccountFriends(SnAccount account, bool isRelated = false)
{ {
return await ListAccountFriends(account.Id, isRelated); return await ListAccountFriends(account.Id, isRelated);