You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
394 lines
13 KiB
394 lines
13 KiB
package com.wbq.service.impl;
|
|
|
|
import com.github.pagehelper.Page;
|
|
import com.github.pagehelper.PageHelper;
|
|
import com.wbq.context.BaseContext;
|
|
import com.wbq.dto.CourseDTO;
|
|
import com.wbq.dto.StudentDTO;
|
|
import com.wbq.dto.StudentLoginDTO;
|
|
import com.wbq.dto.StudentPageQueryDTO;
|
|
import com.wbq.entity.CallRecord;
|
|
import com.wbq.entity.Course;
|
|
import com.wbq.entity.Student;
|
|
import com.wbq.mapper.*;
|
|
import com.wbq.result.PageResult;
|
|
import com.wbq.service.StudentService;
|
|
import com.wbq.vo.CourseCallVO;
|
|
import com.wbq.vo.CourseVO;
|
|
import com.wbq.vo.StudentCourseInfoVO;
|
|
import org.apache.poi.ss.usermodel.*;
|
|
import org.springframework.beans.BeanUtils;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.security.crypto.bcrypt.BCrypt;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
import javax.print.attribute.IntegerSyntax;
|
|
import java.io.InputStream;
|
|
import java.time.LocalDateTime;
|
|
import java.util.ArrayList;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Random;
|
|
|
|
@Service
|
|
public class StudentServiceImpl implements StudentService {
|
|
@Autowired
|
|
private StudentMapper studentMapper;
|
|
@Autowired
|
|
private StudentCourseMapper studentCourseMapper;
|
|
@Autowired
|
|
private CourseMapper courseMapper;
|
|
@Autowired
|
|
private CallRecordMapper callRecordMapper;
|
|
@Autowired
|
|
private AdminMapper adminMapper;
|
|
|
|
@Override
|
|
public Student getById(int id) {
|
|
return studentMapper.getById(id);
|
|
}
|
|
|
|
/**
|
|
* 更新学生信息
|
|
* @param studentDTO
|
|
*/
|
|
@Override
|
|
public void update(StudentDTO studentDTO) {
|
|
studentMapper.update(studentDTO);
|
|
}
|
|
|
|
/**
|
|
* 分页查询学生(按课程积分排名)
|
|
* @param studentPageQueryDTO
|
|
* @param courseId
|
|
* @return
|
|
*/
|
|
@Override
|
|
public PageResult pageQuery(StudentPageQueryDTO studentPageQueryDTO, int courseId) {
|
|
PageHelper.startPage(studentPageQueryDTO.getPage(), studentPageQueryDTO.getPageSize());
|
|
Page<StudentCourseInfoVO> page = studentCourseMapper.pageQuery4CourseInfo(courseId);
|
|
return new PageResult(page.getTotal(), page.getResult());
|
|
}
|
|
|
|
/**
|
|
* 随机点名核心代码
|
|
* @param courseId
|
|
* @param studentIds
|
|
* @return
|
|
*/
|
|
@Override
|
|
public Student coreCall(int courseId, List<Integer> studentIds) {
|
|
// 生成权重
|
|
double totalWeight = 0;
|
|
for (int studentId : studentIds) {
|
|
StudentCourseInfoVO studentCourseInfoVO = studentCourseMapper.getCourseInfo(studentId, courseId);
|
|
double studentScore = studentCourseInfoVO.getScore();
|
|
totalWeight += 1.0/(studentScore + 1);
|
|
}
|
|
|
|
double cumulativeWeight = 0;
|
|
Random random = new Random();
|
|
double rand = random.nextDouble();
|
|
int selectedStudentId = 0;
|
|
|
|
// 轮盘赌算法
|
|
for (int studentId : studentIds) {
|
|
StudentCourseInfoVO studentCourseInfoVO = studentCourseMapper.getCourseInfo(studentId, courseId);
|
|
double studentScore = studentCourseInfoVO.getScore();
|
|
|
|
cumulativeWeight += 1.0/(studentScore + 1);
|
|
if (cumulativeWeight >= rand*totalWeight) {
|
|
selectedStudentId = studentId;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 增加被叫次数
|
|
int oldCallCount = studentCourseMapper.getCourseInfo(selectedStudentId, courseId).getCallCount();
|
|
int newCallCount = oldCallCount + 1;
|
|
studentCourseMapper.updateCallCountByStudentIdAndCourseId(newCallCount, selectedStudentId, courseId);
|
|
|
|
Student selectedStudent = studentMapper.getByStudentId(selectedStudentId);
|
|
// 生成点名记录
|
|
CallRecord callRecord = CallRecord.builder()
|
|
.callTime(LocalDateTime.now())
|
|
.courseDescription(courseMapper.getByCourseId(courseId).getDescription())
|
|
.adminName(adminMapper.getById(BaseContext.getCurrentId()).getName())
|
|
.studentId(selectedStudentId)
|
|
.build();
|
|
callRecordMapper.insert(callRecord);
|
|
return selectedStudent;
|
|
}
|
|
|
|
/**
|
|
* 随机点名
|
|
* @param courseId
|
|
* @return
|
|
*/
|
|
@Override
|
|
public StudentCourseInfoVO callStudent(int courseId) {
|
|
List<Integer> studentIds = studentCourseMapper.getByCourseId(courseId);
|
|
|
|
Student selectedStudent = coreCall(courseId, studentIds);
|
|
|
|
StudentCourseInfoVO studentCourseInfoVO = studentCourseMapper.getCourseInfo(selectedStudent.getStudentId(), courseId);
|
|
|
|
return studentCourseInfoVO;
|
|
}
|
|
|
|
|
|
/**
|
|
* 根据姓氏点名,积分越高,概率越低
|
|
* @param courseId
|
|
* @param firstname
|
|
* @return
|
|
*/
|
|
@Override
|
|
public StudentCourseInfoVO callStudentByFirstname(int courseId, String firstname) {
|
|
List<Integer> studentIds = studentCourseMapper.getByCourseId(courseId);
|
|
|
|
// 筛选方式
|
|
Iterator<Integer> iterator = studentIds.iterator();
|
|
while (iterator.hasNext()) {
|
|
Integer studentId = iterator.next();
|
|
Student student = studentMapper.getByStudentId(studentId);
|
|
String studentName = student.getName();
|
|
if (!firstname.equals(Character.toString(studentName.charAt(0)))) {
|
|
iterator.remove(); // 使用 iterator.remove() 安全地移除元素
|
|
}
|
|
}
|
|
|
|
Student selectedStudent = coreCall(courseId, studentIds);
|
|
|
|
StudentCourseInfoVO studentCourseInfoVO = studentCourseMapper.getCourseInfo(selectedStudent.getStudentId(), courseId);
|
|
|
|
return studentCourseInfoVO;
|
|
}
|
|
|
|
/**
|
|
* 根据学号尾数点名
|
|
* @param courseId
|
|
* @param lastNum
|
|
* @return
|
|
*/
|
|
@Override
|
|
public StudentCourseInfoVO callStudentByLastNum(int courseId, int lastNum) {
|
|
List<Integer> studentIds = studentCourseMapper.getByCourseId(courseId);
|
|
|
|
// 筛选方式
|
|
Iterator<Integer> iterator = studentIds.iterator();
|
|
while (iterator.hasNext()) {
|
|
Integer studentId = iterator.next();
|
|
if (studentId % 10 != lastNum) {
|
|
iterator.remove(); // 使用 iterator.remove() 安全地移除元素
|
|
}
|
|
}
|
|
|
|
Student selectedStudent = coreCall(courseId, studentIds);
|
|
|
|
StudentCourseInfoVO studentCourseInfoVO = studentCourseMapper.getCourseInfo(selectedStudent.getStudentId(), courseId);
|
|
|
|
return studentCourseInfoVO;
|
|
}
|
|
|
|
/**
|
|
* 手动加分
|
|
* @param courseDTO
|
|
* @param studentDTO
|
|
* @param score
|
|
* @return
|
|
*/
|
|
@Override
|
|
public StudentCourseInfoVO addScore(CourseDTO courseDTO, StudentDTO studentDTO, double score) {
|
|
double oldScore = studentCourseMapper.getCourseInfo(studentDTO.getStudentId(), courseDTO.getCourseId()).getScore();
|
|
|
|
studentCourseMapper.updateScoreByStudentIdAndCourseId(oldScore + score,
|
|
studentDTO.getStudentId(),
|
|
courseDTO.getCourseId());
|
|
|
|
// 返回更新值
|
|
StudentCourseInfoVO studentCourseInfoVO = studentCourseMapper.getCourseInfo(studentDTO.getStudentId(), courseDTO.getCourseId());
|
|
|
|
// 更新记录
|
|
List<CallRecord> callRecordList = callRecordMapper.getByStudentId(studentDTO.getStudentId());
|
|
CallRecord newCallRecord = callRecordList.getFirst();
|
|
newCallRecord.setScore(score);
|
|
callRecordMapper.update(newCallRecord);
|
|
|
|
return studentCourseInfoVO;
|
|
}
|
|
|
|
/**
|
|
* 学生登录
|
|
* @param studentLoginDTO
|
|
* @return
|
|
*/
|
|
@Override
|
|
public Student login(StudentLoginDTO studentLoginDTO) {
|
|
Student student = null;
|
|
String hashedPassword = studentMapper.getPasswordByStudentId(studentLoginDTO.getStudentId());
|
|
// 使用BCrypt的checkpw方法来验证密码
|
|
boolean isPasswordCorrect = BCrypt.checkpw(studentLoginDTO.getPassword(), hashedPassword);
|
|
|
|
// 验证成功
|
|
if (isPasswordCorrect)
|
|
student = studentMapper.getByStudentId(studentLoginDTO.getStudentId());
|
|
return student;
|
|
}
|
|
|
|
/**
|
|
* 加入课程
|
|
* @param courseDTO
|
|
*/
|
|
@Override
|
|
public void joinCourse(StudentDTO studentDTO, CourseDTO courseDTO) {
|
|
studentCourseMapper.insert(studentDTO.getStudentId(), courseDTO.getCourseId());
|
|
}
|
|
|
|
/**
|
|
* 退出班级
|
|
* @param courseDTO
|
|
* @param studentDTO
|
|
*/
|
|
@Override
|
|
public void dropCourse(CourseDTO courseDTO, StudentDTO studentDTO) {
|
|
studentCourseMapper.delete(studentDTO.getStudentId(), courseDTO.getCourseId());
|
|
}
|
|
|
|
/**
|
|
* 查询自己加入的班级
|
|
* @return
|
|
*/
|
|
@Override
|
|
public List<CourseVO> courseList() {
|
|
int studentId = studentMapper.getById(BaseContext.getCurrentId()).getStudentId();
|
|
List<CourseVO> courseVOList = new ArrayList<>();
|
|
List<Integer> courseIdList = studentCourseMapper.getByStudentId(studentId);
|
|
List<Course> courseList = courseMapper.getByCourseIdList(courseIdList);
|
|
|
|
for (Course course : courseList) {
|
|
CourseVO courseVO = new CourseVO();
|
|
BeanUtils.copyProperties(course, courseVO);
|
|
courseVOList.add(courseVO);
|
|
}
|
|
|
|
return courseVOList;
|
|
}
|
|
|
|
/**
|
|
* 查询自己的某门课程信息
|
|
* @param studentId
|
|
* @param courseId
|
|
* @return
|
|
*/
|
|
@Override
|
|
public StudentCourseInfoVO getStudentCourseInfo(int studentId, int courseId) {
|
|
return studentCourseMapper.getCourseInfo(studentId, courseId);
|
|
}
|
|
|
|
/**
|
|
* 批量增加点名系统的学生
|
|
* @param courseId
|
|
* @param studentDTOs
|
|
*/
|
|
@Override
|
|
public void batchAddStudents(List<StudentDTO> studentDTOs, int courseId) {
|
|
if (studentDTOs != null && !studentDTOs.isEmpty()) {
|
|
for (StudentDTO studentDTO : studentDTOs) {
|
|
String initPassword = "1234";
|
|
String hashedPassword = BCrypt.hashpw(initPassword, BCrypt.gensalt());
|
|
studentDTO.setPassword(hashedPassword);
|
|
}
|
|
studentCourseMapper.batchInsert(studentDTOs, courseId);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 解析Excel
|
|
* @param file
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
@Override
|
|
public List<StudentDTO> parseExcel(MultipartFile file) throws Exception {
|
|
List<StudentDTO> studentDTOs = new ArrayList<>();
|
|
|
|
// 获取 Excel 文件的输入流
|
|
InputStream inputStream = file.getInputStream();
|
|
Workbook workbook = WorkbookFactory.create(inputStream);
|
|
// 学生信息在第一张表
|
|
Sheet sheet = workbook.getSheetAt(0);
|
|
|
|
for (Row row : sheet) {
|
|
// 跳过表头
|
|
/*if (row.getRowNum() == 0) {
|
|
continue;
|
|
}*/
|
|
|
|
StudentDTO studentDTO = new StudentDTO();
|
|
|
|
if(row.getRowNum() == 103) break;
|
|
|
|
//debug
|
|
System.out.println("第" + row.getRowNum() + "行");
|
|
System.out.println(row.getCell(0).getCellType() + " " +
|
|
row.getCell(1).getCellType() + " " +
|
|
row.getCell(2).getCellType());
|
|
|
|
|
|
if(row.getCell(0).getCellType() == CellType.STRING)
|
|
studentDTO.setStudentId(Integer.parseInt(row.getCell(0).getStringCellValue()));
|
|
else
|
|
studentDTO.setStudentId((int)row.getCell(0).getNumericCellValue()); // 学号
|
|
|
|
studentDTO.setName(row.getCell(1).getStringCellValue()); // 姓名
|
|
studentDTO.setPassword(row.getCell(2).getStringCellValue()); // 密码
|
|
studentDTOs.add(studentDTO);
|
|
}
|
|
|
|
workbook.close();
|
|
return studentDTOs;
|
|
}
|
|
|
|
/**
|
|
* 查询自己某门课程的历次点名记录
|
|
* @param courseId
|
|
* @param studentPageQueryDTO
|
|
* @return
|
|
*/
|
|
@Override
|
|
public PageResult getCallRecord(StudentPageQueryDTO studentPageQueryDTO, int courseId) {
|
|
int studentId = studentMapper.getById(BaseContext.getCurrentId()).getStudentId();
|
|
String courseDescription = courseMapper.getByCourseId(courseId).getDescription();
|
|
|
|
PageHelper.startPage(studentPageQueryDTO.getPage(), studentPageQueryDTO.getPageSize());
|
|
|
|
Page<CallRecord> page = callRecordMapper.pageQuery(studentPageQueryDTO, studentId, courseDescription);
|
|
List<CallRecord> callRecordList = page.getResult();
|
|
|
|
List<CourseCallVO> courseCallVOList = new ArrayList<>();
|
|
|
|
for (CallRecord callRecord : callRecordList) {
|
|
CourseCallVO courseCallVO = new CourseCallVO();
|
|
BeanUtils.copyProperties(callRecord, courseCallVO);
|
|
|
|
courseCallVOList.add(courseCallVO);
|
|
}
|
|
|
|
return new PageResult(page.getTotal(), courseCallVOList);
|
|
}
|
|
|
|
/**
|
|
* 修改密码
|
|
* @param studentDTO
|
|
*/
|
|
@Override
|
|
public void changePassword(StudentDTO studentDTO) {
|
|
String password = studentDTO.getPassword();
|
|
String hashPassword = BCrypt.hashpw(password, BCrypt.gensalt());
|
|
studentDTO.setPassword(hashPassword);
|
|
studentMapper.update(studentDTO);
|
|
}
|
|
}
|