package com.ruoyi.system.controller;
|
|
import java.util.List;
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.Map;
|
import jakarta.servlet.http.HttpServletResponse;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PutMapping;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RestController;
|
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.utils.SecurityUtils;
|
import com.ruoyi.system.domain.CjStudent;
|
import com.ruoyi.system.domain.CjClass;
|
import com.ruoyi.system.domain.CjCollege;
|
import com.ruoyi.system.domain.CjMajor;
|
import com.ruoyi.system.mapper.CjClassMapper;
|
import com.ruoyi.system.mapper.CjCollegeMapper;
|
import com.ruoyi.system.mapper.CjMajorMapper;
|
import com.ruoyi.system.mapper.CjStudentBindMapper;
|
import com.ruoyi.system.mapper.CjStudentMapper;
|
import com.ruoyi.system.service.ICjStudentService;
|
import com.ruoyi.system.service.MiniappTokenService;
|
import com.ruoyi.common.core.redis.RedisCache;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
|
/**
|
* 学生花名册Controller
|
*
|
* 约定:学号全校不唯一、仅班级内唯一,学生唯一性 = 所属班级 + 学号;
|
* Excel 导入/导出用“学院名称/专业名称/班级名称”引用班级,无需数字班级ID。
|
*
|
* @author ruoyi
|
* @date 2026-09-03
|
*/
|
@RestController
|
@RequestMapping("/system/student")
|
public class CjStudentController extends BaseController
|
{
|
@Autowired
|
private ICjStudentService cjStudentService;
|
@Autowired
|
private CjClassMapper cjClassMapper;
|
@Autowired
|
private CjCollegeMapper cjCollegeMapper;
|
@Autowired
|
private CjMajorMapper cjMajorMapper;
|
@Autowired
|
private CjStudentBindMapper cjStudentBindMapper;
|
@Autowired
|
private CjStudentMapper cjStudentMapper;
|
@Autowired
|
private MiniappTokenService miniappTokenService;
|
@Autowired
|
private RedisCache redisCache;
|
|
/**
|
* 全校视野:超管(约定 admin 的 userId 恒为 1,或 admin 角色)或「教务处」角色。
|
* 教务处账号(jwc01)不是 userId=1、也没有 manager_user_id 班级,
|
* 若仍按 userId 判定会看到空花名册,故按角色放行。
|
*/
|
private boolean isSchoolWide()
|
{
|
Long userId = SecurityUtils.getUserId();
|
if (userId != null && userId == 1L)
|
{
|
return true;
|
}
|
try
|
{
|
return SecurityUtils.hasRole("admin") || SecurityUtils.hasRole("jwc");
|
}
|
catch (Exception e)
|
{
|
return false;
|
}
|
}
|
|
/** 当前用户(教师)管理的班级ID集合;超管返回 null 表示不限 */
|
private List<Long> myClassIds()
|
{
|
CjClass q = new CjClass();
|
q.setManagerUserId(SecurityUtils.getUserId());
|
List<CjClass> myClasses = cjClassMapper.selectCjClassList(q);
|
List<Long> ids = new ArrayList<>();
|
if (myClasses != null)
|
{
|
for (CjClass c : myClasses)
|
{
|
ids.add(c.getClassId());
|
}
|
}
|
return ids;
|
}
|
|
/** 当前用户能否管理该学生(超管可管理一切;教师须在本班) */
|
private boolean canManage(CjStudent stu)
|
{
|
if (stu == null || stu.getClassId() == null)
|
{
|
return false;
|
}
|
if (isSchoolWide())
|
{
|
return true;
|
}
|
return myClassIds().contains(stu.getClassId());
|
}
|
|
/** 班级+学号 查已有学生(判重依据:班级内学号唯一) */
|
private CjStudent findByClassAndNo(Long classId, String studentNo)
|
{
|
if (classId == null || studentNo == null)
|
{
|
return null;
|
}
|
CjStudent q = new CjStudent();
|
q.setClassId(classId);
|
q.setStudentNo(studentNo);
|
List<CjStudent> list = cjStudentService.selectCjStudentList(q);
|
return list.isEmpty() ? null : list.get(0);
|
}
|
|
/** 性别码转文本(导出展示列) */
|
private String genderToText(String gender)
|
{
|
if (gender == null)
|
{
|
return "";
|
}
|
if ("0".equals(gender))
|
{
|
return "男";
|
}
|
if ("1".equals(gender))
|
{
|
return "女";
|
}
|
if ("2".equals(gender))
|
{
|
return "未知";
|
}
|
return "";
|
}
|
|
/** 非法性别标记 */
|
private static final String GENDER_INVALID = "GENDER_INVALID";
|
|
/** 解析导入的性别列(兼容 男/女/未知 与 0/1/2);空白返回 null;非法返回 GENDER_INVALID */
|
private String parseGender(String text)
|
{
|
if (text == null)
|
{
|
return null;
|
}
|
String t = text.trim();
|
if (t.isEmpty())
|
{
|
return null;
|
}
|
if ("男".equals(t) || "0".equals(t))
|
{
|
return "0";
|
}
|
if ("女".equals(t) || "1".equals(t))
|
{
|
return "1";
|
}
|
if ("未知".equals(t) || "2".equals(t))
|
{
|
return "2";
|
}
|
return GENDER_INVALID;
|
}
|
|
/**
|
* 导出/展示前回填 学院/专业/班级名称 与 性别中文(transient Excel 列)
|
*/
|
private void fillStudentForExcel(List<CjStudent> list)
|
{
|
if (list == null || list.isEmpty())
|
{
|
return;
|
}
|
Map<Long, CjClass> classMap = new HashMap<>();
|
List<CjClass> classes = cjClassMapper.selectCjClassList(new CjClass());
|
if (classes != null)
|
{
|
for (CjClass c : classes)
|
{
|
classMap.put(c.getClassId(), c);
|
}
|
}
|
Map<Long, CjMajor> majorMap = new HashMap<>();
|
List<CjMajor> majors = cjMajorMapper.selectCjMajorList(new CjMajor());
|
if (majors != null)
|
{
|
for (CjMajor m : majors)
|
{
|
majorMap.put(m.getMajorId(), m);
|
}
|
}
|
Map<Long, String> collegeMap = new HashMap<>();
|
List<CjCollege> colleges = cjCollegeMapper.selectCjCollegeList(new CjCollege());
|
if (colleges != null)
|
{
|
for (CjCollege c : colleges)
|
{
|
collegeMap.put(c.getCollegeId(), c.getCollegeName());
|
}
|
}
|
for (CjStudent s : list)
|
{
|
s.setGenderText(genderToText(s.getGender()));
|
if (s.getClassId() == null)
|
{
|
continue;
|
}
|
CjClass cl = classMap.get(s.getClassId());
|
if (cl == null)
|
{
|
continue;
|
}
|
s.setClassName(cl.getClassName());
|
if (cl.getMajorId() != null)
|
{
|
CjMajor m = majorMap.get(cl.getMajorId());
|
if (m != null)
|
{
|
s.setMajorName(m.getMajorName());
|
if (m.getCollegeId() != null)
|
{
|
s.setCollegeName(collegeMap.get(m.getCollegeId()));
|
}
|
}
|
}
|
}
|
}
|
|
/**
|
* 查询学生花名册列表(数据权限:教师仅见本班)
|
*/
|
@PreAuthorize("@ss.hasPermi('system:student:list')")
|
@GetMapping("/list")
|
public TableDataInfo list(CjStudent cjStudent)
|
{
|
// 非超管(admin=1)时,仅返回其管理班级的学生
|
if (!isSchoolWide())
|
{
|
List<Long> classIds = myClassIds();
|
if (classIds.isEmpty())
|
{
|
return getDataTable(new ArrayList<>());
|
}
|
cjStudent.setClassIds(classIds);
|
}
|
|
startPage();
|
List<CjStudent> list = cjStudentService.selectCjStudentList(cjStudent);
|
// 手机号脱敏(列表展示 138****1234)
|
list.forEach(s -> {
|
if (s.getPhone() != null && s.getPhone().length() == 11) {
|
s.setPhone(s.getPhone().substring(0, 3) + "****" + s.getPhone().substring(7));
|
}
|
});
|
return getDataTable(list);
|
}
|
|
/**
|
* 查询当前教师可管理的班级(新增/查询“我的班”下拉源;超管返回空,走全校级联)
|
*/
|
@PreAuthorize("@ss.hasPermi('system:student:list')")
|
@GetMapping("/myClasses")
|
public AjaxResult myClasses()
|
{
|
if (isSchoolWide())
|
{
|
return success(new ArrayList<>());
|
}
|
return success(myClassIdsForSelect());
|
}
|
|
private List<CjClass> myClassIdsForSelect()
|
{
|
CjClass q = new CjClass();
|
q.setManagerUserId(SecurityUtils.getUserId());
|
return cjClassMapper.selectCjClassList(q);
|
}
|
|
/**
|
* 导出学生花名册列表(教师仅导出本班;导出列含学院/专业/班级名称与性别文本)
|
*/
|
@PreAuthorize("@ss.hasPermi('system:student:export')")
|
@Log(title = "学生花名册", businessType = BusinessType.EXPORT)
|
@PostMapping("/export")
|
public void export(HttpServletResponse response, CjStudent cjStudent)
|
{
|
List<CjStudent> list;
|
if (!isSchoolWide())
|
{
|
List<Long> classIds = myClassIds();
|
if (classIds.isEmpty())
|
{
|
ExcelUtil<CjStudent> emptyUtil = new ExcelUtil<CjStudent>(CjStudent.class);
|
emptyUtil.exportExcel(response, new ArrayList<>(), "学生花名册数据");
|
return;
|
}
|
cjStudent.setClassIds(classIds);
|
}
|
list = cjStudentService.selectCjStudentList(cjStudent);
|
fillStudentForExcel(list);
|
ExcelUtil<CjStudent> util = new ExcelUtil<CjStudent>(CjStudent.class);
|
util.exportExcel(response, list, "学生花名册数据");
|
}
|
|
/**
|
* 获取学生花名册详细信息
|
*/
|
@PreAuthorize("@ss.hasPermi('system:student:query')")
|
@GetMapping(value = "/{studentId}")
|
public AjaxResult getInfo(@PathVariable("studentId") Long studentId)
|
{
|
CjStudent stu = cjStudentService.selectCjStudentByStudentId(studentId);
|
if (!isSchoolWide() && !canManage(stu))
|
{
|
return error("无权访问其他班级学生数据");
|
}
|
return success(stu);
|
}
|
|
/**
|
* 新增学生花名册(教师仅可在本班新增;同班学号不得重复)
|
*/
|
@PreAuthorize("@ss.hasPermi('system:student:add')")
|
@Log(title = "学生花名册", businessType = BusinessType.INSERT)
|
@PostMapping
|
public AjaxResult add(@RequestBody CjStudent cjStudent)
|
{
|
if (!isSchoolWide() && !myClassIds().contains(cjStudent.getClassId()))
|
{
|
return error("只能在本班新增学生");
|
}
|
if (findByClassAndNo(cjStudent.getClassId(), cjStudent.getStudentNo()) != null)
|
{
|
return error("该班级已存在相同学号的学生(学号仅班级内唯一),请核对");
|
}
|
return toAjax(cjStudentService.insertCjStudent(cjStudent));
|
}
|
|
/**
|
* 修改学生花名册(教师仅可维护本班学生,且不能改到他人班级;班级+学号不可重复)
|
*/
|
@PreAuthorize("@ss.hasPermi('system:student:edit')")
|
@Log(title = "学生花名册", businessType = BusinessType.UPDATE)
|
@PutMapping
|
public AjaxResult edit(@RequestBody CjStudent cjStudent)
|
{
|
if (!isSchoolWide())
|
{
|
CjStudent old = cjStudentService.selectCjStudentByStudentId(cjStudent.getStudentId());
|
if (!canManage(old))
|
{
|
return error("无权操作其他班级学生");
|
}
|
if (cjStudent.getClassId() != null && !myClassIds().contains(cjStudent.getClassId()))
|
{
|
return error("只能将学生保留在本人管理的班级");
|
}
|
}
|
CjStudent same = findByClassAndNo(cjStudent.getClassId(), cjStudent.getStudentNo());
|
if (same != null && !same.getStudentId().equals(cjStudent.getStudentId()))
|
{
|
return error("该班级已存在相同学号的学生(学号仅班级内唯一),请核对");
|
}
|
int rows = cjStudentService.updateCjStudent(cjStudent);
|
// 修正学号/姓名/手机号后清掉自助通道的失败锁,避免学生被历史尝试锁在门外
|
if (rows > 0 && cjStudent.getStudentNo() != null && cjStudent.getName() != null)
|
{
|
redisCache.deleteObject(MiniappTokenService.pwdErrKey(cjStudent.getStudentNo(), cjStudent.getName()));
|
redisCache.deleteObject(MiniappTokenService.resetErrKey(cjStudent.getStudentNo(), cjStudent.getName()));
|
}
|
return toAjax(rows);
|
}
|
|
/**
|
* 删除学生花名册(引用保护:已微信绑定的学生禁止删除,请改用停用)
|
*/
|
@PreAuthorize("@ss.hasPermi('system:student:remove')")
|
@Log(title = "学生花名册", businessType = BusinessType.DELETE)
|
@DeleteMapping("/{studentIds}")
|
public AjaxResult remove(@PathVariable Long[] studentIds)
|
{
|
if (studentIds == null || studentIds.length == 0)
|
{
|
return toAjax(0);
|
}
|
if (!isSchoolWide())
|
{
|
for (Long id : studentIds)
|
{
|
CjStudent s = cjStudentService.selectCjStudentByStudentId(id);
|
if (!canManage(s))
|
{
|
return error("无权操作其他班级学生");
|
}
|
}
|
}
|
if (cjStudentBindMapper.countByStudentIds(studentIds) > 0)
|
{
|
return error("所选学生中已存在微信绑定记录,禁止删除;请改用“停用”");
|
}
|
return toAjax(cjStudentService.deleteCjStudentByStudentIds(studentIds));
|
}
|
|
/**
|
* 学生停用/启用(0正常 1停用)
|
*/
|
@PreAuthorize("@ss.hasPermi('system:student:status')")
|
@Log(title = "学生花名册", businessType = BusinessType.UPDATE)
|
@PutMapping("/changeStatus")
|
public AjaxResult changeStatus(@RequestBody CjStudent cjStudent)
|
{
|
if (cjStudent.getStudentId() == null)
|
{
|
return error("缺少学生ID");
|
}
|
if (!isSchoolWide())
|
{
|
CjStudent old = cjStudentService.selectCjStudentByStudentId(cjStudent.getStudentId());
|
if (!canManage(old))
|
{
|
return error("无权操作其他班级学生");
|
}
|
}
|
CjStudent update = new CjStudent();
|
update.setStudentId(cjStudent.getStudentId());
|
update.setStatus(cjStudent.getStatus());
|
update.setUpdateBy(getUsername());
|
return toAjax(cjStudentService.updateCjStudent(update));
|
}
|
|
/**
|
* 重置学生登录密码为初始密码(AA+学号),并置“下次登录强制改密”;
|
* 同时作废该生全部在线会话与登录失败计数。教师仅限本班学生。
|
*/
|
@PreAuthorize("@ss.hasPermi('system:student:resetPwd')")
|
@Log(title = "学生账号", businessType = BusinessType.UPDATE)
|
@PutMapping("/resetPwd/{studentId}")
|
public AjaxResult resetPwd(@PathVariable("studentId") Long studentId)
|
{
|
CjStudent stu = cjStudentService.selectCjStudentByStudentId(studentId);
|
if (stu == null)
|
{
|
return error("学生不存在");
|
}
|
if (!canManage(stu))
|
{
|
return error("无权操作其他班级学生");
|
}
|
String initPwd = initialPassword(stu.getStudentNo());
|
// 从未激活过的学生被重置:视为激活,补 register_time,避免"已激活但激活时间为空"
|
boolean firstActivate = cjStudentMapper.selectPasswordByStudentId(studentId) == null;
|
cjStudentMapper.updateStudentPassword(studentId, SecurityUtils.encryptPassword(initPwd), "1",
|
firstActivate ? new java.util.Date() : null);
|
miniappTokenService.invalidateAll(studentId);
|
// 解除该生的登录失败锁与自助重置锁,否则学生拿到初始密码也可能被锁在门外
|
redisCache.deleteObject(MiniappTokenService.pwdErrKey(stu.getStudentNo(), stu.getName()));
|
redisCache.deleteObject(MiniappTokenService.resetErrKey(stu.getStudentNo(), stu.getName()));
|
return success("密码已重置为初始密码(AA+学号),学生下次登录须修改密码");
|
}
|
|
/**
|
* 强制下线:作废该学生全部小程序/H5 登录会话(下次请求即需重新登录)。教师仅限本班学生。
|
*/
|
@PreAuthorize("@ss.hasPermi('system:student:forceLogout')")
|
@Log(title = "学生账号", businessType = BusinessType.UPDATE)
|
@DeleteMapping("/forceLogout/{studentId}")
|
public AjaxResult forceLogout(@PathVariable("studentId") Long studentId)
|
{
|
CjStudent stu = cjStudentService.selectCjStudentByStudentId(studentId);
|
if (stu == null)
|
{
|
return error("学生不存在");
|
}
|
if (!canManage(stu))
|
{
|
return error("无权操作其他班级学生");
|
}
|
miniappTokenService.invalidateAll(studentId);
|
return success("已强制下线");
|
}
|
|
/** 初始密码规则:AA + 完整学号(满足“8-20位且含字母和数字”的密码策略) */
|
private String initialPassword(String studentNo)
|
{
|
return "AA" + (studentNo == null ? "" : studentNo.trim());
|
}
|
|
/**
|
* 导入学生花名册
|
* 模板列:所属学院 / 所属专业 / 班级名称 / 学号 / 姓名 / 性别(男/女) / 联系电话
|
* 判重键:所属班级 + 学号(班级内学号唯一);班级通过 学院→专业→班级名称 三级解析。
|
* @param file 上传的 Excel
|
* @param updateSupport 是否覆盖更新已存在数据(true=覆盖)
|
* @return {新增X 更新Y 失败Z + 失败名单}
|
*/
|
@PreAuthorize("@ss.hasPermi('system:student:import')")
|
@Log(title = "学生花名册", businessType = BusinessType.IMPORT)
|
@PostMapping("/importData")
|
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
|
{
|
ExcelUtil<CjStudent> util = new ExcelUtil<CjStudent>(CjStudent.class);
|
List<CjStudent> studentList = util.importExcel(file.getInputStream());
|
String message;
|
int insertCount = 0, updateCount = 0, failCount = 0;
|
StringBuilder failMsg = new StringBuilder();
|
String operName = getUsername();
|
|
for (int i = 0; i < studentList.size(); i++)
|
{
|
CjStudent stu = studentList.get(i);
|
int rowNo = i + 1;
|
try
|
{
|
String collegeName = trim(stu.getCollegeName());
|
String majorName = trim(stu.getMajorName());
|
String className = trim(stu.getClassName());
|
String studentNo = trim(stu.getStudentNo());
|
String stuName = trim(stu.getName());
|
if (collegeName == null)
|
{
|
failCount++; failMsg.append("第" + rowNo + "条: 所属学院不能为空; "); continue;
|
}
|
if (majorName == null)
|
{
|
failCount++; failMsg.append("第" + rowNo + "条: 所属专业不能为空; "); continue;
|
}
|
if (className == null)
|
{
|
failCount++; failMsg.append("第" + rowNo + "条: 班级名称不能为空; "); continue;
|
}
|
if (studentNo == null)
|
{
|
failCount++; failMsg.append("第" + rowNo + "条: 学号不能为空; "); continue;
|
}
|
if (stuName == null)
|
{
|
failCount++; failMsg.append("第" + rowNo + "条: 姓名不能为空; "); continue;
|
}
|
|
// 三级名称解析到班级(父级须启用中;班级须已存在且启用)
|
List<CjCollege> colleges = cjCollegeMapper.selectEnabledByCollegeName(collegeName);
|
if (colleges.isEmpty())
|
{
|
failCount++;
|
failMsg.append("第" + rowNo + "条: 所属学院“" + collegeName + "”不存在或已停用; ");
|
continue;
|
}
|
if (colleges.size() > 1)
|
{
|
failCount++;
|
failMsg.append("第" + rowNo + "条: 所属学院“" + collegeName + "”在系统中重复,请先清理; ");
|
continue;
|
}
|
Long collegeId = colleges.get(0).getCollegeId();
|
List<CjMajor> majors = cjMajorMapper.selectEnabledByCollegeIdAndName(collegeId, majorName);
|
if (majors.isEmpty())
|
{
|
failCount++;
|
failMsg.append("第" + rowNo + "条: 所属专业“" + majorName + "”在学院“" + collegeName + "”下不存在或已停用; ");
|
continue;
|
}
|
if (majors.size() > 1)
|
{
|
failCount++;
|
failMsg.append("第" + rowNo + "条: 专业“" + majorName + "”在该学院下重复,请先清理; ");
|
continue;
|
}
|
Long majorId = majors.get(0).getMajorId();
|
List<CjClass> classes = cjClassMapper.selectByMajorIdAndName(majorId, className);
|
if (classes.isEmpty())
|
{
|
failCount++;
|
failMsg.append("第" + rowNo + "条: 班级“" + className + "”在专业“" + majorName + "”下不存在,请先在班级管理中建立; ");
|
continue;
|
}
|
if (classes.size() > 1)
|
{
|
failCount++;
|
failMsg.append("第" + rowNo + "条: 班级“" + className + "”在该专业下重复,无法定位; ");
|
continue;
|
}
|
CjClass cl = classes.get(0);
|
if (cl.getStatus() != null && !"0".equals(cl.getStatus()))
|
{
|
failCount++;
|
failMsg.append("第" + rowNo + "条: 班级“" + className + "”已停用,无法导入学生; ");
|
continue;
|
}
|
|
// 性别兼容 男/女/未知 与 0/1/2
|
String gender = parseGender(stu.getGenderText());
|
if (GENDER_INVALID.equals(gender))
|
{
|
failCount++;
|
failMsg.append("第" + rowNo + "条: 学号" + studentNo + " 性别“" + stu.getGenderText() + "”无法识别(请填男/女/未知); ");
|
continue;
|
}
|
|
stu.setCollegeName(collegeName);
|
stu.setMajorName(majorName);
|
stu.setClassName(className);
|
stu.setClassId(cl.getClassId());
|
stu.setStudentNo(studentNo);
|
stu.setName(stuName);
|
stu.setGender(gender);
|
if (stu.getPhone() != null)
|
{
|
stu.setPhone(stu.getPhone().trim());
|
}
|
|
// 判重:班级 + 学号
|
CjStudent exists = findByClassAndNo(cl.getClassId(), studentNo);
|
if (exists == null)
|
{
|
if (stu.getStatus() == null)
|
{
|
stu.setStatus("0");
|
}
|
stu.setCreateBy(operName);
|
cjStudentService.insertCjStudent(stu);
|
insertCount++;
|
}
|
else if (updateSupport)
|
{
|
// 覆盖导入时电话列为空 = 保留原登记号码(写成空串会静默废掉学生的三要素自助找回密码)
|
if (stu.getPhone() != null && stu.getPhone().trim().isEmpty())
|
{
|
stu.setPhone(null);
|
}
|
stu.setStudentId(exists.getStudentId());
|
stu.setUpdateBy(operName);
|
cjStudentService.updateCjStudent(stu);
|
updateCount++;
|
}
|
else
|
{
|
failCount++;
|
failMsg.append("第" + rowNo + "条: 学号" + studentNo + "在班级“" + className + "”中已存在; ");
|
}
|
}
|
catch (Exception e)
|
{
|
failCount++;
|
failMsg.append("第" + rowNo + "条" + (stu.getStudentNo() != null ? "(学号" + stu.getStudentNo() + ")" : "")
|
+ "(导入失败:" + e.getMessage() + "); ");
|
}
|
}
|
|
if (updateSupport)
|
message = String.format("导入完成!新增 %d 条,更新 %d 条", insertCount, updateCount);
|
else
|
message = String.format("导入完成!新增 %d 条,由于数据重复导致导入失败 %d 条", insertCount, failCount);
|
|
Map<String, Object> data = new HashMap<>();
|
data.put("message", message);
|
data.put("insertCount", insertCount);
|
data.put("updateCount", updateCount);
|
data.put("failCount", failCount);
|
data.put("failMsg", failMsg.toString());
|
return AjaxResult.success(data);
|
}
|
|
/** 字符串去首尾空白;null/空返回 null */
|
private String trim(String s)
|
{
|
return (s == null || s.trim().isEmpty()) ? null : s.trim();
|
}
|
|
/**
|
* 下载学生花名册导入模板
|
*/
|
@PreAuthorize("@ss.hasPermi('system:student:import')")
|
@PostMapping("/importTemplate")
|
public void importTemplate(HttpServletResponse response) throws Exception
|
{
|
ExcelUtil<CjStudent> util = new ExcelUtil<CjStudent>(CjStudent.class);
|
util.importTemplateExcel(response, "学生花名册导入模板");
|
}
|
}
|