package cn.iocoder.yudao.module.mes.service.safety;
|
|
import cn.hutool.core.collection.CollUtil;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.org.SafetyOrgRespVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.org.SafetyOrgSaveReqVO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.safety.SafetyOrgDO;
|
import cn.iocoder.yudao.module.mes.dal.mysql.safety.SafetyOrgMapper;
|
import jakarta.annotation.Resource;
|
import org.springframework.stereotype.Service;
|
import org.springframework.validation.annotation.Validated;
|
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.stream.Collectors;
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.module.mes.enums.SafetyErrorCodeConstants.*;
|
|
/**
|
* 安全生产 - 安全组织架构 Service
|
*
|
* @author 超级管理员
|
*/
|
@Service
|
@Validated
|
public class SafetyOrgService {
|
|
@Resource
|
private SafetyOrgMapper safetyOrgMapper;
|
@Resource
|
private SafetyRefResolver refResolver;
|
|
public Long createOrg(SafetyOrgSaveReqVO reqVO) {
|
reqVO.setId(null);
|
validateParent(reqVO.getParentId(), null);
|
SafetyOrgDO org = BeanUtils.toBean(reqVO, SafetyOrgDO.class);
|
org.setParentId(reqVO.getParentId() == null ? 0L : reqVO.getParentId());
|
applyLeader(org, reqVO.getLeaderId());
|
safetyOrgMapper.insert(org);
|
return org.getId();
|
}
|
|
public void updateOrg(SafetyOrgSaveReqVO reqVO) {
|
validateOrgExists(reqVO.getId());
|
validateParent(reqVO.getParentId(), reqVO.getId());
|
SafetyOrgDO org = BeanUtils.toBean(reqVO, SafetyOrgDO.class);
|
org.setParentId(reqVO.getParentId() == null ? 0L : reqVO.getParentId());
|
applyLeader(org, reqVO.getLeaderId());
|
safetyOrgMapper.updateById(org);
|
}
|
|
/**
|
* 负责人:从员工档案带出姓名与电话并落快照
|
*/
|
private void applyLeader(SafetyOrgDO org, Long leaderId) {
|
org.setLeaderId(leaderId);
|
if (leaderId == null) {
|
org.setLeaderName("");
|
return;
|
}
|
var employee = refResolver.requireEmployee(leaderId, SAFETY_EMPLOYEE_REQUIRED);
|
org.setLeaderName(employee.getName());
|
org.setLeaderPhone(employee.getPhone());
|
}
|
|
public void deleteOrg(Long id) {
|
validateOrgExists(id);
|
if (safetyOrgMapper.selectCountByParentId(id) > 0) {
|
throw exception(SAFETY_ORG_HAS_CHILDREN);
|
}
|
safetyOrgMapper.deleteById(id);
|
}
|
|
public SafetyOrgDO getOrg(Long id) {
|
return validateOrgExists(id);
|
}
|
|
/**
|
* 取负责人最新档案(供单条查询回填用)
|
*/
|
public cn.iocoder.yudao.module.hrm.api.employee.dto.HrmEmployeeSimpleDTO getLeader(Long leaderId) {
|
return refResolver.findEmployee(leaderId);
|
}
|
|
/**
|
* 查询组织树
|
*/
|
public List<SafetyOrgRespVO> getOrgTree() {
|
List<SafetyOrgDO> all = safetyOrgMapper.selectListOrdered();
|
List<SafetyOrgRespVO> nodes = BeanUtils.toBean(all, SafetyOrgRespVO.class);
|
// 负责人用员工档案最新姓名覆盖快照,员工改名/调岗后树也同步
|
var employeeMap = refResolver.employeeMap(
|
all.stream().map(SafetyOrgDO::getLeaderId).toList());
|
nodes.forEach(node -> {
|
var employee = employeeMap.get(node.getLeaderId());
|
if (employee != null) {
|
node.setLeaderName(employee.getName());
|
}
|
});
|
Map<Long, List<SafetyOrgRespVO>> grouped = nodes.stream()
|
.collect(Collectors.groupingBy(SafetyOrgRespVO::getParentId, Collectors.toList()));
|
nodes.forEach(node -> node.setChildren(grouped.getOrDefault(node.getId(), new ArrayList<>())));
|
List<SafetyOrgRespVO> roots = grouped.getOrDefault(0L, new ArrayList<>());
|
if (CollUtil.isEmpty(roots)) {
|
// 兼容 parentId 为空的脏数据
|
roots = nodes.stream().filter(n -> n.getParentId() == null || n.getParentId() == 0L).toList();
|
}
|
return roots;
|
}
|
|
private void validateParent(Long parentId, Long selfId) {
|
if (parentId == null || parentId == 0L) {
|
return;
|
}
|
if (parentId.equals(selfId)) {
|
throw exception(SAFETY_ORG_PARENT_IS_SELF);
|
}
|
SafetyOrgDO parent = safetyOrgMapper.selectById(parentId);
|
if (parent == null) {
|
throw exception(SAFETY_ORG_PARENT_NOT_EXISTS);
|
}
|
// 防止把父节点挂到自己的子孙下,形成环
|
if (selfId != null && isDescendant(parentId, selfId)) {
|
throw exception(SAFETY_ORG_PARENT_IS_CHILD);
|
}
|
}
|
|
private boolean isDescendant(Long candidateId, Long ancestorId) {
|
Long current = candidateId;
|
int guard = 0;
|
while (current != null && current != 0L && guard++ < 100) {
|
if (current.equals(ancestorId)) {
|
return true;
|
}
|
SafetyOrgDO node = safetyOrgMapper.selectById(current);
|
if (node == null) {
|
return false;
|
}
|
current = node.getParentId();
|
}
|
return false;
|
}
|
|
private SafetyOrgDO validateOrgExists(Long id) {
|
if (id == null) {
|
throw exception(SAFETY_ORG_NOT_EXISTS);
|
}
|
SafetyOrgDO org = safetyOrgMapper.selectById(id);
|
if (org == null) {
|
throw exception(SAFETY_ORG_NOT_EXISTS);
|
}
|
return org;
|
}
|
|
}
|