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 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 scopedLocationIds = await TeamMemberListScopeHelper.ResolveListLocationIdsAsync(
CurrentUser,
_dbContext,
input.PartnerId,
input.GroupId,
input.LocationId);
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);
query = await LabelTemplateScopeHelper.ApplyTemplateScopeFilterAsync(
_dbContext.SqlSugarClient,
query,
scopedLocationIds,
input.PartnerId,
input.GroupId,
input.LocationId);
query = LabelTemplateQueryHelper.ApplyListSorting(query, input.Sorting);
query = LabelTemplateQueryHelper.ProjectListColumns(query);
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);
var scopeMap = await LabelTemplateScopeHelper.BuildScopeDisplayMapAsync(
_dbContext.SqlSugarClient, pageEntities);
var itemsMap = await LabelTemplateListItemsHelper.ResolveTemplateItemsMapAsync(
_dbContext.SqlSugarClient, templateIds);
var contentsFromElementsMap = await LabelTemplateContentsHelper.ResolveContentsMapFromElementsAsync(
_dbContext.SqlSugarClient, templateIds);
var items = pageEntities.Select(x =>
{
scopeMap.TryGetValue(x.Id, out var scope);
itemsMap.TryGetValue(x.Id, out var itemsDisplay);
var lastEdited = x.LastModificationTime ?? x.CreationTime;
var contentsCount = elementCountMap.TryGetValue(x.Id, out var c) ? c : 0;
var locationDisplay = scope?.Location ?? EmptyDisplay;
var sizeText = $"{x.Width}x{x.Height}{x.Unit}";
contentsFromElementsMap.TryGetValue(x.Id, out var fromElements);
var contentsText = !string.IsNullOrWhiteSpace(fromElements)
? fromElements!
: (itemsDisplay?.Items ?? FoodLabelingDisplayConsts.NotAvailable);
return new LabelTemplateGetListOutputDto
{
Id = x.TemplateCode, // front-end uses templateCode as identifier
TemplateCode = x.TemplateCode,
TemplateName = x.TemplateName,
LabelType = x.LabelType,
LocationText = locationDisplay,
Company = scope?.Company ?? string.Empty,
Region = scope?.Region ?? string.Empty,
Location = locationDisplay,
PartnerIds = scope?.PartnerIds ?? new List(),
CompanyIds = scope?.PartnerIds ?? new List(),
RegionIds = scope?.RegionIds ?? new List(),
GroupIds = scope?.RegionIds ?? new List(),
LocationIds = scope?.LocationIds ?? new List(),
ContentsCount = contentsCount,
Contents = contentsText,
Items = contentsText,
ItemNames = itemsDisplay?.ItemNames ?? new List(),
SizeText = sizeText,
PrintOrientation = LabelTemplatePrintOrientationHelper.Normalize(x.PrintOrientation),
VersionNo = x.VersionNo,
LastEdited = lastEdited
};
}).ToList();
return BuildPagedResult(input.SkipCount, input.MaxResultCount, total, items);
}
public async Task GetAsync(string id)
{
var template = await LabelTemplateQueryHelper.QueryProjected(_dbContext.SqlSugarClient)
.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