V13-FE-011: finalize search list layout slice
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
using Dapper;
|
||||
using Npgsql;
|
||||
|
||||
namespace Modules.ERP.Items.Search;
|
||||
|
||||
public sealed class SearchItemsHandler(NpgsqlDataSource dataSource)
|
||||
{
|
||||
public async Task<SearchItemsResponse> HandleAsync(SearchItemsRequest request, CancellationToken ct)
|
||||
{
|
||||
var page = Math.Max(request.Page, 1);
|
||||
var pageSize = Math.Clamp(request.PageSize, 1, 500);
|
||||
var offset = (page - 1) * pageSize;
|
||||
var keyword = string.IsNullOrWhiteSpace(request.Keyword) ? null : request.Keyword.Trim();
|
||||
|
||||
const string sql = """
|
||||
select
|
||||
p.id,
|
||||
p.code,
|
||||
p.name,
|
||||
p.category_name as CategoryName,
|
||||
p.specification,
|
||||
p.unit,
|
||||
p.barcode,
|
||||
p.default_warehouse_id as DefaultWarehouseId,
|
||||
p.default_warehouse_name as DefaultWarehouseName,
|
||||
p.lot_managed as LotManaged,
|
||||
p.expiry_managed as ExpiryManaged,
|
||||
p.active,
|
||||
p.version
|
||||
from erp_item_search_projection p
|
||||
where (@Keyword is null or p.search_text ilike '%' || @Keyword || '%')
|
||||
order by p.code
|
||||
limit @PageSize offset @Offset;
|
||||
|
||||
select count(*)::int
|
||||
from erp_item_search_projection p
|
||||
where (@Keyword is null or p.search_text ilike '%' || @Keyword || '%');
|
||||
""";
|
||||
|
||||
await using var connection = await dataSource.OpenConnectionAsync(ct);
|
||||
using var multi = await connection.QueryMultipleAsync(new CommandDefinition(sql, new { Keyword = keyword, PageSize = pageSize, Offset = offset }, cancellationToken: ct));
|
||||
var items = (await multi.ReadAsync<ItemMasterRow>()).AsList();
|
||||
var count = await multi.ReadSingleAsync<int>();
|
||||
return new(items, count);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user