| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- package com.xjrsoft.module.banding.service.impl;
- import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
- import com.baomidou.mybatisplus.core.toolkit.Wrappers;
- import com.github.yulichang.base.MPJBaseServiceImpl;
- import com.github.yulichang.wrapper.MPJLambdaWrapper;
- import com.xjrsoft.common.enums.GenderDictionaryEnum;
- import com.xjrsoft.common.exception.MyException;
- import com.xjrsoft.common.utils.VoToColumnUtil;
- import com.xjrsoft.module.banding.dto.AutomaticBandingTaskDto;
- import com.xjrsoft.module.banding.dto.BandingTaskClassConditionDto;
- import com.xjrsoft.module.banding.dto.SureBandingTaskDto;
- import com.xjrsoft.module.banding.entity.BandingRule;
- import com.xjrsoft.module.banding.entity.BandingTask;
- import com.xjrsoft.module.banding.entity.BandingTaskClass;
- import com.xjrsoft.module.banding.entity.BandingTaskClassStudent;
- import com.xjrsoft.module.banding.entity.BandingTaskRule;
- import com.xjrsoft.module.banding.mapper.BandingRuleMapper;
- import com.xjrsoft.module.banding.mapper.BandingTaskClassMapper;
- import com.xjrsoft.module.banding.mapper.BandingTaskMapper;
- import com.xjrsoft.module.banding.mapper.BandingTaskRuleMapper;
- import com.xjrsoft.module.banding.service.IBandingTaskClassStudentService;
- import com.xjrsoft.module.banding.service.IBandingTaskService;
- import com.xjrsoft.module.outint.vo.IdCountVo;
- import com.xjrsoft.module.student.entity.BaseNewStudent;
- import com.xjrsoft.module.student.entity.EnrollmentPlan;
- import com.xjrsoft.module.student.service.IBaseNewStudentService;
- import lombok.AllArgsConstructor;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Random;
- import java.util.stream.Collectors;
- /**
- * @title: 新生分班任务
- * @Author dzx
- * @Date: 2024-07-01
- * @Version 1.0
- */
- @Service
- @AllArgsConstructor
- public class BandingTaskServiceImpl extends MPJBaseServiceImpl<BandingTaskMapper, BandingTask> implements IBandingTaskService {
- private final BandingTaskMapper bandingTaskMapper;
- private final BandingRuleMapper ruleMapper;
- private final BandingTaskRuleMapper taskRuleMapper;
- private final BandingTaskClassMapper taskClassMapper;
- private final IBaseNewStudentService newStudentService;
- private final IBandingTaskClassStudentService classStudentService;
- @Override
- @Transactional(rollbackFor = Exception.class)
- public Boolean add(BandingTask bandingTask) {
- bandingTask.setCreateDate(new Date());
- bandingTaskMapper.insert(bandingTask);
- return true;
- }
- @Override
- @Transactional(rollbackFor = Exception.class)
- public Boolean update(BandingTask bandingTask) {
- bandingTask.setModifyDate(new Date());
- bandingTaskMapper.updateById(bandingTask);
- return true;
- }
- @Override
- @Transactional(rollbackFor = Exception.class)
- public Boolean delete(List<Long> ids) {
- bandingTaskMapper.deleteBatchIds(ids);
- taskRuleMapper.delete(Wrappers.lambdaQuery(BandingTaskRule.class).in(BandingTaskRule::getBandingTaskId, ids));
- taskClassMapper.delete(Wrappers.lambdaQuery(BandingTaskClass.class).in(BandingTaskClass::getBandingTaskId, ids));
- return true;
- }
- /**
- * 自动分班
- * 1、根据分班任务的信息,查询出来需要分班的学生
- * 2、查询该任务下的班级信息
- * 3、查询该任务使用的规则
- * 4、执行自动分班
- * 5、完成后,将分好班的信息存到banding_task_class_student表中
- */
- @Override
- public Boolean automaticBanding(AutomaticBandingTaskDto dto) {
- BandingTask bandingTask = this.getById(dto.getBandingTaskId());
- if(bandingTask == null){
- throw new MyException("未能查询到该任务,无法自动分班");
- }
- //1、查询需要分班的学生信息
- List<String> orderColumn = new ArrayList();
- orderColumn.add("height");orderColumn.add("score");
- List<BaseNewStudent> baseNewStudents = newStudentService.selectJoinList(BaseNewStudent.class,
- new MPJLambdaWrapper<BaseNewStudent>()
- .select(BaseNewStudent::getId)
- .select(BaseNewStudent.class, x -> VoToColumnUtil.fieldsToColumns(BaseNewStudent.class).contains(x.getProperty()))
- .leftJoin(EnrollmentPlan.class, EnrollmentPlan::getId, BaseNewStudent::getEnrollmentPlanId)
- .eq(EnrollmentPlan::getGradeId, bandingTask.getGradeId())
- .eq(EnrollmentPlan::getEnrollType, bandingTask.getEnrollType())
- .eq(BaseNewStudent::getStatus, 0)
- .orderByDescStr(orderColumn)
- );
- //2、查询所有班级信息
- List<BandingTaskClass> classList = taskClassMapper.selectList(
- new QueryWrapper<BandingTaskClass>().lambda()
- .select(BandingTaskClass::getId)
- .select(BandingTaskClass.class, x -> VoToColumnUtil.fieldsToColumns(BandingTaskClass.class).contains(x.getProperty()))
- .eq(BandingTaskClass::getBandingTaskId, bandingTask.getId())
- .orderByAsc(BandingTaskClass::getSortCode)
- );
- //3、查询所用到的规则
- List<BandingRule> ruleList = ruleMapper.selectJoinList(BandingRule.class,
- new MPJLambdaWrapper<BandingRule>()
- .select(BandingRule::getId)
- .select(BandingRule.class, x -> VoToColumnUtil.fieldsToColumns(BandingRule.class).contains(x.getProperty()))
- .innerJoin(BandingTaskRule.class, BandingTaskRule::getBandingRuleId, BandingRule::getId)
- .eq(BandingTaskRule::getBandingTaskId, bandingTask.getId())
- );
- List<String> ruleCodes = ruleList.stream().map(BandingRule::getCode).collect(Collectors.toList());
- //包含下面个条件,则需要计算每个班级应该分配的人数
- Map<Long, Integer> classLimitMap = new HashMap<>();
- if(ruleCodes.contains("BR0004")){
- //查询每个专业下面的班级人数
- Map<Long, Integer> majorClassStudentCount = taskClassMapper.getMajorClassStudentCount(bandingTask.getId())
- .stream().collect(Collectors.toMap(IdCountVo::getId, IdCountVo::getCount));
- //查询每个专业下面有多少个班级
- Map<Long, Integer> majorClassCount = taskClassMapper.getMajorClassCount(bandingTask.getId())
- .stream().collect(Collectors.toMap(IdCountVo::getId, IdCountVo::getCount));
- //查询每个专业人数
- Map<Long, Integer> majorStudentCount = newStudentService.getMajorStudentCount()
- .stream().collect(Collectors.toMap(IdCountVo::getId, IdCountVo::getCount));
- Map<Long, Integer> majorLimitMap = new HashMap<>();
- for (Long majorSetId : majorClassStudentCount.keySet()) {
- Integer majorClassNumber = majorClassStudentCount.get(majorSetId);
- Integer majorStudentNumber = majorStudentCount.get(majorSetId);
- Integer classCount = majorClassCount.get(majorSetId);
- if(majorStudentNumber < majorClassNumber){//报名人数小于班级人数
- Integer classLimtCount = majorStudentNumber / classCount;
- majorLimitMap.put(majorSetId, classLimtCount);
- }else{
- Integer classLimtCount = majorClassNumber / classCount;
- majorLimitMap.put(majorSetId, classLimtCount);
- }
- }
- for (BandingTaskClass bandingTaskClass : classList) {
- classLimitMap.put(bandingTaskClass.getId(), majorLimitMap.get(bandingTaskClass.getMajorSetId()));
- }
- }
- Map<Long, BandingTaskClassConditionDto> classConditionMap = new HashMap<>();
- for (BandingTaskClassConditionDto classConditionDto : dto.getClassInfo()) {
- classConditionMap.put(classConditionDto.getBandingTaskCassId(), classConditionDto);
- }
- //存班级和学生的关系
- Map<Long, Long> studentClassMap = new HashMap<>();
- //4、开始分班
- for (BandingTaskClass taskClass : classList) {
- Integer number = taskClass.getNumber();//班级总人数
- if(classLimitMap.get(taskClass.getId()) != null){
- number = classLimitMap.get(taskClass.getId());
- }
- Integer maleCount = 0, femaleCount = 0;
- if(ruleCodes.contains("BR0001")){
- maleCount = number / 2;
- femaleCount = number / 2;
- //如果班级人数是奇数,随机分配一个名额
- if(number % 2 != 0){
- Random random = new Random();
- int randomIndex = random.nextInt(GenderDictionaryEnum.getCodes().length);
- String randomGender = GenderDictionaryEnum.getCodes()[randomIndex];
- if(GenderDictionaryEnum.MALE.getCode().equals(randomGender)){
- maleCount ++;
- }else if(GenderDictionaryEnum.FEMALE.getCode().equals(randomGender)){
- femaleCount ++ ;
- }
- }
- }
- List<String> nameList = new ArrayList<>();
- List<BaseNewStudent> maleList = new ArrayList();
- List<BaseNewStudent> femaleList = new ArrayList();
- for (BaseNewStudent newStudent : baseNewStudents) {
- //人数已满,进行下一个班级的的循环
- if(nameList.size() == number){
- break;
- }
- //该学生已被分配
- if(studentClassMap.containsKey(newStudent.getId())){
- continue;
- }
- if(ruleCodes.contains("BR0003") && nameList.contains(newStudent.getName())){
- continue;
- }
- //专业不匹配,直接跳过
- if(taskClass.getMajorSetId() != newStudent.getFirstAmbitionId() && taskClass.getMajorSetId() != newStudent.getSecondAmbitionId()){
- continue;
- }
- //判断该班性别是否已满
- if(ruleCodes.contains("BR0001")){
- if(GenderDictionaryEnum.MALE.getCode().equals(newStudent.getGender()) && maleList.size() == maleCount){
- continue;
- }else if(GenderDictionaryEnum.FEMALE.getCode().equals(newStudent.getGender()) && femaleList.size() == femaleCount){
- continue;
- }
- }
- List<Boolean> conditionList = new ArrayList<>();
- BandingTaskClassConditionDto condition = classConditionMap.get(taskClass.getId());
- if(condition.getHeight() !=null && newStudent.getHeight() != null && newStudent.getHeight().compareTo(condition.getHeight()) >= 0 ){
- conditionList.add(true);
- }else if(condition.getHeight() !=null && newStudent.getHeight() != null && newStudent.getHeight().compareTo(condition.getHeight()) < 0){
- conditionList.add(false);
- }else if(condition.getHeight() !=null && newStudent.getHeight() == null){
- conditionList.add(false);
- }
- if(condition.getScore() !=null && newStudent.getScore() != null && newStudent.getScore().compareTo(condition.getScore()) >= 0 ){
- conditionList.add(true);
- }else if(condition.getScore() !=null && newStudent.getScore() != null && newStudent.getScore().compareTo(condition.getScore()) < 0){
- conditionList.add(false);
- }else if(condition.getScore() !=null && newStudent.getScore() == null){
- conditionList.add(false);
- }
- //如果包含false,则表明不符合条件,这个学生跳过
- if(conditionList.contains(false)){
- continue;
- }
- studentClassMap.put(newStudent.getId(), taskClass.getId());
- if(GenderDictionaryEnum.MALE.getCode().equals(newStudent.getGender())){
- maleList.add(newStudent);
- }else if(GenderDictionaryEnum.FEMALE.getCode().equals(newStudent.getGender())){
- femaleList.add(newStudent);
- }
- nameList.add(newStudent.getName());
- //清除已经被分班的学生
- baseNewStudents.remove(newStudent);
- }
- }
- List<BandingTaskClassStudent> dataList = new ArrayList<>();
- Date createDate = new Date();
- for (Long studentId : studentClassMap.keySet()) {
- dataList.add(
- new BandingTaskClassStudent(){{
- setBandingTaskClassId(studentClassMap.get(studentId));
- setNewStudentId(studentId);
- setStatus(0);
- setCreateDate(createDate);
- }}
- );
- }
- if(!dataList.isEmpty()){
- classStudentService.saveBatch(dataList);
- }
- return true;
- }
- @Override
- public Boolean sure(SureBandingTaskDto dto) {
- List<BandingTaskClassStudent> classStudents = classStudentService.selectJoinList(BandingTaskClassStudent.class,
- new MPJLambdaWrapper<BandingTaskClassStudent>()
- .select(BandingTaskClassStudent::getId)
- .select(BandingTaskClassStudent.class, x -> VoToColumnUtil.fieldsToColumns(BandingTaskClassStudent.class).contains(x.getProperty()))
- .leftJoin(BandingTaskClass.class, BandingTaskClass::getId, BandingTaskClassStudent::getBandingTaskClassId)
- .eq(BandingTaskClass::getBandingTaskId, dto.getId())
- .eq(BandingTaskClassStudent::getStatus, 1)
- );
- List<Long> studentIds = classStudents.stream().map(BandingTaskClassStudent::getNewStudentId).collect(Collectors.toList());
- List<BaseNewStudent> list = newStudentService.list(
- new QueryWrapper<BaseNewStudent>().lambda()
- .in(BaseNewStudent::getId, studentIds)
- );
- List<BaseNewStudent> updateList = new ArrayList<>();
- for (BaseNewStudent student : list) {
- student.setStatus(1);
- updateList.add(student);
- }
- if(!updateList.isEmpty()){
- newStudentService.updateBatchById(updateList);
- }
- BandingTask bandingTask = this.getById(dto.getId());
- bandingTask.setStatus(1);
- bandingTask.setModifyDate(new Date());
- Boolean isSuccess = this.update(bandingTask);
- return isSuccess;
- }
- }
|