191 lines
6.5 KiB
C#
191 lines
6.5 KiB
C#
using BCards.Web.Models;
|
|
using BCards.Web.Repositories;
|
|
using System.Text.RegularExpressions;
|
|
using System.Globalization;
|
|
using System.Text;
|
|
|
|
namespace BCards.Web.Services;
|
|
|
|
public class CategoryService : ICategoryService
|
|
{
|
|
private readonly ICategoryRepository _categoryRepository;
|
|
|
|
public CategoryService(ICategoryRepository categoryRepository)
|
|
{
|
|
_categoryRepository = categoryRepository;
|
|
}
|
|
|
|
public async Task<List<Category>> GetAllCategoriesAsync()
|
|
{
|
|
return await _categoryRepository.GetAllActiveAsync();
|
|
}
|
|
|
|
public async Task<Category?> GetCategoryBySlugAsync(string slug)
|
|
{
|
|
return await _categoryRepository.GetBySlugAsync(slug);
|
|
}
|
|
|
|
public async Task<string> GenerateSlugAsync(string name)
|
|
{
|
|
var slug = GenerateSlug(name);
|
|
var originalSlug = slug;
|
|
var counter = 1;
|
|
|
|
while (await _categoryRepository.SlugExistsAsync(slug))
|
|
{
|
|
slug = $"{originalSlug}-{counter}";
|
|
counter++;
|
|
}
|
|
|
|
return slug;
|
|
}
|
|
|
|
public async Task<bool> ValidateSlugAsync(string slug, string? excludeId = null)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(slug))
|
|
return false;
|
|
|
|
if (!IsValidSlugFormat(slug))
|
|
return false;
|
|
|
|
return !await _categoryRepository.SlugExistsAsync(slug, excludeId);
|
|
}
|
|
|
|
public async Task InitializeDefaultCategoriesAsync()
|
|
{
|
|
var categories = await _categoryRepository.GetAllActiveAsync();
|
|
if (categories.Any()) return;
|
|
|
|
var defaultCategories = new[]
|
|
{
|
|
new Category
|
|
{
|
|
Name = "Corretor de Imóveis",
|
|
Slug = "corretor",
|
|
Icon = "🏠",
|
|
Description = "Profissionais especializados em compra, venda e locação de imóveis",
|
|
SeoKeywords = new List<string> { "corretor", "imóveis", "casa", "apartamento", "venda", "locação" }
|
|
},
|
|
new Category
|
|
{
|
|
Name = "Tecnologia",
|
|
Slug = "tecnologia",
|
|
Icon = "💻",
|
|
Description = "Empresas e profissionais de tecnologia, desenvolvimento e TI",
|
|
SeoKeywords = new List<string> { "desenvolvimento", "software", "programação", "tecnologia", "TI" }
|
|
},
|
|
new Category
|
|
{
|
|
Name = "Saúde",
|
|
Slug = "saude",
|
|
Icon = "🏥",
|
|
Description = "Profissionais da saúde, clínicas e consultórios médicos",
|
|
SeoKeywords = new List<string> { "médico", "saúde", "clínica", "consulta", "tratamento" }
|
|
},
|
|
new Category
|
|
{
|
|
Name = "Educação",
|
|
Slug = "educacao",
|
|
Icon = "📚",
|
|
Description = "Professores, escolas, cursos e instituições de ensino",
|
|
SeoKeywords = new List<string> { "educação", "ensino", "professor", "curso", "escola" }
|
|
},
|
|
new Category
|
|
{
|
|
Name = "Comércio",
|
|
Slug = "comercio",
|
|
Icon = "🛍️",
|
|
Description = "Lojas, e-commerce e estabelecimentos comerciais",
|
|
SeoKeywords = new List<string> { "loja", "comércio", "venda", "produtos", "e-commerce" }
|
|
},
|
|
new Category
|
|
{
|
|
Name = "Serviços",
|
|
Slug = "servicos",
|
|
Icon = "🔧",
|
|
Description = "Prestadores de serviços gerais e especializados",
|
|
SeoKeywords = new List<string> { "serviços", "prestador", "profissional", "especializado" }
|
|
},
|
|
new Category
|
|
{
|
|
Name = "Alimentação",
|
|
Slug = "alimentacao",
|
|
Icon = "🍽️",
|
|
Description = "Restaurantes, delivery, food trucks e estabelecimentos alimentícios",
|
|
SeoKeywords = new List<string> { "restaurante", "comida", "delivery", "alimentação", "gastronomia" }
|
|
},
|
|
new Category
|
|
{
|
|
Name = "Beleza",
|
|
Slug = "beleza",
|
|
Icon = "💄",
|
|
Description = "Salões de beleza, barbearias, estética e cuidados pessoais",
|
|
SeoKeywords = new List<string> { "beleza", "salão", "estética", "cabeleireiro", "manicure" }
|
|
},
|
|
new Category
|
|
{
|
|
Name = "Advocacia",
|
|
Slug = "advocacia",
|
|
Icon = "⚖️",
|
|
Description = "Advogados, escritórios jurídicos e consultoria legal",
|
|
SeoKeywords = new List<string> { "advogado", "jurídico", "direito", "advocacia", "legal" }
|
|
},
|
|
new Category
|
|
{
|
|
Name = "Arquitetura",
|
|
Slug = "arquitetura",
|
|
Icon = "🏗️",
|
|
Description = "Arquitetos, engenheiros e profissionais da construção",
|
|
SeoKeywords = new List<string> { "arquiteto", "engenheiro", "construção", "projeto", "reforma" }
|
|
}
|
|
};
|
|
|
|
foreach (var category in defaultCategories)
|
|
{
|
|
await _categoryRepository.CreateAsync(category);
|
|
}
|
|
}
|
|
|
|
private static string GenerateSlug(string text)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(text))
|
|
return string.Empty;
|
|
|
|
// Remove acentos
|
|
text = RemoveDiacritics(text);
|
|
|
|
// Converter para minúsculas
|
|
text = text.ToLowerInvariant();
|
|
|
|
// Substituir espaços e caracteres especiais por hífens
|
|
text = Regex.Replace(text, @"[^a-z0-9\s-]", "");
|
|
text = Regex.Replace(text, @"[\s-]+", "-");
|
|
|
|
// Remover hífens do início e fim
|
|
text = text.Trim('-');
|
|
|
|
return text;
|
|
}
|
|
|
|
private static string RemoveDiacritics(string text)
|
|
{
|
|
var normalizedString = text.Normalize(NormalizationForm.FormD);
|
|
var stringBuilder = new StringBuilder();
|
|
|
|
foreach (var c in normalizedString)
|
|
{
|
|
var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
|
|
if (unicodeCategory != UnicodeCategory.NonSpacingMark)
|
|
{
|
|
stringBuilder.Append(c);
|
|
}
|
|
}
|
|
|
|
return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
|
|
}
|
|
|
|
private static bool IsValidSlugFormat(string slug)
|
|
{
|
|
return Regex.IsMatch(slug, @"^[a-z0-9-]+$") && !slug.StartsWith('-') && !slug.EndsWith('-');
|
|
}
|
|
} |