mitao
1 天以前 a9f2a7f4fac47c7a5b1302db2e0c363a55459f84
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
package com.ruoyi.system.service.impl;
 
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.dto.asset.AssetTypeDTO;
import com.ruoyi.system.mapper.AssetTypeMapper;
import com.ruoyi.system.model.AssetMain;
import com.ruoyi.system.model.AssetType;
import com.ruoyi.system.service.AssetMainService;
import com.ruoyi.system.service.AssetTypeService;
import com.ruoyi.system.vo.asset.AssetTypeTreeVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
 
/**
 * <p>
 * 资产类型表 服务实现类
 * </p>
 *
 * @author WuGuanFengYue
 * @since 2025-09-15
 */
@Service
@RequiredArgsConstructor
public class AssetTypeServiceImpl extends ServiceImpl<AssetTypeMapper, AssetType> implements AssetTypeService {
 
    private final AssetMainService assetMainService;
 
    @Override
    public List<AssetTypeTreeVO> getAssetTypeTree() {
        // 查询所有未删除的资产类型数据
        LambdaQueryWrapper<AssetType> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(AssetType::getLevel)
                .orderByAsc(AssetType::getId);
        
        List<AssetType> allAssetTypes = this.list(queryWrapper);
        
        if (CollUtil.isEmpty(allAssetTypes)) {
            return new ArrayList<>();
        }
        
        // 转换为VO对象
        List<AssetTypeTreeVO> assetTypeVOs = BeanUtil.copyToList(allAssetTypes, AssetTypeTreeVO.class);
        
        // 按父级ID分组
        Map<Integer, List<AssetTypeTreeVO>> parentIdMap = assetTypeVOs.stream()
                .collect(Collectors.groupingBy(AssetTypeTreeVO::getParentId));
        
        // 构建树形结构
        List<AssetTypeTreeVO> rootNodes = parentIdMap.get(0);
        if (CollUtil.isEmpty(rootNodes)) {
            return new ArrayList<>();
        }
        
        // 为每个根节点设置子节点
        for (AssetTypeTreeVO rootNode : rootNodes) {
            List<AssetTypeTreeVO> children = parentIdMap.get(rootNode.getId());
            rootNode.setChildren(children != null ? children : new ArrayList<>());
        }
        
        return rootNodes;
    }
 
    @Override
    public void addAssetType(AssetTypeDTO dto) {
        // 校验资产类型名称是否重复
        LambdaQueryWrapper<AssetType> nameQueryWrapper = new LambdaQueryWrapper<>();
        nameQueryWrapper.eq(AssetType::getTypeName, dto.getTypeName());
        AssetType existingByName = this.getOne(nameQueryWrapper);
        if (Objects.nonNull(existingByName)) {
            throw new ServiceException("资产类型名称已存在");
        }
 
        // 校验资产简写是否重复
        LambdaQueryWrapper<AssetType> codeQueryWrapper = new LambdaQueryWrapper<>();
        codeQueryWrapper.eq(AssetType::getTypeCode, dto.getTypeCode());
        AssetType existingByCode = this.getOne(codeQueryWrapper);
        if (Objects.nonNull(existingByCode)) {
            throw new ServiceException("资产类型简写已存在");
        }
 
        // 创建资产类型对象
        AssetType assetType = new AssetType();
        assetType.setTypeName(dto.getTypeName());
        assetType.setTypeCode(dto.getTypeCode());
        
        // 处理层级逻辑
        if (Objects.isNull(dto.getParentId()) || dto.getParentId().equals(0)) {
            // 添加一级资产类型
            assetType.setParentId(0);
            assetType.setLevel(1);
        } else {
            // 添加二级资产类型,先校验父级是否存在
            AssetType parentAssetType = this.getById(dto.getParentId());
            if (Objects.isNull(parentAssetType)) {
                throw new ServiceException("父级资产类型不存在");
            }
            if (!parentAssetType.getLevel().equals(1)) {
                throw new ServiceException("只能在一级资产类型下添加二级资产类型");
            }
            assetType.setParentId(dto.getParentId());
            assetType.setLevel(2);
        }
 
        // 设置创建信息
        String username = SecurityUtils.getUsername();
        assetType.setCreateBy(username);
        
        // 保存资产类型
        this.save(assetType);
    }
 
    @Override
    public void editAssetType(AssetTypeDTO dto) {
        // 校验资产类型ID是否为空
        if (Objects.isNull(dto.getId())) {
            throw new ServiceException("资产类型ID不能为空");
        }
 
        // 校验资产类型是否存在
        AssetType existingAssetType = this.getById(dto.getId());
        if (Objects.isNull(existingAssetType)) {
            throw new ServiceException("资产类型不存在");
        }
 
        // 校验是否有关联的资产记录
        LambdaQueryWrapper<AssetMain> assetMainQueryWrapper = new LambdaQueryWrapper<>();
        assetMainQueryWrapper.eq(AssetMain::getAssetTypeId, dto.getId());
        long assetMainCount = assetMainService.count(assetMainQueryWrapper);
        if (assetMainCount > 0) {
            throw new ServiceException("该资产类型已关联资产记录,不能编辑");
        }
 
        // 校验资产类型名称是否重复(排除自身)
        LambdaQueryWrapper<AssetType> nameQueryWrapper = new LambdaQueryWrapper<>();
        nameQueryWrapper.eq(AssetType::getTypeName, dto.getTypeName())
                       .ne(AssetType::getId, dto.getId());
        AssetType existingByName = this.getOne(nameQueryWrapper);
        if (Objects.nonNull(existingByName)) {
            throw new ServiceException("资产类型名称已存在");
        }
        
        // 校验资产简写是否重复(排除自身)
        LambdaQueryWrapper<AssetType> codeQueryWrapper = new LambdaQueryWrapper<>();
        codeQueryWrapper.eq(AssetType::getTypeCode, dto.getTypeCode())
                       .ne(AssetType::getId, dto.getId());
        AssetType existingByCode = this.getOne(codeQueryWrapper);
        if (Objects.nonNull(existingByCode)) {
            throw new ServiceException("资产简写已存在");
        }
 
        // 更新资产类型信息
        AssetType assetType = new AssetType();
        assetType.setId(dto.getId());
        assetType.setTypeName(dto.getTypeName());
        assetType.setTypeCode(dto.getTypeCode());
        
        // 设置更新信息
        String username = SecurityUtils.getUsername();
        assetType.setUpdateBy(username);
        
        // 更新资产类型
        this.updateById(assetType);
    }
 
    @Override
    public void deleteAssetType(Integer id) {
        // 校验资产类型ID是否为空
        if (Objects.isNull(id)) {
            throw new ServiceException("资产类型ID不能为空");
        }
 
        // 校验资产类型是否存在
        AssetType existingAssetType = this.getById(id);
        if (Objects.isNull(existingAssetType)) {
            throw new ServiceException("资产类型不存在");
        }
 
        // 校验是否有子类型
        LambdaQueryWrapper<AssetType> childQueryWrapper = new LambdaQueryWrapper<>();
        childQueryWrapper.eq(AssetType::getParentId, id);
        long childCount = this.count(childQueryWrapper);
        if (childCount > 0) {
            throw new ServiceException(String.format("【%s】存在子类型,不能删除", existingAssetType.getTypeName()));
        }
 
        // 校验是否有关联的资产记录
        LambdaQueryWrapper<AssetMain> assetMainQueryWrapper = new LambdaQueryWrapper<>();
        assetMainQueryWrapper.eq(AssetMain::getAssetTypeId, id);
        long assetMainCount = assetMainService.count(assetMainQueryWrapper);
        if (assetMainCount > 0) {
            throw new ServiceException(String.format("【%s】已关联资产记录,不能删除", existingAssetType.getTypeName()));
        }
 
        // 删除资产类型
        this.removeById(id);
    }
 
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDeleteAssetType(List<Integer> ids) {
        // 校验ID列表是否为空
        if (CollUtil.isEmpty(ids)) {
            throw new ServiceException("删除的资产类型ID列表不能为空");
        }
 
        // 收集删除失败的信息
        List<String> failedMessages = new ArrayList<>();
        
        // 逐个删除资产类型
        for (Integer id : ids) {
            try {
                this.deleteAssetType(id);
            } catch (ServiceException e) {
                failedMessages.add(e.getMessage());
            }
        }
        
        // 如果有删除失败的情况,抛出异常
        if (CollUtil.isNotEmpty(failedMessages)) {
            throw new ServiceException("批量删除失败:" + String.join(";", failedMessages));
        }
    }
 
}