|
|
@@ -1,30 +1,49 @@
|
|
|
package org.dromara.main.service.impl;
|
|
|
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.dromara.common.core.exception.ServiceException;
|
|
|
import org.dromara.common.core.utils.StringUtils;
|
|
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
|
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
|
+import org.dromara.common.satoken.utils.LoginHelper;
|
|
|
+
|
|
|
import org.dromara.main.domain.MainAbilityConfig;
|
|
|
+import org.dromara.main.domain.MainExamApply;
|
|
|
import org.dromara.main.domain.MainExamEvaluation;
|
|
|
+import org.dromara.main.domain.MainStudent;
|
|
|
import org.dromara.main.domain.bo.MainExamEvaluationBo;
|
|
|
+import org.dromara.main.domain.bo.MainExamEvaluationSyncBo;
|
|
|
+import org.dromara.main.domain.vo.MainExamApplyListVo;
|
|
|
+import org.dromara.main.domain.vo.MainExamSyncEmployeeOptionVo;
|
|
|
import org.dromara.main.domain.vo.MainExamEvaluationVo;
|
|
|
import org.dromara.main.mapper.MainAbilityConfigMapper;
|
|
|
+import org.dromara.main.mapper.MainExamApplyMapper;
|
|
|
import org.dromara.main.mapper.MainExamEvaluationMapper;
|
|
|
+import org.dromara.main.mapper.MainStudentMapper;
|
|
|
import org.dromara.main.service.IMainExamEvaluationService;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.dao.DuplicateKeyException;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.Base64;
|
|
|
import java.util.Collection;
|
|
|
+import java.util.Comparator;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
@Slf4j
|
|
|
@RequiredArgsConstructor
|
|
|
@@ -33,6 +52,8 @@ public class MainExamEvaluationServiceImpl implements IMainExamEvaluationService
|
|
|
|
|
|
private final MainExamEvaluationMapper baseMapper;
|
|
|
private final MainAbilityConfigMapper mainAbilityConfigMapper;
|
|
|
+ private final MainStudentMapper mainStudentMapper;
|
|
|
+ private final MainExamApplyMapper mainExamApplyMapper;
|
|
|
|
|
|
@Override
|
|
|
public MainExamEvaluationVo queryById(Long id) {
|
|
|
@@ -158,6 +179,154 @@ public class MainExamEvaluationServiceImpl implements IMainExamEvaluationService
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public TableDataInfo<MainExamApplyListVo> getApplyList(Long evaluationId, String keyword, PageQuery pageQuery) {
|
|
|
+ if (evaluationId == null) {
|
|
|
+ throw new ServiceException("测评ID不能为空");
|
|
|
+ }
|
|
|
+ String tenantId = getCurrentTenantId();
|
|
|
+ List<MainExamApplyListVo> list = baseMapper.selectApplyListByEvaluationId(evaluationId, tenantId, keyword);
|
|
|
+ return TableDataInfo.build(list, pageQuery.build());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Boolean removeApply(Long applyId) {
|
|
|
+ if (applyId == null) {
|
|
|
+ throw new ServiceException("报名记录不能为空");
|
|
|
+ }
|
|
|
+ MainExamApply apply = mainExamApplyMapper.selectById(applyId);
|
|
|
+ if (apply == null || !StringUtils.equals(apply.getTenantId(), getCurrentTenantId())) {
|
|
|
+ throw new ServiceException("报名记录不存在");
|
|
|
+ }
|
|
|
+ return mainExamApplyMapper.deleteById(applyId) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<Long, Map<String, Long>> getParticipantStats(Collection<Long> ids) {
|
|
|
+ Map<Long, Map<String, Long>> result = new HashMap<>();
|
|
|
+ if (CollectionUtils.isEmpty(ids)) {
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ List<Map<String, Object>> stats = baseMapper.selectParticipantStatsByEvaluationIds(ids);
|
|
|
+ for (Map<String, Object> item : stats) {
|
|
|
+ if (item == null || item.get("evaluationId") == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Long evaluationId = ((Number) item.get("evaluationId")).longValue();
|
|
|
+ long participantCount = item.get("participantCount") == null ? 0L : ((Number) item.get("participantCount")).longValue();
|
|
|
+ long totalCount = item.get("totalCount") == null ? 0L : ((Number) item.get("totalCount")).longValue();
|
|
|
+ Map<String, Long> countMap = new HashMap<>();
|
|
|
+ countMap.put("participantCount", participantCount);
|
|
|
+ countMap.put("totalCount", totalCount);
|
|
|
+ result.put(evaluationId, countMap);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<MainExamSyncEmployeeOptionVo> getSyncEmployeeOptions() {
|
|
|
+ String tenantId = getCurrentTenantId();
|
|
|
+ List<MainStudent> studentList = mainStudentMapper.selectList(
|
|
|
+ Wrappers.<MainStudent>lambdaQuery()
|
|
|
+ .eq(MainStudent::getTenantId, tenantId)
|
|
|
+ .eq(MainStudent::getStatus, "0")
|
|
|
+ .orderByDesc(MainStudent::getCreateTime)
|
|
|
+ );
|
|
|
+ if (CollectionUtils.isEmpty(studentList)) {
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+ List<MainExamSyncEmployeeOptionVo> result = new ArrayList<>();
|
|
|
+ for (MainStudent student : studentList) {
|
|
|
+ MainExamSyncEmployeeOptionVo option = new MainExamSyncEmployeeOptionVo();
|
|
|
+ option.setId(student.getId());
|
|
|
+ option.setName(student.getName());
|
|
|
+ option.setMobile(student.getMobile());
|
|
|
+ option.setStudentNo(student.getStudentNo());
|
|
|
+ result.add(option);
|
|
|
+ }
|
|
|
+ return result.stream()
|
|
|
+ .collect(Collectors.toMap(MainExamSyncEmployeeOptionVo::getId, item -> item, (left, right) -> left))
|
|
|
+ .values()
|
|
|
+ .stream()
|
|
|
+ .sorted(Comparator.comparing(MainExamSyncEmployeeOptionVo::getId).reversed())
|
|
|
+ .toList();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Boolean syncToEmployees(MainExamEvaluationSyncBo bo) {
|
|
|
+ if (bo == null || CollectionUtils.isEmpty(bo.getEvaluationIds()) || CollectionUtils.isEmpty(bo.getStudentIds())) {
|
|
|
+ throw new ServiceException("同步参数不能为空");
|
|
|
+ }
|
|
|
+ String tenantId = getCurrentTenantId();
|
|
|
+ Set<Long> evaluationIds = new HashSet<>(bo.getEvaluationIds());
|
|
|
+ Set<Long> studentIds = new HashSet<>(bo.getStudentIds());
|
|
|
+ List<MainStudent> validStudents = mainStudentMapper.selectList(
|
|
|
+ Wrappers.<MainStudent>lambdaQuery()
|
|
|
+ .eq(MainStudent::getTenantId, tenantId)
|
|
|
+ .eq(MainStudent::getStatus, "0")
|
|
|
+ .in(MainStudent::getId, studentIds)
|
|
|
+ );
|
|
|
+ Set<Long> validStudentIds = validStudents.stream()
|
|
|
+ .map(MainStudent::getId)
|
|
|
+ .filter(ObjectUtil::isNotNull)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+ if (CollectionUtils.isEmpty(validStudentIds)) {
|
|
|
+ throw new ServiceException("未找到可同步的员工");
|
|
|
+ }
|
|
|
+ List<MainExamApply> exists = mainExamApplyMapper.selectList(
|
|
|
+ Wrappers.<MainExamApply>lambdaQuery()
|
|
|
+ .eq(MainExamApply::getTenantId, tenantId)
|
|
|
+ .in(MainExamApply::getEvaluationId, evaluationIds)
|
|
|
+ .in(MainExamApply::getStudentId, validStudentIds)
|
|
|
+ );
|
|
|
+ Set<String> existingKeys = exists.stream()
|
|
|
+ .map(item -> item.getEvaluationId() + "_" + item.getStudentId())
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+ Date now = new Date();
|
|
|
+ List<MainExamApply> addList = new ArrayList<>();
|
|
|
+ for (Long evaluationId : evaluationIds) {
|
|
|
+ for (Long studentId : validStudentIds) {
|
|
|
+ String key = evaluationId + "_" + studentId;
|
|
|
+ if (existingKeys.contains(key)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ MainExamApply apply = new MainExamApply();
|
|
|
+ apply.setEvaluationId(evaluationId);
|
|
|
+ apply.setTenantId(tenantId);
|
|
|
+ apply.setStudentId(studentId);
|
|
|
+ apply.setApplySource("3");
|
|
|
+ apply.setApplyStatus("0");
|
|
|
+ apply.setMaxAttemptCount(1);
|
|
|
+ apply.setScheduleStartTime(now);
|
|
|
+ apply.setDelFlag("0");
|
|
|
+ addList.add(apply);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (MainExamApply apply : addList) {
|
|
|
+ try {
|
|
|
+ mainExamApplyMapper.insert(apply);
|
|
|
+ } catch (DuplicateKeyException e) {
|
|
|
+ MainExamApply existApply = mainExamApplyMapper.selectAnyByUniqueKey(apply.getEvaluationId(), apply.getTenantId(), apply.getStudentId());
|
|
|
+ if (existApply != null && StringUtils.equals(existApply.getDelFlag(), "1")) {
|
|
|
+ mainExamApplyMapper.restoreDeletedApply(existApply.getId());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ log.warn("测评报名已存在,跳过本条: evaluationId={}, studentId={}, tenantId={}", apply.getEvaluationId(), apply.getStudentId(), apply.getTenantId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getCurrentTenantId() {
|
|
|
+ String tenantId = LoginHelper.getTenantId();
|
|
|
+ if (StringUtils.isBlank(tenantId)) {
|
|
|
+ throw new ServiceException("未登录或token已失效");
|
|
|
+ }
|
|
|
+ return tenantId;
|
|
|
+ }
|
|
|
+
|
|
|
private void decodeDetailFieldInBo(MainExamEvaluationBo bo) {
|
|
|
if (StringUtils.isNotBlank(bo.getDetail())) {
|
|
|
try {
|