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.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataImportExcelVO; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataImportReqVO; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataImportRespVO; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataSaveReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO; import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictTypeDO; import cn.iocoder.yudao.module.system.dal.mysql.dict.DictDataMapper; import com.google.common.annotations.VisibleForTesting; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; 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 ruoyi */ @Service @Slf4j public class DictDataServiceImpl implements DictDataService { /** * 排序 dictType > sort */ private static final Comparator COMPARATOR_TYPE_AND_SORT = Comparator .comparing(DictDataDO::getDictType) .thenComparingInt(DictDataDO::getSort); @Resource private DictTypeService dictTypeService; @Resource private DictDataMapper dictDataMapper; @Override public List getDictDataList(Integer status, String dictType) { List list = dictDataMapper.selectListByStatusAndDictType(status, dictType); list.sort(COMPARATOR_TYPE_AND_SORT); return list; } @Override public PageResult getDictDataPage(DictDataPageReqVO pageReqVO) { return dictDataMapper.selectPage(pageReqVO); } @Override public DictDataDO getDictData(Long id) { return dictDataMapper.selectById(id); } @Override public Long createDictData(DictDataSaveReqVO createReqVO) { // 校验字典类型有效 validateDictTypeExists(createReqVO.getDictType()); // 校验字典数据的值的唯一性 validateDictDataValueUnique(null, createReqVO.getDictType(), createReqVO.getValue()); // 插入字典类型 DictDataDO dictData = BeanUtils.toBean(createReqVO, DictDataDO.class); dictDataMapper.insert(dictData); return dictData.getId(); } @Override public void updateDictData(DictDataSaveReqVO updateReqVO) { // 校验自己存在 validateDictDataExists(updateReqVO.getId()); // 校验字典类型有效 validateDictTypeExists(updateReqVO.getDictType()); // 校验字典数据的值的唯一性 validateDictDataValueUnique(updateReqVO.getId(), updateReqVO.getDictType(), updateReqVO.getValue()); // 更新字典类型 DictDataDO updateObj = BeanUtils.toBean(updateReqVO, DictDataDO.class); dictDataMapper.updateById(updateObj); } @Override public void deleteDictData(Long id) { // 校验是否存在 validateDictDataExists(id); // 删除字典数据 dictDataMapper.deleteById(id); } @Override public void deleteDictDataList(List ids) { dictDataMapper.deleteByIds(ids); } @Override public long getDictDataCountByDictType(String dictType) { return dictDataMapper.selectCountByDictType(dictType); } @VisibleForTesting public void validateDictDataValueUnique(Long id, String dictType, String value) { DictDataDO dictData = dictDataMapper.selectByDictTypeAndValue(dictType, value); if (dictData == null) { return; } // 如果 id 为空,说明不用比较是否为相同 id 的字典数据 if (id == null) { throw exception(DICT_DATA_VALUE_DUPLICATE); } if (!dictData.getId().equals(id)) { throw exception(DICT_DATA_VALUE_DUPLICATE); } } @VisibleForTesting public void validateDictDataExists(Long id) { if (id == null) { return; } DictDataDO dictData = dictDataMapper.selectById(id); if (dictData == null) { throw exception(DICT_DATA_NOT_EXISTS); } } @VisibleForTesting public void validateDictTypeExists(String type) { DictTypeDO dictType = dictTypeService.getDictType(type); if (dictType == null) { throw exception(DICT_TYPE_NOT_EXISTS); } if (!CommonStatusEnum.ENABLE.getStatus().equals(dictType.getStatus())) { throw exception(DICT_TYPE_NOT_ENABLE); } } @Override public void validateDictDataList(String dictType, Collection values) { if (CollUtil.isEmpty(values)) { return; } Map dictDataMap = CollectionUtils.convertMap( dictDataMapper.selectByDictTypeAndValues(dictType, values), DictDataDO::getValue); // 校验 values.forEach(value -> { DictDataDO dictData = dictDataMap.get(value); if (dictData == null) { throw exception(DICT_DATA_NOT_EXISTS); } if (!CommonStatusEnum.ENABLE.getStatus().equals(dictData.getStatus())) { throw exception(DICT_DATA_NOT_ENABLE, dictData.getLabel()); } }); } @Override public DictDataDO getDictData(String dictType, String value) { return dictDataMapper.selectByDictTypeAndValue(dictType, value); } @Override public DictDataDO parseDictData(String dictType, String label) { return dictDataMapper.selectByDictTypeAndLabel(dictType, label); } @Override public List getDictDataListByDictType(String dictType) { List list = dictDataMapper.selectList(DictDataDO::getDictType, dictType); list.sort(Comparator.comparing(DictDataDO::getSort)); return list; } @Override public DictDataImportRespVO importDictDataList(List importDictDatas, DictDataImportReqVO importReqVO) { importDictDatas = filterList(importDictDatas, item -> StrUtil.isNotBlank(item.getLabel())); if (CollUtil.isEmpty(importDictDatas)) { throw exception(DICT_DATA_IMPORT_LIST_IS_EMPTY); } DictDataImportRespVO respVO = DictDataImportRespVO.builder() .createDictDataNames(new ArrayList<>()) .updateDictDataNames(new ArrayList<>()) .failureDictDataNames(new LinkedHashMap<>()) .build(); importDictDatas.forEach(importDictData -> { try { // 1. 校验字典类型有效 validateDictTypeExists(importDictData.getDictType()); // 2. 判断是否存在(字典类型 + 字典值 唯一) DictDataDO existDictData = dictDataMapper.selectByDictTypeAndValue( importDictData.getDictType(), importDictData.getValue()); if (existDictData == null) { // 2.1 新增 validateDictDataValueUnique(null, importDictData.getDictType(), importDictData.getValue()); DictDataDO dictData = BeanUtils.toBean(importDictData, DictDataDO.class); dictDataMapper.insert(dictData); respVO.getCreateDictDataNames().add(importDictData.getLabel()); return; } // 2.2 已存在,判断是否允许更新 if (!importReqVO.getUpdateSupport()) { respVO.getFailureDictDataNames().put(importDictData.getLabel(), StrUtil.format(DICT_DATA_VALUE_DUPLICATE.getMsg())); return; } DictDataDO updateDictData = BeanUtils.toBean(importDictData, DictDataDO.class) .setId(existDictData.getId()); dictDataMapper.updateById(updateDictData); respVO.getUpdateDictDataNames().add(importDictData.getLabel()); } catch (ServiceException ex) { respVO.getFailureDictDataNames().put(importDictData.getLabel(), ex.getMessage()); } }); return respVO; } }