ReportsPrintLogDailyLabelIdHelper.cs 2.69 KB
using FoodLabeling.Application.Services.DbModels;
using SqlSugar;

namespace FoodLabeling.Application.Helpers;

/// <summary>
/// Print Log「Label ID」:按门店 + 自然日对打印任务排序,格式 <c>yyyyMMdd-n</c>(非 fl_label.LabelCode)。
/// </summary>
public static class ReportsPrintLogDailyLabelIdHelper
{
    /// <summary>
    /// 为列表/导出行计算门店当日打印序号。
    /// </summary>
    public static async Task<Dictionary<string, string>> ResolveDailyLabelIdsAsync(
        ISqlSugarClient db,
        IReadOnlyList<PrintTaskScopeKey> tasks)
    {
        var result = new Dictionary<string, string>(StringComparer.Ordinal);
        if (tasks.Count == 0)
        {
            return result;
        }

        foreach (var task in tasks)
        {
            if (string.IsNullOrWhiteSpace(task.TaskId))
            {
                continue;
            }

            result.TryAdd(task.TaskId.Trim(), "无");
        }

        var buckets = tasks
            .Where(t =>
                !string.IsNullOrWhiteSpace(t.TaskId) &&
                !string.IsNullOrWhiteSpace(t.LocationId) &&
                t.PrintedAt != default)
            .GroupBy(t => (LocationId: t.LocationId!.Trim(), Day: t.PrintedAt.Date))
            .ToList();

        foreach (var bucket in buckets)
        {
            var locId = bucket.Key.LocationId;
            var dayStart = bucket.Key.Day;
            var dayEnd = dayStart.AddDays(1);

            var dayTasks = await db.Queryable<FlLabelPrintTaskDbEntity>()
                .Where(t => t.LocationId == locId)
                .Where(t =>
                    SqlFunc.IsNull(t.PrintedAt, t.CreationTime) >= dayStart &&
                    SqlFunc.IsNull(t.PrintedAt, t.CreationTime) < dayEnd)
                .OrderBy(t => SqlFunc.IsNull(t.PrintedAt, t.CreationTime), OrderByType.Asc)
                .OrderBy(t => t.Id, OrderByType.Asc)
                .Select(t => new { t.Id, PrintedAt = SqlFunc.IsNull(t.PrintedAt, t.CreationTime) })
                .ToListAsync();

            for (var i = 0; i < dayTasks.Count; i++)
            {
                result[dayTasks[i].Id] = Format(dayStart, i + 1);
            }
        }

        return result;
    }

    public static string Format(DateTime printDay, int sequence) =>
        $"{printDay:yyyyMMdd}-{sequence}";

    public readonly struct PrintTaskScopeKey
    {
        public PrintTaskScopeKey(string taskId, string? locationId, DateTime printedAt)
        {
            TaskId = taskId;
            LocationId = locationId;
            PrintedAt = printedAt;
        }

        public string TaskId { get; }

        public string? LocationId { get; }

        public DateTime PrintedAt { get; }
    }
}