Searching in posts

This commit is contained in:
LittleSheep 2025-07-01 23:39:13 +08:00
parent 71fcc26534
commit ad730832db

View File

@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using NodaTime; using NodaTime;
using NpgsqlTypes;
namespace DysonNetwork.Sphere.Post; namespace DysonNetwork.Sphere.Post;
@ -18,14 +19,16 @@ public class PostController(
PostService ps, PostService ps,
PublisherService pub, PublisherService pub,
RelationshipService rels, RelationshipService rels,
IServiceScopeFactory factory,
ActionLogService als ActionLogService als
) )
: ControllerBase : ControllerBase
{ {
[HttpGet] [HttpGet]
public async Task<ActionResult<List<Post>>> ListPosts([FromQuery] int offset = 0, [FromQuery] int take = 20, public async Task<ActionResult<List<Post>>> ListPosts(
[FromQuery(Name = "pub")] string? pubName = null) [FromQuery] int offset = 0,
[FromQuery] int take = 20,
[FromQuery(Name = "pub")] string? pubName = null
)
{ {
HttpContext.Items.TryGetValue("CurrentUser", out var currentUserValue); HttpContext.Items.TryGetValue("CurrentUser", out var currentUserValue);
var currentUser = currentUserValue as Account.Account; var currentUser = currentUserValue as Account.Account;
@ -83,6 +86,48 @@ public class PostController(
return Ok(post); return Ok(post);
} }
[HttpGet("search")]
public async Task<ActionResult<List<Post>>> SearchPosts(
[FromQuery] string query,
[FromQuery] int offset = 0,
[FromQuery] int take = 20,
[FromQuery] bool useVector = true
)
{
if (string.IsNullOrWhiteSpace(query))
return BadRequest("Search query cannot be empty");
HttpContext.Items.TryGetValue("CurrentUser", out var currentUserValue);
var currentUser = currentUserValue as Account.Account;
var userFriends = currentUser is null ? [] : await rels.ListAccountFriends(currentUser);
var userPublishers = currentUser is null ? [] : await pub.GetUserPublishers(currentUser.Id);
var queryable = db.Posts
.FilterWithVisibility(currentUser, userFriends, userPublishers, isListing: true)
.AsQueryable();
if (useVector)
queryable = queryable.Where(p => p.SearchVector.Matches(EF.Functions.ToTsQuery(query)));
else
queryable = queryable.Where(p => EF.Functions.ILike(p.Title, $"%{query}%") ||
EF.Functions.ILike(p.Content, $"%{query}%"));
var totalCount = await queryable.CountAsync();
var posts = await queryable
.Include(e => e.RepliedPost)
.Include(e => e.ForwardedPost)
.Include(e => e.Categories)
.Include(e => e.Tags)
.OrderByDescending(e => e.PublishedAt ?? e.CreatedAt)
.Skip(offset)
.Take(take)
.ToListAsync();
posts = await ps.LoadPostInfo(posts, currentUser, true);
Response.Headers["X-Total"] = totalCount.ToString();
return Ok(posts);
}
[HttpGet("{id:guid}/replies")] [HttpGet("{id:guid}/replies")]
public async Task<ActionResult<List<Post>>> ListReplies(Guid id, [FromQuery] int offset = 0, public async Task<ActionResult<List<Post>>> ListReplies(Guid id, [FromQuery] int offset = 0,
[FromQuery] int take = 20) [FromQuery] int take = 20)