package xiaozhi.modules.sys.service.impl; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import cn.hutool.core.collection.CollUtil; import lombok.AllArgsConstructor; import xiaozhi.common.exception.RenException; import xiaozhi.common.exception.ErrorCode; import xiaozhi.common.page.PageData; import xiaozhi.common.redis.RedisKeys; import xiaozhi.common.redis.RedisUtils; import xiaozhi.common.service.impl.BaseServiceImpl; import xiaozhi.common.utils.ConvertUtils; import xiaozhi.common.utils.JsonUtils; import xiaozhi.modules.sys.dao.SysDictDataDao; import xiaozhi.modules.sys.dao.SysUserDao; import xiaozhi.modules.sys.dto.SysDictDataDTO; import xiaozhi.modules.sys.entity.SysDictDataEntity; import xiaozhi.modules.sys.entity.SysUserEntity; import xiaozhi.modules.sys.service.SysDictDataService; import xiaozhi.modules.sys.vo.SysDictDataItem; import xiaozhi.modules.sys.vo.SysDictDataVO; /** * 字典类型 */ @Service @AllArgsConstructor public class SysDictDataServiceImpl extends BaseServiceImpl implements SysDictDataService { private final SysUserDao sysUserDao; private final RedisUtils redisUtils; @Override public PageData page(Map params) { IPage page = baseDao.selectPage(getPage(params, "sort", true), getWrapper(params)); PageData pageData = getPageData(page, SysDictDataVO.class); setUserName(pageData.getList()); return pageData; } private QueryWrapper getWrapper(Map params) { String dictTypeId = (String) params.get("dictTypeId"); String dictLabel = (String) params.get("dictLabel"); String dictValue = (String) params.get("dictValue"); QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("dict_type_id", Long.parseLong(dictTypeId)); wrapper.like(StringUtils.isNotBlank(dictLabel), "dict_label", dictLabel); wrapper.like(StringUtils.isNotBlank(dictValue), "dict_value", dictValue); return wrapper; } @Override public SysDictDataVO get(Long id) { SysDictDataEntity entity = baseDao.selectById(id); return ConvertUtils.sourceToTarget(entity, SysDictDataVO.class); } @Override @Transactional(rollbackFor = Exception.class) public void save(SysDictDataDTO dto) { // 相同字典类型的标签不能相同 checkDictValueUnique(dto.getDictTypeId(), dto.getDictValue(), null); SysDictDataEntity entity = ConvertUtils.sourceToTarget(dto, SysDictDataEntity.class); insert(entity); // 删除Redis缓存 String dictType = baseDao.getTypeByTypeId(dto.getDictTypeId()); redisUtils.delete(RedisKeys.getDictDataByTypeKey(dictType)); } @Override @Transactional(rollbackFor = Exception.class) public void update(SysDictDataDTO dto) { // 相同字典类型的标签不能相同 checkDictValueUnique(dto.getDictTypeId(), dto.getDictValue(), String.valueOf(dto.getId())); SysDictDataEntity entity = ConvertUtils.sourceToTarget(dto, SysDictDataEntity.class); updateById(entity); // 删除Redis缓存 String dictType = baseDao.getTypeByTypeId(dto.getDictTypeId()); redisUtils.delete(RedisKeys.getDictDataByTypeKey(dictType)); } @Override @Transactional(rollbackFor = Exception.class) public void delete(Long[] ids) { List idList = Arrays.asList(ids); if (CollUtil.isNotEmpty(idList)) { //批量删除redis字典 List redisKeyList = new ArrayList<>(); //批量获取字典类型 List dictTypeList = Optional.ofNullable(baseDao.getDictTypesByIdList(idList)).orElseGet(ArrayList::new); dictTypeList.forEach(dictType -> redisKeyList.add(RedisKeys.getDictDataByTypeKey(dictType))); if (CollUtil.isNotEmpty(redisKeyList)) { //清除缓存 redisUtils.delete(redisKeyList); } //批量删除字典数据 deleteBatchIds(Arrays.asList(ids)); } } @Override @Transactional(rollbackFor = Exception.class) public void deleteByTypeId(Long dictTypeId) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(SysDictDataEntity::getDictTypeId, dictTypeId); baseDao.delete(wrapper); } /** * 设置用户名 * * @param sysDictDataList 字典类型集合 */ private void setUserName(List sysDictDataList) { // 收集所有用户 ID Set userIds = sysDictDataList.stream().flatMap(vo -> Stream.of(vo.getCreator(), vo.getUpdater())) .filter(Objects::nonNull).collect(Collectors.toSet()); // 设置更新者和创建者名称 if (!userIds.isEmpty()) { List sysUserEntities = sysUserDao.selectByIds(userIds); // 把List转成Map,Map Map userNameMap = sysUserEntities.stream().collect(Collectors.toMap(SysUserEntity::getId, SysUserEntity::getUsername, (existing, replacement) -> existing)); sysDictDataList.forEach(vo -> { vo.setCreatorName(userNameMap.get(vo.getCreator())); vo.setUpdaterName(userNameMap.get(vo.getUpdater())); }); } } private void checkDictValueUnique(Long dictTypeId, String dictValue, String excludeId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(SysDictDataEntity::getDictTypeId, dictTypeId).eq(SysDictDataEntity::getDictLabel, dictValue); if (StringUtils.isNotBlank(excludeId)) { queryWrapper.ne(SysDictDataEntity::getId, excludeId); } boolean exists = baseDao.exists(queryWrapper); if (exists) { throw new RenException(ErrorCode.DICT_LABEL_DUPLICATE); } } @Override public List getDictDataByType(String dictType) { if (StringUtils.isBlank(dictType)) { return null; } // 先从Redis获取缓存 String key = RedisKeys.getDictDataByTypeKey(dictType); List cachedData = JsonUtils.toList(redisUtils.get(key), SysDictDataItem.class); if (cachedData != null) { return cachedData; } // 如果缓存中没有,则从数据库获取 List data = baseDao.getDictDataByType(dictType); // 存入Redis缓存 if (data != null) { redisUtils.set(key, data); } return data; } }