using System.Globalization;
using System.Security.Cryptography;
using System.Text;
namespace JiDangJia.Core;
public sealed record DueNotification(string Key,string Day);
public static class DueNotificationPlan
{
public static string Key(string kind,string id,string dueDate,int days)=>Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(kind+"/"+id+"/"+dueDate+"/"+days))).ToLowerInvariant();
public static List<DueNotification> Read(Database db,DateTime today)=>db.Read(c=>
{
var result=new List<DueNotification>();
var read=Database.Query(c,"SELECT id FROM Reminder WHERE status IN ('READ','DONE')").Select(r=>r.Id).ToHashSet();
var rows=Database.Query(c,"SELECT 'PAWN' kind,id,dueDate FROM PawnTicket WHERE status='ACTIVE' AND deletedAt IS NULL UNION ALL SELECT kind,id,dueDate FROM BusinessOrder WHERE status='OPEN' AND deletedAt IS NULL");
foreach(var row in rows)
{
if(!DateTime.TryParseExact(row.Text("dueDate"),"yyyy-MM-dd",CultureInfo.InvariantCulture,DateTimeStyles.None,out var due))continue;
foreach(int days in new[]{7,0})
{
if(due.Date<DateTime.MinValue.AddDays(days))continue;var day=due.Date.AddDays(-days);if(day<today.Date)continue;
// 持久化通知计划仅保存匿名标识与日期,不含客户、货品或金额。
var key=Key(row.Text("kind"),row.Id,row.Text("dueDate"),days);if(!read.Contains(key))result.Add(new(key,Display.Day(day)));
}
}
return result.OrderBy(r=>r.Day,StringComparer.Ordinal).ThenBy(r=>r.Key,StringComparer.Ordinal).ToList();
});
}
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
namespace JiDangJia.Core;
public sealed record DueNotification(string Key,string Day);
public static class DueNotificationPlan
{
public static string Key(string kind,string id,string dueDate,int days)=>Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(kind+"/"+id+"/"+dueDate+"/"+days))).ToLowerInvariant();
public static List<DueNotification> Read(Database db,DateTime today)=>db.Read(c=>
{
var result=new List<DueNotification>();
var read=Database.Query(c,"SELECT id FROM Reminder WHERE status IN ('READ','DONE')").Select(r=>r.Id).ToHashSet();
var rows=Database.Query(c,"SELECT 'PAWN' kind,id,dueDate FROM PawnTicket WHERE status='ACTIVE' AND deletedAt IS NULL UNION ALL SELECT kind,id,dueDate FROM BusinessOrder WHERE status='OPEN' AND deletedAt IS NULL");
foreach(var row in rows)
{
if(!DateTime.TryParseExact(row.Text("dueDate"),"yyyy-MM-dd",CultureInfo.InvariantCulture,DateTimeStyles.None,out var due))continue;
foreach(int days in new[]{7,0})
{
if(due.Date<DateTime.MinValue.AddDays(days))continue;var day=due.Date.AddDays(-days);if(day<today.Date)continue;
// 持久化通知计划仅保存匿名标识与日期,不含客户、货品或金额。
var key=Key(row.Text("kind"),row.Id,row.Text("dueDate"),days);if(!read.Contains(key))result.Add(new(key,Display.Day(day)));
}
}
return result.OrderBy(r=>r.Day,StringComparer.Ordinal).ThenBy(r=>r.Key,StringComparer.Ordinal).ToList();
});
}