using FoodLabeling.Application.Services.DbModels;
using SqlSugar;
namespace FoodLabeling.Application.Helpers;
///
/// Print Log「Label ID」:按门店 + 自然日对打印任务排序,格式 yyyyMMdd-n(非 fl_label.LabelCode)。
///
public static class ReportsPrintLogDailyLabelIdHelper
{
///
/// 为列表/导出行计算门店当日打印序号。
///
public static async Task> ResolveDailyLabelIdsAsync(
ISqlSugarClient db,
IReadOnlyList tasks)
{
var result = new Dictionary(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()
.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 async Task ResolveNextDailyLabelIdAsync(
ISqlSugarClient db,
string locationId,
DateTime referenceTime)
{
var locId = locationId?.Trim();
if (string.IsNullOrWhiteSpace(locId))
{
return "无";
}
var dayStart = referenceTime.Date;
var dayEnd = dayStart.AddDays(1);
var count = await db.Queryable()
.Where(t => t.LocationId == locId)
.Where(t =>
SqlFunc.IsNull(t.PrintedAt, t.CreationTime) >= dayStart &&
SqlFunc.IsNull(t.PrintedAt, t.CreationTime) < dayEnd)
.CountAsync();
return Format(dayStart, count + 1);
}
public static string Format(DateTime printDay, int sequence) =>
$"{printDay:yyyyMMdd}-{sequence}";
///
/// 为门店当日后续打印任务预留连续序号(不含已存在任务之外的并发锁,与列表展示规则一致)。
///
public static async Task> ResolveNextDailyLabelIdsAsync(
ISqlSugarClient db,
string locationId,
DateTime day,
int count)
{
var result = new List();
if (count <= 0 || string.IsNullOrWhiteSpace(locationId))
{
return result;
}
var locId = locationId.Trim();
var dayStart = day.Date;
var dayEnd = dayStart.AddDays(1);
var existingCount = await db.Queryable()
.Where(t => t.LocationId == locId)
.Where(t =>
SqlFunc.IsNull(t.PrintedAt, t.CreationTime) >= dayStart &&
SqlFunc.IsNull(t.PrintedAt, t.CreationTime) < dayEnd)
.CountAsync();
for (var i = 1; i <= count; i++)
{
result.Add(Format(dayStart, existingCount + i));
}
return result;
}
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; }
}
}