erp-platform/api/src/Erp.Platform.Application/Note/NoteAppService.cs
2026-02-04 21:51:18 +03:00

209 lines
7 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text.Json;
using System.Threading.Tasks;
using Erp.Platform.BlobStoring;
using Erp.Platform.Entities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;
namespace Erp.Platform.Notes;
[Authorize]
public class NoteAppService : CrudAppService<
Note,
NoteDto,
Guid,
NoteListRequestDto>
{
private readonly IRepository<IdentityUser, Guid> _repositoryUser;
private readonly BlobManager _blobContainer;
public NoteAppService(
IRepository<Note, Guid> repo,
IRepository<IdentityUser, Guid> repositoryUser,
BlobManager blobContainer
) : base(repo)
{
_repositoryUser = repositoryUser;
_blobContainer = blobContainer;
// CreatePolicyName = $"{AppCodes.Listforms.Listform}.Create";
// UpdatePolicyName = $"{AppCodes.Listforms.Listform}.Update";
// DeletePolicyName = $"{AppCodes.Listforms.Listform}.Delete";
// bool canAccess = await authManager.CanAccess(listFormCode, AuthorizationTypeEnum.Update);
// if (!canAccess)
// {
// throw new UserFriendlyException(L[AppErrorCodes.NoAuth]);
// }
}
public async Task<NoteFileDto> GetDownloadAsync(string savedFileName)
{
if (string.IsNullOrWhiteSpace(savedFileName))
throw new UserFriendlyException("Dosya adı geçersiz");
var stream = await _blobContainer.GetAsync(BlobContainerNames.Note, savedFileName);
if (stream == null)
throw new UserFriendlyException("Dosya bulunamadı");
// Performans: TÜM notları çekmek yerine sadece bu dosyayı içereni bul
var queryable = await Repository.GetQueryableAsync();
var notes = await AsyncExecuter.ToListAsync(
queryable.Where(a => a.FilesJson.Contains(savedFileName))
);
var fileDto = notes
.SelectMany(a => JsonSerializer.Deserialize<List<NoteFileDto>>(a.FilesJson ?? "[]"))
.FirstOrDefault(f => f.SavedFileName == savedFileName);
using var ms = new MemoryStream();
await stream.CopyToAsync(ms);
var bytes = ms.ToArray();
// Base64 olarak encode ediyoruz
return new NoteFileDto
{
FileName = fileDto?.FileName ?? savedFileName,
FileType = fileDto?.FileType ?? "application/octet-stream",
FileBase64 = Convert.ToBase64String(bytes) // <-- byte[] yerine Base64 string
};
}
public override async Task<PagedResultDto<NoteDto>> GetListAsync(NoteListRequestDto input)
{
// 1⃣ Filtreleme
var query = await Repository.GetQueryableAsync();
if (!string.IsNullOrWhiteSpace(input.EntityName))
query = query.Where(a => a.EntityName == input.EntityName);
if (!string.IsNullOrWhiteSpace(input.EntityId))
query = query.Where(a => a.EntityId == input.EntityId);
// 2⃣ Sıralama (database'de)
if (!string.IsNullOrWhiteSpace(input.Sorting))
query = query.OrderBy(input.Sorting);
else
query = query.OrderByDescending(a => a.CreationTime);
// 3⃣ Toplam sayı (sayfalama öncesi)
var totalCount = await AsyncExecuter.CountAsync(query);
// 4⃣ Paging
var activities = await AsyncExecuter.ToListAsync(
query.Skip(input.SkipCount).Take(input.MaxResultCount)
);
// 5⃣ Kullanıcı bilgilerini Dictionary ile al (N+1 önleme)
var userIds = activities.Where(a => a.CreatorId.HasValue)
.Select(a => a.CreatorId!.Value)
.Distinct()
.ToList();
var userDict = new Dictionary<Guid, string>();
if (userIds.Any())
{
var userQueryable = await _repositoryUser.GetQueryableAsync();
var users = await AsyncExecuter.ToListAsync(
userQueryable.Where(u => userIds.Contains(u.Id))
.Select(u => new { u.Id, u.UserName })
);
userDict = users.ToDictionary(u => u.Id, u => u.UserName);
}
// 6⃣ DTO mapping - Dictionary lookup ile hızlı
var noteDtos = activities.Select(a =>
{
var dto = ObjectMapper.Map<Note, NoteDto>(a);
dto.CreateUserName = a.CreatorId.HasValue && userDict.TryGetValue(a.CreatorId.Value, out var userName)
? userName
: "Unknown";
return dto;
}).ToList();
// 7⃣ Sonuç dön
return new PagedResultDto<NoteDto>(totalCount, noteDtos);
}
public override async Task<NoteDto> CreateAsync([FromForm] NoteDto input)
{
var fileDtos = new List<NoteFileDto>();
if (input.Files != null && input.Files.Length > 0)
{
foreach (var file in input.Files)
{
await using var stream = file.GetStream();
var savedFileName = $"{Guid.NewGuid()}_{file.FileName}";
await _blobContainer.SaveAsync(
BlobContainerNames.Note,
savedFileName,
stream,
true
);
// Dosya bilgisini DTO olarak ekle
fileDtos.Add(new NoteFileDto
{
FileName = file.FileName,
FileType = file.ContentType,
FileSize = file.ContentLength ?? 0,
SavedFileName = savedFileName
});
}
}
input.FilesJson = JsonSerializer.Serialize(fileDtos);
var dto = await base.CreateAsync(input);
dto.CreateUserName = CurrentUser.UserName;
return dto;
}
public override async Task DeleteAsync(Guid id)
{
// Önce entity'i alıyoruz
var note = await Repository.GetAsync(id);
// if (!string.IsNullOrEmpty(note.FilesJson))
// {
// try
// {
// // FilesJson içindeki dosya bilgilerini deserialize ediyoruz
// var files = JsonSerializer.Deserialize<List<NoteFileDto>>(note.FilesJson);
// if (files != null)
// {
// foreach (var file in files)
// {
// // Blob storage'dan sil
// await _noteBlobContainer.DeleteAsync(file.SavedFileName, cancellationToken: default);
// }
// }
// }
// catch (Exception ex)
// {
// // Opsiyonel: silme sırasında hata loglayabilirsin
// Logger.LogWarning(ex, "Blob dosyaları silinirken hata oluştu.");
// }
// }
// Sonra veritabanındaki kaydı sil
await base.DeleteAsync(id);
}
}