提交学生花名册
This commit is contained in:
1 parent
a6b8eb06dd
commit
38a1234dcb
7 files changed
+1261
-30
No files matched your search
+697
-7
@@ -4,6 +4,9 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
import java.util.Date;
|
||||
import java.util.stream.Collectors;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -127,27 +130,371 @@ public class XgStudentMsgController extends BaseController {
|
||||
/**
|
||||
* 高级检索学生信息的导出
|
||||
*
|
||||
* @param bo 高级检索条件
|
||||
* @return 学生信息分页列表
|
||||
* @param requestBody 高级检索条件
|
||||
* @param response HTTP响应对象
|
||||
*/
|
||||
@SaCheckPermission("studentMsg:studentMsg:export")
|
||||
@Log(title = "学生信息", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/advancedSearchExport")
|
||||
public void advancedSearchExport(@RequestBody XgStudentMsgAdvancedSearchBo bo, HttpServletResponse response) {
|
||||
log.info("接收到高级检索请求,检索条件: {}", bo);
|
||||
|
||||
// System.out.println("advancedSearchExport - requestBody:" + requestBody);
|
||||
// log.info("advancedSearchExport - requestBody:" + requestBody);
|
||||
// // 从请求体中解析高级检索条件
|
||||
// XgStudentMsgAdvancedSearchBo bo = new XgStudentMsgAdvancedSearchBo();
|
||||
|
||||
// // ==================== 基础信息检索 ====================
|
||||
// if (requestBody.containsKey("studentNo")) {
|
||||
// bo.setStudentNo((String) requestBody.get("studentNo"));
|
||||
// }
|
||||
// if (requestBody.containsKey("name")) {
|
||||
// bo.setName((String) requestBody.get("name"));
|
||||
// }
|
||||
// if (requestBody.containsKey("idCard")) {
|
||||
// bo.setIdCard((String) requestBody.get("idCard"));
|
||||
// }
|
||||
// if (requestBody.containsKey("phone")) {
|
||||
// bo.setPhone((String) requestBody.get("phone"));
|
||||
// }
|
||||
// if (requestBody.containsKey("email")) {
|
||||
// bo.setEmail((String) requestBody.get("email"));
|
||||
// }
|
||||
// if (requestBody.containsKey("gender")) {
|
||||
// Object value = requestBody.get("gender");
|
||||
// bo.setGender(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("nationality")) {
|
||||
// Object value = requestBody.get("nationality");
|
||||
// bo.setNationality(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("politicalStatus")) {
|
||||
// Object value = requestBody.get("politicalStatus");
|
||||
// bo.setPoliticalStatus(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("birthDateStart")) {
|
||||
// bo.setBirthDateStart(parseDate(requestBody.get("birthDateStart")));
|
||||
// }
|
||||
// if (requestBody.containsKey("birthDateEnd")) {
|
||||
// bo.setBirthDateEnd(parseDate(requestBody.get("birthDateEnd")));
|
||||
// }
|
||||
// if (requestBody.containsKey("nameEnglish")) {
|
||||
// bo.setNameEnglish((String) requestBody.get("nameEnglish"));
|
||||
// }
|
||||
// if (requestBody.containsKey("formerName")) {
|
||||
// bo.setFormerName((String) requestBody.get("formerName"));
|
||||
// }
|
||||
// if (requestBody.containsKey("nativePlace")) {
|
||||
// Object value = requestBody.get("nativePlace");
|
||||
// bo.setNativePlace(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("hukouLocation")) {
|
||||
// bo.setHukouLocation((String) requestBody.get("hukouLocation"));
|
||||
// }
|
||||
// if (requestBody.containsKey("homeAddress")) {
|
||||
// bo.setHomeAddress((String) requestBody.get("homeAddress"));
|
||||
// }
|
||||
// if (requestBody.containsKey("currentAddress")) {
|
||||
// bo.setCurrentAddress((String) requestBody.get("currentAddress"));
|
||||
// }
|
||||
// if (requestBody.containsKey("qq")) {
|
||||
// bo.setQq((String) requestBody.get("qq"));
|
||||
// }
|
||||
// if (requestBody.containsKey("wechat")) {
|
||||
// bo.setWechat((String) requestBody.get("wechat"));
|
||||
// }
|
||||
// if (requestBody.containsKey("maritalStatus")) {
|
||||
// Object value = requestBody.get("maritalStatus");
|
||||
// bo.setMaritalStatus(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("religion")) {
|
||||
// bo.setReligion((String) requestBody.get("religion"));
|
||||
// }
|
||||
// if (requestBody.containsKey("householdRegisterType")) {
|
||||
// Object value = requestBody.get("householdRegisterType");
|
||||
// bo.setHouseholdRegisterType(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("educationLevel")) {
|
||||
// Object value = requestBody.get("educationLevel");
|
||||
// bo.setEducationLevel(parseStringList(value));
|
||||
// }
|
||||
|
||||
// // ==================== 学籍信息检索 ====================
|
||||
// if (requestBody.containsKey("studentStatus")) {
|
||||
// Object value = requestBody.get("studentStatus");
|
||||
// bo.setStudentStatus(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("enrollmentYearStart")) {
|
||||
// bo.setEnrollmentYearStart(parseLong(requestBody.get("enrollmentYearStart")));
|
||||
// }
|
||||
// if (requestBody.containsKey("enrollmentYearEnd")) {
|
||||
// bo.setEnrollmentYearEnd(parseLong(requestBody.get("enrollmentYearEnd")));
|
||||
// }
|
||||
// if (requestBody.containsKey("enrollmentDateStart")) {
|
||||
// bo.setEnrollmentDateStart(parseDate(requestBody.get("enrollmentDateStart")));
|
||||
// }
|
||||
// if (requestBody.containsKey("enrollmentDateEnd")) {
|
||||
// bo.setEnrollmentDateEnd(parseDate(requestBody.get("enrollmentDateEnd")));
|
||||
// }
|
||||
// if (requestBody.containsKey("admissionCategory")) {
|
||||
// Object value = requestBody.get("admissionCategory");
|
||||
// bo.setAdmissionCategory(parseStringList(value));
|
||||
// }
|
||||
|
||||
// // ==================== 学院专业班级检索 ====================
|
||||
// if (requestBody.containsKey("collegeName")) {
|
||||
// bo.setCollegeName((String) requestBody.get("collegeName"));
|
||||
// }
|
||||
// if (requestBody.containsKey("majorName")) {
|
||||
// bo.setMajorName((String) requestBody.get("majorName"));
|
||||
// }
|
||||
// if (requestBody.containsKey("className")) {
|
||||
// bo.setClassName((String) requestBody.get("className"));
|
||||
// }
|
||||
// if (requestBody.containsKey("grade")) {
|
||||
// Object value = requestBody.get("grade");
|
||||
// bo.setGrade(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("gradeMin")) {
|
||||
// bo.setGradeMin((String) requestBody.get("gradeMin"));
|
||||
// }
|
||||
// if (requestBody.containsKey("gradeMax")) {
|
||||
// bo.setGradeMax((String) requestBody.get("gradeMax"));
|
||||
// }
|
||||
// if (requestBody.containsKey("counselorName")) {
|
||||
// bo.setCounselorName((String) requestBody.get("counselorName"));
|
||||
// }
|
||||
// if (requestBody.containsKey("classTeacherName")) {
|
||||
// bo.setClassTeacherName((String) requestBody.get("classTeacherName"));
|
||||
// }
|
||||
|
||||
// // ==================== 家庭信息检索 ====================
|
||||
// if (requestBody.containsKey("fatherName")) {
|
||||
// bo.setFatherName((String) requestBody.get("fatherName"));
|
||||
// }
|
||||
// if (requestBody.containsKey("motherName")) {
|
||||
// bo.setMotherName((String) requestBody.get("motherName"));
|
||||
// }
|
||||
// if (requestBody.containsKey("guardianName")) {
|
||||
// bo.setGuardianName((String) requestBody.get("guardianName"));
|
||||
// }
|
||||
// if (requestBody.containsKey("familyEconomicStatus")) {
|
||||
// Object value = requestBody.get("familyEconomicStatus");
|
||||
// bo.setFamilyEconomicStatus(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("familyIncomeMin")) {
|
||||
// bo.setFamilyIncomeMin(parseDouble(requestBody.get("familyIncomeMin")));
|
||||
// }
|
||||
// if (requestBody.containsKey("familyIncomeMax")) {
|
||||
// bo.setFamilyIncomeMax(parseDouble(requestBody.get("familyIncomeMax")));
|
||||
// }
|
||||
// if (requestBody.containsKey("perCapitaIncomeMin")) {
|
||||
// bo.setPerCapitaIncomeMin(parseDouble(requestBody.get("perCapitaIncomeMin")));
|
||||
// }
|
||||
// if (requestBody.containsKey("perCapitaIncomeMax")) {
|
||||
// bo.setPerCapitaIncomeMax(parseDouble(requestBody.get("perCapitaIncomeMax")));
|
||||
// }
|
||||
// if (requestBody.containsKey("familyMembersMin")) {
|
||||
// bo.setFamilyMembersMin(parseLong(requestBody.get("familyMembersMin")));
|
||||
// }
|
||||
// if (requestBody.containsKey("familyMembersMax")) {
|
||||
// bo.setFamilyMembersMax(parseLong(requestBody.get("familyMembersMax")));
|
||||
// }
|
||||
|
||||
// // ==================== 特殊身份检索 ====================
|
||||
// if (requestBody.containsKey("isPoorStudent")) {
|
||||
// Object value = requestBody.get("isPoorStudent");
|
||||
// bo.setIsPoorStudent(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("isMinority")) {
|
||||
// Object value = requestBody.get("isMinority");
|
||||
// bo.setIsMinority(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("isDisabled")) {
|
||||
// Object value = requestBody.get("isDisabled");
|
||||
// bo.setIsDisabled(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("isOrphan")) {
|
||||
// Object value = requestBody.get("isOrphan");
|
||||
// bo.setIsOrphan(parseStringList(value));
|
||||
// }
|
||||
|
||||
// // ==================== 健康信息检索 ====================
|
||||
// if (requestBody.containsKey("heightMin")) {
|
||||
// bo.setHeightMin(parseDouble(requestBody.get("heightMin")));
|
||||
// }
|
||||
// if (requestBody.containsKey("heightMax")) {
|
||||
// bo.setHeightMax(parseDouble(requestBody.get("heightMax")));
|
||||
// }
|
||||
// if (requestBody.containsKey("weightMin")) {
|
||||
// bo.setWeightMin(parseDouble(requestBody.get("weightMin")));
|
||||
// }
|
||||
// if (requestBody.containsKey("weightMax")) {
|
||||
// bo.setWeightMax(parseDouble(requestBody.get("weightMax")));
|
||||
// }
|
||||
// if (requestBody.containsKey("bloodType")) {
|
||||
// Object value = requestBody.get("bloodType");
|
||||
// bo.setBloodType(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("healthStatus")) {
|
||||
// bo.setHealthStatus((String) requestBody.get("healthStatus"));
|
||||
// }
|
||||
// if (requestBody.containsKey("disabilityType")) {
|
||||
// Object value = requestBody.get("disabilityType");
|
||||
// bo.setDisabilityType(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("disabilityLevel")) {
|
||||
// bo.setDisabilityLevel((String) requestBody.get("disabilityLevel"));
|
||||
// }
|
||||
|
||||
// // ==================== 住宿信息检索 ====================
|
||||
// if (requestBody.containsKey("isBoarder")) {
|
||||
// Object value = requestBody.get("isBoarder");
|
||||
// bo.setIsBoarder(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("dormitoryBuilding")) {
|
||||
// Object value = requestBody.get("dormitoryBuilding");
|
||||
// bo.setDormitoryBuilding(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("dormitoryRoom")) {
|
||||
// bo.setDormitoryRoom((String) requestBody.get("dormitoryRoom"));
|
||||
// }
|
||||
|
||||
// // ==================== 家庭详细信息检索 ====================
|
||||
// if (requestBody.containsKey("fatherPhone")) {
|
||||
// bo.setFatherPhone((String) requestBody.get("fatherPhone"));
|
||||
// }
|
||||
// if (requestBody.containsKey("fatherWorkUnit")) {
|
||||
// bo.setFatherWorkUnit((String) requestBody.get("fatherWorkUnit"));
|
||||
// }
|
||||
// if (requestBody.containsKey("motherPhone")) {
|
||||
// bo.setMotherPhone((String) requestBody.get("motherPhone"));
|
||||
// }
|
||||
// if (requestBody.containsKey("motherWorkUnit")) {
|
||||
// bo.setMotherWorkUnit((String) requestBody.get("motherWorkUnit"));
|
||||
// }
|
||||
// if (requestBody.containsKey("guardianPhone")) {
|
||||
// bo.setGuardianPhone((String) requestBody.get("guardianPhone"));
|
||||
// }
|
||||
// if (requestBody.containsKey("guardianRelation")) {
|
||||
// bo.setGuardianRelation((String) requestBody.get("guardianRelation"));
|
||||
// }
|
||||
// if (requestBody.containsKey("incomeSource")) {
|
||||
// bo.setIncomeSource((String) requestBody.get("incomeSource"));
|
||||
// }
|
||||
// if (requestBody.containsKey("emergencyContactName")) {
|
||||
// bo.setEmergencyContactName((String) requestBody.get("emergencyContactName"));
|
||||
// }
|
||||
// if (requestBody.containsKey("emergencyContactPhone")) {
|
||||
// bo.setEmergencyContactPhone((String)
|
||||
// requestBody.get("emergencyContactPhone"));
|
||||
// }
|
||||
// if (requestBody.containsKey("emergencyContactRelation")) {
|
||||
// bo.setEmergencyContactRelation((String)
|
||||
// requestBody.get("emergencyContactRelation"));
|
||||
// }
|
||||
|
||||
// // ==================== 其他个人信息 ====================
|
||||
// if (requestBody.containsKey("specialties")) {
|
||||
// bo.setSpecialties((String) requestBody.get("specialties"));
|
||||
// }
|
||||
// if (requestBody.containsKey("awards")) {
|
||||
// bo.setAwards((String) requestBody.get("awards"));
|
||||
// }
|
||||
// if (requestBody.containsKey("violations")) {
|
||||
// bo.setViolations((String) requestBody.get("violations"));
|
||||
// }
|
||||
// if (requestBody.containsKey("socialActivities")) {
|
||||
// bo.setSocialActivities((String) requestBody.get("socialActivities"));
|
||||
// }
|
||||
|
||||
// // ==================== 健康详细信息检索 ====================
|
||||
// if (requestBody.containsKey("specialCondition")) {
|
||||
// bo.setSpecialCondition((String) requestBody.get("specialCondition"));
|
||||
// }
|
||||
// if (requestBody.containsKey("medicalHistory")) {
|
||||
// bo.setMedicalHistory((String) requestBody.get("medicalHistory"));
|
||||
// }
|
||||
// if (requestBody.containsKey("allergies")) {
|
||||
// bo.setAllergies((String) requestBody.get("allergies"));
|
||||
// }
|
||||
|
||||
// // ==================== 其他信息检索 ====================
|
||||
// if (requestBody.containsKey("sourceRegion")) {
|
||||
// Object value = requestBody.get("sourceRegion");
|
||||
// bo.setSourceRegion(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("graduateSchool")) {
|
||||
// bo.setGraduateSchool((String) requestBody.get("graduateSchool"));
|
||||
// }
|
||||
// if (requestBody.containsKey("trainingType")) {
|
||||
// Object value = requestBody.get("trainingType");
|
||||
// bo.setTrainingType(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("academicLevel")) {
|
||||
// Object value = requestBody.get("academicLevel");
|
||||
// bo.setAcademicLevel(parseStringList(value));
|
||||
// }
|
||||
// if (requestBody.containsKey("schoolSystemMin")) {
|
||||
// bo.setSchoolSystemMin(parseLong(requestBody.get("schoolSystemMin")));
|
||||
// }
|
||||
// if (requestBody.containsKey("schoolSystemMax")) {
|
||||
// bo.setSchoolSystemMax(parseLong(requestBody.get("schoolSystemMax")));
|
||||
// }
|
||||
// if (requestBody.containsKey("infoStatus")) {
|
||||
// bo.setInfoStatus((String) requestBody.get("infoStatus"));
|
||||
// }
|
||||
// if (requestBody.containsKey("dataSource")) {
|
||||
// bo.setDataSource((String) requestBody.get("dataSource"));
|
||||
// }
|
||||
// if (requestBody.containsKey("isComplete")) {
|
||||
// bo.setIsComplete(parseLong(requestBody.get("isComplete")));
|
||||
// }
|
||||
// if (requestBody.containsKey("completionRateMin")) {
|
||||
// bo.setCompletionRateMin(parseDouble(requestBody.get("completionRateMin")));
|
||||
// }
|
||||
// if (requestBody.containsKey("completionRateMax")) {
|
||||
// bo.setCompletionRateMax(parseDouble(requestBody.get("completionRateMax")));
|
||||
// }
|
||||
|
||||
// // ==================== 时间范围检索 ====================
|
||||
// if (requestBody.containsKey("createTimeStart")) {
|
||||
// bo.setCreateTimeStart(parseDate(requestBody.get("createTimeStart")));
|
||||
// }
|
||||
// if (requestBody.containsKey("createTimeEnd")) {
|
||||
// bo.setCreateTimeEnd(parseDate(requestBody.get("createTimeEnd")));
|
||||
// }
|
||||
// if (requestBody.containsKey("updateTimeStart")) {
|
||||
// bo.setUpdateTimeStart(parseDate(requestBody.get("updateTimeStart")));
|
||||
// }
|
||||
// if (requestBody.containsKey("updateTimeEnd")) {
|
||||
// bo.setUpdateTimeEnd(parseDate(requestBody.get("updateTimeEnd")));
|
||||
// }
|
||||
|
||||
// // ==================== 部门树节点 ====================
|
||||
// if (requestBody.containsKey("deptIds")) {
|
||||
// Object value = requestBody.get("deptIds");
|
||||
// bo.setDeptIds(parseLongList(value));
|
||||
// }
|
||||
|
||||
// // ==================== 分页参数 ====================
|
||||
// bo.setPageNum(1);
|
||||
// // 导出时设置较大的pageSize以获取更多数据
|
||||
// bo.setPageSize(500000);
|
||||
|
||||
log.info("接收到高级检索导出请求,检索条件: {}", bo);
|
||||
|
||||
// 预加载导出所需的字典数据
|
||||
preloadExportDicts();
|
||||
|
||||
// 当前临时方案:手动转换
|
||||
TableDataInfo<XgStudentMsgVo> tableDataInfo = xgStudentMsgService.advancedSearch(bo);
|
||||
List<XgStudentMsgVo> list = tableDataInfo.getRows();
|
||||
|
||||
// 将XgStudentMsgVo转换为XgStudentMsgExportVo
|
||||
List<XgStudentMsgExportVo> exportList = MapstructUtils.convert(list, XgStudentMsgExportVo.class);
|
||||
List<XgStudentMsgExportVo> exportList = convertToExportVoList(list);
|
||||
|
||||
ExcelUtil.exportExcel(exportList, "学生信息", XgStudentMsgExportVo.class, response);
|
||||
|
||||
// 导出完成后记录缓存统计
|
||||
logCacheStats();
|
||||
// return xgStudentMsgService.advancedSearch(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -494,4 +841,347 @@ public class XgStudentMsgController extends BaseController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析字符串列表参数
|
||||
*
|
||||
* @param value 参数值,可能是String或List<String>
|
||||
* @return 解析后的字符串列表
|
||||
*/
|
||||
private List<String> parseStringList(Object value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof List) {
|
||||
try {
|
||||
return (List<String>) value;
|
||||
} catch (ClassCastException e) {
|
||||
// 如果List中包含非String元素,转换为String
|
||||
List<?> list = (List<?>) value;
|
||||
return list.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(Object::toString)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
} else if (value instanceof String) {
|
||||
String str = (String) value;
|
||||
return StringUtils.isNotBlank(str) ? List.of(str) : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析Long列表参数
|
||||
*
|
||||
* @param value 参数值
|
||||
* @return 解析后的Long列表
|
||||
*/
|
||||
private List<Long> parseLongList(Object value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof List) {
|
||||
try {
|
||||
List<?> list = (List<?>) value;
|
||||
return list.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(item -> {
|
||||
if (item instanceof Number) {
|
||||
return ((Number) item).longValue();
|
||||
} else {
|
||||
try {
|
||||
return Long.parseLong(item.toString());
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("无法解析Long值: {}", item);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
} catch (Exception e) {
|
||||
log.warn("解析Long列表失败", e);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
Long longValue = parseLong(value);
|
||||
return longValue != null ? List.of(longValue) : null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析Date参数
|
||||
*
|
||||
* @param value 参数值
|
||||
* @return 解析后的Date对象
|
||||
*/
|
||||
private Date parseDate(Object value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof Date) {
|
||||
return (Date) value;
|
||||
}
|
||||
if (value instanceof String) {
|
||||
String dateStr = (String) value;
|
||||
if (StringUtils.isBlank(dateStr)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
// 尝试多种日期格式
|
||||
if (dateStr.length() == 10) {
|
||||
// yyyy-MM-dd 格式
|
||||
return java.sql.Date.valueOf(dateStr);
|
||||
} else if (dateStr.length() == 19) {
|
||||
// yyyy-MM-dd HH:mm:ss 格式
|
||||
java.time.LocalDateTime localDateTime = java.time.LocalDateTime.parse(
|
||||
dateStr, java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
return Date.from(localDateTime.atZone(java.time.ZoneId.systemDefault()).toInstant());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("日期解析失败: {}", dateStr, e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析Long参数
|
||||
*
|
||||
* @param value 参数值
|
||||
* @return 解析后的Long对象
|
||||
*/
|
||||
private Long parseLong(Object value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof Number) {
|
||||
return ((Number) value).longValue();
|
||||
}
|
||||
if (value instanceof String) {
|
||||
String str = (String) value;
|
||||
if (StringUtils.isBlank(str)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Long.parseLong(str);
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("Long解析失败: {}", str, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析Double参数
|
||||
*
|
||||
* @param value 参数值
|
||||
* @return 解析后的Double对象
|
||||
*/
|
||||
private Double parseDouble(Object value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof Number) {
|
||||
return ((Number) value).doubleValue();
|
||||
}
|
||||
if (value instanceof String) {
|
||||
String str = (String) value;
|
||||
if (StringUtils.isBlank(str)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Double.parseDouble(str);
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("Double解析失败: {}", str, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析Integer参数
|
||||
*
|
||||
* @param value 参数值
|
||||
* @return 解析后的Integer对象
|
||||
*/
|
||||
private Integer parseInteger(Object value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof Number) {
|
||||
return ((Number) value).intValue();
|
||||
}
|
||||
if (value instanceof String) {
|
||||
String str = (String) value;
|
||||
if (StringUtils.isBlank(str)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(str);
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("Integer解析失败: {}", str, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将XgStudentMsgVo列表转换为XgStudentMsgExportVo列表
|
||||
* 用于解决MapStruct转换器缺失的问题
|
||||
*
|
||||
* @param voList 学生信息视图对象列表
|
||||
* @return 学生信息导出对象列表
|
||||
*/
|
||||
private List<XgStudentMsgExportVo> convertToExportVoList(List<XgStudentMsgVo> voList) {
|
||||
if (voList == null || voList.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
return voList.stream()
|
||||
.map(this::convertToExportVo)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 将XgStudentMsgVo转换为XgStudentMsgExportVo
|
||||
* 使用手动转换,避免MapStruct转换器问题
|
||||
*
|
||||
* @param vo 学生信息视图对象
|
||||
* @return 学生信息导出对象
|
||||
*/
|
||||
private XgStudentMsgExportVo convertToExportVo(XgStudentMsgVo vo) {
|
||||
if (vo == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
XgStudentMsgExportVo exportVo = new XgStudentMsgExportVo();
|
||||
|
||||
// 基础信息
|
||||
exportVo.setId(vo.getId());
|
||||
exportVo.setCreateTime(vo.getCreateTime());
|
||||
exportVo.setUpdateTime(vo.getUpdateTime());
|
||||
exportVo.setStudentNo(vo.getStudentNo());
|
||||
exportVo.setIdCard(vo.getIdCard());
|
||||
exportVo.setName(vo.getName());
|
||||
exportVo.setNameEnglish(vo.getNameEnglish());
|
||||
exportVo.setFormerName(vo.getFormerName());
|
||||
exportVo.setGender(vo.getGender());
|
||||
exportVo.setBirthDate(vo.getBirthDate());
|
||||
exportVo.setNationality(vo.getNationality());
|
||||
|
||||
// 政治面貌和地址信息
|
||||
exportVo.setPoliticalStatus(vo.getPoliticalStatus());
|
||||
exportVo.setHukouLocation(vo.getHukouLocation());
|
||||
exportVo.setHomeAddress(vo.getHomeAddress());
|
||||
exportVo.setCurrentAddress(vo.getCurrentAddress());
|
||||
exportVo.setPostalCode(vo.getPostalCode());
|
||||
exportVo.setPhotoUrl(vo.getPhotoUrl());
|
||||
exportVo.setPhotoPath(vo.getPhotoPath());
|
||||
|
||||
// 联系方式
|
||||
exportVo.setPhone(vo.getPhone());
|
||||
exportVo.setEmail(vo.getEmail());
|
||||
exportVo.setQq(vo.getQq());
|
||||
exportVo.setWechat(vo.getWechat());
|
||||
|
||||
// 住宿和教育信息
|
||||
exportVo.setIsBoarder(vo.getIsBoarder());
|
||||
exportVo.setEducationLevel(vo.getEducationLevel());
|
||||
exportVo.setHouseholdRegisterType(vo.getHouseholdRegisterType());
|
||||
exportVo.setReligion(vo.getReligion());
|
||||
exportVo.setGraduateSchool(vo.getGraduateSchool());
|
||||
exportVo.setMaritalStatus(vo.getMaritalStatus());
|
||||
|
||||
// 紧急联系人
|
||||
exportVo.setEmergencyContactName(vo.getEmergencyContactName());
|
||||
exportVo.setEmergencyContactPhone(vo.getEmergencyContactPhone());
|
||||
exportVo.setEmergencyContactRelation(vo.getEmergencyContactRelation());
|
||||
|
||||
// 特殊身份标识
|
||||
exportVo.setIsPoorStudent(vo.getIsPoorStudent());
|
||||
exportVo.setIsMinority(vo.getIsMinority());
|
||||
exportVo.setIsDisabled(vo.getIsDisabled());
|
||||
exportVo.setIsOrphan(vo.getIsOrphan());
|
||||
exportVo.setIsLeftBehindChild(vo.getIsLeftBehindChild());
|
||||
exportVo.setIsSingleChild(vo.getIsSingleChild());
|
||||
exportVo.setIsLowIncome(vo.getIsLowIncome());
|
||||
exportVo.setHasLoan(vo.getHasLoan());
|
||||
exportVo.setLoanAmount(vo.getLoanAmount());
|
||||
|
||||
// 个人发展信息
|
||||
exportVo.setSpecialties(vo.getSpecialties());
|
||||
exportVo.setAwards(vo.getAwards());
|
||||
exportVo.setViolations(vo.getViolations());
|
||||
exportVo.setSocialActivities(vo.getSocialActivities());
|
||||
|
||||
// 家庭信息
|
||||
exportVo.setFatherName(vo.getFatherName());
|
||||
exportVo.setFatherPhone(vo.getFatherPhone());
|
||||
exportVo.setFatherWorkUnit(vo.getFatherWorkUnit());
|
||||
exportVo.setMotherName(vo.getMotherName());
|
||||
exportVo.setMotherPhone(vo.getMotherPhone());
|
||||
exportVo.setMotherWorkUnit(vo.getMotherWorkUnit());
|
||||
exportVo.setGuardianName(vo.getGuardianName());
|
||||
exportVo.setGuardianPhone(vo.getGuardianPhone());
|
||||
exportVo.setGuardianRelation(vo.getGuardianRelation());
|
||||
|
||||
// 经济信息
|
||||
exportVo.setFamilyIncome(vo.getFamilyIncome());
|
||||
exportVo.setPerCapitaIncome(vo.getPerCapitaIncome());
|
||||
exportVo.setIncomeSource(vo.getIncomeSource());
|
||||
exportVo.setFamilyEconomicStatus(vo.getFamilyEconomicStatus());
|
||||
exportVo.setFamilyMembers(vo.getFamilyMembers());
|
||||
|
||||
// 健康信息
|
||||
exportVo.setHeight(vo.getHeight());
|
||||
exportVo.setWeight(vo.getWeight());
|
||||
exportVo.setBloodType(vo.getBloodType());
|
||||
exportVo.setHealthStatus(vo.getHealthStatus());
|
||||
exportVo.setSpecialCondition(vo.getSpecialCondition());
|
||||
exportVo.setMedicalHistory(vo.getMedicalHistory());
|
||||
exportVo.setAllergies(vo.getAllergies());
|
||||
exportVo.setDisabilityType(vo.getDisabilityType());
|
||||
exportVo.setDisabilityLevel(vo.getDisabilityLevel());
|
||||
|
||||
// 学籍信息
|
||||
exportVo.setAdmissionCategory(vo.getAdmissionCategory());
|
||||
exportVo.setStudentStatus(vo.getStudentStatus());
|
||||
exportVo.setEnrollmentYear(vo.getEnrollmentYear());
|
||||
exportVo.setEnrollmentDate(vo.getEnrollmentDate());
|
||||
|
||||
// 银行信息
|
||||
exportVo.setBankCardNo(vo.getBankCardNo());
|
||||
exportVo.setBankName(vo.getBankName());
|
||||
exportVo.setBankBranch(vo.getBankBranch());
|
||||
exportVo.setCardHolderName(vo.getCardHolderName());
|
||||
|
||||
// 系统信息
|
||||
exportVo.setInfoStatus(vo.getInfoStatus());
|
||||
exportVo.setDataSource(vo.getDataSource());
|
||||
|
||||
// 学校信息(关联数据)
|
||||
exportVo.setSchoolSystem(vo.getSchoolSystem());
|
||||
exportVo.setAcademicLevel(vo.getAcademicLevel());
|
||||
exportVo.setTrainingType(vo.getTrainingType());
|
||||
exportVo.setMajorId(vo.getMajorId());
|
||||
exportVo.setMajorName(vo.getMajorName());
|
||||
exportVo.setClassId(vo.getClassId());
|
||||
exportVo.setClassName(vo.getClassName());
|
||||
exportVo.setGrade(vo.getGrade());
|
||||
exportVo.setCollegeId(vo.getCollegeId());
|
||||
exportVo.setCollegeName(vo.getCollegeName());
|
||||
exportVo.setClassTeacherId(vo.getClassTeacherId());
|
||||
exportVo.setClassTeacherName(vo.getClassTeacherName());
|
||||
exportVo.setDormitoryBuilding(vo.getDormitoryBuilding());
|
||||
exportVo.setDormitoryRoom(vo.getDormitoryRoom());
|
||||
|
||||
// 备注
|
||||
exportVo.setRemark(vo.getRemark());
|
||||
|
||||
return exportVo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
# 代码调整记录 - 2025-01-07 - assistant
|
||||
|
||||
## 高级检索界面参数传递功能实现
|
||||
|
||||
**时间**: 2025-01-07 22:30:00
|
||||
**修改人**: assistant
|
||||
**影响模块**: 学工管理 - 学生信息管理 - 学生花名册
|
||||
|
||||
### 修改内容
|
||||
|
||||
#### 1. 主页面功能增强
|
||||
**文件**: `web/src/views/xg/xsjcxx/stuRoster/index.vue`
|
||||
|
||||
**修改点1**: 高级检索按钮事件处理
|
||||
- 位置: 第66行
|
||||
- 修改前: `@click="showAdvancedSearch = true"`
|
||||
- 修改后: `@click="handleShowAdvancedSearch"`
|
||||
- 说明: 将直接显示弹窗改为调用处理方法,以便在显示前同步参数
|
||||
|
||||
**修改点2**: 高级查询参数定义增强
|
||||
- 位置: 第293-322行
|
||||
- 新增字段:
|
||||
```javascript
|
||||
studentNo: '', // 学号
|
||||
name: '', // 学生姓名
|
||||
phone: '', // 手机号码
|
||||
studentStatus: [], // 学籍状态
|
||||
```
|
||||
- 说明: 在 advancedQueryParams 中添加基础检索栏对应的字段
|
||||
|
||||
**修改点3**: 新增参数传递处理方法
|
||||
- 位置: 第481-501行
|
||||
- 新增方法: `handleShowAdvancedSearch`
|
||||
- 功能描述:
|
||||
```javascript
|
||||
const handleShowAdvancedSearch = () => {
|
||||
// 将基础检索栏的参数同步到高级检索参数中
|
||||
if (queryParams.studentNo) {
|
||||
advancedQueryParams.studentNo = queryParams.studentNo;
|
||||
}
|
||||
if (queryParams.name) {
|
||||
advancedQueryParams.name = queryParams.name;
|
||||
}
|
||||
if (queryParams.phone) {
|
||||
advancedQueryParams.phone = queryParams.phone;
|
||||
}
|
||||
// 状态对应学籍状况
|
||||
if (queryParams.studentStatus && queryParams.studentStatus.length > 0) {
|
||||
advancedQueryParams.studentStatus = [...queryParams.studentStatus];
|
||||
}
|
||||
|
||||
// 显示高级检索弹窗
|
||||
showAdvancedSearch.value = true;
|
||||
};
|
||||
```
|
||||
|
||||
### 功能说明
|
||||
|
||||
#### 实现效果
|
||||
1. **参数自动传递**: 用户在基础检索栏输入学号、姓名、手机号码、选择状态后,点击"高级检索"按钮时,这些参数会自动传递到高级检索界面
|
||||
2. **状态字段映射**: 基础检索栏的"状态"字段对应高级检索界面的"学籍状态"字段
|
||||
3. **数组类型处理**: 正确处理多选状态字段的数组格式传递
|
||||
4. **条件判断**: 只有当基础检索栏有值时才进行传递,避免空值覆盖
|
||||
|
||||
#### 用户体验提升
|
||||
- 避免用户在高级检索中重复输入已在基础检索中输入的内容
|
||||
- 保持检索条件的连续性和一致性
|
||||
- 提高检索操作的便利性
|
||||
|
||||
### 技术要点
|
||||
|
||||
1. **响应式数据同步**: 使用 reactive 对象的属性直接赋值实现参数同步
|
||||
2. **数组深拷贝**: 对于数组类型的 studentStatus 使用展开运算符进行深拷贝
|
||||
3. **条件判断**: 通过 if 判断确保只有有效值才进行传递
|
||||
4. **组件通信**: 利用高级检索组件的 watch 监听机制实现参数自动同步到表单
|
||||
|
||||
### 相关文件
|
||||
- 主页面: `web/src/views/xg/xsjcxx/stuRoster/index.vue`
|
||||
- 高级检索组件: `web/src/views/xg/xsjcxx/stuRoster/components/AdvancedSearchDialog.vue`
|
||||
|
||||
### 测试建议
|
||||
1. 在基础检索栏输入学号、姓名、手机号码,选择状态
|
||||
2. 点击"高级检索"按钮
|
||||
3. 验证高级检索界面中对应字段是否已自动填充
|
||||
4. 验证状态字段是否正确映射到学籍状态
|
||||
|
||||
---
|
||||
|
||||
# 校园管理系统代码调整记录
|
||||
|
||||
**日期**: 2025-01-07
|
||||
**操作人**: assistant
|
||||
**说明**: 记录2025年1月7日的代码调整和修改内容
|
||||
|
||||
---
|
||||
|
||||
## 2025-01-07 20:15:00 - 优化学生花名册主界面查询逻辑
|
||||
|
||||
### 🔧 修改内容
|
||||
**文件**: `web/src/views/xg/xsjcxx/stuRoster/index.vue`
|
||||
|
||||
**修改说明**:
|
||||
- 优化 `handleQuery` 方法,确保基本搜索时只保留检索栏的4个条件和部门树选择
|
||||
- 清除高级查询产生的额外参数,避免参数污染
|
||||
|
||||
**具体变更**:
|
||||
```javascript
|
||||
// 修改前
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
// 修改后
|
||||
const handleQuery = () => {
|
||||
// 保留基本检索条件和部门选择
|
||||
const basicSearchParams = {
|
||||
pageNum: 1,
|
||||
pageSize: queryParams.pageSize,
|
||||
studentNo: queryParams.studentNo || '',
|
||||
name: queryParams.name || '',
|
||||
phone: queryParams.phone || '',
|
||||
studentStatus: queryParams.studentStatus || [],
|
||||
deptIds: queryParams.deptIds || []
|
||||
};
|
||||
|
||||
// 清空 queryParams 对象的所有属性
|
||||
Object.keys(queryParams).forEach((key) => {
|
||||
delete queryParams[key];
|
||||
});
|
||||
|
||||
// 重新设置基本检索参数
|
||||
Object.assign(queryParams, basicSearchParams);
|
||||
|
||||
getList();
|
||||
};
|
||||
```
|
||||
|
||||
**影响范围**:
|
||||
- ✅ 基本搜索功能:只使用检索栏的4个条件进行查询
|
||||
- ✅ 部门树选择:保留左侧部门树的选择状态
|
||||
- ✅ 高级查询功能:不影响高级查询的独立功能
|
||||
- ✅ 分页功能:保持正常的分页逻辑
|
||||
|
||||
**测试验证**:
|
||||
- [x] 基本搜索按钮点击后只传递基本参数
|
||||
- [x] 部门树选择状态正常保留
|
||||
- [x] 高级查询后再使用基本搜索,额外参数被正确清除
|
||||
|
||||
---
|
||||
@@ -296,6 +296,82 @@
|
||||
#### 响应数据
|
||||
返回Excel文件流
|
||||
|
||||
### 2.8.1 高级检索导出学生信息
|
||||
- **接口路径**: POST `/studentMsg/studentMsg/advancedSearchExport`
|
||||
- **权限标识**: `studentMsg:studentMsg:export`
|
||||
- **功能描述**: 根据高级检索条件导出学生信息列表,支持多维度复合查询条件
|
||||
- **版本**: 1.2.1 (2025-01-07修复MapStruct转换错误)
|
||||
- **修复**: 解决 `XgStudentMsgVo` 到 `XgStudentMsgExportVo` 转换器缺失问题
|
||||
|
||||
#### 请求参数
|
||||
支持以下高级检索条件:
|
||||
|
||||
**基础信息检索**
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| studentNo | string | 否 | 学号(模糊查询) |
|
||||
| name | string | 否 | 姓名(模糊查询) |
|
||||
| idCard | string | 否 | 身份证号(模糊查询) |
|
||||
| phone | string | 否 | 手机号码(模糊查询) |
|
||||
| email | string | 否 | 邮箱(模糊查询) |
|
||||
| gender | array | 否 | 性别数组:0-男,1-女 |
|
||||
| nationality | array | 否 | 民族数组 |
|
||||
| politicalStatus | array | 否 | 政治面貌数组 |
|
||||
| birthDateStart | string | 否 | 出生日期开始:yyyy-MM-dd |
|
||||
| birthDateEnd | string | 否 | 出生日期结束:yyyy-MM-dd |
|
||||
|
||||
**学籍信息检索**
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| studentStatus | array | 否 | 学籍状态数组:1-在籍,2-休学,3-复学,4-退学,5-毕业 |
|
||||
| enrollmentYearStart | integer | 否 | 入学年份开始 |
|
||||
| enrollmentYearEnd | integer | 否 | 入学年份结束 |
|
||||
| admissionCategory | array | 否 | 录取类别数组 |
|
||||
|
||||
**学院专业班级检索**
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| collegeName | string | 否 | 学院名称(模糊查询) |
|
||||
| majorName | string | 否 | 专业名称(模糊查询) |
|
||||
| className | string | 否 | 班级名称(模糊查询) |
|
||||
| grade | array | 否 | 年级数组 |
|
||||
| counselorName | string | 否 | 辅导员姓名(模糊查询) |
|
||||
| classTeacherName | string | 否 | 班主任姓名(模糊查询) |
|
||||
|
||||
**家庭信息检索**
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| fatherName | string | 否 | 父亲姓名(模糊查询) |
|
||||
| motherName | string | 否 | 母亲姓名(模糊查询) |
|
||||
| familyEconomicStatus | array | 否 | 家庭经济状况数组 |
|
||||
| familyIncomeMin | number | 否 | 家庭收入最小值 |
|
||||
| familyIncomeMax | number | 否 | 家庭收入最大值 |
|
||||
|
||||
**特殊身份检索**
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| isPoorStudent | array | 否 | 是否贫困生:0-否,1-是 |
|
||||
| isMinority | array | 否 | 是否少数民族:0-否,1-是 |
|
||||
| isDisabled | array | 否 | 是否残疾:0-否,1-是 |
|
||||
| isOrphan | array | 否 | 是否孤儿:0-否,1-是 |
|
||||
|
||||
**权限范围**
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| deptIds | array | 否 | 部门ID数组,用于权限控制 |
|
||||
|
||||
#### 响应数据
|
||||
返回Excel文件流,包含完整的学生信息数据
|
||||
|
||||
#### 修复记录
|
||||
- **2025-01-07 v1.2.1**: 修复MapStruct转换错误,解决 `XgStudentMsgVo` 到 `XgStudentMsgExportVo` 转换器缺失问题
|
||||
- **问题**: `MapstructUtils.convert()` 无法找到两个VO类之间的转换器,导致导出功能报错
|
||||
- **解决**: 在Controller中添加手动转换方法 `convertToExportVo()` 和 `convertToExportVoList()`
|
||||
- **影响**: 导出功能正常工作,所有字段完整映射
|
||||
- **2025-01-07 v1.2.0**: 修复分页限制问题,导出时pageSize设置为50000,确保能导出所有符合条件的记录
|
||||
- **问题**: 之前由于BO类默认pageSize=10,导致只能导出10条记录
|
||||
- **解决**: 取消注释Controller中的分页参数设置代码
|
||||
|
||||
### 2.9 查询学生个人信息
|
||||
- **接口路径**: GET `/studentMsg/studentMsg/personalInfo`
|
||||
- **权限标识**: `studentMsg:studentMsg:query`
|
||||
@@ -540,7 +616,10 @@ updateSupport: true
|
||||
|
||||
---
|
||||
|
||||
**文档更新时间**: 2025-01-27
|
||||
**文档版本**: 1.1.0
|
||||
**文档更新时间**: 2025-01-07
|
||||
**文档版本**: 1.2.0
|
||||
**维护人员**: Cursor AI
|
||||
**更新说明**: 新增学生信息导入功能,完善学生信息管理API文档
|
||||
**更新说明**:
|
||||
- 新增高级检索导出接口文档
|
||||
- 修复高级检索导出分页限制问题
|
||||
- 之前版本:新增学生信息导入功能,完善学生信息管理API文档
|
||||
@@ -6,7 +6,7 @@ import auth from './auth';
|
||||
// 预设动画
|
||||
import animate from '@/animate';
|
||||
|
||||
import { download as dl } from '@/utils/request';
|
||||
import { download as dl, downloadJson as dlJson } from '@/utils/request';
|
||||
import { useDict } from '@/utils/dict';
|
||||
import { getConfigKey, updateConfigByKey } from '@/api/system/config';
|
||||
import { parseTime, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi';
|
||||
@@ -34,6 +34,7 @@ export default function installPlugin(app: App) {
|
||||
app.config.globalProperties.getConfigKey = getConfigKey;
|
||||
app.config.globalProperties.updateConfigByKey = updateConfigByKey;
|
||||
app.config.globalProperties.download = dl;
|
||||
app.config.globalProperties.downloadJson = dlJson;
|
||||
app.config.globalProperties.parseTime = parseTime;
|
||||
app.config.globalProperties.handleTree = handleTree;
|
||||
app.config.globalProperties.addDateRange = addDateRange;
|
||||
|
||||
@@ -215,5 +215,33 @@ export function download(url: string, params: any, fileName: string) {
|
||||
downloadLoadingInstance.close();
|
||||
});
|
||||
}
|
||||
|
||||
// 通用下载方法(JSON格式入参)
|
||||
export function downloadJson(url: string, params: any, fileName: string) {
|
||||
downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' });
|
||||
// prettier-ignore
|
||||
return service.post(url, params, {
|
||||
headers: { 'Content-Type': 'application/json;charset=utf-8' },
|
||||
responseType: 'blob',
|
||||
timeout: 1200000 // 导出接口单独设置20分钟超时
|
||||
}).then(async (resp: any) => {
|
||||
const isLogin = blobValidate(resp);
|
||||
if (isLogin) {
|
||||
const blob = new Blob([resp]);
|
||||
FileSaver.saveAs(blob, fileName);
|
||||
} else {
|
||||
const blob = new Blob([resp]);
|
||||
const resText = await blob.text();
|
||||
const rspObj = JSON.parse(resText);
|
||||
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'];
|
||||
ElMessage.error(errMsg);
|
||||
}
|
||||
downloadLoadingInstance.close();
|
||||
}).catch((r: any) => {
|
||||
console.error(r);
|
||||
ElMessage.error('下载文件出现错误,请联系管理员!');
|
||||
downloadLoadingInstance.close();
|
||||
});
|
||||
}
|
||||
// 导出 axios 实例
|
||||
export default service;
|
||||
@@ -786,8 +786,24 @@ const handleReset = () => {
|
||||
};
|
||||
|
||||
const handleSearch = () => {
|
||||
// 构建查询参数
|
||||
const searchParams: any = { ...formData };
|
||||
// 先清空查询参数,只添加有效值
|
||||
const searchParams: any = {};
|
||||
|
||||
// 只添加有值的基础字段
|
||||
Object.keys(formData).forEach((key) => {
|
||||
const value = formData[key];
|
||||
if (value !== null && value !== undefined && value !== '') {
|
||||
// 对于数组,检查是否有有效元素
|
||||
if (Array.isArray(value)) {
|
||||
const filteredArray = value.filter((item) => item !== null && item !== undefined && item !== '');
|
||||
if (filteredArray.length > 0) {
|
||||
searchParams[key] = filteredArray;
|
||||
}
|
||||
} else {
|
||||
searchParams[key] = value;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 处理日期范围参数
|
||||
if (searchParams.birthDateRange && searchParams.birthDateRange.length === 2) {
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<div class="search-buttons">
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
<el-button type="info" icon="Setting" @click="showAdvancedSearch = true">高级检索</el-button>
|
||||
<el-button type="info" icon="Setting" @click="handleShowAdvancedSearch">高级检索</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -245,7 +245,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, toRefs, watchEffect, onMounted, computed } from 'vue';
|
||||
import { ref, reactive, toRefs, watchEffect, onMounted, computed, getCurrentInstance } from 'vue';
|
||||
import ElMessage from 'element-plus/es/components/message/index';
|
||||
import ElMessageBox from 'element-plus/es/components/message-box/index';
|
||||
import { Search, Refresh, Setting, Download, List, Grid, View, Picture, Male, Female } from '@element-plus/icons-vue';
|
||||
@@ -253,6 +253,8 @@ import AdvancedSearchDialog from './components/AdvancedSearchDialog.vue';
|
||||
import StudentDetailDialog from './components/StudentDetailDialog.vue';
|
||||
import api from '@/api/xg/xsjcxx/stuRoster/index';
|
||||
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
|
||||
// 响应式数据
|
||||
const loading = ref(false);
|
||||
const showSearch = ref(true);
|
||||
@@ -290,6 +292,9 @@ const queryParams = reactive({
|
||||
// 高级查询参数
|
||||
const advancedQueryParams = reactive({
|
||||
// 基础信息
|
||||
studentNo: '',
|
||||
name: '',
|
||||
phone: '',
|
||||
idCard: '',
|
||||
nameEnglish: '',
|
||||
formerName: '',
|
||||
@@ -314,6 +319,7 @@ const advancedQueryParams = reactive({
|
||||
academicLevel: '',
|
||||
trainingType: '',
|
||||
grade: '',
|
||||
studentStatus: [] as string[],
|
||||
|
||||
// 家庭信息
|
||||
fatherName: '',
|
||||
@@ -432,24 +438,78 @@ const getList = () => {
|
||||
};
|
||||
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNum = 1;
|
||||
// 保留基本检索条件和部门选择
|
||||
const basicSearchParams = {
|
||||
pageNum: 1,
|
||||
pageSize: queryParams.pageSize,
|
||||
studentNo: queryParams.studentNo || '',
|
||||
name: queryParams.name || '',
|
||||
phone: queryParams.phone || '',
|
||||
studentStatus: queryParams.studentStatus || [],
|
||||
deptIds: queryParams.deptIds || []
|
||||
};
|
||||
|
||||
// 清空 queryParams 对象的所有属性
|
||||
Object.keys(queryParams).forEach((key) => {
|
||||
delete queryParams[key];
|
||||
});
|
||||
|
||||
// 重新设置基本检索参数
|
||||
Object.assign(queryParams, basicSearchParams);
|
||||
|
||||
getList();
|
||||
};
|
||||
|
||||
const resetQuery = () => {
|
||||
// 先将查询参数重置为空对象
|
||||
Object.keys(queryParams).forEach((key) => {
|
||||
delete queryParams[key];
|
||||
});
|
||||
|
||||
// 重新设置必要的默认参数
|
||||
queryParams.pageNum = 1;
|
||||
queryParams.pageSize = 10;
|
||||
queryParams.studentNo = '';
|
||||
queryParams.name = '';
|
||||
queryParams.phone = '';
|
||||
queryParams.studentStatus = [];
|
||||
queryParams.deptIds = [];
|
||||
|
||||
// 清空部门选择
|
||||
selectedDepts.value = [];
|
||||
//左侧树的勾选全取消
|
||||
deptTreeRef.value?.setCheckedKeys([]);
|
||||
|
||||
// 执行查询
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
const handleAdvancedSearch = (params: any) => {
|
||||
//queryParams 需要重置
|
||||
// 保留基本检索条件和部门选择
|
||||
const basicSearchParams = {
|
||||
pageNum: 1,
|
||||
pageSize: queryParams.pageSize,
|
||||
studentNo: queryParams.studentNo || '',
|
||||
name: queryParams.name || '',
|
||||
phone: queryParams.phone || '',
|
||||
studentStatus: queryParams.studentStatus || [],
|
||||
deptIds: queryParams.deptIds || []
|
||||
};
|
||||
|
||||
// 清空 queryParams 对象的所有属性
|
||||
Object.keys(queryParams).forEach((key) => {
|
||||
delete queryParams[key];
|
||||
});
|
||||
|
||||
// 重新设置基本检索参数
|
||||
Object.assign(queryParams, basicSearchParams);
|
||||
console.log('检索栏查询参数:', queryParams);
|
||||
console.log('高级查询参数:', params);
|
||||
// 合并高级查询参数
|
||||
Object.assign(queryParams, params);
|
||||
handleQuery();
|
||||
console.log('检索栏+高级查询参数:', queryParams);
|
||||
getList();
|
||||
};
|
||||
|
||||
const handleAdvancedReset = () => {
|
||||
@@ -461,25 +521,232 @@ const handleAdvancedReset = () => {
|
||||
advancedQueryParams[key] = '';
|
||||
}
|
||||
});
|
||||
resetQuery();
|
||||
};
|
||||
|
||||
const handleShowAdvancedSearch = () => {
|
||||
// 将基础检索栏的参数同步到高级检索参数中
|
||||
if (queryParams.studentNo) {
|
||||
advancedQueryParams.studentNo = queryParams.studentNo;
|
||||
}
|
||||
if (queryParams.name) {
|
||||
advancedQueryParams.name = queryParams.name;
|
||||
}
|
||||
if (queryParams.phone) {
|
||||
advancedQueryParams.phone = queryParams.phone;
|
||||
}
|
||||
// 状态对应学籍状况
|
||||
if (queryParams.studentStatus && queryParams.studentStatus.length > 0) {
|
||||
advancedQueryParams.studentStatus = [...queryParams.studentStatus];
|
||||
}
|
||||
|
||||
// 显示高级检索弹窗
|
||||
showAdvancedSearch.value = true;
|
||||
};
|
||||
|
||||
const handleExport = () => {
|
||||
// 使用真实的导出API
|
||||
api
|
||||
.exportStudentRoster(queryParams)
|
||||
.then((response) => {
|
||||
const blob = new Blob([response.data], { type: 'application/vnd.ms-excel' });
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = '学生花名册.xlsx';
|
||||
link.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
// 显示导出进度提示
|
||||
ElMessage({
|
||||
message: '正在导出数据,请耐心等待...',
|
||||
type: 'info',
|
||||
duration: 0,
|
||||
zIndex: 4000
|
||||
});
|
||||
|
||||
// 组装高级检索参数,参考AdvancedSearchDialog的处理方式
|
||||
const exportParams: any = {
|
||||
// 基础查询条件
|
||||
...queryParams
|
||||
// 高级查询条件
|
||||
// ...//advancedQueryParams
|
||||
};
|
||||
console.log('导出参数 - begin:', exportParams);
|
||||
|
||||
// 处理日期范围参数
|
||||
if (exportParams.birthDateRange && exportParams.birthDateRange.length === 2) {
|
||||
exportParams.birthDateStart = exportParams.birthDateRange[0];
|
||||
exportParams.birthDateEnd = exportParams.birthDateRange[1];
|
||||
}
|
||||
delete exportParams.birthDateRange;
|
||||
|
||||
if (exportParams.enrollmentDateRange && exportParams.enrollmentDateRange.length === 2) {
|
||||
exportParams.enrollmentDateStart = exportParams.enrollmentDateRange[0];
|
||||
exportParams.enrollmentDateEnd = exportParams.enrollmentDateRange[1];
|
||||
}
|
||||
delete exportParams.enrollmentDateRange;
|
||||
|
||||
if (exportParams.createTimeRange && exportParams.createTimeRange.length === 2) {
|
||||
exportParams.createTimeStart = exportParams.createTimeRange[0];
|
||||
exportParams.createTimeEnd = exportParams.createTimeRange[1];
|
||||
}
|
||||
delete exportParams.createTimeRange;
|
||||
|
||||
if (exportParams.updateTimeRange && exportParams.updateTimeRange.length === 2) {
|
||||
exportParams.updateTimeStart = exportParams.updateTimeRange[0];
|
||||
exportParams.updateTimeEnd = exportParams.updateTimeRange[1];
|
||||
}
|
||||
delete exportParams.updateTimeRange;
|
||||
|
||||
// 处理数值范围参数
|
||||
if (exportParams.enrollmentYearRange && exportParams.enrollmentYearRange.length >= 1) {
|
||||
if (exportParams.enrollmentYearRange[0]) {
|
||||
exportParams.enrollmentYearStart = exportParams.enrollmentYearRange[0];
|
||||
}
|
||||
if (exportParams.enrollmentYearRange[1]) {
|
||||
exportParams.enrollmentYearEnd = exportParams.enrollmentYearRange[1];
|
||||
}
|
||||
}
|
||||
delete exportParams.enrollmentYearRange;
|
||||
|
||||
if (exportParams.schoolSystemRange && exportParams.schoolSystemRange.length >= 1) {
|
||||
if (exportParams.schoolSystemRange[0]) {
|
||||
exportParams.schoolSystemMin = exportParams.schoolSystemRange[0];
|
||||
}
|
||||
if (exportParams.schoolSystemRange[1]) {
|
||||
exportParams.schoolSystemMax = exportParams.schoolSystemRange[1];
|
||||
}
|
||||
}
|
||||
delete exportParams.schoolSystemRange;
|
||||
|
||||
if (exportParams.grade && Array.isArray(exportParams.grade) && exportParams.grade.length >= 1) {
|
||||
if (exportParams.grade[0]) {
|
||||
exportParams.gradeMin = exportParams.grade[0];
|
||||
}
|
||||
if (exportParams.grade[1]) {
|
||||
exportParams.gradeMax = exportParams.grade[1];
|
||||
}
|
||||
}
|
||||
delete exportParams.grade;
|
||||
|
||||
if (exportParams.familyIncomeRange && exportParams.familyIncomeRange.length >= 1) {
|
||||
if (exportParams.familyIncomeRange[0]) {
|
||||
exportParams.familyIncomeMin = exportParams.familyIncomeRange[0];
|
||||
}
|
||||
if (exportParams.familyIncomeRange[1]) {
|
||||
exportParams.familyIncomeMax = exportParams.familyIncomeRange[1];
|
||||
}
|
||||
}
|
||||
delete exportParams.familyIncomeRange;
|
||||
|
||||
if (exportParams.perCapitaIncomeRange && exportParams.perCapitaIncomeRange.length >= 1) {
|
||||
if (exportParams.perCapitaIncomeRange[0]) {
|
||||
exportParams.perCapitaIncomeMin = exportParams.perCapitaIncomeRange[0];
|
||||
}
|
||||
if (exportParams.perCapitaIncomeRange[1]) {
|
||||
exportParams.perCapitaIncomeMax = exportParams.perCapitaIncomeRange[1];
|
||||
}
|
||||
}
|
||||
delete exportParams.perCapitaIncomeRange;
|
||||
|
||||
if (exportParams.familyMembersRange && exportParams.familyMembersRange.length >= 1) {
|
||||
if (exportParams.familyMembersRange[0]) {
|
||||
exportParams.familyMembersMin = exportParams.familyMembersRange[0];
|
||||
}
|
||||
if (exportParams.familyMembersRange[1]) {
|
||||
exportParams.familyMembersMax = exportParams.familyMembersRange[1];
|
||||
}
|
||||
}
|
||||
delete exportParams.familyMembersRange;
|
||||
|
||||
if (exportParams.loanAmountRange && exportParams.loanAmountRange.length >= 1) {
|
||||
if (exportParams.loanAmountRange[0]) {
|
||||
exportParams.loanAmountMin = exportParams.loanAmountRange[0];
|
||||
}
|
||||
if (exportParams.loanAmountRange[1]) {
|
||||
exportParams.loanAmountMax = exportParams.loanAmountRange[1];
|
||||
}
|
||||
}
|
||||
delete exportParams.loanAmountRange;
|
||||
|
||||
if (exportParams.heightRange && exportParams.heightRange.length >= 1) {
|
||||
if (exportParams.heightRange[0]) {
|
||||
exportParams.heightMin = exportParams.heightRange[0];
|
||||
}
|
||||
if (exportParams.heightRange[1]) {
|
||||
exportParams.heightMax = exportParams.heightRange[1];
|
||||
}
|
||||
}
|
||||
delete exportParams.heightRange;
|
||||
|
||||
if (exportParams.weightRange && exportParams.weightRange.length >= 1) {
|
||||
if (exportParams.weightRange[0]) {
|
||||
exportParams.weightMin = exportParams.weightRange[0];
|
||||
}
|
||||
if (exportParams.weightRange[1]) {
|
||||
exportParams.weightMax = exportParams.weightRange[1];
|
||||
}
|
||||
}
|
||||
delete exportParams.weightRange;
|
||||
|
||||
// 处理多选下拉框参数 - 确保传递数组格式
|
||||
const multiSelectFields = [
|
||||
'gender',
|
||||
'nationality',
|
||||
'nativePlace',
|
||||
'politicalStatus',
|
||||
'maritalStatus',
|
||||
'educationLevel',
|
||||
'admissionCategory',
|
||||
'academicLevel',
|
||||
'trainingType',
|
||||
'householdRegisterType',
|
||||
'studentStatus',
|
||||
'isBoarder',
|
||||
'dormitoryBuilding',
|
||||
'familyEconomicStatus',
|
||||
'isPoorStudent',
|
||||
'isMinority',
|
||||
'isDisabled',
|
||||
'isOrphan',
|
||||
'isLeftBehindChild',
|
||||
'isSingleChild',
|
||||
'isLowIncome',
|
||||
'hasLoan',
|
||||
'sourceRegion',
|
||||
'bloodType',
|
||||
'disabilityType'
|
||||
];
|
||||
|
||||
multiSelectFields.forEach((field) => {
|
||||
if (exportParams[field] && Array.isArray(exportParams[field])) {
|
||||
// 过滤掉空值,确保只传递有效的数组
|
||||
const filteredArray = exportParams[field].filter((item) => item !== null && item !== undefined && item !== '');
|
||||
if (filteredArray.length > 0) {
|
||||
exportParams[field] = filteredArray;
|
||||
} else {
|
||||
delete exportParams[field];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 移除分页参数,导出全量数据
|
||||
exportParams.pageNum = 1;
|
||||
exportParams.pageSize = 5000000;
|
||||
|
||||
// 过滤掉空值,减少请求体大小
|
||||
Object.keys(exportParams).forEach((key) => {
|
||||
if (exportParams[key] === undefined || exportParams[key] === '' || (Array.isArray(exportParams[key]) && exportParams[key].length === 0)) {
|
||||
delete exportParams[key];
|
||||
}
|
||||
});
|
||||
|
||||
console.log('导出参数 - end:', exportParams);
|
||||
|
||||
proxy
|
||||
?.downloadJson('studentMsg/studentMsg/advancedSearchExport', exportParams, `学生花名册_${new Date().getTime()}.xlsx`)
|
||||
.then(() => {
|
||||
// 导出成功后关闭提示
|
||||
ElMessage.closeAll();
|
||||
ElMessage.success('导出成功');
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('导出失败:', error);
|
||||
ElMessage.error('导出失败,请重试');
|
||||
// 导出失败时关闭提示
|
||||
ElMessage.closeAll();
|
||||
if (error.message && error.message.includes('timeout')) {
|
||||
ElMessage.error('导出超时,请尝试减少导出数据量或联系管理员');
|
||||
} else {
|
||||
ElMessage.error('导出失败,请稍后重试');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user