package cn.iocoder.yudao.module.mes.service.safety;
|
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.training.MesSafetyTrainingAttendeeSaveReqVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.training.MesSafetyTrainingPageReqVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.training.MesSafetyTrainingSaveReqVO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.safety.MesSafetyTrainingAttendeeDO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.safety.MesSafetyTrainingDO;
|
import cn.iocoder.yudao.module.mes.dal.mysql.safety.MesSafetyTrainingAttendeeMapper;
|
import cn.iocoder.yudao.module.mes.dal.mysql.safety.MesSafetyTrainingMapper;
|
import jakarta.annotation.Resource;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.validation.annotation.Validated;
|
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.time.LocalDateTime;
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.Objects;
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
|
|
/**
|
* 安全生产 - 培训 Service 实现
|
*
|
* @author 超级管理员
|
*/
|
@Service
|
@Validated
|
public class MesSafetyTrainingServiceImpl implements MesSafetyTrainingService {
|
|
@Resource
|
private MesSafetyTrainingMapper trainingMapper;
|
|
@Resource
|
private MesSafetyTrainingAttendeeMapper attendeeMapper;
|
|
@Override
|
public PageResult<MesSafetyTrainingDO> getTrainingPage(MesSafetyTrainingPageReqVO pageReqVO) {
|
return trainingMapper.selectPage(pageReqVO);
|
}
|
|
@Override
|
public MesSafetyTrainingDO getTraining(Long id) {
|
return trainingMapper.selectById(id);
|
}
|
|
@Override
|
public Long createTraining(MesSafetyTrainingSaveReqVO createReqVO) {
|
validateCodeUnique(null, createReqVO.getCode());
|
validateTimeRange(createReqVO);
|
MesSafetyTrainingDO training = BeanUtils.toBean(createReqVO, MesSafetyTrainingDO.class);
|
training.setAttendeeCount(0);
|
training.setSignedCount(0);
|
trainingMapper.insert(training);
|
return training.getId();
|
}
|
|
@Override
|
public void updateTraining(MesSafetyTrainingSaveReqVO updateReqVO) {
|
validateTrainingExists(updateReqVO.getId());
|
validateCodeUnique(updateReqVO.getId(), updateReqVO.getCode());
|
validateTimeRange(updateReqVO);
|
MesSafetyTrainingDO updateObj = BeanUtils.toBean(updateReqVO, MesSafetyTrainingDO.class);
|
// 统计字段由参训人员维护,不通过此接口修改
|
updateObj.setAttendeeCount(null);
|
updateObj.setSignedCount(null);
|
updateObj.setAvgScore(null);
|
trainingMapper.updateById(updateObj);
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void deleteTraining(Long id) {
|
validateTrainingExists(id);
|
// 级联删除参训记录,避免孤儿数据
|
attendeeMapper.deleteByTrainingId(id);
|
trainingMapper.deleteById(id);
|
}
|
|
@Override
|
public MesSafetyTrainingDO validateTrainingExists(Long id) {
|
if (id == null) {
|
throw exception(MES_SAFETY_TRAINING_NOT_EXISTS);
|
}
|
MesSafetyTrainingDO training = trainingMapper.selectById(id);
|
if (training == null) {
|
throw exception(MES_SAFETY_TRAINING_NOT_EXISTS);
|
}
|
return training;
|
}
|
|
@Override
|
public List<MesSafetyTrainingAttendeeDO> getAttendeeList(Long trainingId) {
|
return attendeeMapper.selectListByTrainingId(trainingId);
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void saveAttendees(Long trainingId, List<MesSafetyTrainingAttendeeSaveReqVO> attendees) {
|
validateTrainingExists(trainingId);
|
// 全量覆盖:先清空再插入,保证与前端列表一致
|
attendeeMapper.deleteByTrainingId(trainingId);
|
if (attendees != null && !attendees.isEmpty()) {
|
List<MesSafetyTrainingAttendeeDO> list = new ArrayList<>(attendees.size());
|
for (MesSafetyTrainingAttendeeSaveReqVO vo : attendees) {
|
MesSafetyTrainingAttendeeDO attendee = BeanUtils.toBean(vo, MesSafetyTrainingAttendeeDO.class);
|
attendee.setId(null);
|
attendee.setTrainingId(trainingId);
|
if (attendee.getSignStatus() == null) {
|
attendee.setSignStatus(MesSafetyTrainingAttendeeDO.SIGN_NONE);
|
}
|
if (attendee.getPassed() == null) {
|
attendee.setPassed(MesSafetyTrainingAttendeeDO.PASS_NONE);
|
}
|
list.add(attendee);
|
}
|
attendeeMapper.insertBatch(list);
|
}
|
refreshStatistics(trainingId);
|
}
|
|
@Override
|
public void updateAttendee(MesSafetyTrainingAttendeeSaveReqVO reqVO) {
|
if (reqVO.getId() == null) {
|
throw exception(MES_SAFETY_TRAINING_ATTENDEE_NOT_EXISTS);
|
}
|
MesSafetyTrainingAttendeeDO exists = attendeeMapper.selectById(reqVO.getId());
|
if (exists == null) {
|
throw exception(MES_SAFETY_TRAINING_ATTENDEE_NOT_EXISTS);
|
}
|
MesSafetyTrainingAttendeeDO updateObj = new MesSafetyTrainingAttendeeDO();
|
updateObj.setId(reqVO.getId());
|
updateObj.setSignStatus(reqVO.getSignStatus());
|
updateObj.setSignTime(reqVO.getSignTime());
|
updateObj.setScore(reqVO.getScore());
|
updateObj.setPassed(reqVO.getPassed());
|
updateObj.setRemark(reqVO.getRemark());
|
attendeeMapper.updateById(updateObj);
|
refreshStatistics(exists.getTrainingId());
|
}
|
|
@Override
|
public void deleteAttendee(Long id) {
|
MesSafetyTrainingAttendeeDO exists = attendeeMapper.selectById(id);
|
if (exists == null) {
|
throw exception(MES_SAFETY_TRAINING_ATTENDEE_NOT_EXISTS);
|
}
|
attendeeMapper.deleteById(id);
|
refreshStatistics(exists.getTrainingId());
|
}
|
|
@Override
|
public void refreshStatistics(Long trainingId) {
|
Long total = attendeeMapper.selectCountByTrainingId(trainingId);
|
Long signed = attendeeMapper.selectCountSignedByTrainingId(trainingId);
|
List<MesSafetyTrainingAttendeeDO> list = attendeeMapper.selectListByTrainingId(trainingId);
|
// 平均分只统计有成绩的
|
BigDecimal sum = BigDecimal.ZERO;
|
int scored = 0;
|
for (MesSafetyTrainingAttendeeDO a : list) {
|
if (a.getScore() != null) {
|
sum = sum.add(a.getScore());
|
scored++;
|
}
|
}
|
BigDecimal avg = scored > 0
|
? sum.divide(BigDecimal.valueOf(scored), 2, RoundingMode.HALF_UP)
|
: null;
|
MesSafetyTrainingDO updateObj = new MesSafetyTrainingDO();
|
updateObj.setId(trainingId);
|
updateObj.setAttendeeCount(total == null ? 0 : total.intValue());
|
updateObj.setSignedCount(signed == null ? 0 : signed.intValue());
|
updateObj.setAvgScore(avg);
|
trainingMapper.updateById(updateObj);
|
}
|
|
/**
|
* 校验培训时间区间
|
*/
|
private void validateTimeRange(MesSafetyTrainingSaveReqVO reqVO) {
|
LocalDateTime start = reqVO.getStartTime();
|
LocalDateTime end = reqVO.getEndTime();
|
if (start != null && end != null && !end.isAfter(start)) {
|
throw exception(MES_SAFETY_TRAINING_TIME_INVALID);
|
}
|
}
|
|
private void validateCodeUnique(Long id, String code) {
|
MesSafetyTrainingDO exists = trainingMapper.selectByCode(code);
|
if (exists == null) {
|
return;
|
}
|
if (id == null || !Objects.equals(exists.getId(), id)) {
|
throw exception(MES_SAFETY_TRAINING_CODE_DUPLICATE);
|
}
|
}
|
|
}
|