using Common;
using Common.Constant;
using Common.Http;
using Esim.Apis.Singleton;
using Database.Database;
using log4net;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace Esim.Apis.Business
{
public class ArticleBusinessImpl : IArticleBusiness
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(
typeof(ArticleBusinessImpl)
);
private ModelContext dbContext;
IConfiguration configuration;
public ArticleBusinessImpl(ModelContext _dbContext, IConfiguration _configuration)
{
dbContext = _dbContext;
configuration = _configuration;
}
private string GetParameter(string key)
{
return configuration.GetSection(key).Value ?? "";
}
///
/// Load article categories with pagination
///
public async Task ArticleCategory(HttpRequest httpRequest, ArticleCategoryReq request)
{
var url = httpRequest.Path;
var json = JsonConvert.SerializeObject(request);
log.Debug("URL: " + url + " => Request: " + json);
try
{
string lang = (request.lang ?? "lo").ToLower();
int pageNumber = request.pageNumber < 0 ? 0 : request.pageNumber;
int pageSize = request.pageSize <= 0 ? 10 : request.pageSize;
// Query categories
var query = dbContext.ArticleCategories
.Where(c => c.Status == true);
// Filter by parent category
if (request.parentId.HasValue)
{
query = query.Where(c => c.ParentId == request.parentId);
}
else
{
query = query.Where(c => c.ParentId == null); // Root categories
}
// Get total count for pagination
int totalCount = query.Count();
int totalPages = (int)Math.Ceiling((double)totalCount / pageSize);
// Apply pagination and ordering
var categories = query
.OrderBy(c => c.DisplayOrder)
.ThenBy(c => c.Id)
.Skip(pageNumber * pageSize)
.Take(pageSize)
.Select(c => new
{
c.Id,
categoryName = lang == "en"
? (c.CategoryNameEn ?? c.CategoryName)
: (c.CategoryNameLo ?? c.CategoryName),
c.CategorySlug,
description = lang == "en"
? (c.DescriptionEn ?? c.Description)
: (c.DescriptionLo ?? c.Description),
c.IconUrl,
c.ParentId,
c.DisplayOrder
})
.ToList();
return DotnetLib.Http.HttpResponse.BuildResponse(
log,
url,
json,
CommonErrorCode.Success,
ConfigManager.Instance.GetConfigWebValue("LOAD_SUCCESS", lang),
new
{
items = categories,
pagination = new
{
pageNumber,
pageSize,
totalCount,
totalPages
}
}
);
}
catch (Exception exception)
{
log.Error("Exception: ", exception);
}
return DotnetLib.Http.HttpResponse.BuildResponse(
log,
url,
json,
CommonErrorCode.SystemError,
ConfigManager.Instance.GetConfigWebValue("SYSTEM_FAILURE"),
new { }
);
}
///
/// Load articles with pagination and filters
///
public async Task ArticleLoad(HttpRequest httpRequest, ArticleLoadReq request)
{
var url = httpRequest.Path;
var json = JsonConvert.SerializeObject(request);
log.Debug("URL: " + url + " => Request: " + json);
try
{
string lang = (request.lang ?? "lo").ToLower();
int pageNumber = request.pageNumber < 0 ? 0 : request.pageNumber;
int pageSize = request.pageSize <= 0 ? 10 : request.pageSize;
// If slug is provided, return single article detail
if (!string.IsNullOrEmpty(request.slug))
{
var article = dbContext.Articles
.Where(a => a.Slug == request.slug && a.Status == true)
.Select(a => new
{
a.Id,
title = lang == "en"
? (a.TitleEn ?? a.Title)
: (a.TitleLo ?? a.Title),
a.Slug,
summary = lang == "en"
? (a.SummaryEn ?? a.Summary)
: (a.SummaryLo ?? a.Summary),
content = lang == "en"
? (a.ContentEn ?? a.Content)
: (a.ContentLo ?? a.Content),
a.ThumbnailUrl,
a.CoverImageUrl,
metaDescription = lang == "en"
? (a.MetaDescriptionEn ?? a.MetaDescription)
: (a.MetaDescriptionLo ?? a.MetaDescription),
a.MetaKeywords,
a.CategoryId,
a.ViewCount,
a.IsFeatured,
a.PublishedDate,
a.CreatedDate
})
.FirstOrDefault();
if (article == null)
{
return DotnetLib.Http.HttpResponse.BuildResponse(
log,
url,
json,
CommonErrorCode.Error,
ConfigManager.Instance.GetConfigWebValue("ARTICLE_NOT_FOUND", lang),
new { }
);
}
// Increment view count
var articleEntity = dbContext.Articles.FirstOrDefault(a => a.Slug == request.slug);
if (articleEntity != null)
{
articleEntity.ViewCount = (articleEntity.ViewCount ?? 0) + 1;
await dbContext.SaveChangesAsync();
}
return DotnetLib.Http.HttpResponse.BuildResponse(
log,
url,
json,
CommonErrorCode.Success,
ConfigManager.Instance.GetConfigWebValue("LOAD_SUCCESS", lang),
new { article }
);
}
// Query articles list
var query = dbContext.Articles
.Where(a => a.Status == true);
// Filter by category
if (request.categoryId.HasValue)
{
query = query.Where(a => a.CategoryId == request.categoryId);
}
// Filter by featured
if (request.isFeatured.HasValue && request.isFeatured.Value)
{
query = query.Where(a => a.IsFeatured == true);
}
// Get total count for pagination
int totalCount = query.Count();
int totalPages = (int)Math.Ceiling((double)totalCount / pageSize);
// Apply pagination and ordering (pinned first, then by published date)
var articles = query
.OrderByDescending(a => a.IsPinned)
.ThenByDescending(a => a.PublishedDate)
.ThenByDescending(a => a.CreatedDate)
.Skip(pageNumber * pageSize)
.Take(pageSize)
.Select(a => new
{
a.Id,
title = lang == "en"
? (a.TitleEn ?? a.Title)
: (a.TitleLo ?? a.Title),
a.Slug,
summary = lang == "en"
? (a.SummaryEn ?? a.Summary)
: (a.SummaryLo ?? a.Summary),
a.ThumbnailUrl,
a.CategoryId,
a.ViewCount,
a.IsFeatured,
a.IsPinned,
a.PublishedDate
})
.ToList();
return DotnetLib.Http.HttpResponse.BuildResponse(
log,
url,
json,
CommonErrorCode.Success,
ConfigManager.Instance.GetConfigWebValue("LOAD_SUCCESS", lang),
new
{
items = articles,
pagination = new
{
pageNumber,
pageSize,
totalCount,
totalPages
}
}
);
}
catch (Exception exception)
{
log.Error("Exception: ", exception);
}
return DotnetLib.Http.HttpResponse.BuildResponse(
log,
url,
json,
CommonErrorCode.SystemError,
ConfigManager.Instance.GetConfigWebValue("SYSTEM_FAILURE"),
new { }
);
}
}
}