package cn.iocoder.yudao.module.system.service.dict; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.type.DictTypeImportExcelVO; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.type.DictTypeImportReqVO; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.type.DictTypeImportRespVO; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.type.DictTypePageReqVO; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.type.DictTypeSaveReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictTypeDO; import cn.iocoder.yudao.module.system.dal.mysql.dict.DictTypeMapper; import com.google.common.annotations.VisibleForTesting; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; /** * 字典类型 Service 实现类 * * @author 超级管理员 */ @Service public class DictTypeServiceImpl implements DictTypeService { @Resource private DictDataService dictDataService; @Resource private DictTypeMapper dictTypeMapper; @Override public PageResult getDictTypePage(DictTypePageReqVO pageReqVO) { return dictTypeMapper.selectPage(pageReqVO); } @Override public DictTypeDO getDictType(Long id) { return dictTypeMapper.selectById(id); } @Override public DictTypeDO getDictType(String type) { return dictTypeMapper.selectByType(type); } @Override public Long createDictType(DictTypeSaveReqVO createReqVO) { // 校验字典类型的名字的唯一性 validateDictTypeNameUnique(null, createReqVO.getName()); // 校验字典类型的类型的唯一性 validateDictTypeUnique(null, createReqVO.getType()); // 插入字典类型 DictTypeDO dictType = BeanUtils.toBean(createReqVO, DictTypeDO.class); dictType.setDeletedTime(LocalDateTimeUtils.EMPTY); // 唯一索引,避免 null 值 dictTypeMapper.insert(dictType); return dictType.getId(); } @Override public void updateDictType(DictTypeSaveReqVO updateReqVO) { // 校验自己存在 validateDictTypeExists(updateReqVO.getId()); // 校验字典类型的名字的唯一性 validateDictTypeNameUnique(updateReqVO.getId(), updateReqVO.getName()); // 校验字典类型的类型的唯一性 validateDictTypeUnique(updateReqVO.getId(), updateReqVO.getType()); // 更新字典类型 DictTypeDO updateObj = BeanUtils.toBean(updateReqVO, DictTypeDO.class); dictTypeMapper.updateById(updateObj); } @Override public void deleteDictType(Long id) { // 校验是否存在 DictTypeDO dictType = validateDictTypeExists(id); // 校验是否有字典数据 if (dictDataService.getDictDataCountByDictType(dictType.getType()) > 0) { throw exception(DICT_TYPE_HAS_CHILDREN); } // 删除字典类型 dictTypeMapper.updateToDelete(id, LocalDateTime.now()); } @Override public void deleteDictTypeList(List ids) { // 1. 校验是否有字典数据 List dictTypes = dictTypeMapper.selectByIds(ids); dictTypes.forEach(dictType -> { if (dictDataService.getDictDataCountByDictType(dictType.getType()) > 0) { throw exception(DICT_TYPE_HAS_CHILDREN); } }); // 2. 批量删除字典类型 LocalDateTime now = LocalDateTime.now(); ids.forEach(id -> dictTypeMapper.updateToDelete(id, now)); } @Override public List getDictTypeList() { return dictTypeMapper.selectList(); } @Override public DictTypeImportRespVO importDictTypeList(List importDictTypes, DictTypeImportReqVO importReqVO) { importDictTypes = filterList(importDictTypes, item -> StrUtil.isNotBlank(item.getType())); if (CollUtil.isEmpty(importDictTypes)) { throw exception(DICT_TYPE_IMPORT_LIST_IS_EMPTY); } DictTypeImportRespVO respVO = DictTypeImportRespVO.builder() .createDictTypeNames(new ArrayList<>()) .updateDictTypeNames(new ArrayList<>()) .failureDictTypeNames(new LinkedHashMap<>()) .build(); importDictTypes.forEach(importDictType -> { try { // 1. 判断是否存在(优先按字典类型编码,其次按名称) DictTypeDO existDictType = dictTypeMapper.selectByType(importDictType.getType()); if (existDictType == null && StrUtil.isNotBlank(importDictType.getName())) { existDictType = dictTypeMapper.selectByName(importDictType.getName()); } if (existDictType == null) { // 2.1 新增 validateDictTypeNameUnique(null, importDictType.getName()); validateDictTypeUnique(null, importDictType.getType()); DictTypeDO dictType = BeanUtils.toBean(importDictType, DictTypeDO.class); dictType.setDeletedTime(LocalDateTimeUtils.EMPTY); // 唯一索引,避免 null 值 dictTypeMapper.insert(dictType); respVO.getCreateDictTypeNames().add(importDictType.getType()); return; } // 2.2 已存在,判断是否允许更新 if (!importReqVO.getUpdateSupport()) { respVO.getFailureDictTypeNames().put(importDictType.getType(), StrUtil.format(DICT_TYPE_TYPE_DUPLICATE.getMsg(), importDictType.getType())); return; } DictTypeDO updateDictType = BeanUtils.toBean(importDictType, DictTypeDO.class) .setId(existDictType.getId()); dictTypeMapper.updateById(updateDictType); respVO.getUpdateDictTypeNames().add(importDictType.getType()); } catch (ServiceException ex) { respVO.getFailureDictTypeNames().put(importDictType.getType(), ex.getMessage()); } }); return respVO; } @VisibleForTesting void validateDictTypeNameUnique(Long id, String name) { DictTypeDO dictType = dictTypeMapper.selectByName(name); if (dictType == null) { return; } // 如果 id 为空,说明不用比较是否为相同 id 的字典类型 if (id == null) { throw exception(DICT_TYPE_NAME_DUPLICATE); } if (!dictType.getId().equals(id)) { throw exception(DICT_TYPE_NAME_DUPLICATE); } } @VisibleForTesting void validateDictTypeUnique(Long id, String type) { if (StrUtil.isEmpty(type)) { return; } DictTypeDO dictType = dictTypeMapper.selectByType(type); if (dictType == null) { return; } // 如果 id 为空,说明不用比较是否为相同 id 的字典类型 if (id == null) { throw exception(DICT_TYPE_TYPE_DUPLICATE); } if (!dictType.getId().equals(id)) { throw exception(DICT_TYPE_TYPE_DUPLICATE); } } @VisibleForTesting DictTypeDO validateDictTypeExists(Long id) { if (id == null) { return null; } DictTypeDO dictType = dictTypeMapper.selectById(id); if (dictType == null) { throw exception(DICT_TYPE_NOT_EXISTS); } return dictType; } }