Compare commits

..

2 Commits

Author SHA1 Message Date
shenzhidan 42d2a4efb5 Merge branch 'dev' of http://47.92.113.182:3000/zcloud_gbs/zcloud_gbs_edu into dev 2026-02-25 14:48:41 +08:00
shenzhidan e40233c426 1、修改申请培训时同步增加培训人员
2、修改审批时同步修改培训人员的审批状态
2026-02-25 14:48:18 +08:00
6 changed files with 137 additions and 49 deletions

View File

@ -5,6 +5,7 @@ import com.jjb.saas.framework.auth.utils.AuthContext;
import com.zcloud.edu.domain.gateway.training.TrainingApplyProcessGateway; import com.zcloud.edu.domain.gateway.training.TrainingApplyProcessGateway;
import com.zcloud.edu.domain.gateway.training.TrainingApplyRecordGateway; import com.zcloud.edu.domain.gateway.training.TrainingApplyRecordGateway;
import com.zcloud.edu.domain.gateway.training.TrainingApplyUserGateway; import com.zcloud.edu.domain.gateway.training.TrainingApplyUserGateway;
import com.zcloud.edu.domain.gateway.training.TrainingUserGateway;
import com.zcloud.edu.domain.model.training.TrainingApplyRecordE; import com.zcloud.edu.domain.model.training.TrainingApplyRecordE;
import com.zcloud.edu.domain.model.training.TrainingApplyUserE; import com.zcloud.edu.domain.model.training.TrainingApplyUserE;
import com.zcloud.edu.dto.training.TrainingApplyRecordAddCmd; import com.zcloud.edu.dto.training.TrainingApplyRecordAddCmd;
@ -32,6 +33,7 @@ public class TrainingApplyRecordAddExe {
private final TrainingApplyUserGateway trainingApplyUserGateway; private final TrainingApplyUserGateway trainingApplyUserGateway;
private final TrainingApplyProcessGateway trainingApplyProcessGateway; private final TrainingApplyProcessGateway trainingApplyProcessGateway;
private final TrainingUserGateway trainingUserGateway;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public String execute(TrainingApplyRecordAddCmd cmd) { public String execute(TrainingApplyRecordAddCmd cmd) {
@ -52,6 +54,14 @@ public class TrainingApplyRecordAddExe {
} }
} }
// 保存培训人员
if (!CollectionUtils.isEmpty(record.getTrainingUsers())) {
boolean trainingUserResult = trainingUserGateway.addBatch(record.getTrainingUsers());
if (!trainingUserResult) {
throw new BizException("培训人员保存失败");
}
}
// 保存流程记录 // 保存流程记录
if (!CollectionUtils.isEmpty(record.getProcesses())) { if (!CollectionUtils.isEmpty(record.getProcesses())) {
boolean processResult = trainingApplyProcessGateway.addBatch(record.getProcesses()); boolean processResult = trainingApplyProcessGateway.addBatch(record.getProcesses());

View File

@ -1,24 +1,16 @@
package com.zcloud.edu.command.training; package com.zcloud.edu.command.training;
import com.alibaba.cola.exception.BizException; import com.alibaba.cola.exception.BizException;
import com.jjb.saas.framework.auth.model.SSOUser;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.zcloud.edu.domain.gateway.training.TrainingApplyProcessGateway;
import com.zcloud.edu.domain.gateway.training.TrainingApplyRecordGateway; import com.zcloud.edu.domain.gateway.training.TrainingApplyRecordGateway;
import com.zcloud.edu.domain.gateway.training.TrainingApplyUserGateway; import com.zcloud.edu.domain.gateway.training.TrainingApplyUserGateway;
import com.zcloud.edu.domain.gateway.training.TrainingUserGateway; import com.zcloud.edu.domain.gateway.training.TrainingUserGateway;
import com.zcloud.edu.domain.model.training.TrainingApplyRecordE; import com.zcloud.edu.domain.model.training.TrainingApplyRecordE;
import com.zcloud.edu.dto.training.TrainingApplyRecordUpdateCmd; import com.zcloud.edu.dto.training.TrainingApplyRecordUpdateCmd;
import com.zcloud.edu.persistence.dataobject.TrainingApplyRecordDO;
import com.zcloud.edu.persistence.repository.training.TrainingUserRepository;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* web-app * web-app
* @Author makejava * @Author makejava
@ -41,7 +33,6 @@ public class TrainingApplyRecordUpdateExe {
} }
} }
/** /**
* *
*/ */
@ -52,18 +43,21 @@ public class TrainingApplyRecordUpdateExe {
BeanUtils.copyProperties(trainingApplyRecordUpdateCmd, trainingApplyRecordE); BeanUtils.copyProperties(trainingApplyRecordUpdateCmd, trainingApplyRecordE);
trainingApplyRecordE.approve(oldTrainingRecord.getApprovalStatus()); trainingApplyRecordE.approve(oldTrainingRecord.getApprovalStatus());
trainingApplyRecordE.addTrainingUser(); trainingApplyRecordE.addTrainingUser();
// 修改申请人员状态
boolean updateUserStatus = trainingApplyUserGateway.updateStatusByApprove(trainingApplyRecordE.getApplyUsers()); boolean updateUserStatus = trainingApplyUserGateway.updateStatusByApprove(trainingApplyRecordE.getApplyUsers());
if (!updateUserStatus) { if (!updateUserStatus) {
throw new BizException("修改申请人员状态失败"); throw new BizException("修改申请人员状态失败");
} }
boolean addTrainingUser = trainingUserGateway.addBatch(trainingApplyRecordE.getTrainingUsers()); // 修改培训人员状态
if (!addTrainingUser) { boolean updateTrainingUserStatus = trainingUserGateway.updateStatusByApprove(trainingApplyRecordE.getTrainingUsers());
throw new BizException("新增培训人员失败"); if (!updateTrainingUserStatus) {
throw new BizException("修改培训人员状态失败");
} }
boolean res = trainingApplyRecordGateway.update(trainingApplyRecordE); boolean res = trainingApplyRecordGateway.update(trainingApplyRecordE);
if (!res) { if (!res) {
throw new BizException("修改失败"); throw new BizException("修改失败");
} }
} }
} }

View File

@ -12,13 +12,18 @@ public interface TrainingUserGateway {
/** /**
* *
*/ */
Boolean add(TrainingUserE trainingUserE) ; Boolean add(TrainingUserE trainingUserE);
/** /**
* *
*/ */
Boolean addBatch(java.util.List<TrainingUserE> trainingUserEList); Boolean addBatch(java.util.List<TrainingUserE> trainingUserEList);
/**
*
*/
Boolean updateStatusByApprove(java.util.List<TrainingUserE> trainingUserEList);
/** /**
* *
*/ */
@ -30,4 +35,3 @@ public interface TrainingUserGateway {
Boolean deletedTrainingUserById(Long id); Boolean deletedTrainingUserById(Long id);
Boolean deletedTrainingUserByIds(Long[] id); Boolean deletedTrainingUserByIds(Long[] id);
} }

View File

@ -8,14 +8,14 @@ import com.jjb.saas.framework.domain.model.BaseE;
import com.zcloud.edu.domain.enums.ApplyStatusEnum; import com.zcloud.edu.domain.enums.ApplyStatusEnum;
import com.zcloud.edu.domain.enums.ApplyTypeEnum; import com.zcloud.edu.domain.enums.ApplyTypeEnum;
import com.zcloud.edu.domain.enums.ApprovalStatusEnum; import com.zcloud.edu.domain.enums.ApprovalStatusEnum;
import com.zcloud.edu.domain.enums.ExamineStatusEnum; import com.zcloud.gbscommon.utils.Tools;
import lombok.Data; import lombok.Data;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Set;
import java.util.stream.Collectors;
/** /**
* web-domain * web-domain
@ -48,24 +48,24 @@ public class TrainingApplyRecordE extends BaseE {
private Long approvalUserId; private Long approvalUserId;
//审批用户名称 //审批用户名称
private String approvalUserName; private String approvalUserName;
// 关联项目 //关联项目
private String projectName; private String projectName;
//审批状态1:待审批2:审批中,3:审批完成 //审批状态:1待审批,2审批中,3审批完成
private Long approvalStatus; private Long approvalStatus;
// 申请人员列表 //申请人员列表
private List<TrainingApplyUserE> applyUsers = new ArrayList<>(); private List<TrainingApplyUserE> applyUsers = new ArrayList<>();
// 审批流程列表 //审批流程列表
private List<TrainingApplyProcessE> processes = new ArrayList<>(); private List<TrainingApplyProcessE> processes = new ArrayList<>();
// 审批人员列表 //审批人员列表
private List<TrainingApplyUserE> approvalUsers; private List<TrainingApplyUserE> approvalUsers;
// 审批和委托信息 //审批和委托信息
private List<ApproveDetailE> approveDetails; private List<ApproveDetailE> approveDetails;
// 培训人员 //培训人员
private List<TrainingUserE> trainingUsers = new ArrayList<>(); private List<TrainingUserE> trainingUsers = new ArrayList<>();
/** /**
@ -76,19 +76,31 @@ public class TrainingApplyRecordE extends BaseE {
this.applyUserId = ssoUser.getUserId(); this.applyUserId = ssoUser.getUserId();
this.applyDepartmentId = ssoUser.getOrgId(); this.applyDepartmentId = ssoUser.getOrgId();
this.applyCorpinfoId = ssoUser.getTenantId(); this.applyCorpinfoId = ssoUser.getTenantId();
}else { } else {
throw new BizException("参数异常"); throw new BizException("参数异常");
} }
this.trainingApplyRecordId = StrUtil.isNotBlank(this.trainingApplyRecordId) ? this.trainingApplyRecordId : IdUtil.simpleUUID(); this.trainingApplyRecordId = StrUtil.isNotBlank(this.trainingApplyRecordId)
? this.trainingApplyRecordId : IdUtil.simpleUUID();
this.approvalStatus = ApprovalStatusEnum.PENDING.getCode(); this.approvalStatus = ApprovalStatusEnum.PENDING.getCode();
// 初始化申请人员 // 初始化申请人员
if (!CollectionUtils.isEmpty(this.applyUsers)) { if (!CollectionUtils.isEmpty(this.applyUsers)) {
Set<String> trainingUserPhones = new HashSet<>();
this.applyUsers.forEach(user -> { this.applyUsers.forEach(user -> {
user.setTrainingApplyUserId(StrUtil.isBlank(user.getTrainingApplyUserId()) ? IdUtil.simpleUUID() : user.getTrainingApplyUserId()); user.setTrainingApplyUserId(
StrUtil.isBlank(user.getTrainingApplyUserId()) ? IdUtil.simpleUUID() : user.getTrainingApplyUserId());
user.setTrainingApplyRecordId(this.trainingApplyRecordId); user.setTrainingApplyRecordId(this.trainingApplyRecordId);
user.setApplyStatus(ApplyStatusEnum.PENDING.getCode()); user.setApplyStatus(ApplyStatusEnum.PENDING.getCode());
String phone = user.getPhone();
if (StrUtil.isNotBlank(phone) && trainingUserPhones.add(phone)) {
TrainingUserE trainingUser = new TrainingUserE();
trainingUser.setTrainingUserId(Tools.get32UUID());
trainingUser.setPhone(phone);
trainingUser.setApplyStatus(ApplyStatusEnum.PENDING.getCode());
trainingUsers.add(trainingUser);
}
}); });
} }
@ -117,7 +129,7 @@ public class TrainingApplyRecordE extends BaseE {
/** /**
* *
*/ */
public void approve(Long approvalStatus){ public void approve(Long approvalStatus) {
// 状态校验 // 状态校验
if (!ApprovalStatusEnum.PENDING.getCode().equals(approvalStatus) if (!ApprovalStatusEnum.PENDING.getCode().equals(approvalStatus)
&& !ApprovalStatusEnum.APPROVING.getCode().equals(approvalStatus)) { && !ApprovalStatusEnum.APPROVING.getCode().equals(approvalStatus)) {
@ -127,23 +139,26 @@ public class TrainingApplyRecordE extends BaseE {
if (CollectionUtils.isEmpty(this.applyUsers)) { if (CollectionUtils.isEmpty(this.applyUsers)) {
throw new BizException("申请人员列表不能为空"); throw new BizException("申请人员列表不能为空");
} }
} }
/** /**
* *
*/ */
public void addTrainingUser() { public void addTrainingUser() {
if (this.applyUsers == null) return; if (this.applyUsers == null) {
return;
}
applyUsers.forEach(user -> { applyUsers.forEach(user -> {
if (user != null && user.getApplyStatus().equals(ApplyStatusEnum.APPROVED.getCode())) { if (user != null && user.getApplyStatus().equals(ApplyStatusEnum.APPROVED.getCode())) {
TrainingUserE trainingUser = new TrainingUserE(); TrainingUserE trainingUser = new TrainingUserE();
trainingUser.setTrainingUserId(IdUtil.simpleUUID()); trainingUser.setTrainingUserId(IdUtil.simpleUUID());
trainingUser.setPhone(user.getPhone()); trainingUser.setPhone(user.getPhone());
trainingUser.setApplyStatus(user.getApplyStatus());
this.trainingUsers.add(trainingUser); this.trainingUsers.add(trainingUser);
} }
}); });
} }
/** /**
* *
*/ */
@ -161,7 +176,4 @@ public class TrainingApplyRecordE extends BaseE {
this.approveDetails = approveDetails; this.approveDetails = approveDetails;
} }
} }
}
}

View File

@ -1,6 +1,8 @@
package com.zcloud.edu.gatewayimpl.training; package com.zcloud.edu.gatewayimpl.training;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.zcloud.edu.domain.enums.ApplyStatusEnum;
import com.zcloud.edu.domain.gateway.training.TrainingUserGateway; import com.zcloud.edu.domain.gateway.training.TrainingUserGateway;
import com.zcloud.edu.domain.model.training.TrainingUserE; import com.zcloud.edu.domain.model.training.TrainingUserE;
import com.zcloud.edu.persistence.dataobject.TrainingUserDO; import com.zcloud.edu.persistence.dataobject.TrainingUserDO;
@ -10,9 +12,8 @@ import com.zcloud.gbscommon.utils.Tools;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Arrays; import java.util.*;
import java.util.List; import java.time.LocalDateTime;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -36,22 +37,41 @@ public class TrainingUserGatewayImpl implements TrainingUserGateway {
@Override @Override
public Boolean addBatch(List<TrainingUserE> trainingUserEList) { public Boolean addBatch(List<TrainingUserE> trainingUserEList) {
if (trainingUserEList == null || trainingUserEList.isEmpty()) { List<String> phones = getPhoneList(trainingUserEList);
if (phones.isEmpty()) {
return true; return true;
} }
List<String> phones = trainingUserEList.stream()
.map(TrainingUserE::getPhone)
.filter(StrUtil::isNotBlank)
.distinct()
.collect(Collectors.toList());
List<TrainingUserDO> existingUsers = trainingUserRepository.lambdaQuery() List<TrainingUserDO> existingUsers = trainingUserRepository.lambdaQuery()
.select(TrainingUserDO::getPhone) .select(TrainingUserDO::getPhone, TrainingUserDO::getStartTime, TrainingUserDO::getEndTime)
.in(TrainingUserDO::getPhone, phones) .in(TrainingUserDO::getPhone, phones)
.list(); .list();
Set<String> existingPhones = existingUsers.stream() Map<String, TrainingUserDO> existingUserMap = existingUsers.stream()
.map(TrainingUserDO::getPhone) .collect(Collectors.toMap(TrainingUserDO::getPhone, u -> u, (a, b) -> a));
Set<String> existingPhones = existingUserMap.keySet();
LocalDateTime submitTime = LocalDateTime.now();
Set<String> resetPhones = trainingUserEList.stream()
.map(TrainingUserE::getPhone)
.filter(StrUtil::isNotBlank)
.filter(existingPhones::contains)
.filter(phone -> {
TrainingUserDO user = existingUserMap.get(phone);
return user != null
&& user.getEndTime() != null
&& submitTime.isAfter(user.getEndTime());
})
.collect(Collectors.toSet()); .collect(Collectors.toSet());
for (String phone : resetPhones) {
trainingUserRepository.lambdaUpdate()
.set(TrainingUserDO::getStartTime, null)
.set(TrainingUserDO::getEndTime, null)
.set(TrainingUserDO::getApplyStatus, ApplyStatusEnum.PENDING.getCode())
.eq(TrainingUserDO::getPhone, phone)
.update();
}
List<TrainingUserDO> doList = trainingUserEList.stream() List<TrainingUserDO> doList = trainingUserEList.stream()
.filter(e -> StrUtil.isNotBlank(e.getPhone()) .filter(e -> StrUtil.isNotBlank(e.getPhone())
&& !existingPhones.contains(e.getPhone())) && !existingPhones.contains(e.getPhone()))
@ -69,6 +89,54 @@ public class TrainingUserGatewayImpl implements TrainingUserGateway {
return true; return true;
} }
@Override
public Boolean updateStatusByApprove(List<TrainingUserE> trainingUserEList) {
List<String> phones = getPhoneList(trainingUserEList);
if (phones.isEmpty()) {
return true;
}
List<TrainingUserDO> existingUsers = trainingUserRepository.lambdaQuery()
.select(TrainingUserDO::getId, TrainingUserDO::getPhone, TrainingUserDO::getApplyStatus)
.in(TrainingUserDO::getPhone, phones)
.list();
if (existingUsers == null || existingUsers.isEmpty()) {
return true;
}
List<TrainingUserDO> needUpdateUsers = existingUsers.stream()
.filter(u -> !ApplyStatusEnum.APPROVED.getCode().equals(u.getApplyStatus()))
.map(u -> {
TrainingUserDO d = new TrainingUserDO();
d.setId(u.getId());
d.setApplyStatus(ApplyStatusEnum.APPROVED.getCode());
return d;
})
.collect(Collectors.toList());
if (needUpdateUsers.isEmpty()) {
return true;
}
return trainingUserRepository.updateBatchById(needUpdateUsers);
}
/**
*
* @param trainingUserEList
* @return
*/
private List<String> getPhoneList(List<TrainingUserE> trainingUserEList) {
if (CollUtil.isEmpty(trainingUserEList)) {
return Collections.emptyList();
}
return trainingUserEList.stream()
.map(TrainingUserE::getPhone)
.filter(StrUtil::isNotBlank)
.distinct()
.collect(Collectors.toList());
}
@Override @Override
public Boolean update(TrainingUserE trainingUserE) { public Boolean update(TrainingUserE trainingUserE) {
TrainingUserDO d = new TrainingUserDO(); TrainingUserDO d = new TrainingUserDO();

View File

@ -48,7 +48,7 @@
r.project_name, r.project_name,
r.approval_status, r.approval_status,
r.version, r.version,
u.username AS apply_user_name, u.name AS apply_user_name,
COALESCE(tau_cnt.apply_user_count, 0) AS apply_user_count COALESCE(tau_cnt.apply_user_count, 0) AS apply_user_count
FROM FROM
training_apply_record r training_apply_record r