using System.Text.Json;
using FoodLabeling.Application.Helpers;
using FoodLabeling.Application.Contracts.Dtos.Common;
using FoodLabeling.Application.Contracts.Dtos.LabelTemplate;
using FoodLabeling.Application.Contracts.IServices;
using FoodLabeling.Application.Services.DbModels;
using FoodLabeling.Domain.Entities;
using SqlSugar;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Guids;
using Volo.Abp.Uow;
using Yi.Framework.SqlSugarCore.Abstractions;
namespace FoodLabeling.Application.Services;
///
/// 标签模板管理(Label Templates)
///
public class LabelTemplateAppService : ApplicationService, ILabelTemplateAppService
{
private readonly ISqlSugarDbContext _dbContext;
private readonly IGuidGenerator _guidGenerator;
public LabelTemplateAppService(ISqlSugarDbContext dbContext, IGuidGenerator guidGenerator)
{
_dbContext = dbContext;
_guidGenerator = guidGenerator;
}
public async Task> GetListAsync(LabelTemplateGetListInputVo input)
{
RefAsync total = 0;
var keyword = input.Keyword?.Trim();
var locationId = input.LocationId?.Trim();
var specifiedTemplateIds = new HashSet();
if (!string.IsNullOrWhiteSpace(locationId))
{
var rows = await _dbContext.SqlSugarClient.Queryable()
.Where(x => x.LocationId == locationId)
.Select(x => x.TemplateId)
.ToListAsync();
specifiedTemplateIds = rows.ToHashSet();
}
var query = _dbContext.SqlSugarClient.Queryable()
.Where(x => !x.IsDeleted)
.WhereIF(!string.IsNullOrWhiteSpace(keyword), x =>
x.TemplateName.Contains(keyword!) || x.TemplateCode.Contains(keyword!))
.WhereIF(!string.IsNullOrWhiteSpace(input.LabelType), x => x.LabelType == input.LabelType)
.WhereIF(input.State != null, x => x.State == input.State);
if (!string.IsNullOrWhiteSpace(locationId))
{
query = query.Where(x => x.AppliedLocationType == "ALL" || specifiedTemplateIds.Contains(x.Id));
}
query = !string.IsNullOrWhiteSpace(input.Sorting)
? query.OrderBy(input.Sorting)
: query.OrderByDescending(x => x.LastModificationTime ?? x.CreationTime);
var pageEntities = await query.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
var templateIds = pageEntities.Select(x => x.Id).ToList();
// element count (Contents)
var elementCounts = await _dbContext.SqlSugarClient.Queryable()
.Where(x => templateIds.Contains(x.TemplateId))
.GroupBy(x => x.TemplateId)
.Select(x => new { TemplateId = x.TemplateId, Count = SqlFunc.AggregateCount(x.Id) })
.ToListAsync();
var elementCountMap = elementCounts.ToDictionary(x => x.TemplateId, x => (int)x.Count);
// applied locations (for LocationText)
var templateLocationRows = await _dbContext.SqlSugarClient.Queryable()
.Where(x => templateIds.Contains(x.TemplateId))
.ToListAsync();
var locationIdSet = templateLocationRows.Select(x => x.LocationId).Where(x => !string.IsNullOrWhiteSpace(x)).Distinct().ToList();
var locationGuidList = locationIdSet
.Where(x => Guid.TryParse(x, out _))
.Select(Guid.Parse)
.Distinct()
.ToList();
var locationMap = new Dictionary();
if (locationGuidList.Count > 0)
{
var locations = await _dbContext.SqlSugarClient.Queryable()
.Where(x => !x.IsDeleted)
.Where(x => locationGuidList.Contains(x.Id))
.ToListAsync();
locationMap = locations.ToDictionary(x => x.Id, x => x);
}
string GetFirstLocationName(string templateDbId)
{
var first = templateLocationRows.FirstOrDefault(x => x.TemplateId == templateDbId);
if (first is null) return "Specified";
if (Guid.TryParse(first.LocationId, out var gid) && locationMap.TryGetValue(gid, out var loc))
{
return loc.LocationName ?? loc.LocationCode;
}
return "Specified";
}
var items = pageEntities.Select(x =>
{
var lastEdited = x.LastModificationTime ?? x.CreationTime;
var contentsCount = elementCountMap.TryGetValue(x.Id, out var c) ? c : 0;
var locationText = x.AppliedLocationType == "ALL" ? "All Locations" : GetFirstLocationName(x.Id);
var sizeText = $"{x.Width}x{x.Height}{x.Unit}";
return new LabelTemplateGetListOutputDto
{
Id = x.TemplateCode, // front-end uses templateCode as identifier
TemplateCode = x.TemplateCode,
TemplateName = x.TemplateName,
LabelType = x.LabelType,
LocationText = locationText,
ContentsCount = contentsCount,
SizeText = sizeText,
VersionNo = x.VersionNo,
LastEdited = lastEdited
};
}).ToList();
return BuildPagedResult(input.SkipCount, input.MaxResultCount, total, items);
}
public async Task GetAsync(string id)
{
var template = await _dbContext.SqlSugarClient.Queryable()
.FirstAsync(x => !x.IsDeleted && x.TemplateCode == id);
if (template is null)
{
throw new UserFriendlyException("模板不存在");
}
var elements = await _dbContext.SqlSugarClient.Queryable()
.Where(x => x.TemplateId == template.Id)
.OrderBy(x => x.OrderNum)
.ToListAsync();
List MapElements()
{
return elements.Select(e =>
{
object? cfg = null;
if (!string.IsNullOrWhiteSpace(e.ConfigJson))
{
cfg = JsonSerializer.Deserialize