2025-10-13 14:48:55 +00:00
|
|
|
|
using System;
|
2025-10-14 21:10:47 +00:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Linq.Dynamic.Core;
|
|
|
|
|
|
using System.Text.Json;
|
2025-10-13 21:47:53 +00:00
|
|
|
|
using System.Threading.Tasks;
|
2025-11-11 19:49:52 +00:00
|
|
|
|
using Erp.Platform.BlobStoring;
|
|
|
|
|
|
using Erp.Platform.Entities;
|
2025-10-13 14:48:55 +00:00
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
2025-10-13 21:47:53 +00:00
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
2025-10-14 21:10:47 +00:00
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
|
|
using Volo.Abp;
|
2025-10-13 14:48:55 +00:00
|
|
|
|
using Volo.Abp.Application.Dtos;
|
|
|
|
|
|
using Volo.Abp.Application.Services;
|
|
|
|
|
|
using Volo.Abp.Domain.Repositories;
|
2025-10-14 21:10:47 +00:00
|
|
|
|
using Volo.Abp.Identity;
|
2025-10-13 14:48:55 +00:00
|
|
|
|
|
2025-11-11 19:49:52 +00:00
|
|
|
|
namespace Erp.Platform.Activities;
|
2025-10-13 14:48:55 +00:00
|
|
|
|
|
|
|
|
|
|
[Authorize]
|
|
|
|
|
|
public class ActivityAppService : CrudAppService<
|
|
|
|
|
|
Activity,
|
|
|
|
|
|
ActivityDto,
|
|
|
|
|
|
Guid,
|
2025-10-14 21:10:47 +00:00
|
|
|
|
ActivityListRequestDto>
|
2025-10-13 14:48:55 +00:00
|
|
|
|
{
|
2025-10-14 21:10:47 +00:00
|
|
|
|
private readonly IRepository<IdentityUser, Guid> _repositoryUser;
|
2025-10-25 23:42:35 +00:00
|
|
|
|
private readonly BlobManager _blobContainer;
|
2025-10-13 21:47:53 +00:00
|
|
|
|
|
2025-10-13 14:48:55 +00:00
|
|
|
|
public ActivityAppService(
|
2025-10-13 21:47:53 +00:00
|
|
|
|
IRepository<Activity, Guid> repo,
|
2025-10-25 23:42:35 +00:00
|
|
|
|
IRepository<IdentityUser, Guid> repositoryUser,
|
|
|
|
|
|
BlobManager blobContainer
|
2025-10-13 21:47:53 +00:00
|
|
|
|
) : base(repo)
|
2025-10-13 14:48:55 +00:00
|
|
|
|
{
|
2025-10-14 21:10:47 +00:00
|
|
|
|
_repositoryUser = repositoryUser;
|
2025-10-25 23:42:35 +00:00
|
|
|
|
_blobContainer = blobContainer;
|
2025-10-13 21:47:53 +00:00
|
|
|
|
|
|
|
|
|
|
// CreatePolicyName = $"{AppCodes.Listforms.Listform}.Create";
|
|
|
|
|
|
// UpdatePolicyName = $"{AppCodes.Listforms.Listform}.Update";
|
|
|
|
|
|
// DeletePolicyName = $"{AppCodes.Listforms.Listform}.Delete";
|
2025-10-13 14:48:55 +00:00
|
|
|
|
|
2025-10-13 21:47:53 +00:00
|
|
|
|
// bool canAccess = await authManager.CanAccess(listFormCode, AuthorizationTypeEnum.Update);
|
|
|
|
|
|
// if (!canAccess)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// throw new UserFriendlyException(L[AppErrorCodes.NoAuth]);
|
|
|
|
|
|
// }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-14 21:10:47 +00:00
|
|
|
|
public async Task<ActivityFileDto> GetDownloadAsync(string savedFileName)
|
2025-10-13 21:47:53 +00:00
|
|
|
|
{
|
2025-10-14 21:10:47 +00:00
|
|
|
|
if (string.IsNullOrWhiteSpace(savedFileName))
|
|
|
|
|
|
throw new UserFriendlyException("Dosya adı geçersiz");
|
|
|
|
|
|
|
2025-10-25 23:42:35 +00:00
|
|
|
|
var stream = await _blobContainer.GetAsync(BlobContainerNames.Activity, savedFileName);
|
2025-10-14 21:10:47 +00:00
|
|
|
|
if (stream == null)
|
|
|
|
|
|
throw new UserFriendlyException("Dosya bulunamadı");
|
|
|
|
|
|
|
|
|
|
|
|
var activities = await Repository.GetListAsync();
|
|
|
|
|
|
var fileDto = activities
|
|
|
|
|
|
.SelectMany(a => JsonSerializer.Deserialize<List<ActivityFileDto>>(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 ActivityFileDto
|
|
|
|
|
|
{
|
|
|
|
|
|
FileName = fileDto?.FileName ?? savedFileName,
|
|
|
|
|
|
FileType = fileDto?.FileType ?? "application/octet-stream",
|
|
|
|
|
|
FileBase64 = Convert.ToBase64String(bytes) // <-- byte[] yerine Base64 string
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override async Task<PagedResultDto<ActivityDto>> GetListAsync(ActivityListRequestDto 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 (opsiyonel)
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(input.Sorting))
|
|
|
|
|
|
query = query.OrderBy(input.Sorting);
|
|
|
|
|
|
else
|
|
|
|
|
|
query = query.OrderByDescending(a => a.CreationTime);
|
|
|
|
|
|
|
|
|
|
|
|
// 3️⃣ Paging
|
|
|
|
|
|
var totalCount = await AsyncExecuter.CountAsync(query);
|
|
|
|
|
|
var activities = await AsyncExecuter.ToListAsync(
|
|
|
|
|
|
query.Skip(input.SkipCount).Take(input.MaxResultCount)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// 4️⃣ Kullanıcı bilgilerini al
|
|
|
|
|
|
var userIds = activities.Select(a => a.CreatorId).Distinct().ToList();
|
|
|
|
|
|
var userQueryable = await _repositoryUser.GetQueryableAsync();
|
|
|
|
|
|
var users = await userQueryable
|
|
|
|
|
|
.Where(u => userIds.Contains(u.Id))
|
|
|
|
|
|
.Select(u => new { u.Id, u.UserName })
|
|
|
|
|
|
.ToListAsync();
|
|
|
|
|
|
|
|
|
|
|
|
// 5️⃣ DTO map ve kullanıcı adı ekleme
|
|
|
|
|
|
var activityDtos = activities.Select(a =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var dto = ObjectMapper.Map<Activity, ActivityDto>(a);
|
|
|
|
|
|
dto.CreateUserName = users.FirstOrDefault(u => u.Id == a.CreatorId)?.UserName ?? "Unknown";
|
|
|
|
|
|
return dto;
|
|
|
|
|
|
}).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
// 6️⃣ Sonuç dön
|
|
|
|
|
|
return new PagedResultDto<ActivityDto>(totalCount, activityDtos);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override async Task<ActivityDto> CreateAsync([FromForm] ActivityDto input)
|
|
|
|
|
|
{
|
|
|
|
|
|
var fileDtos = new List<ActivityFileDto>();
|
|
|
|
|
|
|
|
|
|
|
|
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}";
|
|
|
|
|
|
|
2025-10-25 23:42:35 +00:00
|
|
|
|
await _blobContainer.SaveAsync(
|
|
|
|
|
|
BlobContainerNames.Activity,
|
2025-10-14 21:10:47 +00:00
|
|
|
|
savedFileName,
|
|
|
|
|
|
stream,
|
|
|
|
|
|
true
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// Dosya bilgisini DTO olarak ekle
|
|
|
|
|
|
fileDtos.Add(new ActivityFileDto
|
|
|
|
|
|
{
|
|
|
|
|
|
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 activity = await Repository.GetAsync(id);
|
|
|
|
|
|
|
|
|
|
|
|
// if (!string.IsNullOrEmpty(activity.FilesJson))
|
|
|
|
|
|
// {
|
|
|
|
|
|
// try
|
|
|
|
|
|
// {
|
|
|
|
|
|
// // FilesJson içindeki dosya bilgilerini deserialize ediyoruz
|
|
|
|
|
|
// var files = JsonSerializer.Deserialize<List<ActivityFileDto>>(activity.FilesJson);
|
|
|
|
|
|
|
|
|
|
|
|
// if (files != null)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// foreach (var file in files)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// // Blob storage'dan sil
|
|
|
|
|
|
// await _activityBlobContainer.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);
|
2025-10-13 14:48:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-11-11 19:49:52 +00:00
|
|
|
|
|