This commit is contained in:
2026-05-06 04:41:48 +03:30
parent f7184c7b79
commit 6b869e82d8
4 changed files with 344 additions and 265 deletions
-33
View File
@@ -1,33 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using xCommons.Attributes;
using xCommons.Configurations;
using xCommons.Providers;
using xIdentityService.Controllers;
using xIdentityService.Interfaces;
namespace xAiApi.Base
{
[ApiController]
[ApiVersion("1.0")]
[RequireXPowered(true)]
[Route("api/v{version:apiVersion}/[controller]")]
public abstract class XIBaseV1Controller : XIBaseController
{
//
#region Constructor ...
protected XIBaseV1Controller(
ILogger<XIBaseV1Controller> logger,
XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider,
XValidationProvider validationProvider
) : base(
logger,
appConfiguration,
identityProvider,
validationProvider
)
{ }
#endregion
}
}
-120
View File
@@ -1,120 +0,0 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using xCommons.Attributes;
using xCommons.Configurations;
using xCommons.Extensions;
using xCommons.Providers;
using xDataService.Interfaces;
using xIdentityService.Controllers;
using xIdentityService.Interfaces;
using xModels.Base;
using xPushService.Base;
using xPushService.Constants;
namespace xAiApi.Base
{
[ApiController]
[ApiVersion("1.0")]
[RequireXPowered(true)]
[Route("api/v{version:apiVersion}/entities/[controller]")]
public abstract class XIBaseV1EntityController<TEntity, TKey> : XIBaseEntityController<TEntity, TKey>
where TEntity : XBaseEntity<TKey>
{
//
#region Constructor ...
protected XIBaseV1EntityController(
ILogger<XIBaseV1EntityController<TEntity, TKey>> logger,
XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider,
XValidationProvider validationProvider,
IXBaseRepository<TEntity, TKey> repository
) : base(
logger,
appConfiguration,
identityProvider,
validationProvider,
repository
)
{ }
#endregion
}
public abstract class XIBaseV1EntityHubController<TEntity, TKey> : XIBaseV1EntityController<TEntity, TKey>
where TEntity : XBaseEntity<TKey>
{
//
#region Props ...
public IHubContext<XBaseEntityHub<TEntity, TKey>> Hub { get; }
#endregion
//
#region Constructor ...
protected XIBaseV1EntityHubController(
ILogger<XIBaseV1EntityHubController<TEntity, TKey>> logger,
XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider,
XValidationProvider validationProvider,
IXBaseRepository<TEntity, TKey> repository,
IHubContext<XBaseEntityHub<TEntity, TKey>> hub = null
) : base(
logger,
appConfiguration,
identityProvider,
validationProvider,
repository
)
{
Hub = hub;
}
#endregion
//
#region Hub ...
[NonAction]
public async Task SendPush(
string action,
string payLoad
)
{
//
var actions = new List<string>
{
XBaseEntityHubAction.Add.GetStringValue(),
XBaseEntityHubAction.Update.GetStringValue(),
XBaseEntityHubAction.Delete.GetStringValue(),
XBaseEntityHubAction.AddMany.GetStringValue(),
XBaseEntityHubAction.DeleteMany.GetStringValue(),
XBaseEntityHubAction.UpdateMany.GetStringValue(),
XBaseEntityHubAction.AddOrUpdate.GetStringValue(),
};
//
// Validate ...
var isValid =
!Hub.IsNull() &&
!action.IsNullOrEmpty() &&
!payLoad.IsNullOrEmpty() &&
actions.Contains(action);
if (!isValid)
{
return;
}
//
// Retrieve Connection Id ...
var connectionId = GetConnectionId();
var clients = Hub.Clients.All;
if (!connectionId.IsNullOrEmpty())
{
clients = Hub.Clients.AllExcept(connectionId);
}
//
await clients.SendAsync(action, payLoad, connectionId);
}
#endregion
}
}
+340 -109
View File
@@ -1,8 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.Extensions.Logging;
using xAiApi.Base;
using xAiApi.Data.Interfaces;
@@ -32,102 +36,53 @@ namespace xAiApi.Controllers.V1.Entities
IXIdentityProvider identityProvider,
XValidationProvider validationProvider,
IXTestRepository repository,
IHubContext<XBaseEntityHub<XTest, int>> hub = null
IHubContext<XBaseEntityHub<XTest, int>> hub = null,
Func<IQueryable<XTest>, IOrderedQueryable<XTest>> defaultOrderBuilder = null,
Func<IQueryable<XTest>, IIncludableQueryable<XTest, object>> defaultIncludeBuilder = null
) : base(
logger,
appConfiguration,
identityProvider,
validationProvider,
repository,
hub
hub: hub,
logger: logger,
repository: repository,
appConfiguration: appConfiguration,
identityProvider: identityProvider,
validationProvider: validationProvider,
defaultOrderBuilder: defaultOrderBuilder,
defaultIncludeBuilder: defaultIncludeBuilder
)
{ }
#endregion
//
#region Interface Implementations ...
//
#region Retrieve ...
[HttpGet("{id}")]
[Authorize(Policy = XPolicies.EnabledUser)]
public override async Task<ActionResult<XTest>> Get(
[FromRoute] int id, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool containsDetail = false
)
{
return await base
.Get(
id: id,
containsDetail: containsDetail,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
}
[HttpGet]
[Authorize(Policy = XPolicies.EnabledUser)]
public override async Task<ActionResult<IEnumerable<XTest>>> GetAll(
[FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool containsDetail = false
)
{
return await base
.GetAll(
containsDetail: containsDetail,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
}
[HttpGet("FindOne/{query}")]
[Authorize(Policy = XPolicies.EnabledUser)]
public override async Task<ActionResult<XTest>> FindOne(
[FromRoute] string query, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool containsDetail = false
)
{
return await base
.FindOne(
query: query,
containsDetail: containsDetail,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
}
[HttpGet("FindMany/{query}")]
[Authorize(Policy = XPolicies.EnabledUser)]
public override async Task<ActionResult<IEnumerable<XTest>>> FindMany(
[FromRoute] string query, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool containsDetail = false
)
{
return await base
.FindMany(
query: query,
containsDetail: containsDetail,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
}
[HttpGet("Query")]
[Authorize(Policy = XPolicies.EnabledUser)]
public override async Task<ActionResult<XQueryResult<XTest>>> Query(
[FromQuery] XQuery query, [FromQuery] bool ignoreSoftDeleteds = true
)
{
return await base
.Query(
query: query,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
}
#endregion
#region Actions ...
//
#region Add ...
/// <summary>
/// Add Specified Item ...
/// </summary>
/// <remarks>
/// Sample request:
///
/// {
/// "title": ""
/// }
///
/// </remarks>
/// <param name="item"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPost]
[Authorize(Policy = XPolicies.EnabledAdminOrAgent)]
public override async Task<ActionResult<XTest>> Add(
[FromBody] XTest item
[FromBody] XTest item,
CancellationToken cancellationToken = default
)
{
//
var entity = await base
.Add(item);
.Add(
item: item,
cancellationToken: cancellationToken
);
//
// Handle Sending Push Notification ...
@@ -135,8 +90,9 @@ namespace xAiApi.Controllers.V1.Entities
{
//
await SendPush(
action: XBaseEntityHubAction.Add.GetStringValue(),
payLoad: entity.ToJSON()
payLoad: entity.ToJSON(),
cancellationToken: cancellationToken,
action: XBaseEntityHubAction.Add.GetStringValue()
);
}
@@ -144,15 +100,33 @@ namespace xAiApi.Controllers.V1.Entities
return entity;
}
/// <summary>
/// Update Specified Item ...
/// </summary>
/// <remarks>
/// Sample request:
///
/// {
/// "title": ""
/// }
///
/// </remarks>
/// <param name="item"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPost("AddOrUpdate")]
[Authorize(Policy = XPolicies.EnabledAdminOrAgent)]
public override async Task<ActionResult<XTest>> AddOrUpdate(
[FromBody] XTest item
[FromBody] XTest item,
CancellationToken cancellationToken = default
)
{
//
var entity = await base
.AddOrUpdate(item);
.AddOrUpdate(
item: item,
cancellationToken: cancellationToken
);
//
// Handle Sending Push Notification ...
@@ -160,8 +134,9 @@ namespace xAiApi.Controllers.V1.Entities
{
//
await SendPush(
action: XBaseEntityHubAction.AddOrUpdate.GetStringValue(),
payLoad: entity.ToJSON()
payLoad: entity.ToJSON(),
cancellationToken: cancellationToken,
action: XBaseEntityHubAction.AddOrUpdate.GetStringValue()
);
}
@@ -169,23 +144,46 @@ namespace xAiApi.Controllers.V1.Entities
return entity;
}
/// <summary>
/// Add Many Specified Items ...
/// </summary>
/// <remarks>
/// Sample request:
///
/// {
/// "items": [
/// {
/// "title": ""
/// }
/// ]
/// }
///
/// </remarks>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPost("AddMany")]
[Authorize(Policy = XPolicies.EnabledAdminOrAgent)]
public override async Task<ActionResult> AddMany(
[FromBody] XBaseRangeRequest<XTest> request
[FromBody] XBaseRangeRequest<XTest> request,
CancellationToken cancellationToken = default
)
{
//
var result = await base
.AddMany(request);
.AddMany(
request: request,
cancellationToken: cancellationToken
);
//
if (!(result as OkObjectResult).IsNull())
{
//
await SendPush(
action: XBaseEntityHubAction.AddMany.GetStringValue(),
payLoad: request.Items.ToJSON()
payLoad: request.Items.ToJSON(),
cancellationToken: cancellationToken,
action: XBaseEntityHubAction.AddMany.GetStringValue()
);
}
@@ -194,19 +192,181 @@ namespace xAiApi.Controllers.V1.Entities
}
#endregion
//
#region Retrieve ...
/// <summary>
/// Get Specified Item by Providing Identifier ...
/// </summary>
/// <param name="id"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="useDefaultIncludes"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("{id}")]
[Authorize(Policy = XPolicies.EnabledUser)]
public override async Task<ActionResult<XTest>> Get(
[FromRoute] int id,
[FromQuery] bool ignoreSoftDeleteds = true,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
)
{
//
return await base
.Get(
id: id,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds,
useDefaultIncludes: useDefaultIncludes
);
}
/// <summary>
/// Get all Exists Items ...
/// </summary>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="useDefaultOrders"></param>
/// <param name="useDefaultIncludes"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet]
[Authorize(Policy = XPolicies.EnabledUser)]
public override async Task<ActionResult<IEnumerable<XTest>>> GetAll(
[FromQuery] bool ignoreSoftDeleteds = true,
[FromQuery] bool useDefaultOrders = false,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
)
{
//
return await base
.GetAll(
useDefaultOrders: useDefaultOrders,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds,
useDefaultIncludes: useDefaultIncludes
);
}
/// <summary>
/// Find Item based on Provided Query ....
/// </summary>
/// <param name="query"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="useDefaultIncludes"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("FindOne/{query}")]
[Authorize(Policy = XPolicies.EnabledUser)]
public override async Task<ActionResult<XTest>> FindOne(
[FromRoute] string query,
[FromQuery] bool ignoreSoftDeleteds = true,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
)
{
//
return await base
.FindOne(
query: query,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds,
useDefaultIncludes: useDefaultIncludes
);
}
/// <summary>
/// Find Items based on Provided Query ...
/// </summary>
/// <param name="query"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="useDefaultOrders"></param>
/// <param name="useDefaultIncludes"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("FindMany/{query}")]
[Authorize(Policy = XPolicies.EnabledUser)]
public override async Task<ActionResult<IEnumerable<XTest>>> FindMany(
[FromRoute] string query,
[FromQuery] bool ignoreSoftDeleteds = true,
[FromQuery] bool useDefaultOrders = false,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
)
{
//
return await base
.FindMany(
query: query,
useDefaultOrders: useDefaultOrders,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds,
useDefaultIncludes: useDefaultIncludes
);
}
/// <summary>
/// Retrieve Items based on Query Mechanism ...
/// </summary>
/// <param name="query"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="useDefaultOrders"></param>
/// <param name="useDefaultIncludes"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("Query")]
[Authorize(Policy = XPolicies.EnabledUser)]
public override async Task<ActionResult<XQueryResult<XTest>>> Query(
[FromQuery] XQuery query,
[FromQuery] bool ignoreSoftDeleteds = true,
[FromQuery] bool useDefaultOrders = false,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
)
{
//
return await base
.Query(
query: query,
useDefaultOrders: useDefaultOrders,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds,
useDefaultIncludes: useDefaultIncludes
);
}
#endregion
//
#region Update ...
/// <summary>
/// Update an Item ...
/// </summary>
/// <remarks>
/// Sample request:
///
/// {
/// "title": ""
/// }
///
/// </remarks>
/// <param name="id"></param>
/// <param name="item"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPut("{id}")]
[Authorize(Policy = XPolicies.EnabledAdminOrAgent)]
public override async Task<ActionResult<XTest>> Update(
[FromRoute] int id, [FromBody] XTest item
[FromRoute] int id,
[FromBody] XTest item,
CancellationToken cancellationToken = default
)
{
//
var entity = await base
.Update(
id,
item
id: id,
item: item,
cancellationToken: cancellationToken
);
//
@@ -214,8 +374,9 @@ namespace xAiApi.Controllers.V1.Entities
{
//
await SendPush(
action: XBaseEntityHubAction.Update.GetStringValue(),
payLoad: entity.ToJSON()
payLoad: entity.ToJSON(),
cancellationToken: cancellationToken,
action: XBaseEntityHubAction.Update.GetStringValue()
);
}
@@ -223,15 +384,38 @@ namespace xAiApi.Controllers.V1.Entities
return entity;
}
/// <summary>
/// Update a Collection of Items ...
/// </summary>
/// <remarks>
/// Sample request:
///
/// {
/// "items": [
/// {
/// "id": 1,
/// "title": "Hi there ..."
/// }
/// ]
/// }
///
/// </remarks>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPost("UpdateMany")]
[Authorize(Policy = XPolicies.EnabledAdminOrAgent)]
public override async Task<ActionResult<bool>> UpdateMany(
[FromBody] XBaseRangeRequest<XTest> request
[FromBody] XBaseRangeRequest<XTest> request,
CancellationToken cancellationToken = default
)
{
//
var result = await base
.UpdateMany(request);
.UpdateMany(
request: request,
cancellationToken: cancellationToken
);
//
var resultObject = (result.Result as OkObjectResult).Value;
@@ -239,8 +423,9 @@ namespace xAiApi.Controllers.V1.Entities
{
//
await SendPush(
action: XBaseEntityHubAction.UpdateMany.GetStringValue(),
payLoad: request.Items.ToJSON()
payLoad: request.Items.ToJSON(),
cancellationToken: cancellationToken,
action: XBaseEntityHubAction.UpdateMany.GetStringValue()
);
}
@@ -251,15 +436,26 @@ namespace xAiApi.Controllers.V1.Entities
//
#region Exists ...
/// <summary>
/// Check an Item Exists or not ...
/// </summary>
/// <param name="id"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("{id}/IsExists")]
[Authorize(Policy = XPolicies.EnabledUser)]
public override async Task<ActionResult<bool>> IsExists(
[FromRoute] int id, [FromQuery] bool ignoreSoftDeleteds = true
[FromRoute] int id,
[FromQuery] bool ignoreSoftDeleteds = true,
CancellationToken cancellationToken = default
)
{
//
return await base
.IsExists(
id: id,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
}
@@ -267,17 +463,27 @@ namespace xAiApi.Controllers.V1.Entities
//
#region Remove ...
/// <summary>
/// Remove an Item ...
/// </summary>
/// <param name="id"></param>
/// <param name="softDelete"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpDelete("{id}")]
[Authorize(Policy = XPolicies.EnabledAdminOrAgent)]
public override async Task<ActionResult<XTest>> Remove(
[FromRoute] int id, bool softDelete = true
[FromRoute] int id,
[FromQuery] bool softDelete = true,
CancellationToken cancellationToken = default
)
{
//
var entity = await base
.Remove(
id: id,
softDelete: softDelete
softDelete: softDelete,
cancellationToken: cancellationToken
);
//
@@ -285,8 +491,9 @@ namespace xAiApi.Controllers.V1.Entities
{
//
await SendPush(
action: XBaseEntityHubAction.Delete.GetStringValue(),
payLoad: entity.ToJSON()
payLoad: entity.ToJSON(),
cancellationToken: cancellationToken,
action: XBaseEntityHubAction.Delete.GetStringValue()
);
}
@@ -294,17 +501,40 @@ namespace xAiApi.Controllers.V1.Entities
return entity;
}
/// <summary>
/// Remove Many Items ...
/// </summary>
/// <remarks>
/// Sample request:
///
/// {
/// "items": [
/// {
/// "id": 1,
/// "title": "Hi there ..."
/// }
/// ]
/// }
///
/// </remarks>
/// <param name="request"></param>
/// <param name="softDelete"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPost("RemoveMany")]
[Authorize(Policy = XPolicies.EnabledAdminOrAgent)]
public override async Task<ActionResult> RemoveMany(
[FromBody] XBaseRangeRequest<XTest> request, bool softDelete = true
[FromBody] XBaseRangeRequest<XTest> request,
[FromQuery] bool softDelete = true,
CancellationToken cancellationToken = default
)
{
//
var result = await base
.RemoveMany(
request: request,
softDelete: softDelete
softDelete: softDelete,
cancellationToken: cancellationToken
);
//
@@ -312,8 +542,9 @@ namespace xAiApi.Controllers.V1.Entities
{
//
await SendPush(
action: XBaseEntityHubAction.DeleteMany.GetStringValue(),
payLoad: request.Items.ToJSON()
payLoad: request.Items.ToJSON(),
cancellationToken: cancellationToken,
action: XBaseEntityHubAction.DeleteMany.GetStringValue()
);
}
+4 -3
View File
@@ -19,21 +19,22 @@
<ItemGroup>
<ProjectReference Include="..\Modules\xCommons\xCommons.csproj" />
<ProjectReference Include="..\Modules\xAiModels\xAiModels.csproj" />
<ProjectReference Include="..\Modules\xDataService\xDataService.csproj" />
<ProjectReference Include="..\Modules\xPushService\xPushService.csproj" />
<ProjectReference Include="..\Modules\xIdentityHelper\xIdentityHelper.csproj" />
</ItemGroup>
<!-- Local Modules -->
<ItemGroup>
<!-- <PackageReference Include="xDashboard.xCommons" Version="1.0.0" /> -->
<PackageReference Include="xDashboard.xDataService" Version="1.0.0" />
<PackageReference Include="xDashboard.xPushService" Version="1.0.0" />
<!-- <PackageReference Include="xDashboard.xDataService" Version="1.0.0" />
<PackageReference Include="xDashboard.xPushService" Version="1.0.0" /> -->
</ItemGroup>
<!-- Dependencies -->
<ItemGroup>
<PackageReference Include="OllamaSharp" Version="5.4.25" />
<PackageReference Include="Microsoft.SemanticKernel" Version="1.65.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.11" />
<PackageReference Include="IdentityModel.AspNetCore.OAuth2Introspection" Version="5.0.0" />
</ItemGroup>