From de898f75ce0b522209a7a6e40c0882b12ad76111 Mon Sep 17 00:00:00 2001
From: ltx <1006158920@qq.com>
Date: Thu, 8 Oct 2026 15:18:44 +0800
Subject: [PATCH] =?UTF-8?q?=E5=85=81=E8=AE=B8=E5=88=A0=E9=99=A4=E5=B7=B2?=
=?UTF-8?q?=E5=8D=87=E5=AD=A6=E5=AD=A6=E7=94=9F=E5=B9=B6=E6=A0=A1=E9=AA=8C?=
=?UTF-8?q?=E7=A9=BA=E7=8F=AD=E7=BA=A7=E5=88=A0=E9=99=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../IServices/School/IS_ClassService.cs | 5 +
.../Services/School/S_ClassService.cs | 41 +++++-
.../Services/School/S_StudentService.cs | 119 +++++++++---------
.../Controllers/Business/ClassController.cs | 18 +++
4 files changed, 122 insertions(+), 61 deletions(-)
diff --git a/VOL.Business/IServices/School/IS_ClassService.cs b/VOL.Business/IServices/School/IS_ClassService.cs
index a9a88be..3d6b279 100644
--- a/VOL.Business/IServices/School/IS_ClassService.cs
+++ b/VOL.Business/IServices/School/IS_ClassService.cs
@@ -57,6 +57,11 @@ namespace VOL.Business.IServices.School
///
Task ModifyClass(ModifyClassParam paramDto);
+ ///
+ /// 删除没有学生的班级
+ ///
+ Task DeleteClass(int classId);
+
///
/// 班级数据统计
///
diff --git a/VOL.Business/Services/School/S_ClassService.cs b/VOL.Business/Services/School/S_ClassService.cs
index de4f9e9..c847db5 100644
--- a/VOL.Business/Services/School/S_ClassService.cs
+++ b/VOL.Business/Services/School/S_ClassService.cs
@@ -3,6 +3,7 @@ using Castle.DynamicProxy.Generators;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
+using System.Data;
using VOL.Business.IServices.Norm;
using VOL.Business.IServices.School;
using VOL.Core.CacheManager;
@@ -384,6 +385,44 @@ namespace VOL.Business.Services.School
}
}
+ ///
+ /// 删除空班级,同时清理班级与老师的关联
+ ///
+ public async Task DeleteClass(int classId)
+ {
+ if (classId <= 0)
+ throw new ArgumentException("班级参数无效");
+
+ var tenantId = UserContext.Current.TenantId;
+ await using var transaction = await _classRepository.DbContext.Database.BeginTransactionAsync(IsolationLevel.Serializable);
+
+ var classModel = await _classRepository.DbContext.Set()
+ .FirstOrDefaultAsync(x => x.Id == classId && x.SchoolCode == tenantId);
+ if (classModel == null)
+ throw new Exception("班级不存在或无权删除,请刷新列表后重试");
+
+ var hasStudents = await _classRepository.DbContext.Set()
+ .AnyAsync(x => x.ClassId == classId);
+ if (hasStudents)
+ return false;
+
+ var teacherAssociations = await _classRepository.DbContext.Set()
+ .Where(x => x.ClassId == classId)
+ .ToListAsync();
+ _classRepository.DbContext.RemoveRange(teacherAssociations);
+ _classRepository.DbContext.Remove(classModel);
+ await _classRepository.SaveChangesAsync();
+ await transaction.CommitAsync();
+
+ await _iotDataSyncService.DataSyncCallBack(new DataSyncCallBackParam
+ {
+ EventType = EventType.Delete.GetDisplayName(),
+ DataType = IOTDataSyncType.Class.GetDisplayName(),
+ Json = JsonConvert.SerializeObject(classModel)
+ });
+ return true;
+ }
+
///
/// 添加班级
///
@@ -902,4 +941,4 @@ namespace VOL.Business.Services.School
return result;
}
}
-}
\ No newline at end of file
+}
diff --git a/VOL.Business/Services/School/S_StudentService.cs b/VOL.Business/Services/School/S_StudentService.cs
index 94f4e7f..3cef4d4 100644
--- a/VOL.Business/Services/School/S_StudentService.cs
+++ b/VOL.Business/Services/School/S_StudentService.cs
@@ -8,6 +8,7 @@ using Newtonsoft.Json;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using System;
using System.Collections.Generic;
+using System.Data;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
@@ -443,27 +444,25 @@ namespace VOL.Business.Services.School
if (studentIds.Count == 0)
throw new ArgumentException("请至少选择一名学生");
+ await using var transaction = await _studentRepository.DbContext.Database.BeginTransactionAsync(IsolationLevel.Serializable);
+
+ var activeBatchIds = await _studentRepository.DbContext.Set()
+ .Where(x => x.SchoolCode == UserContext.Current.TenantId && x.Status == 1)
+ .Select(x => x.Id)
+ .ToListAsync();
+ var promotionDetails = await _studentRepository.DbContext.Set()
+ .Where(x => activeBatchIds.Contains(x.BatchId) && studentIds.Contains(x.StudentId))
+ .ToListAsync();
var students = await _studentRepository.FindAsIQueryable(x =>
x.SchoolCode == UserContext.Current.TenantId && studentIds.Contains(x.Id))
.ToListAsync();
if (students.Count != studentIds.Count)
throw new Exception("部分学生不存在或不属于当前学校,请刷新列表后重新选择");
- var activeBatchId = await _studentRepository.DbContext.Set()
- .Where(x => x.SchoolCode == UserContext.Current.TenantId && x.Status == 1)
- .OrderByDescending(x => x.Id)
- .Select(x => (int?)x.Id)
- .FirstOrDefaultAsync();
- if (activeBatchId.HasValue)
- {
- var promotionStudentCount = await _studentRepository.DbContext.Set()
- .CountAsync(x => x.BatchId == activeBatchId.Value && studentIds.Contains(x.StudentId));
- if (promotionStudentCount > 0)
- throw new Exception($"所选学生中有{promotionStudentCount}人属于当前可撤回的升学记录,请先撤回升学后再删除");
- }
-
+ _studentRepository.DbContext.RemoveRange(promotionDetails);
_studentRepository.DbContext.RemoveRange(students);
await _studentRepository.SaveChangesAsync();
+ await transaction.CommitAsync();
await _iotDataSyncService.DataSyncCallBack(new DataSyncCallBackParam
{
@@ -1789,6 +1788,8 @@ namespace VOL.Business.Services.School
public async Task UndoPromotion()
{
var school = await GetPromotionSchool();
+ await using (var transaction = await _studentRepository.DbContext.Database.BeginTransactionAsync(IsolationLevel.Serializable))
+ {
var batch = await _studentRepository.DbContext.Set()
.Where(x => x.SchoolCode == school.SchoolCode)
.OrderByDescending(x => x.Id)
@@ -1832,58 +1833,56 @@ namespace VOL.Business.Services.School
throw new Exception($"升学后已有{changedTeacherCount}条教师班级关系被修改,无法自动撤回");
var now = DateTime.Now;
- using (var transaction = await _studentRepository.DbContext.Database.BeginTransactionAsync())
+ try
{
- try
+ foreach (var detail in details)
{
- foreach (var detail in details)
- {
- var student = studentById[detail.StudentId];
- student.ClassId = detail.OriginalClassId;
- student.ClassName = detail.OriginalClassName;
- student.StudentStatus = detail.OriginalStatus;
- student.Age = detail.OriginalAge;
- student.Modifier = UserContext.Current.UserId;
- student.ModifyDate = now;
- }
-
- foreach (var snapshot in teacherSnapshots)
- {
- if (snapshot.TargetClassId > 0)
- {
- var association = currentTeacherAssociationById[snapshot.AssociationId];
- association.ClassId = snapshot.OriginalClassId;
- association.Modifier = snapshot.Modifier;
- association.ModifyDate = snapshot.ModifyDate;
- _studentRepository.DbContext.Set().Update(association);
- }
- else
- {
- await _studentRepository.DbContext.Set().AddAsync(new S_ClassAssocTeacher
- {
- ClassId = snapshot.OriginalClassId,
- TeacherId = snapshot.TeacherId,
- Creator = snapshot.Creator,
- CreateDate = snapshot.CreateDate,
- Modifier = snapshot.Modifier,
- ModifyDate = snapshot.ModifyDate
- });
- }
- }
-
- batch.Status = 2;
- batch.RevokeOperatorId = UserContext.Current.UserId;
- batch.RevokeDate = now;
- _studentRepository.UpdateRange(students);
- _studentRepository.DbContext.Set().Update(batch);
- await _studentRepository.SaveChangesAsync();
- await transaction.CommitAsync();
+ var student = studentById[detail.StudentId];
+ student.ClassId = detail.OriginalClassId;
+ student.ClassName = detail.OriginalClassName;
+ student.StudentStatus = detail.OriginalStatus;
+ student.Age = detail.OriginalAge;
+ student.Modifier = UserContext.Current.UserId;
+ student.ModifyDate = now;
}
- catch
+
+ foreach (var snapshot in teacherSnapshots)
{
- await transaction.RollbackAsync();
- throw;
+ if (snapshot.TargetClassId > 0)
+ {
+ var association = currentTeacherAssociationById[snapshot.AssociationId];
+ association.ClassId = snapshot.OriginalClassId;
+ association.Modifier = snapshot.Modifier;
+ association.ModifyDate = snapshot.ModifyDate;
+ _studentRepository.DbContext.Set().Update(association);
+ }
+ else
+ {
+ await _studentRepository.DbContext.Set().AddAsync(new S_ClassAssocTeacher
+ {
+ ClassId = snapshot.OriginalClassId,
+ TeacherId = snapshot.TeacherId,
+ Creator = snapshot.Creator,
+ CreateDate = snapshot.CreateDate,
+ Modifier = snapshot.Modifier,
+ ModifyDate = snapshot.ModifyDate
+ });
+ }
}
+
+ batch.Status = 2;
+ batch.RevokeOperatorId = UserContext.Current.UserId;
+ batch.RevokeDate = now;
+ _studentRepository.UpdateRange(students);
+ _studentRepository.DbContext.Set().Update(batch);
+ await _studentRepository.SaveChangesAsync();
+ await transaction.CommitAsync();
+ }
+ catch
+ {
+ await transaction.RollbackAsync();
+ throw;
+ }
}
return await GetPromotionStatus();
diff --git a/VOL.WebApi/Controllers/Business/ClassController.cs b/VOL.WebApi/Controllers/Business/ClassController.cs
index 3113a5c..79e9ed1 100644
--- a/VOL.WebApi/Controllers/Business/ClassController.cs
+++ b/VOL.WebApi/Controllers/Business/ClassController.cs
@@ -101,6 +101,24 @@ namespace VOL.WebApi.Controllers.Business
return Ok("更新成功");
}
+ ///
+ /// 删除空班级
+ ///
+ [HttpPost(nameof(DeleteClass))]
+ public async Task DeleteClass([FromQuery] int classId)
+ {
+ if (!await _classService.DeleteClass(classId))
+ {
+ return new JsonResult(new WebResponseContent
+ {
+ Code = 409,
+ Status = false,
+ Message = "班级内还有学生,请先删除学生后再删除班级"
+ });
+ }
+ return Ok("删除成功");
+ }
+
///
/// 班级列表导出
///