using FoodLabeling.Application.Services.DbModels; using SqlSugar; namespace FoodLabeling.Application.Helpers; /// /// 标签模板查询列投影:仅映射库内真实列,避免 ORM SELECT 不存在的 scope / border 列。 /// public static class LabelTemplateQueryHelper { private static readonly HashSet AllowedSortFields = new(StringComparer.OrdinalIgnoreCase) { "TemplateName", "TemplateCode", "CreationTime", "LastModificationTime" }; /// 只读查询入口:强制列投影。 public static ISugarQueryable QueryProjected(ISqlSugarClient db) => ProjectListColumns(db.Queryable()); /// /// 列表/详情/引用校验等只读场景:强制 SQL 不含 AppliedPartnerType / AppliedRegionType / BorderType。 /// public static ISugarQueryable ProjectListColumns( ISugarQueryable query) => query.Select(x => new FlLabelTemplateDbEntity { Id = x.Id, IsDeleted = x.IsDeleted, CreationTime = x.CreationTime, CreatorId = x.CreatorId, LastModifierId = x.LastModifierId, LastModificationTime = x.LastModificationTime, ConcurrencyStamp = x.ConcurrencyStamp, TemplateCode = x.TemplateCode, TemplateName = x.TemplateName, LabelType = x.LabelType, Unit = x.Unit, Width = x.Width, Height = x.Height, PrintOrientation = x.PrintOrientation, AppliedLocationType = x.AppliedLocationType, ShowRuler = x.ShowRuler, ShowGrid = x.ShowGrid, VersionNo = x.VersionNo, State = x.State }); /// 列表安全排序:默认 IFNULL(LastModificationTime, CreationTime) DESC。 public static ISugarQueryable ApplyListSorting( ISugarQueryable query, string? sorting) { if (string.IsNullOrWhiteSpace(sorting)) { return query.OrderBy("IFNULL(LastModificationTime, CreationTime) desc, TemplateCode asc"); } var parts = sorting.Trim().Split(' ', StringSplitOptions.RemoveEmptyEntries); if (parts.Length >= 1 && AllowedSortFields.Contains(parts[0])) { var field = parts[0]; var dir = parts.Length > 1 && parts[1].Equals("asc", StringComparison.OrdinalIgnoreCase) ? "asc" : "desc"; return query.OrderBy($"{field} {dir}"); } return query.OrderBy("IFNULL(LastModificationTime, CreationTime) desc, TemplateCode asc"); } }