2026-06-29 940c8481d2fdcf51341db4ccd6fd6fcc2d43debb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
package cn.iocoder.yudao.module.mes.service.dv.machinery;
 
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.type.MesDvMachineryTypeListReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.type.MesDvMachineryTypeSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryTypeDO;
import cn.iocoder.yudao.module.mes.dal.mysql.dv.machinery.MesDvMachineryTypeMapper;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
 
import java.util.*;
 
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
 
/**
 * MES 设备类型 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class MesDvMachineryTypeServiceImpl implements MesDvMachineryTypeService {
 
    @Resource
    private MesDvMachineryTypeMapper machineryTypeMapper;
 
    @Resource
    @Lazy // 延迟加载,避免循环依赖
    private MesDvMachineryService machineryService;
 
    @Override
    public Long createMachineryType(MesDvMachineryTypeSaveReqVO createReqVO) {
        // 校验
        validateMachineryTypeSaveData(createReqVO);
 
        // 插入
        MesDvMachineryTypeDO machineryType = BeanUtils.toBean(createReqVO, MesDvMachineryTypeDO.class);
        machineryTypeMapper.insert(machineryType);
        return machineryType.getId();
    }
 
    @Override
    public void updateMachineryType(MesDvMachineryTypeSaveReqVO updateReqVO) {
        // 校验
        validateMachineryTypeSaveData(updateReqVO);
 
        // 更新
        MesDvMachineryTypeDO updateObj = BeanUtils.toBean(updateReqVO, MesDvMachineryTypeDO.class);
        machineryTypeMapper.updateById(updateObj);
    }
 
    @Override
    public void deleteMachineryType(Long id) {
        // 1.1 校验存在
        validateMachineryTypeExists(id);
        // 1.2 校验是否有子类型
        if (machineryTypeMapper.selectCountByParentId(id) > 0) {
            throw exception(DV_MACHINERY_TYPE_EXITS_CHILDREN);
        }
        // 1.3 校验是否有设备
        if (machineryService.getMachineryCountByMachineryTypeId(id) > 0) {
            throw exception(DV_MACHINERY_TYPE_HAS_MACHINERY);
        }
 
        // 2. 删除
        machineryTypeMapper.deleteById(id);
    }
 
    private void validateMachineryTypeSaveData(MesDvMachineryTypeSaveReqVO saveReqVO) {
        if (saveReqVO.getId() != null) {
            validateMachineryTypeExists(saveReqVO.getId());
        }
        // 校验父级节点有效性
        validateParentMachineryType(saveReqVO.getId(), saveReqVO.getParentId());
        // 校验类型名称唯一性
        validateMachineryTypeNameUnique(saveReqVO.getId(), saveReqVO.getParentId(), saveReqVO.getName());
        // 校验类型编码唯一性
        validateMachineryTypeCodeUnique(saveReqVO.getId(), saveReqVO.getParentId(), saveReqVO.getCode());
    }
 
    private void validateMachineryTypeExists(Long id) {
        if (machineryTypeMapper.selectById(id) == null) {
            throw exception(DV_MACHINERY_TYPE_NOT_EXISTS);
        }
    }
 
    private void validateParentMachineryType(Long id, Long parentId) {
        if (parentId == null || MesDvMachineryTypeDO.PARENT_ID_ROOT.equals(parentId)) {
            return;
        }
        // 1. 不能设置自己为父类型
        if (Objects.equals(id, parentId)) {
            throw exception(DV_MACHINERY_TYPE_PARENT_ERROR);
        }
        // 2. 父类型不存在
        MesDvMachineryTypeDO parentType = machineryTypeMapper.selectById(parentId);
        if (parentType == null) {
            throw exception(DV_MACHINERY_TYPE_PARENT_NOT_EXITS);
        }
        // 3. 递归校验父类型,如果父类型是自己的子类型,则报错,避免形成环路
        if (id == null) { // id 为空,说明新增,不需要考虑环路
            return;
        }
        for (int i = 0; i < Short.MAX_VALUE; i++) {
            // 3.1 校验环路
            parentId = parentType.getParentId();
            if (Objects.equals(id, parentId)) {
                throw exception(DV_MACHINERY_TYPE_PARENT_IS_CHILD);
            }
            // 3.2 继续递归下一级父类型
            if (parentId == null || MesDvMachineryTypeDO.PARENT_ID_ROOT.equals(parentId)) {
                break;
            }
            parentType = machineryTypeMapper.selectById(parentId);
            if (parentType == null) {
                break;
            }
        }
    }
 
    private void validateMachineryTypeNameUnique(Long id, Long parentId, String name) {
        MesDvMachineryTypeDO machineryType = machineryTypeMapper.selectByParentIdAndName(parentId, name);
        if (machineryType == null) {
            return;
        }
        if (ObjUtil.notEqual(machineryType.getId(), id)) {
            throw exception(DV_MACHINERY_TYPE_NAME_DUPLICATE);
        }
    }
 
    private void validateMachineryTypeCodeUnique(Long id, Long parentId, String code) {
        MesDvMachineryTypeDO machineryType = machineryTypeMapper.selectByCode(code);
        if (machineryType == null) {
            return;
        }
        if (ObjUtil.notEqual(machineryType.getId(), id)) {
            throw exception(DV_MACHINERY_TYPE_CODE_DUPLICATE);
        }
    }
 
    @Override
    public MesDvMachineryTypeDO getMachineryType(Long id) {
        return machineryTypeMapper.selectById(id);
    }
 
    @Override
    public List<MesDvMachineryTypeDO> getMachineryTypeList(MesDvMachineryTypeListReqVO listReqVO) {
        return machineryTypeMapper.selectList(listReqVO);
    }
 
    @Override
    public List<MesDvMachineryTypeDO> getMachineryTypeList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return machineryTypeMapper.selectByIds(ids);
    }
 
    @Override
    public List<MesDvMachineryTypeDO> getMachineryTypeChildrenList(Long parentId) {
        List<MesDvMachineryTypeDO> allList = machineryTypeMapper.selectList(); // 类型总量小,全量查
        // 1. 构建 parentId -> children 的 Map(类似 menu 的 treeNodeMap 思路)
        Map<Long, List<MesDvMachineryTypeDO>> parentChildrenMap = new LinkedHashMap<>();
        allList.forEach(type -> parentChildrenMap
                .computeIfAbsent(type.getParentId(), k -> new ArrayList<>()).add(type));
        // 2. 收集所有后代节点
        List<MesDvMachineryTypeDO> result = new ArrayList<>();
        List<Long> parentIds = new ArrayList<>();
        parentIds.add(parentId);
        for (int i = 0; i < Short.MAX_VALUE; i++) {
            if (i >= parentIds.size()) {
                break;
            }
            List<MesDvMachineryTypeDO> children = parentChildrenMap.get(parentIds.get(i));
            if (children == null) {
                continue;
            }
            for (MesDvMachineryTypeDO child : children) {
                result.add(child);
                parentIds.add(child.getId());
            }
        }
        return result;
    }
 
}