mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-10-31 22:57:17 +08:00 
			
		
		
		
	fix: 修复偶发性报错 zip file closed
fix #I9OHXP
This commit is contained in:
		| @@ -41,11 +41,6 @@ public class CacheConstants { | |||||||
|      */ |      */ | ||||||
|     public static final String CAPTCHA_KEY_PREFIX = "CAPTCHA" + DELIMITER; |     public static final String CAPTCHA_KEY_PREFIX = "CAPTCHA" + DELIMITER; | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 限流键前缀 |  | ||||||
|      */ |  | ||||||
|     public static final String LIMIT_KEY_PREFIX = "LIMIT" + DELIMITER; |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 用户缓存键前缀 |      * 用户缓存键前缀 | ||||||
|      */ |      */ | ||||||
| @@ -56,6 +51,11 @@ public class CacheConstants { | |||||||
|      */ |      */ | ||||||
|     public static final String MENU_KEY_PREFIX = "MENU" + DELIMITER; |     public static final String MENU_KEY_PREFIX = "MENU" + DELIMITER; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 字典缓存键前缀 | ||||||
|  |      */ | ||||||
|  |     public static final String DICT_KEY_PREFIX = "DICT" + DELIMITER; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 参数缓存键前缀 |      * 参数缓存键前缀 | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -16,19 +16,30 @@ | |||||||
|  |  | ||||||
| package top.continew.admin.system.service.impl; | package top.continew.admin.system.service.impl; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.util.ClassUtil; | ||||||
|  | import cn.hutool.core.util.StrUtil; | ||||||
|  | import com.alicp.jetcache.anno.Cached; | ||||||
|  | import jakarta.annotation.PostConstruct; | ||||||
| import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||||
|  | import top.continew.admin.common.constant.CacheConstants; | ||||||
| import top.continew.admin.system.mapper.DictItemMapper; | import top.continew.admin.system.mapper.DictItemMapper; | ||||||
| import top.continew.admin.system.model.entity.DictItemDO; | import top.continew.admin.system.model.entity.DictItemDO; | ||||||
| import top.continew.admin.system.model.query.DictItemQuery; | import top.continew.admin.system.model.query.DictItemQuery; | ||||||
| import top.continew.admin.system.model.req.DictItemReq; | import top.continew.admin.system.model.req.DictItemReq; | ||||||
| import top.continew.admin.system.model.resp.DictItemResp; | import top.continew.admin.system.model.resp.DictItemResp; | ||||||
| import top.continew.admin.system.service.DictItemService; | import top.continew.admin.system.service.DictItemService; | ||||||
|  | import top.continew.starter.cache.redisson.util.RedisUtils; | ||||||
|  | import top.continew.starter.core.autoconfigure.project.ProjectProperties; | ||||||
|  | import top.continew.starter.core.constant.StringConstants; | ||||||
| import top.continew.starter.core.util.validate.CheckUtils; | import top.continew.starter.core.util.validate.CheckUtils; | ||||||
|  | import top.continew.starter.data.mybatis.plus.base.IBaseEnum; | ||||||
| import top.continew.starter.extension.crud.model.resp.LabelValueResp; | import top.continew.starter.extension.crud.model.resp.LabelValueResp; | ||||||
| import top.continew.starter.extension.crud.service.impl.BaseServiceImpl; | import top.continew.starter.extension.crud.service.impl.BaseServiceImpl; | ||||||
|  |  | ||||||
| import java.util.List; | import java.util.*; | ||||||
|  | import java.util.concurrent.ConcurrentHashMap; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 字典项业务实现 |  * 字典项业务实现 | ||||||
| @@ -40,26 +51,34 @@ import java.util.List; | |||||||
| @RequiredArgsConstructor | @RequiredArgsConstructor | ||||||
| public class DictItemServiceImpl extends BaseServiceImpl<DictItemMapper, DictItemDO, DictItemResp, DictItemResp, DictItemQuery, DictItemReq> implements DictItemService { | public class DictItemServiceImpl extends BaseServiceImpl<DictItemMapper, DictItemDO, DictItemResp, DictItemResp, DictItemQuery, DictItemReq> implements DictItemService { | ||||||
|  |  | ||||||
|  |     private final ProjectProperties projectProperties; | ||||||
|  |     private final Map<String, List<LabelValueResp>> enumDictCache = new ConcurrentHashMap<>(); | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     protected void beforeAdd(DictItemReq req) { |     protected void beforeAdd(DictItemReq req) { | ||||||
|         String value = req.getValue(); |         String value = req.getValue(); | ||||||
|         CheckUtils.throwIf(this.isValueExists(value, null, req.getDictId()), "新增失败,字典值 [{}] 已存在", value); |         CheckUtils.throwIf(this.isValueExists(value, null, req.getDictId()), "新增失败,字典值 [{}] 已存在", value); | ||||||
|  |         RedisUtils.deleteByPattern(CacheConstants.DICT_KEY_PREFIX + StringConstants.ASTERISK); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     protected void beforeUpdate(DictItemReq req, Long id) { |     protected void beforeUpdate(DictItemReq req, Long id) { | ||||||
|         String value = req.getValue(); |         String value = req.getValue(); | ||||||
|         CheckUtils.throwIf(this.isValueExists(value, id, req.getDictId()), "修改失败,字典值 [{}] 已存在", value); |         CheckUtils.throwIf(this.isValueExists(value, id, req.getDictId()), "修改失败,字典值 [{}] 已存在", value); | ||||||
|  |         RedisUtils.deleteByPattern(CacheConstants.DICT_KEY_PREFIX + StringConstants.ASTERISK); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|  |     @Cached(key = "#dictCode", name = CacheConstants.DICT_KEY_PREFIX) | ||||||
|     public List<LabelValueResp> listByDictCode(String dictCode) { |     public List<LabelValueResp> listByDictCode(String dictCode) { | ||||||
|         return baseMapper.listByDictCode(dictCode); |         return Optional.ofNullable(enumDictCache.get(dictCode.toLowerCase())) | ||||||
|  |             .orElseGet(() -> baseMapper.listByDictCode(dictCode)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void deleteByDictIds(List<Long> dictIds) { |     public void deleteByDictIds(List<Long> dictIds) { | ||||||
|         baseMapper.lambdaUpdate().in(DictItemDO::getDictId, dictIds).remove(); |         baseMapper.lambdaUpdate().in(DictItemDO::getDictId, dictIds).remove(); | ||||||
|  |         RedisUtils.deleteByPattern(CacheConstants.DICT_KEY_PREFIX + StringConstants.ASTERISK); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -77,4 +96,29 @@ public class DictItemServiceImpl extends BaseServiceImpl<DictItemMapper, DictIte | |||||||
|             .ne(null != id, DictItemDO::getId, id) |             .ne(null != id, DictItemDO::getId, id) | ||||||
|             .exists(); |             .exists(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 将枚举转换为枚举字典 | ||||||
|  |      * | ||||||
|  |      * @param enumClass 枚举类型 | ||||||
|  |      * @return 枚举字典 | ||||||
|  |      */ | ||||||
|  |     private List<LabelValueResp> toEnumDict(Class<?> enumClass) { | ||||||
|  |         Object[] enumConstants = enumClass.getEnumConstants(); | ||||||
|  |         return Arrays.stream(enumConstants).map(e -> { | ||||||
|  |             IBaseEnum baseEnum = (IBaseEnum)e; | ||||||
|  |             return new LabelValueResp(baseEnum.getDescription(), baseEnum.getValue(), baseEnum.getColor()); | ||||||
|  |         }).toList(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 缓存枚举字典 | ||||||
|  |      */ | ||||||
|  |     @PostConstruct | ||||||
|  |     public void init() { | ||||||
|  |         Set<Class<?>> classSet = ClassUtil.scanPackageBySuper(projectProperties.getBasePackage(), IBaseEnum.class); | ||||||
|  |         enumDictCache.putAll(classSet.stream() | ||||||
|  |             .collect(Collectors.toMap(cls -> StrUtil.toUnderlineCase(cls.getSimpleName()) | ||||||
|  |                 .toLowerCase(), this::toEnumDict))); | ||||||
|  |     } | ||||||
| } | } | ||||||
| @@ -18,7 +18,6 @@ package top.continew.admin.controller.common; | |||||||
|  |  | ||||||
| import cn.dev33.satoken.annotation.SaIgnore; | import cn.dev33.satoken.annotation.SaIgnore; | ||||||
| import cn.hutool.core.lang.tree.Tree; | import cn.hutool.core.lang.tree.Tree; | ||||||
| import cn.hutool.core.util.ClassUtil; |  | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
| import com.alicp.jetcache.anno.Cached; | import com.alicp.jetcache.anno.Cached; | ||||||
| import io.swagger.v3.oas.annotations.Operation; | import io.swagger.v3.oas.annotations.Operation; | ||||||
| @@ -41,16 +40,12 @@ import top.continew.admin.system.model.resp.FileUploadResp; | |||||||
| import top.continew.admin.system.service.*; | import top.continew.admin.system.service.*; | ||||||
| import top.continew.starter.core.autoconfigure.project.ProjectProperties; | import top.continew.starter.core.autoconfigure.project.ProjectProperties; | ||||||
| import top.continew.starter.core.util.validate.ValidationUtils; | import top.continew.starter.core.util.validate.ValidationUtils; | ||||||
| import top.continew.starter.data.mybatis.plus.base.IBaseEnum; |  | ||||||
| import top.continew.starter.extension.crud.model.query.SortQuery; | import top.continew.starter.extension.crud.model.query.SortQuery; | ||||||
| import top.continew.starter.extension.crud.model.resp.LabelValueResp; | import top.continew.starter.extension.crud.model.resp.LabelValueResp; | ||||||
| import top.continew.starter.log.core.annotation.Log; | import top.continew.starter.log.core.annotation.Log; | ||||||
| import top.continew.starter.web.model.R; | import top.continew.starter.web.model.R; | ||||||
|  |  | ||||||
| import java.util.Arrays; |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Optional; |  | ||||||
| import java.util.Set; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 公共 API |  * 公共 API | ||||||
| @@ -101,12 +96,12 @@ public class CommonController { | |||||||
|         return R.ok(roleService.listDict(query, sortQuery)); |         return R.ok(roleService.listDict(query, sortQuery)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @SaIgnore | ||||||
|     @Operation(summary = "查询字典", description = "查询字典列表") |     @Operation(summary = "查询字典", description = "查询字典列表") | ||||||
|     @Parameter(name = "code", description = "字典编码", example = "notice_type", in = ParameterIn.PATH) |     @Parameter(name = "code", description = "字典编码", example = "notice_type", in = ParameterIn.PATH) | ||||||
|     @GetMapping("/dict/{code}") |     @GetMapping("/dict/{code}") | ||||||
|     public R<List<LabelValueResp>> listDict(@PathVariable String code) { |     public R<List<LabelValueResp>> listDict(@PathVariable String code) { | ||||||
|         Optional<Class<?>> enumClassOptional = this.getEnumClassByName(code); |         return R.ok(dictItemService.listByDictCode(code)); | ||||||
|         return R.ok(enumClassOptional.map(this::listEnumDict).orElseGet(() -> dictItemService.listByDictCode(code))); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @SaIgnore |     @SaIgnore | ||||||
| @@ -122,32 +117,4 @@ public class CommonController { | |||||||
|                 .getDefaultValue()))) |                 .getDefaultValue()))) | ||||||
|             .toList()); |             .toList()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 根据枚举类名查询 |  | ||||||
|      * |  | ||||||
|      * @param enumClassName 枚举类名 |  | ||||||
|      * @return 枚举类型 |  | ||||||
|      */ |  | ||||||
|     private Optional<Class<?>> getEnumClassByName(String enumClassName) { |  | ||||||
|         Set<Class<?>> classSet = ClassUtil.scanPackageBySuper(projectProperties.getBasePackage(), IBaseEnum.class); |  | ||||||
|         return classSet.stream() |  | ||||||
|             .filter(c -> StrUtil.equalsAnyIgnoreCase(c.getSimpleName(), enumClassName, StrUtil |  | ||||||
|                 .toCamelCase(enumClassName))) |  | ||||||
|             .findFirst(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 查询枚举字典 |  | ||||||
|      * |  | ||||||
|      * @param enumClass 枚举类型 |  | ||||||
|      * @return 枚举字典 |  | ||||||
|      */ |  | ||||||
|     private List<LabelValueResp> listEnumDict(Class<?> enumClass) { |  | ||||||
|         Object[] enumConstants = enumClass.getEnumConstants(); |  | ||||||
|         return Arrays.stream(enumConstants).map(e -> { |  | ||||||
|             IBaseEnum baseEnum = (IBaseEnum)e; |  | ||||||
|             return new LabelValueResp(baseEnum.getDescription(), baseEnum.getValue(), baseEnum.getColor()); |  | ||||||
|         }).toList(); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user