提交代码

This commit is contained in:
zlwu committed 2025-09-08 01:52:37 +08:00
1 parent bf25ceba66
commit 55457496b7
7 files changed
+1494 -167

No files matched your search

@@ -111,4 +111,15 @@ public class XgHolidayStayController extends BaseController {
public TableDataInfo<StudentOptionVo> getStudentOptions(StudentOptionBo bo, PageQuery pageQuery) {
return xgHolidayStayService.getStudentOptions(bo, pageQuery);
}
/**
* 查询单人留宿有效数据
* 获取所有有效的假期留宿数据,筛选出在同一时间段内该宿舍只有一个学生留宿的记录
*/
@SaCheckPermission("holidayStay:holidayStay:list")
@GetMapping("/singlePersonValidStay")
public R<List<XgHolidayStayVo>> getSinglePersonValidStay() {
List<XgHolidayStayVo> result = xgHolidayStayService.querySinglePersonValidStay();
return R.ok(result);
}
}
@@ -77,4 +77,12 @@ public interface IXgHolidayStayService {
*/
TableDataInfo<StudentOptionVo> getStudentOptions(StudentOptionBo bo, PageQuery pageQuery);
/**
* 查询单人留宿有效数据
* 获取所有有效的假期留宿数据,筛选出在同一时间段内该宿舍只有一个学生留宿的记录
*
* @return 单人留宿有效数据列表
*/
List<XgHolidayStayVo> querySinglePersonValidStay();
}
@@ -22,6 +22,15 @@ import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.util.Set;
import java.util.TreeSet;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Calendar;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.beans.BeanUtils;
/**
* 假期留宿管理Service业务层处理
@@ -165,30 +174,19 @@ public class XgHolidayStayServiceImpl implements IXgHolidayStayService {
if (StringUtils.isNotBlank(statusType) && StringUtils.isNotBlank(currentTime)) {
if ("valid".equals(statusType)) {
// 有效状态:当前时间在留宿开始时间和结束时间之间(包含边界)
// 条件:applyStartDate <= currentTime AND applyEndDate >= currentTime
// AND applyStartDate IS NOT NULL AND applyEndDate IS NOT NULL
lqw.le(XgHolidayStay::getApplyStartDate, currentTime)
.ge(XgHolidayStay::getApplyEndDate, currentTime)
.isNotNull(XgHolidayStay::getApplyStartDate)
// 有效状态:当前时间还没有超过留宿结束时间(包括预约状态)
// 条件:applyEndDate >= currentTime AND applyEndDate IS NOT NULL
lqw.ge(XgHolidayStay::getApplyEndDate, currentTime)
.isNotNull(XgHolidayStay::getApplyEndDate);
log.debug(
"添加有效状态过滤条件: apply_start_date <= {} AND apply_end_date >= {} AND start/end dates are not null",
currentTime, currentTime);
log.debug("添加有效状态过滤条件: apply_end_date >= {} AND end_date is not null", currentTime);
} else if ("invalid".equals(statusType)) {
// 失效状态:当前时间不在留宿时间范围内
// 条件:applyStartDate > currentTime OR applyEndDate < currentTime
// OR applyStartDate IS NULL OR applyEndDate IS NULL
// 失效状态:当前时间已超过留宿结束时间
// 条件:applyEndDate < currentTime OR applyEndDate IS NULL
lqw.and(wrapper -> wrapper
.gt(XgHolidayStay::getApplyStartDate, currentTime)
.or()
.lt(XgHolidayStay::getApplyEndDate, currentTime)
.or()
.isNull(XgHolidayStay::getApplyStartDate)
.or()
.isNull(XgHolidayStay::getApplyEndDate));
log.debug("添加失效状态过滤条件: apply_start_date > {} OR apply_end_date < {} OR start/end dates are null",
currentTime, currentTime);
log.debug("添加失效状态过滤条件: apply_end_date < {} OR end_date is null", currentTime);
}
}
}
@@ -258,4 +256,503 @@ public class XgHolidayStayServiceImpl implements IXgHolidayStayService {
Page<StudentOptionVo> result = baseMapper.selectStudentOptions(pageQuery.build(), bo);
return TableDataInfo.build(result);
}
/**
* 查询单人留宿有效数据
* 获取所有有效的假期留宿数据,筛选出在同一时间段内该宿舍只有一个学生留宿的记录
*
* @return 单人留宿有效数据列表
*/
@Override
public List<XgHolidayStayVo> querySinglePersonValidStay() {
// 1. 获取所有有效的假期留宿数据
XgHolidayStayBo bo = new XgHolidayStayBo();
Map<String, Object> params = bo.getParams();
if (params == null) {
params = new HashMap<>();
bo.setParams(params);
}
// 设置查询有效状态的留宿数据
String currentTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
params.put("statusType", "valid");
params.put("currentTime", currentTime);
List<XgHolidayStayVo> validStayList = queryList(bo);
log.info("查询到有效的假期留宿数据总数: {}", validStayList.size());
if (validStayList.isEmpty()) {
return new ArrayList<>();
}
// 2. 按房间分组,筛选出单人留宿的数据
List<XgHolidayStayVo> singlePersonStayList = new ArrayList<>();
// 按房间ID分组
Map<Long, List<XgHolidayStayVo>> roomGroupMap = validStayList.stream()
.filter(stay -> stay.getRoomId() != null)
.collect(Collectors.groupingBy(XgHolidayStayVo::getRoomId));
log.info("按房间分组后,涉及房间数量: {}", roomGroupMap.size());
// 遍历每个房间的留宿数据
for (Map.Entry<Long, List<XgHolidayStayVo>> entry : roomGroupMap.entrySet()) {
Long roomId = entry.getKey();
List<XgHolidayStayVo> roomStayList = entry.getValue();
log.debug("处理房间ID: {}, 该房间留宿人数: {}", roomId, roomStayList.size());
// 3. 对于每个房间,检查是否存在单人留宿的时间段
List<XgHolidayStayVo> singlePersonInRoom = findSinglePersonPeriodsInRoom(roomStayList);
singlePersonStayList.addAll(singlePersonInRoom);
}
log.info("筛选出单人留宿有效数据总数: {}", singlePersonStayList.size());
// 按ID倒序排序(作为时间排序的替代)
return singlePersonStayList.stream()
.sorted((a, b) -> {
if (a.getId() == null && b.getId() == null)
return 0;
if (a.getId() == null)
return 1;
if (b.getId() == null)
return -1;
return b.getId().compareTo(a.getId());
})
.collect(Collectors.toList());
}
/**
* 检查房间内是否存在单人留宿的时间段
*
* @param roomStayList 同一房间内的留宿数据列表
* @return 单人留宿的数据列表
*/
private List<XgHolidayStayVo> findSinglePersonPeriodsInRoom(List<XgHolidayStayVo> roomStayList) {
List<XgHolidayStayVo> singlePersonList = new ArrayList<>();
if (roomStayList == null || roomStayList.isEmpty()) {
return singlePersonList;
}
// 如果房间内只有一个人留宿,直接返回
if (roomStayList.size() == 1) {
singlePersonList.add(roomStayList.get(0));
log.debug("房间 {} 只有一个人留宿: {}", roomStayList.get(0).getRoomName(), roomStayList.get(0).getStudentName());
return singlePersonList;
}
// 按学生分组,处理每个学生的多个留宿记录
Map<Long, List<XgHolidayStayVo>> studentStaysMap = roomStayList.stream()
.collect(Collectors.groupingBy(XgHolidayStayVo::getStudentId));
// 为每个学生创建时间段
Map<Long, List<TimeSegment>> studentTimeSegments = new HashMap<>();
for (Map.Entry<Long, List<XgHolidayStayVo>> entry : studentStaysMap.entrySet()) {
Long studentId = entry.getKey();
List<XgHolidayStayVo> stays = entry.getValue();
List<TimeSegment> segments = new ArrayList<>();
for (XgHolidayStayVo stay : stays) {
if (stay.getApplyStartDate() != null && stay.getApplyEndDate() != null) {
segments.add(new TimeSegment(stay.getApplyStartDate(), stay.getApplyEndDate(), studentId, stay));
}
}
// 合并同一学生的重叠时间段
List<TimeSegment> mergedSegments = mergeTimeSegments(segments);
studentTimeSegments.put(studentId, mergedSegments);
}
// 收集所有关键时间点
Set<Date> keyTimePoints = new TreeSet<>();
for (List<TimeSegment> segments : studentTimeSegments.values()) {
for (TimeSegment segment : segments) {
keyTimePoints.add(segment.getStartTime());
keyTimePoints.add(segment.getEndTime());
}
}
List<Date> sortedTimePoints = new ArrayList<>(keyTimePoints);
log.debug("房间 {} 关键时间点数量: {}", roomStayList.get(0).getRoomName(), sortedTimePoints.size());
// 分析每个时间段内的留宿人数
for (int i = 0; i < sortedTimePoints.size() - 1; i++) {
Date segmentStart = sortedTimePoints.get(i);
Date segmentEnd = sortedTimePoints.get(i + 1);
// 找出在这个时间段内留宿的所有学生
List<Long> studentsInSegment = new ArrayList<>();
Map<Long, XgHolidayStayVo> studentStayMap = new HashMap<>();
for (Map.Entry<Long, List<TimeSegment>> entry : studentTimeSegments.entrySet()) {
Long studentId = entry.getKey();
List<TimeSegment> segments = entry.getValue();
for (TimeSegment segment : segments) {
// 检查时间段是否重叠(注意边界条件)
if (segment.getStartTime().compareTo(segmentEnd) < 0 &&
segment.getEndTime().compareTo(segmentStart) > 0) {
studentsInSegment.add(studentId);
studentStayMap.put(studentId, segment.getOriginalStay());
break; // 一个学生在同一时间段内只能有一个记录
}
}
}
// 如果只有一个学生,这是单人留宿时间段
if (studentsInSegment.size() == 1) {
Long singleStudentId = studentsInSegment.get(0);
XgHolidayStayVo originalStay = studentStayMap.get(singleStudentId);
// 创建单人留宿记录
XgHolidayStayVo singlePersonStay = createSinglePersonStayFromSegment(
originalStay, segmentStart, segmentEnd);
singlePersonList.add(singlePersonStay);
log.debug("找到单人留宿时间段: {} ({} - {}) 学生: {}",
originalStay.getRoomName(),
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(segmentStart),
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(segmentEnd),
originalStay.getStudentName());
}
}
// 合并同一学生的连续单人留宿时间段
return mergeConsecutiveSinglePersonStays(singlePersonList);
}
/**
* 获取两个日期之间的所有日期(包含起始和结束日期)
*
* @param startDate 开始日期
* @param endDate 结束日期
* @param dateFormat 日期格式化器
* @return 日期字符串列表
*/
private List<String> getDatesBetween(Date startDate, Date endDate, SimpleDateFormat dateFormat) {
List<String> dates = new ArrayList<>();
if (startDate == null || endDate == null) {
return dates;
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDate);
// 只取日期部分,忽略时间
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(endDate);
endCalendar.set(Calendar.HOUR_OF_DAY, 0);
endCalendar.set(Calendar.MINUTE, 0);
endCalendar.set(Calendar.SECOND, 0);
endCalendar.set(Calendar.MILLISECOND, 0);
// 生成日期列表
while (!calendar.after(endCalendar)) {
dates.add(dateFormat.format(calendar.getTime()));
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
return dates;
}
/**
* 创建单人留宿记录,调整时间范围为单人留宿的日期范围
*
* @param originalStay 原始留宿记录
* @param singlePersonDates 单人留宿的日期列表
* @param dateFormat 日期格式化器
* @return 调整后的单人留宿记录
*/
private XgHolidayStayVo createSinglePersonStayRecord(XgHolidayStayVo originalStay, List<String> singlePersonDates,
SimpleDateFormat dateFormat) {
if (singlePersonDates.isEmpty()) {
return originalStay;
}
try {
// 排序日期列表
singlePersonDates.sort(String::compareTo);
// 获取单人留宿的开始和结束日期
String startDateStr = singlePersonDates.get(0);
String endDateStr = singlePersonDates.get(singlePersonDates.size() - 1);
// 克隆原始记录
XgHolidayStayVo singlePersonStay = new XgHolidayStayVo();
BeanUtils.copyProperties(originalStay, singlePersonStay);
// 调整时间范围为单人留宿的日期范围
Date adjustedStartDate = dateFormat.parse(startDateStr);
Date adjustedEndDate = dateFormat.parse(endDateStr);
// 结束日期设置为当天的23:59:59
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(adjustedEndDate);
endCalendar.set(Calendar.HOUR_OF_DAY, 23);
endCalendar.set(Calendar.MINUTE, 59);
endCalendar.set(Calendar.SECOND, 59);
adjustedEndDate = endCalendar.getTime();
singlePersonStay.setApplyStartDate(adjustedStartDate);
singlePersonStay.setApplyEndDate(adjustedEndDate);
// 在备注中添加单人留宿信息
String originalRemark = singlePersonStay.getRemark() == null ? "" : singlePersonStay.getRemark();
String singlePersonInfo = String.format("【单人留宿】%s天(%s至%s)",
singlePersonDates.size(), startDateStr, endDateStr);
singlePersonStay
.setRemark(originalRemark.isEmpty() ? singlePersonInfo : originalRemark + " " + singlePersonInfo);
log.debug("为学生 {} 创建单人留宿记录: {} 天 ({} - {})",
singlePersonStay.getStudentName(), singlePersonDates.size(), startDateStr, endDateStr);
return singlePersonStay;
} catch (Exception e) {
log.error("创建单人留宿记录失败", e);
return originalStay;
}
}
/**
* 检查两个留宿时间段是否重叠
*
* @param stay1 留宿记录1
* @param stay2 留宿记录2
* @return 是否重叠
*/
private boolean isTimeOverlap(XgHolidayStayVo stay1, XgHolidayStayVo stay2) {
if (stay1.getApplyStartDate() == null || stay1.getApplyEndDate() == null ||
stay2.getApplyStartDate() == null || stay2.getApplyEndDate() == null) {
return false;
}
Date start1 = stay1.getApplyStartDate();
Date end1 = stay1.getApplyEndDate();
Date start2 = stay2.getApplyStartDate();
Date end2 = stay2.getApplyEndDate();
// 检查时间段是否重叠:两个时间段重叠当且仅当 start1 <= end2 && start2 <= end1
boolean overlap = start1.compareTo(end2) <= 0 && start2.compareTo(end1) <= 0;
if (overlap) {
log.debug("时间段重叠: {} ({} - {}) 与 {} ({} - {})",
stay1.getStudentName(), start1, end1,
stay2.getStudentName(), start2, end2);
}
return overlap;
}
/**
* 合并同一学生的重叠时间段
*/
private List<TimeSegment> mergeTimeSegments(List<TimeSegment> segments) {
if (segments.isEmpty()) {
return new ArrayList<>();
}
// 按开始时间排序
segments.sort(Comparator.comparing(TimeSegment::getStartTime));
List<TimeSegment> merged = new ArrayList<>();
TimeSegment current = segments.get(0);
for (int i = 1; i < segments.size(); i++) {
TimeSegment next = segments.get(i);
// 如果时间段重叠或相邻,合并它们
if (current.getEndTime().compareTo(next.getStartTime()) >= 0) {
// 扩展当前时间段
if (next.getEndTime().compareTo(current.getEndTime()) > 0) {
current = new TimeSegment(
current.getStartTime(),
next.getEndTime(),
current.getStudentId(),
current.getOriginalStay()
);
}
} else {
// 不重叠,添加当前时间段到结果中
merged.add(current);
current = next;
}
}
// 添加最后一个时间段
merged.add(current);
return merged;
}
/**
* 从时间段创建单人留宿记录
*/
private XgHolidayStayVo createSinglePersonStayFromSegment(XgHolidayStayVo template, Date startTime, Date endTime) {
XgHolidayStayVo singlePersonStay = new XgHolidayStayVo();
// 复制基本信息
BeanUtils.copyProperties(template, singlePersonStay);
// 设置ID为null,表示这是计算出来的记录
singlePersonStay.setId(null);
// 设置单人留宿的时间段
singlePersonStay.setApplyStartDate(startTime);
singlePersonStay.setApplyEndDate(endTime);
// 计算单人留宿天数
long timeDiff = endTime.getTime() - startTime.getTime();
long days = Math.max(1, timeDiff / (24 * 60 * 60 * 1000) + 1); // 至少1天
// 设置备注信息
String originalRemark = template.getRemark() != null ? template.getRemark() : "";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String singlePersonRemark = String.format("单人留宿%d天 (%s至%s)",
days,
sdf.format(startTime),
sdf.format(endTime)
);
if (!originalRemark.isEmpty()) {
singlePersonStay.setRemark(originalRemark + " | " + singlePersonRemark);
} else {
singlePersonStay.setRemark(singlePersonRemark);
}
return singlePersonStay;
}
/**
* 合并同一学生的连续单人留宿时间段
*/
private List<XgHolidayStayVo> mergeConsecutiveSinglePersonStays(List<XgHolidayStayVo> singlePersonStays) {
if (singlePersonStays.isEmpty()) {
return new ArrayList<>();
}
// 按学生ID和开始时间分组排序
Map<Long, List<XgHolidayStayVo>> studentStaysMap = singlePersonStays.stream()
.collect(Collectors.groupingBy(XgHolidayStayVo::getStudentId));
List<XgHolidayStayVo> mergedStays = new ArrayList<>();
for (Map.Entry<Long, List<XgHolidayStayVo>> entry : studentStaysMap.entrySet()) {
List<XgHolidayStayVo> stays = entry.getValue();
// 按开始时间排序
stays.sort(Comparator.comparing(XgHolidayStayVo::getApplyStartDate));
XgHolidayStayVo current = stays.get(0);
for (int i = 1; i < stays.size(); i++) {
XgHolidayStayVo next = stays.get(i);
// 如果时间段连续或重叠,合并它们
if (current.getApplyEndDate().compareTo(next.getApplyStartDate()) >= 0) {
// 扩展当前时间段
if (next.getApplyEndDate().compareTo(current.getApplyEndDate()) > 0) {
current.setApplyEndDate(next.getApplyEndDate());
}
// 更新备注信息
updateMergedRemark(current, next);
} else {
// 不连续,添加当前时间段到结果中
mergedStays.add(current);
current = next;
}
}
// 添加最后一个时间段
mergedStays.add(current);
}
return mergedStays;
}
/**
* 更新合并后的备注信息
*/
private void updateMergedRemark(XgHolidayStayVo current, XgHolidayStayVo next) {
// 重新计算合并后的天数
long timeDiff = current.getApplyEndDate().getTime() - current.getApplyStartDate().getTime();
long totalDays = Math.max(1, timeDiff / (24 * 60 * 60 * 1000) + 1);
// 更新备注
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String mergedRemark = String.format("单人留宿%d天 (%s至%s)",
totalDays,
sdf.format(current.getApplyStartDate()),
sdf.format(current.getApplyEndDate())
);
// 保留原始备注的非单人留宿信息
String originalPart = extractOriginalRemark(current.getRemark());
if (!originalPart.isEmpty()) {
current.setRemark(originalPart + " | " + mergedRemark);
} else {
current.setRemark(mergedRemark);
}
}
/**
* 提取原始备注信息(去除单人留宿相关的备注)
*/
private String extractOriginalRemark(String remark) {
if (remark == null || remark.isEmpty()) {
return "";
}
// 如果包含单人留宿标记,提取原始部分
if (remark.contains(" | 单人留宿")) {
return remark.split(" \\| 单人留宿")[0].trim();
}
// 如果以单人留宿开头,返回空
if (remark.startsWith("单人留宿")) {
return "";
}
return remark;
}
/**
* 时间段内部类
*/
private static class TimeSegment {
private Date startTime;
private Date endTime;
private Long studentId;
private XgHolidayStayVo originalStay;
public TimeSegment(Date startTime, Date endTime, Long studentId, XgHolidayStayVo originalStay) {
this.startTime = startTime;
this.endTime = endTime;
this.studentId = studentId;
this.originalStay = originalStay;
}
public Date getStartTime() {
return startTime;
}
public Date getEndTime() {
return endTime;
}
public Long getStudentId() {
return studentId;
}
public XgHolidayStayVo getOriginalStay() {
return originalStay;
}
}
}
+1
View File
@@ -19,6 +19,7 @@
- [宿舍管理员授权API](./宿舍管理员授权API.md)
- [学生管理员授权关系API](./学生管理员授权关系API.md)
- [学生销假管理API](./学生销假管理API.md)
- [假期留宿管理API](./假期留宿管理API.md) - **重要修复:单人留宿计算逻辑**(2025-01-03)
### 1. 用户认证登录
@@ -80,6 +80,18 @@ export const getStudentOptions = (
});
};
/**
* 查询单人留宿有效数据
* 获取所有有效的假期留宿数据,筛选出在同一时间段内该宿舍只有一个学生留宿的记录
* @returns 单人留宿有效数据列表
*/
export const getSinglePersonValidStay = (): AxiosPromise<HolidayStayVO[]> => {
return request({
url: '/holidayStay/holidayStay/singlePersonValidStay',
method: 'get'
});
};
/**
* 获取校区选项列表
* @returns 校区选项列表
File diff suppressed because it is too large. Load diff
@@ -723,7 +723,7 @@ const data = reactive<PageData<HolidayStayForm, HolidayStayQuery>>({
extField1: undefined,
extField2: undefined,
extField3: undefined,
status: undefined,
status: 'valid', // 默认显示有效状态的记录
params: {}
},
rules: {
@@ -769,7 +769,7 @@ const getList = async () => {
const requestParams = { ...queryParams.value };
// 添加创建人过滤条件 - 班主任只能看到自己创建的数据
requestParams.createBy = userStore.userId;
(requestParams as any).createBy = userStore.userId;
// 根据状态设置时间过滤条件
if (requestParams.status) {
@@ -855,6 +855,44 @@ const handleUpdate = async (row?: HolidayStayVO) => {
const res = await getHolidayStay(_id);
Object.assign(form.value, res.data);
// 确保当前学生信息在选项中(修复学生选择器显示问题)
if (form.value.studentId && form.value.studentName && form.value.studentNo) {
const currentStudent: StudentOptionVO = {
id: form.value.studentId,
name: form.value.studentName,
studentNo: form.value.studentNo,
gender: '0', // 默认值,实际不影响显示
phone: form.value.studentPhone,
collegeId: form.value.collegeId,
collegeName: form.value.collegeName,
majorId: form.value.majorId,
majorName: form.value.majorName,
classId: form.value.classId,
className: form.value.className,
dormInfo: {
campusId: form.value.campusId,
campusName: form.value.campusName,
areaId: form.value.areaId,
areaName: form.value.areaName,
buildingId: form.value.buildingId,
buildingName: form.value.buildingName,
roomId: form.value.roomId,
roomName: form.value.roomName,
bedId: form.value.bedId,
bedName: form.value.bedName
}
};
// 检查是否已经存在,避免重复添加
const existingStudent = studentOptions.value.find((s) => s.id === form.value.studentId);
if (!existingStudent) {
studentOptions.value = [currentStudent];
} else {
// 更新现有学生信息
Object.assign(existingStudent, currentStudent);
}
}
// 根据已有数据级联加载宿舍选项
await loadCascadeOptionsForUpdate(form.value);
@@ -921,7 +959,7 @@ const remoteSearchStudents = async (query: string) => {
const res = await getStudentOptions(params);
// 根据实际接口返回格式调整数据获取方式
console.log('学生搜索响应:', res);
studentOptions.value = res.rows || [];
studentOptions.value = (res as any).rows || [];
// 调试:检查第一个学生的数据
if (studentOptions.value.length > 0) {
@@ -964,7 +1002,7 @@ const loadInitialStudents = async () => {
const res = await getStudentOptions(params);
// 根据实际接口返回格式调整数据获取方式
console.log('初始学生数据响应:', res);
studentOptions.value = res.rows || [];
studentOptions.value = (res as any).rows || [];
// 调试:检查第一个学生的数据
if (studentOptions.value.length > 0) {
@@ -1542,6 +1580,7 @@ const handleAttachmentData = async () => {
// 将逗号分隔的字符串转换为数组
const ossIdsArray = form.value.attachmentOssIds
.toString()
.split(',')
.map((id) => id.trim())
.filter((id) => id);