feat(web-client-tpos): connect product catalog and create to catalog-service API
This commit is contained in:
@@ -149,4 +149,85 @@ public class BffDataController : ControllerBase
|
||||
new { ShopId = shopId });
|
||||
return Ok(resources);
|
||||
}
|
||||
|
||||
// ═══ ADMIN-LEVEL PRODUCT ENDPOINTS ═══
|
||||
|
||||
/// <summary>
|
||||
/// EN: Get all products across all shops (admin level).
|
||||
/// VI: Lấy tất cả sản phẩm trên tất cả cửa hàng (cấp admin).
|
||||
/// </summary>
|
||||
[HttpGet("products")]
|
||||
public async Task<IActionResult> GetAllProducts([FromQuery] Guid? shopId = null)
|
||||
{
|
||||
await using var conn = new NpgsqlConnection(ConnStr("catalog_service"));
|
||||
var sql = @"SELECT p.id, p.name, p.price, p.sku, p.description, p.image_url,
|
||||
p.is_active, pt.name as type, p.shop_id, p.created_at,
|
||||
'' as category_name
|
||||
FROM products p
|
||||
JOIN product_types pt ON p.type_id = pt.id";
|
||||
if (shopId.HasValue)
|
||||
sql += " WHERE p.shop_id = @ShopId";
|
||||
sql += " ORDER BY p.name";
|
||||
var products = await conn.QueryAsync<dynamic>(sql, new { ShopId = shopId });
|
||||
return Ok(products);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EN: Get all categories across all shops (admin level).
|
||||
/// VI: Lấy tất cả danh mục trên tất cả cửa hàng (cấp admin).
|
||||
/// </summary>
|
||||
[HttpGet("categories")]
|
||||
public async Task<IActionResult> GetAllCategories([FromQuery] Guid? shopId = null)
|
||||
{
|
||||
await using var conn = new NpgsqlConnection(ConnStr("catalog_service"));
|
||||
var sql = @"SELECT id, name, description, display_order, shop_id, parent_id, is_active
|
||||
FROM categories WHERE is_active = true";
|
||||
if (shopId.HasValue)
|
||||
sql += " AND shop_id = @ShopId";
|
||||
sql += " ORDER BY display_order, name";
|
||||
var categories = await conn.QueryAsync<dynamic>(sql, new { ShopId = shopId });
|
||||
return Ok(categories);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EN: Create a product via BFF (writes directly to catalog DB).
|
||||
/// VI: Tạo sản phẩm qua BFF (ghi trực tiếp vào catalog DB).
|
||||
/// </summary>
|
||||
[HttpPost("products")]
|
||||
public async Task<IActionResult> CreateProduct([FromBody] CreateProductRequest req)
|
||||
{
|
||||
var id = Guid.NewGuid();
|
||||
// EN: Map type string to type_id / VI: Chuyển type string sang type_id
|
||||
var typeId = (req.Type ?? "PreparedFood") switch
|
||||
{
|
||||
"Physical" => 1,
|
||||
"Service" => 2,
|
||||
"PreparedFood" => 3,
|
||||
_ => 3
|
||||
};
|
||||
await using var conn = new NpgsqlConnection(ConnStr("catalog_service"));
|
||||
await conn.ExecuteAsync(
|
||||
@"INSERT INTO products (id, shop_id, name, description, price, type_id, sku, image_url, is_active, created_at)
|
||||
VALUES (@Id, @ShopId, @Name, @Description, @Price, @TypeId, @Sku, @ImageUrl, true, NOW())",
|
||||
new { Id = id, req.ShopId, req.Name, req.Description, req.Price, TypeId = typeId, req.Sku, req.ImageUrl });
|
||||
return CreatedAtAction(nameof(GetAllProducts), new { }, new { id });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EN: Delete (deactivate) a product.
|
||||
/// VI: Xóa (vô hiệu hóa) sản phẩm.
|
||||
/// </summary>
|
||||
[HttpDelete("products/{productId:guid}")]
|
||||
public async Task<IActionResult> DeleteProduct(Guid productId)
|
||||
{
|
||||
await using var conn = new NpgsqlConnection(ConnStr("catalog_service"));
|
||||
await conn.ExecuteAsync(
|
||||
"UPDATE products SET is_active = false WHERE id = @Id",
|
||||
new { Id = productId });
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
// EN: Request DTOs / VI: DTO yêu cầu
|
||||
public record CreateProductRequest(Guid ShopId, string Name, string? Description, decimal Price, string? Type, string? Sku, string? ImageUrl);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user