fix: 门店资质日期字段改为date
This commit is contained in:
@@ -130,19 +130,19 @@ public sealed class GetStoreAuditDetailQueryHandler(
|
||||
}
|
||||
|
||||
// 2. (空行后) 映射资质 DTO
|
||||
var now = DateTime.UtcNow.Date;
|
||||
var today = DateOnly.FromDateTime(DateTime.UtcNow);
|
||||
while (await reader.ReadAsync(cancellationToken))
|
||||
{
|
||||
DateTime? expiresAt = reader.IsDBNull(reader.GetOrdinal("ExpiresAt"))
|
||||
DateOnly? expiresAt = reader.IsDBNull(reader.GetOrdinal("ExpiresAt"))
|
||||
? null
|
||||
: reader.GetDateTime(reader.GetOrdinal("ExpiresAt"));
|
||||
: DateOnly.FromDateTime(reader.GetDateTime(reader.GetOrdinal("ExpiresAt")));
|
||||
int? daysUntilExpiry = expiresAt.HasValue
|
||||
? (int)Math.Ceiling((expiresAt.Value.Date - now).TotalDays)
|
||||
? expiresAt.Value.DayNumber - today.DayNumber
|
||||
: null;
|
||||
var isExpired = expiresAt.HasValue && expiresAt.Value < DateTime.UtcNow;
|
||||
var isExpired = expiresAt.HasValue && expiresAt.Value < today;
|
||||
var isExpiringSoon = expiresAt.HasValue
|
||||
&& expiresAt.Value >= DateTime.UtcNow
|
||||
&& expiresAt.Value <= DateTime.UtcNow.AddDays(30);
|
||||
&& expiresAt.Value >= today
|
||||
&& expiresAt.Value <= today.AddDays(30);
|
||||
|
||||
// 2.1 (空行后) 写入列表
|
||||
items.Add(new StoreQualificationDto
|
||||
@@ -156,7 +156,7 @@ public sealed class GetStoreAuditDetailQueryHandler(
|
||||
: reader.GetString(reader.GetOrdinal("DocumentNumber")),
|
||||
IssuedAt = reader.IsDBNull(reader.GetOrdinal("IssuedAt"))
|
||||
? null
|
||||
: reader.GetDateTime(reader.GetOrdinal("IssuedAt")),
|
||||
: DateOnly.FromDateTime(reader.GetDateTime(reader.GetOrdinal("IssuedAt"))),
|
||||
ExpiresAt = expiresAt,
|
||||
IsExpired = isExpired,
|
||||
IsExpiringSoon = isExpiringSoon,
|
||||
|
||||
@@ -32,12 +32,12 @@ public sealed record CreateStoreQualificationCommand : IRequest<StoreQualificati
|
||||
/// <summary>
|
||||
/// 签发日期。
|
||||
/// </summary>
|
||||
public DateTime? IssuedAt { get; init; }
|
||||
public DateOnly? IssuedAt { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 到期日期。
|
||||
/// </summary>
|
||||
public DateTime? ExpiresAt { get; init; }
|
||||
public DateOnly? ExpiresAt { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序值。
|
||||
|
||||
@@ -31,12 +31,12 @@ public sealed record UpdateStoreQualificationCommand : IRequest<StoreQualificati
|
||||
/// <summary>
|
||||
/// 签发日期。
|
||||
/// </summary>
|
||||
public DateTime? IssuedAt { get; init; }
|
||||
public DateOnly? IssuedAt { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 到期日期。
|
||||
/// </summary>
|
||||
public DateTime? ExpiresAt { get; init; }
|
||||
public DateOnly? ExpiresAt { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序值。
|
||||
|
||||
@@ -50,7 +50,7 @@ public sealed record StoreQualificationAlertDto
|
||||
/// <summary>
|
||||
/// 过期时间。
|
||||
/// </summary>
|
||||
public DateTime? ExpiresAt { get; init; }
|
||||
public DateOnly? ExpiresAt { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 距离过期天数。
|
||||
|
||||
@@ -39,12 +39,12 @@ public sealed class StoreQualificationDto
|
||||
/// <summary>
|
||||
/// 签发日期。
|
||||
/// </summary>
|
||||
public DateTime? IssuedAt { get; init; }
|
||||
public DateOnly? IssuedAt { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 到期日期。
|
||||
/// </summary>
|
||||
public DateTime? ExpiresAt { get; init; }
|
||||
public DateOnly? ExpiresAt { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否已过期。
|
||||
|
||||
@@ -30,7 +30,7 @@ public sealed class ListExpiringStoreQualificationsQueryHandler(
|
||||
daysThreshold = 365;
|
||||
}
|
||||
var offset = (page - 1) * pageSize;
|
||||
var now = DateTime.UtcNow;
|
||||
var now = DateOnly.FromDateTime(DateTime.UtcNow);
|
||||
var expiringBefore = now.AddDays(daysThreshold);
|
||||
|
||||
// 2. (空行后) 执行查询
|
||||
@@ -92,12 +92,12 @@ public sealed class ListExpiringStoreQualificationsQueryHandler(
|
||||
List<StoreQualificationAlertDto> items = [];
|
||||
while (await reader.ReadAsync(token))
|
||||
{
|
||||
DateTime? expiresAt = reader.IsDBNull(expiresAtOrdinal)
|
||||
DateOnly? expiresAt = reader.IsDBNull(expiresAtOrdinal)
|
||||
? null
|
||||
: reader.GetDateTime(expiresAtOrdinal);
|
||||
: DateOnly.FromDateTime(reader.GetDateTime(expiresAtOrdinal));
|
||||
var isExpired = expiresAt.HasValue && expiresAt.Value < now;
|
||||
int? daysUntilExpiry = expiresAt.HasValue
|
||||
? (int)Math.Ceiling((expiresAt.Value.Date - now.Date).TotalDays)
|
||||
? expiresAt.Value.DayNumber - now.DayNumber
|
||||
: null;
|
||||
|
||||
items.Add(new StoreQualificationAlertDto
|
||||
@@ -146,8 +146,8 @@ public sealed class ListExpiringStoreQualificationsQueryHandler(
|
||||
|
||||
private static async Task<StoreQualificationAlertSummaryDto> ExecuteSummaryAsync(
|
||||
IDbConnection connection,
|
||||
DateTime now,
|
||||
DateTime expiringBefore,
|
||||
DateOnly now,
|
||||
DateOnly expiringBefore,
|
||||
long? tenantId,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
|
||||
@@ -78,8 +78,9 @@ public static class StoreMapping
|
||||
/// <returns>DTO。</returns>
|
||||
public static StoreQualificationDto ToDto(StoreQualification qualification)
|
||||
{
|
||||
var today = DateOnly.FromDateTime(DateTime.UtcNow);
|
||||
int? daysUntilExpiry = qualification.ExpiresAt.HasValue
|
||||
? (int)Math.Ceiling((qualification.ExpiresAt.Value.Date - DateTime.UtcNow.Date).TotalDays)
|
||||
? qualification.ExpiresAt.Value.DayNumber - today.DayNumber
|
||||
: null;
|
||||
|
||||
return new StoreQualificationDto
|
||||
|
||||
@@ -21,7 +21,7 @@ public sealed class CreateStoreQualificationCommandValidator : AbstractValidator
|
||||
RuleFor(x => x.DocumentNumber).MaximumLength(100);
|
||||
|
||||
RuleFor(x => x.ExpiresAt)
|
||||
.Must(date => date.HasValue && date.Value.Date > DateTime.UtcNow.Date)
|
||||
.Must(date => date.HasValue && date.Value > DateOnly.FromDateTime(DateTime.UtcNow))
|
||||
.When(x => IsLicenseType(x.QualificationType))
|
||||
.WithMessage("证照有效期必须晚于今天");
|
||||
|
||||
@@ -32,7 +32,7 @@ public sealed class CreateStoreQualificationCommandValidator : AbstractValidator
|
||||
.WithMessage("证照编号不能为空");
|
||||
|
||||
RuleFor(x => x.ExpiresAt)
|
||||
.Must(date => !date.HasValue || date.Value.Date > DateTime.UtcNow.Date)
|
||||
.Must(date => !date.HasValue || date.Value > DateOnly.FromDateTime(DateTime.UtcNow))
|
||||
.When(x => !IsLicenseType(x.QualificationType))
|
||||
.WithMessage("证照有效期必须晚于今天");
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ public sealed class UpdateStoreQualificationCommandValidator : AbstractValidator
|
||||
RuleFor(x => x.DocumentNumber).MaximumLength(100).When(x => !string.IsNullOrWhiteSpace(x.DocumentNumber));
|
||||
RuleFor(x => x.SortOrder).GreaterThanOrEqualTo(0).When(x => x.SortOrder.HasValue);
|
||||
RuleFor(x => x.ExpiresAt)
|
||||
.Must(date => !date.HasValue || date.Value.Date > DateTime.UtcNow.Date)
|
||||
.Must(date => !date.HasValue || date.Value > DateOnly.FromDateTime(DateTime.UtcNow))
|
||||
.When(x => x.ExpiresAt.HasValue)
|
||||
.WithMessage("证照有效期必须晚于今天");
|
||||
}
|
||||
|
||||
@@ -31,24 +31,25 @@ public sealed class StoreQualification : MultiTenantEntityBase
|
||||
/// <summary>
|
||||
/// 签发日期。
|
||||
/// </summary>
|
||||
public DateTime? IssuedAt { get; set; }
|
||||
public DateOnly? IssuedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 到期日期。
|
||||
/// </summary>
|
||||
public DateTime? ExpiresAt { get; set; }
|
||||
public DateOnly? ExpiresAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否已过期。
|
||||
/// </summary>
|
||||
public bool IsExpired => ExpiresAt.HasValue && ExpiresAt.Value < DateTime.UtcNow;
|
||||
public bool IsExpired => ExpiresAt.HasValue
|
||||
&& ExpiresAt.Value < DateOnly.FromDateTime(DateTime.UtcNow);
|
||||
|
||||
/// <summary>
|
||||
/// 是否即将过期(30天内)。
|
||||
/// </summary>
|
||||
public bool IsExpiringSoon => ExpiresAt.HasValue
|
||||
&& ExpiresAt.Value >= DateTime.UtcNow
|
||||
&& ExpiresAt.Value <= DateTime.UtcNow.AddDays(30);
|
||||
&& ExpiresAt.Value >= DateOnly.FromDateTime(DateTime.UtcNow)
|
||||
&& ExpiresAt.Value <= DateOnly.FromDateTime(DateTime.UtcNow).AddDays(30);
|
||||
|
||||
/// <summary>
|
||||
/// 排序值。
|
||||
|
||||
@@ -625,6 +625,8 @@ public sealed class TakeoutAppDbContext(
|
||||
builder.Property(x => x.QualificationType).HasConversion<int>();
|
||||
builder.Property(x => x.FileUrl).HasMaxLength(500).IsRequired();
|
||||
builder.Property(x => x.DocumentNumber).HasMaxLength(100);
|
||||
builder.Property(x => x.IssuedAt).HasColumnType("date");
|
||||
builder.Property(x => x.ExpiresAt).HasColumnType("date");
|
||||
builder.Property(x => x.SortOrder).HasDefaultValue(100);
|
||||
builder.HasIndex(x => new { x.TenantId, x.StoreId });
|
||||
builder.HasIndex(x => x.ExpiresAt)
|
||||
|
||||
@@ -105,11 +105,12 @@ public sealed class StoreSchedulerService(
|
||||
public async Task<int> CheckQualificationExpiryAsync(DateTime now, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 查询过期门店
|
||||
var today = DateOnly.FromDateTime(now);
|
||||
var expiredStoreIds = await context.StoreQualifications
|
||||
.AsNoTracking()
|
||||
.Where(qualification => qualification.DeletedAt == null
|
||||
&& qualification.ExpiresAt.HasValue
|
||||
&& qualification.ExpiresAt.Value < now)
|
||||
&& qualification.ExpiresAt.Value < today)
|
||||
.Select(qualification => qualification.StoreId)
|
||||
.Distinct()
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TakeoutSaaS.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ChangeStoreQualificationDateColumns : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<DateOnly>(
|
||||
name: "IssuedAt",
|
||||
table: "store_qualifications",
|
||||
type: "date",
|
||||
nullable: true,
|
||||
comment: "签发日期。",
|
||||
oldClrType: typeof(DateTime),
|
||||
oldType: "timestamp with time zone",
|
||||
oldNullable: true,
|
||||
oldComment: "签发日期。");
|
||||
|
||||
migrationBuilder.AlterColumn<DateOnly>(
|
||||
name: "ExpiresAt",
|
||||
table: "store_qualifications",
|
||||
type: "date",
|
||||
nullable: true,
|
||||
comment: "到期日期。",
|
||||
oldClrType: typeof(DateTime),
|
||||
oldType: "timestamp with time zone",
|
||||
oldNullable: true,
|
||||
oldComment: "到期日期。");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "IssuedAt",
|
||||
table: "store_qualifications",
|
||||
type: "timestamp with time zone",
|
||||
nullable: true,
|
||||
comment: "签发日期。",
|
||||
oldClrType: typeof(DateOnly),
|
||||
oldType: "date",
|
||||
oldNullable: true,
|
||||
oldComment: "签发日期。");
|
||||
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "ExpiresAt",
|
||||
table: "store_qualifications",
|
||||
type: "timestamp with time zone",
|
||||
nullable: true,
|
||||
comment: "到期日期。",
|
||||
oldClrType: typeof(DateOnly),
|
||||
oldType: "date",
|
||||
oldNullable: true,
|
||||
oldComment: "到期日期。");
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace TakeoutSaaS.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class UpdateStoreQualificationDateFields : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<DateOnly>(
|
||||
name: "IssuedAt",
|
||||
table: "store_qualifications",
|
||||
type: "date",
|
||||
nullable: true,
|
||||
comment: "签发日期。",
|
||||
oldClrType: typeof(DateTime),
|
||||
oldType: "timestamp with time zone",
|
||||
oldNullable: true,
|
||||
oldComment: "签发日期。");
|
||||
|
||||
migrationBuilder.AlterColumn<DateOnly>(
|
||||
name: "ExpiresAt",
|
||||
table: "store_qualifications",
|
||||
type: "date",
|
||||
nullable: true,
|
||||
comment: "到期日期。",
|
||||
oldClrType: typeof(DateTime),
|
||||
oldType: "timestamp with time zone",
|
||||
oldNullable: true,
|
||||
oldComment: "到期日期。");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "IssuedAt",
|
||||
table: "store_qualifications",
|
||||
type: "timestamp with time zone",
|
||||
nullable: true,
|
||||
comment: "签发日期。",
|
||||
oldClrType: typeof(DateOnly),
|
||||
oldType: "date",
|
||||
oldNullable: true,
|
||||
oldComment: "签发日期。");
|
||||
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "ExpiresAt",
|
||||
table: "store_qualifications",
|
||||
type: "timestamp with time zone",
|
||||
nullable: true,
|
||||
comment: "到期日期。",
|
||||
oldClrType: typeof(DateOnly),
|
||||
oldType: "date",
|
||||
oldNullable: true,
|
||||
oldComment: "到期日期。");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5731,8 +5731,8 @@ namespace TakeoutSaaS.Infrastructure.Migrations
|
||||
.HasColumnType("character varying(100)")
|
||||
.HasComment("证照编号。");
|
||||
|
||||
b.Property<DateTime?>("ExpiresAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
b.Property<DateOnly?>("ExpiresAt")
|
||||
.HasColumnType("date")
|
||||
.HasComment("到期日期。");
|
||||
|
||||
b.Property<string>("FileUrl")
|
||||
@@ -5741,8 +5741,8 @@ namespace TakeoutSaaS.Infrastructure.Migrations
|
||||
.HasColumnType("character varying(500)")
|
||||
.HasComment("证照文件 URL。");
|
||||
|
||||
b.Property<DateTime?>("IssuedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
b.Property<DateOnly?>("IssuedAt")
|
||||
.HasColumnType("date")
|
||||
.HasComment("签发日期。");
|
||||
|
||||
b.Property<int>("QualificationType")
|
||||
|
||||
Reference in New Issue
Block a user