Skip to content

Commit ac41f85

Browse files
committed
Full Materials for Subjects
1 parent 181343d commit ac41f85

10 files changed

Lines changed: 812 additions & 1 deletion

File tree

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
using FPTStella.Application.Common.Interfaces.Services;
2+
using FPTStella.Contracts.DTOs.Materials;
3+
using Microsoft.AspNetCore.Http;
4+
using Microsoft.AspNetCore.Mvc;
5+
6+
namespace FPTStella.API.Controllers
7+
{
8+
[Route("api/[controller]")]
9+
[ApiController]
10+
public class MaterialController : BaseController
11+
{
12+
private readonly IMaterialService _materialService;
13+
public MaterialController(IMaterialService materialService)
14+
{
15+
_materialService = materialService;
16+
}
17+
[HttpGet]
18+
public async Task<IActionResult> GetAllMaterials()
19+
{
20+
try
21+
{
22+
var materials = await _materialService.GetAllMaterialsAsync();
23+
return Ok(materials);
24+
}
25+
catch (Exception ex)
26+
{
27+
return HandleException(ex);
28+
}
29+
}
30+
31+
[HttpGet("{id}")]
32+
public async Task<IActionResult> GetMaterialById(string id)
33+
{
34+
try
35+
{
36+
var material = await _materialService.GetMaterialByIdAsync(id);
37+
return Ok(material);
38+
}
39+
catch (KeyNotFoundException ex)
40+
{
41+
return NotFound(ex.Message);
42+
}
43+
catch (Exception ex)
44+
{
45+
return HandleException(ex);
46+
}
47+
}
48+
49+
[HttpGet("name/{name}")]
50+
public async Task<IActionResult> GetMaterialByName(string name)
51+
{
52+
try
53+
{
54+
var material = await _materialService.GetMaterialByNameAsync(name);
55+
if (material == null)
56+
{
57+
return NotFound($"Material with name '{name}' not found.");
58+
}
59+
return Ok(material);
60+
}
61+
catch (Exception ex)
62+
{
63+
return HandleException(ex);
64+
}
65+
}
66+
67+
[HttpGet("subject/{subjectId}")]
68+
public async Task<IActionResult> GetMaterialsBySubjectId(Guid subjectId)
69+
{
70+
try
71+
{
72+
var materials = await _materialService.GetMaterialsBySubjectIdAsync(subjectId);
73+
return Ok(materials);
74+
}
75+
catch (Exception ex)
76+
{
77+
return HandleException(ex);
78+
}
79+
}
80+
81+
[HttpGet("type/{type}")]
82+
public async Task<IActionResult> GetMaterialsByType(string type)
83+
{
84+
try
85+
{
86+
var materials = await _materialService.GetMaterialsByTypeAsync(type);
87+
return Ok(materials);
88+
}
89+
catch (Exception ex)
90+
{
91+
return HandleException(ex);
92+
}
93+
}
94+
95+
/// <summary>
96+
/// Search for materials with filters and pagination
97+
/// </summary>
98+
/// <param name="searchTerm">Optional search term</param>
99+
/// <param name="subjectId">Optional subject ID filter</param>
100+
/// <param name="materialType">Optional material type filter</param>
101+
/// <param name="pageNumber">Page number (default: 1)</param>
102+
/// <param name="pageSize">Page size (default: 10)</param>
103+
/// <returns>Paged results of materials</returns>
104+
[HttpGet("search")]
105+
public async Task<IActionResult> SearchMaterials(
106+
[FromQuery] string? searchTerm = null,
107+
[FromQuery] Guid? subjectId = null,
108+
[FromQuery] string? materialType = null,
109+
[FromQuery] int pageNumber = 1,
110+
[FromQuery] int pageSize = 10)
111+
{
112+
try
113+
{
114+
var results = await _materialService.SearchMaterialsAsync(
115+
searchTerm,
116+
subjectId,
117+
materialType,
118+
pageNumber,
119+
pageSize);
120+
121+
return Ok(results);
122+
}
123+
catch (Exception ex)
124+
{
125+
return HandleException(ex);
126+
}
127+
}
128+
129+
[HttpPost]
130+
public async Task<IActionResult> CreateMaterial([FromBody] CreateMaterialDto createMaterialDto)
131+
{
132+
try
133+
{
134+
var material = await _materialService.CreateMaterialAsync(createMaterialDto);
135+
return CreatedAtAction(nameof(GetMaterialById), new { id = material.Id }, material);
136+
}
137+
catch (InvalidOperationException ex)
138+
{
139+
return BadRequest(ex.Message);
140+
}
141+
catch (KeyNotFoundException ex)
142+
{
143+
return NotFound(ex.Message);
144+
}
145+
catch (Exception ex)
146+
{
147+
return HandleException(ex);
148+
}
149+
}
150+
151+
[HttpPut("{id}")]
152+
public async Task<IActionResult> UpdateMaterial(string id, [FromBody] UpdateMaterialDto updateMaterialDto)
153+
{
154+
try
155+
{
156+
var success = await _materialService.UpdateMaterialAsync(id, updateMaterialDto);
157+
return success ? NoContent() : BadRequest("Failed to update material.");
158+
}
159+
catch (KeyNotFoundException ex)
160+
{
161+
return NotFound(ex.Message);
162+
}
163+
catch (InvalidOperationException ex)
164+
{
165+
return BadRequest(ex.Message);
166+
}
167+
catch (Exception ex)
168+
{
169+
return HandleException(ex);
170+
}
171+
}
172+
173+
[HttpDelete("{id}")]
174+
public async Task<IActionResult> DeleteMaterial(string id)
175+
{
176+
try
177+
{
178+
var success = await _materialService.DeleteMaterialAsync(id);
179+
return success ? NoContent() : BadRequest("Failed to delete material.");
180+
}
181+
catch (KeyNotFoundException ex)
182+
{
183+
return NotFound(ex.Message);
184+
}
185+
catch (Exception ex)
186+
{
187+
return HandleException(ex);
188+
}
189+
}
190+
191+
[HttpDelete("subject/{subjectId}")]
192+
public async Task<IActionResult> DeleteMaterialsBySubjectId(Guid subjectId)
193+
{
194+
try
195+
{
196+
var success = await _materialService.DeleteMaterialsBySubjectIdAsync(subjectId);
197+
return success ? NoContent() : BadRequest("Failed to delete materials for subject.");
198+
}
199+
catch (Exception ex)
200+
{
201+
return HandleException(ex);
202+
}
203+
}
204+
}
205+
}

FPTStella/FPTStella.API/Program.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
builder.Services.AddSingleton<ISubjectComboSubjectRepository, SubjectComboSubjectRepository>();
4848
builder.Services.AddSingleton<IToolRepository, ToolRepository>();
4949
builder.Services.AddScoped<ISubjectToolRepository, SubjectToolRepository>();
50+
builder.Services.AddSingleton<IMaterialRepository, MaterialRepository>();
5051

5152

5253
// Đăng ký DI cho Application
@@ -65,6 +66,7 @@
6566
builder.Services.AddSingleton<ISubjectComboService, SubjectComboService>();
6667
builder.Services.AddSingleton<ISubjectComboSubjectService, SubjectComboSubjectService>();
6768
builder.Services.AddSingleton<IToolService, ToolService>();
69+
builder.Services.AddSingleton<IMaterialService, MaterialService>();
6870

6971
builder.Services.AddScoped<IGoogleAuthService, GoogleAuthService>();
7072
builder.Services.AddScoped<GoogleLoginUseCase>();
@@ -97,7 +99,7 @@
9799
builder.Services.AddEndpointsApiExplorer();
98100
builder.Services.AddSwaggerGen(c =>
99101
{
100-
c.SwaggerDoc("v1", new OpenApiInfo { Title = "✨ FPT Stella ✨", Version = "v1.3.0" });
102+
c.SwaggerDoc("v1", new OpenApiInfo { Title = "✨ FPT Stella ✨", Version = "v2.0.0" });
101103

102104
// Cấu hình Bearer token
103105
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using FPTStella.Application.Common.Interfaces.UnitOfWorks;
2+
using FPTStella.Domain.Common;
3+
using FPTStella.Domain.Entities;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using System.Text;
8+
using System.Threading.Tasks;
9+
10+
namespace FPTStella.Application.Common.Interfaces.Repositories
11+
{
12+
public interface IMaterialRepository : IRepository<Materials>
13+
{
14+
/// <summary>
15+
/// Gets materials by subject ID
16+
/// </summary>
17+
/// <param name="subjectId">The subject ID to search for</param>
18+
/// <returns>List of materials related to the subject</returns>
19+
Task<List<Materials>> GetBySubjectIdAsync(Guid subjectId);
20+
/// <summary>
21+
/// Gets a material by its name
22+
/// </summary>
23+
/// <param name="materialName">The material name to search for</param>
24+
/// <returns>The material if found, otherwise null</returns>
25+
Task<Materials?> GetByMaterialNameAsync(string materialName);
26+
/// <summary>
27+
/// Gets materials by material type
28+
/// </summary>
29+
/// <param name="materialType">The material type to search for</param>
30+
/// <returns>List of materials of the specified type</returns>
31+
Task<List<Materials>> GetByMaterialTypeAsync(string materialType);
32+
/// <summary>
33+
/// Searches for materials with advanced filtering options and pagination
34+
/// </summary>
35+
/// <param name="searchTerm">Optional search term for text-based fields</param>
36+
/// <param name="subjectId">Optional subject ID filter</param>
37+
/// <param name="materialType">Optional material type filter</param>
38+
/// <param name="paginationParams">Pagination parameters</param>
39+
/// <returns>Paginated results of materials</returns>
40+
Task<PagedResult<Materials>> SearchMaterialsAsync(
41+
string? searchTerm = null,
42+
Guid? subjectId = null,
43+
string? materialType = null,
44+
PaginationParams? paginationParams = null);
45+
}
46+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using FPTStella.Contracts.DTOs.Materials;
2+
using FPTStella.Domain.Common;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
9+
namespace FPTStella.Application.Common.Interfaces.Services
10+
{
11+
public interface IMaterialService
12+
{
13+
/// <summary>
14+
/// Creates a new material
15+
/// </summary>
16+
/// <param name="createMaterialDto">The data for the new material</param>
17+
/// <returns>The created material as a DTO</returns>
18+
Task<MaterialDto> CreateMaterialAsync(CreateMaterialDto createMaterialDto);
19+
/// <summary>
20+
/// Gets a material by its ID
21+
/// </summary>
22+
/// <param name="id">The ID of the material</param>
23+
/// <returns>The material as a DTO if found</returns>
24+
Task<MaterialDto> GetMaterialByIdAsync(string id);
25+
/// <summary>
26+
/// Gets a material by its name
27+
/// </summary>
28+
/// <param name="materialName">The name of the material</param>
29+
/// <returns>The material as a DTO if found, otherwise null</returns>
30+
Task<MaterialDto?> GetMaterialByNameAsync(string materialName);
31+
/// <summary>
32+
/// Gets all materials for a specific subject
33+
/// </summary>
34+
/// <param name="subjectId">The subject ID</param>
35+
/// <returns>List of materials as DTOs</returns>
36+
Task<List<MaterialDto>> GetMaterialsBySubjectIdAsync(Guid subjectId);
37+
/// <summary>
38+
/// Gets all materials with a specific type
39+
/// </summary>
40+
/// <param name="materialType">The material type</param>
41+
/// <returns>List of materials as DTOs</returns>
42+
Task<List<MaterialDto>> GetMaterialsByTypeAsync(string materialType);
43+
/// <summary>
44+
/// Gets all materials
45+
/// </summary>
46+
/// <returns>List of all materials as DTOs</returns>
47+
Task<List<MaterialDto>> GetAllMaterialsAsync();
48+
/// <summary>
49+
/// Updates a material
50+
/// </summary>
51+
/// <param name="id">The ID of the material to update</param>
52+
/// <param name="updateMaterialDto">The update data</param>
53+
/// <returns>True if successful, otherwise false</returns>
54+
Task<bool> UpdateMaterialAsync(string id, UpdateMaterialDto updateMaterialDto);
55+
/// <summary>
56+
/// Deletes a material by its ID
57+
/// </summary>
58+
/// <param name="id">The ID of the material to delete</param>
59+
/// <returns>True if successful, otherwise false</returns>
60+
Task<bool> DeleteMaterialAsync(string id);
61+
/// <summary>
62+
/// Deletes all materials for a specific subject
63+
/// </summary>
64+
/// <param name="subjectId">The subject ID</param>
65+
/// <returns>True if successful, otherwise false</returns>
66+
Task<bool> DeleteMaterialsBySubjectIdAsync(Guid subjectId);
67+
/// <summary>
68+
/// Searches for materials with pagination
69+
/// </summary>
70+
/// <param name="searchTerm">Optional search term for material name or description</param>
71+
/// <param name="subjectId">Optional subject ID filter</param>
72+
/// <param name="materialType">Optional material type filter</param>
73+
/// <param name="pageNumber">Page number (default: 1)</param>
74+
/// <param name="pageSize">Page size (default: 10)</param>
75+
/// <returns>Paged result of materials as DTOs</returns>
76+
Task<PagedResult<MaterialDto>> SearchMaterialsAsync(
77+
string? searchTerm = null,
78+
Guid? subjectId = null,
79+
string? materialType = null,
80+
int pageNumber = 1,
81+
int pageSize = 10);
82+
}
83+
}

0 commit comments

Comments
 (0)