refactor: 排班替换改为事务内先删后增
All checks were successful
Build and Deploy TenantApi / build-and-deploy (push) Successful in 43s

This commit is contained in:
2026-02-20 09:14:39 +08:00
parent 669db14f64
commit 9651022261

View File

@@ -305,6 +305,7 @@ public sealed class StoreStaffController(
throw new BusinessException(ErrorCodes.BadRequest, "请先配置班次模板"); throw new BusinessException(ErrorCodes.BadRequest, "请先配置班次模板");
} }
var existingRows = await dbContext.StoreStaffWeeklySchedules var existingRows = await dbContext.StoreStaffWeeklySchedules
.AsNoTracking()
.Where(x => x.TenantId == tenantId && x.StoreId == parsedStoreId && x.StaffId == parsedStaffId) .Where(x => x.TenantId == tenantId && x.StoreId == parsedStoreId && x.StaffId == parsedStaffId)
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
@@ -314,7 +315,14 @@ public sealed class StoreStaffController(
: NormalizeShifts(request.Shifts, fallback, template); : NormalizeShifts(request.Shifts, fallback, template);
var nextRows = ToWeeklyEntities(parsedStoreId, parsedStaffId, shifts, template).ToList(); var nextRows = ToWeeklyEntities(parsedStoreId, parsedStaffId, shifts, template).ToList();
await ReplaceWeeklySchedulesAsync(existingRows, nextRows, cancellationToken); await ReplaceWeeklySchedulesAsync(
dbContext.StoreStaffWeeklySchedules
.Where(x =>
x.TenantId == tenantId &&
x.StoreId == parsedStoreId &&
x.StaffId == parsedStaffId),
nextRows,
cancellationToken);
return ApiResponse<StaffScheduleDto>.Ok(new StaffScheduleDto return ApiResponse<StaffScheduleDto>.Ok(new StaffScheduleDto
{ {
@@ -350,6 +358,7 @@ public sealed class StoreStaffController(
throw new BusinessException(ErrorCodes.BadRequest, "请先配置班次模板"); throw new BusinessException(ErrorCodes.BadRequest, "请先配置班次模板");
} }
var existingRows = await dbContext.StoreStaffWeeklySchedules var existingRows = await dbContext.StoreStaffWeeklySchedules
.AsNoTracking()
.Where(x => x.TenantId == tenantId && x.StoreId == parsedStoreId) .Where(x => x.TenantId == tenantId && x.StoreId == parsedStoreId)
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
var existingMap = existingRows var existingMap = existingRows
@@ -403,7 +412,13 @@ public sealed class StoreStaffController(
var entities = finalSchedules var entities = finalSchedules
.SelectMany(x => ToWeeklyEntities(parsedStoreId, long.Parse(x.StaffId), x.Shifts, template)) .SelectMany(x => ToWeeklyEntities(parsedStoreId, long.Parse(x.StaffId), x.Shifts, template))
.ToList(); .ToList();
await ReplaceWeeklySchedulesAsync(existingRows, entities, cancellationToken); await ReplaceWeeklySchedulesAsync(
dbContext.StoreStaffWeeklySchedules
.Where(x =>
x.TenantId == tenantId &&
x.StoreId == parsedStoreId),
entities,
cancellationToken);
return ApiResponse<StoreStaffScheduleDto>.Ok(new StoreStaffScheduleDto return ApiResponse<StoreStaffScheduleDto>.Ok(new StoreStaffScheduleDto
{ {
@@ -509,10 +524,6 @@ public sealed class StoreStaffController(
} }
await dbContext.SaveChangesAsync(cancellationToken); await dbContext.SaveChangesAsync(cancellationToken);
var targetRows = await dbContext.StoreStaffWeeklySchedules
.Where(x => x.TenantId == tenantId && accessibleTargetIds.Contains(x.StoreId))
.ToListAsync(cancellationToken);
var targetStaffs = await dbContext.MerchantStaff var targetStaffs = await dbContext.MerchantStaff
.AsNoTracking() .AsNoTracking()
.Where(x => x.TenantId == tenantId && x.StoreId.HasValue && accessibleTargetIds.Contains(x.StoreId.Value)) .Where(x => x.TenantId == tenantId && x.StoreId.HasValue && accessibleTargetIds.Contains(x.StoreId.Value))
@@ -541,7 +552,13 @@ public sealed class StoreStaffController(
} }
} }
await ReplaceWeeklySchedulesAsync(targetRows, entities, cancellationToken); await ReplaceWeeklySchedulesAsync(
dbContext.StoreStaffWeeklySchedules
.Where(x =>
x.TenantId == tenantId &&
accessibleTargetIds.Contains(x.StoreId)),
entities,
cancellationToken);
return ApiResponse<CopyStoreStaffScheduleResult>.Ok(new CopyStoreStaffScheduleResult return ApiResponse<CopyStoreStaffScheduleResult>.Ok(new CopyStoreStaffScheduleResult
{ {
@@ -795,25 +812,22 @@ public sealed class StoreStaffController(
} }
private async Task ReplaceWeeklySchedulesAsync( private async Task ReplaceWeeklySchedulesAsync(
IReadOnlyCollection<StoreStaffWeeklySchedule> existingRows, IQueryable<StoreStaffWeeklySchedule> deleteQuery,
IReadOnlyCollection<StoreStaffWeeklySchedule> nextRows, IReadOnlyCollection<StoreStaffWeeklySchedule> nextRows,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
if (existingRows.Count > 0) await using var transaction = await dbContext.Database.BeginTransactionAsync(cancellationToken);
{ await deleteQuery.ExecuteDeleteAsync(cancellationToken);
dbContext.StoreStaffWeeklySchedules.RemoveRange(existingRows);
await dbContext.SaveChangesAsync(cancellationToken);
}
if (nextRows.Count == 0) if (nextRows.Count > 0)
{ {
return;
}
await dbContext.StoreStaffWeeklySchedules.AddRangeAsync(nextRows, cancellationToken); await dbContext.StoreStaffWeeklySchedules.AddRangeAsync(nextRows, cancellationToken);
await dbContext.SaveChangesAsync(cancellationToken); await dbContext.SaveChangesAsync(cancellationToken);
} }
await transaction.CommitAsync(cancellationToken);
}
private static List<StaffDayShiftDto> CreateOffWeekShifts() private static List<StaffDayShiftDto> CreateOffWeekShifts()
{ {
return Enumerable.Range(0, 7).Select(day => new StaffDayShiftDto return Enumerable.Range(0, 7).Select(day => new StaffDayShiftDto