diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/options/OptionsApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/options/OptionsApi.java index 5680b862..3226b3d9 100644 --- a/opsli-api/src/main/java/org/opsli/api/web/system/options/OptionsApi.java +++ b/opsli-api/src/main/java/org/opsli/api/web/system/options/OptionsApi.java @@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletResponse; import org.opsli.api.wrapper.system.options.OptionsModel; import java.util.List; +import java.util.Map; /** @@ -91,6 +92,15 @@ public interface OptionsApi { @PostMapping("/update") ResultVo update(@RequestBody OptionsModel model); + /** + * 系统参数 修改 + * @param params Map + * @return ResultVo + */ + @PostMapping("/updateOptions") + ResultVo updateOptions(@RequestBody Map params); + + /** * 系统参数 删除 * @param id ID @@ -150,6 +160,13 @@ public interface OptionsApi { @GetMapping("/getByCode") ResultVo getByCode(String optionCode); + /** + * 系统参数 查询全部 + * @return ResultVo + */ + @GetMapping("/findAllOptions") + ResultVo> findAllOptions(); + /** * 系统参数 查询全部 * @return ResultVo diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/other/crypto/OtherCryptoAsymmetricRestApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/other/crypto/OtherCryptoAsymmetricRestApi.java deleted file mode 100644 index 3870a325..00000000 --- a/opsli-api/src/main/java/org/opsli/api/web/system/other/crypto/OtherCryptoAsymmetricRestApi.java +++ /dev/null @@ -1,162 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package org.opsli.api.web.system.other.crypto; - - -import org.opsli.api.base.result.ResultVo; -import org.opsli.api.wrapper.system.other.crypto.OtherCryptoAsymmetricModel; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.multipart.MultipartHttpServletRequest; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - - - - - -/** - * @BelongsProject: opsli-boot - - * @BelongsPackage: org.opsli.api.web.other.crypto - - * @Author: Parker - * @CreateTime: 2021-02-10 17:09:34 - * @Description: 非对称加密 - * - * 对外 API 直接 暴露 @GetMapping 或者 @PostMapping - * 对内也推荐 单机版 不需要设置 Mapping 但是调用方法得从Controller写起 - * - * 这样写法虽然比较绕,但是当单体项目想要改造微服务架构时 时非常容易的 - * - * - */ -public interface OtherCryptoAsymmetricRestApi { - - /** 标题 */ - String TITLE = "非对称加密"; - - /** - * 非对称加密 查一条 - * @param model 模型 - * @return ResultVo - */ - @GetMapping("/get") - ResultVo get(OtherCryptoAsymmetricModel model); - - /** - * 非对称加密 查询分页 - * @param pageNo 当前页 - * @param pageSize 每页条数 - * @param request request - * @return ResultVo - */ - @GetMapping("/findPage") - ResultVo findPage( - @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, - @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, - HttpServletRequest request - ); - - /** - * 非对称加密 新增 - * @param model 模型 - * @return ResultVo - */ - @PostMapping("/insert") - ResultVo insert(@RequestBody OtherCryptoAsymmetricModel model); - - /** - * 非对称加密 修改 - * @param model 模型 - * @return ResultVo - */ - @PostMapping("/update") - ResultVo update(@RequestBody OtherCryptoAsymmetricModel model); - - /** - * 非对称加密 删除 - * @param id ID - * @return ResultVo - */ - @PostMapping("/del") - ResultVo del(String id); - - /** - * 非对称加密 批量删除 - * @param ids ID 数组 - * @return ResultVo - */ - @PostMapping("/delAll") - ResultVo delAll(String ids); - - /** - * 非对称加密 Excel 导出 - * - * 导出时,Token认证和方法权限认证 全部都由自定义完成 - * 因为在 导出不成功时,需要推送错误信息, - * 前端直接走下载流,当失败时无法获得失败信息,即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时 - * ,且如果数据量过大,前端进行渲染时直接会把浏览器卡死 - * 而直接开启socket接口推送显然是太过浪费资源了,所以目前采用Java最原始的手段 - * response 推送 javascript代码 alert 提示报错信息 - * - * @param request request - * @param response response - * @return ResultVo - */ - @GetMapping("/exportExcel") - void exportExcel(HttpServletRequest request, HttpServletResponse response); - - /** - * 非对称加密 Excel 导入 - * @param request 文件流 request - * @return ResultVo - */ - @PostMapping("/importExcel") - ResultVo importExcel(MultipartHttpServletRequest request); - - /** - * 非对称加密 Excel 下载导入模版 - * @param response response - * @return ResultVo - */ - @GetMapping("/importExcel/template") - void importTemplate(HttpServletResponse response); - - - /** - * 系统参数 查一条 - * @param optionCode 参数编号 - * @return ResultVo - */ - @GetMapping("/getByCryptoType") - ResultVo getByCryptoType(String optionCode); - - - // =================== - - /** - * 非对称加密 新增 - * @param model 模型 - * @return ResultVo - */ - ResultVo insertInner(@RequestBody OtherCryptoAsymmetricModel model); - -} diff --git a/opsli-api/src/main/java/org/opsli/api/wrapper/system/other/crypto/OtherCryptoAsymmetricModel.java b/opsli-api/src/main/java/org/opsli/api/wrapper/system/other/crypto/OtherCryptoAsymmetricModel.java deleted file mode 100644 index d08787a4..00000000 --- a/opsli-api/src/main/java/org/opsli/api/wrapper/system/other/crypto/OtherCryptoAsymmetricModel.java +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package org.opsli.api.wrapper.system.other.crypto; - - -import java.util.Date; -import com.alibaba.excel.annotation.ExcelProperty; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import org.opsli.api.base.warpper.ApiWrapper; -import org.opsli.common.annotation.validation.ValidationArgs; -import org.opsli.common.annotation.validation.ValidationArgsLenMax; -import org.opsli.common.enums.ValiArgsType; -import org.opsli.plugins.excel.annotation.ExcelInfo; -import com.fasterxml.jackson.annotation.JsonFormat; -import org.springframework.format.annotation.DateTimeFormat; - -/** - * @BelongsProject: opsli-boot - - * @BelongsPackage: org.opsli.api.wrapper.other.crypto - - * @Author: Parker - * @CreateTime: 2021-02-10 17:09:34 - * @Description: 非对称加密 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class OtherCryptoAsymmetricModel extends ApiWrapper { - - - /** 加解密类别 */ - @ApiModelProperty(value = "加解密类别") - @ExcelProperty(value = "加解密类别", order = 1) - @ExcelInfo - @ValidationArgs({ValiArgsType.IS_NOT_NULL, ValiArgsType.IS_GENERAL}) - @ValidationArgsLenMax(100) - private String cryptoType; - - /** 公钥 */ - @ApiModelProperty(value = "公钥") - @ExcelProperty(value = "公钥", order = 2) - @ExcelInfo - @ValidationArgs({ValiArgsType.IS_NOT_NULL}) - @ValidationArgsLenMax(2000) - private String publicKey; - - /** 私钥 */ - @ApiModelProperty(value = "私钥") - @ExcelProperty(value = "私钥", order = 3) - @ExcelInfo - @ValidationArgs({ValiArgsType.IS_NOT_NULL}) - @ValidationArgsLenMax(2000) - private String privateKey; - - -} diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/local/CacheUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/local/CacheUtil.java index d7e17ede..cf7412a1 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/local/CacheUtil.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/local/CacheUtil.java @@ -15,11 +15,13 @@ */ package org.opsli.core.cache.local; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.XmlUtil; import com.alibaba.fastjson.JSONObject; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import lombok.extern.slf4j.Slf4j; import org.opsli.common.constants.CacheConstants; import org.opsli.common.enums.CacheType; @@ -37,6 +39,7 @@ import org.w3c.dom.NodeList; import java.io.IOException; import java.util.List; +import java.util.Map; import static org.opsli.common.constants.OrderConstants.UTIL_ORDER; @@ -323,6 +326,46 @@ public class CacheUtil { return null; } + + /** + * 获得 Hash 缓存 + * @param key 键 + * @return Object + */ + public static Map getHashAll(final String key){ + try { + // 缓存 Key + String cacheKey = CacheUtil.handleKey(CacheType.EDEN_HASH, key); + + Map retMap = Maps.newHashMap(); + + // 如果本地缓存找不到该缓存 则去远端缓存拉去缓存 + Map allCache = redisPlugin.hGetAll(cacheKey); + if(CollUtil.isEmpty(allCache)){ + return retMap; + } + + for (Map.Entry entry : allCache.entrySet()) { + // 赋值 + JSONObject jsonObject = (JSONObject) entry.getValue(); + if (jsonObject == null) { + continue; + } + Object data = jsonObject.get(CacheUtil.JSON_KEY); + if (data == null) { + continue; + } + + retMap.put(Convert.toStr(entry.getKey()), data); + } + + return retMap; + }catch (Exception e){ + log.error(e.getMessage(),e); + } + return null; + } + // ========================= PUT ========================= diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/CryptoAsymmetricUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/CryptoAsymmetricUtil.java index 39366914..4f7e76af 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/CryptoAsymmetricUtil.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/CryptoAsymmetricUtil.java @@ -24,26 +24,17 @@ import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.RSA; import cn.hutool.crypto.asymmetric.SM2; import com.alibaba.fastjson.JSONObject; +import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.opsli.api.base.result.ResultVo; -import org.opsli.api.web.system.other.crypto.OtherCryptoAsymmetricRestApi; import org.opsli.api.wrapper.system.options.OptionsModel; -import org.opsli.api.wrapper.system.other.crypto.OtherCryptoAsymmetricModel; import org.opsli.common.enums.CryptoAsymmetricType; import org.opsli.common.enums.OptionsType; import org.opsli.common.exception.ServiceException; -import org.opsli.core.cache.local.CacheUtil; import org.opsli.core.msg.CoreMsg; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Lazy; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; import java.util.Collection; -import static org.opsli.common.constants.OrderConstants.UTIL_ORDER; - /** * @BelongsProject: opsli-boot * @BelongsPackage: org.opsli.core.utils @@ -52,158 +43,18 @@ import static org.opsli.common.constants.OrderConstants.UTIL_ORDER; * @Description: 非对称加密工具类 */ @Slf4j -@Order(UTIL_ORDER) -@Component -@Lazy(false) -public class CryptoAsymmetricUtil { - - /** 前缀 */ - public static final String PREFIX_CODE = "crypto:asymmetric:code:"; - - /** 非对称加密 Api */ - private static OtherCryptoAsymmetricRestApi otherCryptoAsymmetricRestApi; +public final class CryptoAsymmetricUtil { /** Crypto KEY */ private static final String CRYPTO_KEY = "data"; - /** - * 根据 cryptoAsymmetricType 枚举 获得参数 - * @param cryptoAsymmetricType type - * @return model - */ - public static OtherCryptoAsymmetricModel getCryptoAsymmetric(final CryptoAsymmetricType cryptoAsymmetricType){ - if(cryptoAsymmetricType == null){ - return null; - } - - String typeCode = cryptoAsymmetricType.getCode(); - - // 缓存Key - String cacheKey = PREFIX_CODE + typeCode; - - // 先从缓存里拿 - OtherCryptoAsymmetricModel model = CacheUtil.getTimed(OtherCryptoAsymmetricModel.class, cacheKey); - if (model != null){ - return model; - } - - // 拿不到 -------- - // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey); - if(hasNilFlag){ - return null; - } - - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKey)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); - return null; - } - - // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 - model = CacheUtil.getTimed(OtherCryptoAsymmetricModel.class, cacheKey); - if (model != null){ - return model; - } - - boolean noData = true; - // 查询数据库 - ResultVo resultVo = otherCryptoAsymmetricRestApi.getByCryptoType(typeCode); - if(resultVo.isSuccess()){ - model = resultVo.getData(); - if(model != null){ - noData = false; - // 存入缓存 - CacheUtil.put(cacheKey, model); - } - } - - // 如果没取到数值 则自动创建 - if(noData){ - // 获得系统配置参数 非对称加密枚举 - CryptoAsymmetricType asymmetricType = null; - OptionsModel optionsModel = OptionsUtil.getOptionByCode(OptionsType.CRYPTO_ASYMMETRIC); - if(optionsModel != null){ - // 获得加密类型 - asymmetricType = CryptoAsymmetricType.getCryptoType( - optionsModel.getOptionValue()); - } - - // 默认 RSA 算法 - model = create(asymmetricType!=null?asymmetricType:CryptoAsymmetricType.RSA); - ResultVo insertModel = otherCryptoAsymmetricRestApi.insertInner(model); - if(insertModel.isSuccess()){ - // 存入缓存 - CacheUtil.put(cacheKey, model); - } - } - }catch (Exception e){ - log.error(e.getMessage(),e); - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKey); - } - - if(model == null){ - // 设置空变量 用于防止穿透判断 - CacheUtil.putNilFlag(cacheKey); - return null; - } - - return model; - } - - - // ============== 刷新缓存 ============== - - /** - * 刷新参数 - 删就完了 - * @param model m - * @return boolean - */ - public static boolean refresh(final OtherCryptoAsymmetricModel model){ - if(model == null || StringUtils.isEmpty(model.getCryptoType())){ - return true; - } - - // 计数器 - int count = 0; - - OtherCryptoAsymmetricModel tmpModel = CacheUtil.getTimed(OtherCryptoAsymmetricModel.class, PREFIX_CODE + model.getCryptoType()); - boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_CODE + model.getCryptoType()); - - // 只要不为空 则执行刷新 - if (hasNilFlag){ - count++; - // 清除空拦截 - boolean tmp = CacheUtil.delNilFlag(PREFIX_CODE + model.getCryptoType()); - if(tmp){ - count--; - } - } - - if(tmpModel != null){ - count++; - // 先删除 - boolean tmp = CacheUtil.del(PREFIX_CODE + model.getCryptoType()); - if(tmp){ - count--; - } - } - - return count == 0; - } - - /** * 创建公私钥 * @param cryptoAsymmetricType 枚举 * @return Model */ - public static OtherCryptoAsymmetricModel create(final CryptoAsymmetricType cryptoAsymmetricType){ - OtherCryptoAsymmetricModel model = new OtherCryptoAsymmetricModel(); + public static CryptoAsymmetricUtil.CryptoAsymmetric create(final CryptoAsymmetricType cryptoAsymmetricType){ + CryptoAsymmetricUtil.CryptoAsymmetric model = new CryptoAsymmetricUtil.CryptoAsymmetric(); model.setCryptoType(cryptoAsymmetricType.getCode()); switch (cryptoAsymmetricType){ case RSA: @@ -356,7 +207,7 @@ public class CryptoAsymmetricUtil { switch (cryptoType){ case RSA: RSA rsa = SecureUtil.rsa(cryptoAsymmetricPrivateKey.getOptionValue(), cryptoAsymmetricPublicKey.getOptionValue()); - tmp = rsa.decryptStr(currData, KeyType.PrivateKey); + tmp = rsa.decryptStr(data, KeyType.PrivateKey); break; case SM2: SM2 sm2 = SmUtil.sm2(cryptoAsymmetricPrivateKey.getOptionValue(), cryptoAsymmetricPublicKey.getOptionValue()); @@ -386,12 +237,22 @@ public class CryptoAsymmetricUtil { return decryptStr; } - // ===================================== - @Autowired - public void setOtherCryptoAsymmetricRestApi(OtherCryptoAsymmetricRestApi otherCryptoAsymmetricRestApi) { - CryptoAsymmetricUtil.otherCryptoAsymmetricRestApi = otherCryptoAsymmetricRestApi; + @Data + public static class CryptoAsymmetric { + + + /** 加解密类别 */ + private String cryptoType; + + /** 公钥 */ + private String publicKey; + + /** 私钥 */ + private String privateKey; } + private CryptoAsymmetricUtil(){} + } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/DictUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/DictUtil.java index 7f4c53d7..e8a24f30 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/DictUtil.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/DictUtil.java @@ -229,72 +229,65 @@ public class DictUtil { // 缓存Key String cacheKey = DictConstants.CACHE_PREFIX_NAME + typeCode; - List dictWrapperModels; + // 处理集合数据 + List dictWrapperModels = handleDictList( + CacheUtil.getHashAll(cacheKey), typeCode); + if(CollUtil.isNotEmpty(dictWrapperModels)){ + return sortDictWrappers(dictWrapperModels); + } + + // 防止缓存穿透判断 + boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey); + if(hasNilFlag){ + return sortDictWrappers(dictWrapperModels); + } + try { - String key = CacheUtil.handleKey(CacheType.EDEN_HASH, cacheKey); - // 处理集合数据 - dictWrapperModels = handleDictList(redisPlugin.hGetAll(key), typeCode); - if(CollUtil.isNotEmpty(dictWrapperModels)){ - return dictWrapperModels; + // 分布式加锁 + if(!DistributedLockUtil.lock(cacheKey)){ + // 无法申领分布式锁 + log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); + return sortDictWrappers(dictWrapperModels); } - // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey); - if(hasNilFlag){ - return dictWrapperModels; + // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 + // 处理集合数据 + dictWrapperModels = handleDictList( + CacheUtil.getHashAll(cacheKey), typeCode); + if(CollUtil.isNotEmpty(dictWrapperModels)){ + return sortDictWrappers(dictWrapperModels); } - try { - // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKey)){ - // 无法申领分布式锁 - log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); - return dictWrapperModels; - } - - // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 - key = CacheUtil.handleKey(CacheType.EDEN_HASH, cacheKey); - // 处理集合数据 - dictWrapperModels = handleDictList(redisPlugin.hGetAll(key), typeCode); - if(CollUtil.isNotEmpty(dictWrapperModels)){ - return dictWrapperModels; - } - - // 查询数据库 并保存到缓存内 - ResultVo> resultVo = dictDetailApi.findListByTypeCode(typeCode); - if(resultVo.isSuccess()){ - List dictDetailModels = resultVo.getData(); - // 处理数据库查询数据 - if(CollUtil.isNotEmpty(dictDetailModels)){ - dictWrapperModels = Lists.newArrayListWithCapacity(dictDetailModels.size()); - for (DictDetailModel model : dictDetailModels) { - // 保存至缓存 - DictWrapper dictWrapper = DictUtil.putByModel(model); - dictWrapperModels.add(dictWrapper); - } + // 查询数据库 并保存到缓存内 + ResultVo> resultVo = dictDetailApi.findListByTypeCode(typeCode); + if(resultVo.isSuccess()){ + List dictDetailModels = resultVo.getData(); + // 处理数据库查询数据 + if(CollUtil.isNotEmpty(dictDetailModels)){ + dictWrapperModels = Lists.newArrayListWithCapacity(dictDetailModels.size()); + for (DictDetailModel model : dictDetailModels) { + // 保存至缓存 + DictWrapper dictWrapper = DictUtil.putByModel(model); + dictWrapperModels.add(dictWrapper); } - } - - }catch (Exception e){ - log.error(e.getMessage(),e); - return dictWrapperModels; - }finally { - // 释放锁 - DistributedLockUtil.unlock(cacheKey); - } - - // 如果值还是 为空 则赋默认值 - if(CollUtil.isEmpty(dictWrapperModels)){ - // 加入缓存防穿透 - // 设置空变量 用于防止穿透判断 - CacheUtil.putNilFlag(cacheKey); + return sortDictWrappers(dictWrapperModels); + } } }catch (Exception e){ log.error(e.getMessage(),e); - dictWrapperModels = Lists.newArrayList(); + }finally { + // 释放锁 + DistributedLockUtil.unlock(cacheKey); + } + + // 如果值还是 为空 则赋默认值 + if(CollUtil.isEmpty(dictWrapperModels)){ + // 加入缓存防穿透 + // 设置空变量 用于防止穿透判断 + CacheUtil.putNilFlag(cacheKey); } // 排序 @@ -311,6 +304,7 @@ public class DictUtil { if(dictWrapperModels == null){ return null; } + ListUtil.sort(dictWrapperModels, (o1, o2) -> { int oInt1 = Integer.MAX_VALUE; int oInt2 = Integer.MAX_VALUE; @@ -453,33 +447,24 @@ public class DictUtil { * @param typeCode 类型编号 * @return List */ - public static List handleDictList(Map dictMap, String typeCode){ - if(CollUtil.isEmpty(dictMap)){ - return null; - } - + public static List handleDictList(Map dictMap, String typeCode){ List dictWrapperModels = Lists.newArrayList(); - for (Map.Entry entry : dictMap.entrySet()) { - // 赋值 - JSONObject jsonObject = (JSONObject) entry.getValue(); - if(jsonObject == null){ - continue; - } - Object data = jsonObject.get(CacheUtil.JSON_KEY); - if(data == null){ - continue; + if(CollUtil.isNotEmpty(dictMap)){ + for (Map.Entry entry : dictMap.entrySet()) { + // 赋值 + Object data = entry.getValue(); + + DictDetailModel model = Convert.convert(DictDetailModel.class, data); + DictWrapper dictWrapperModel = new DictWrapper(); + dictWrapperModel.setTypeCode(typeCode); + dictWrapperModel.setDictName(model.getDictName()); + dictWrapperModel.setDictValue(model.getDictValue()); + dictWrapperModels.add(dictWrapperModel); } - - DictDetailModel model = Convert.convert(DictDetailModel.class, data); - DictWrapper dictWrapperModel = new DictWrapper(); - dictWrapperModel.setTypeCode(typeCode); - dictWrapperModel.setDictName(model.getDictName()); - dictWrapperModel.setDictValue(model.getDictValue()); - dictWrapperModels.add(dictWrapperModel); - } + } // 返回排序后 list - return CollUtil.isNotEmpty(dictWrapperModels)?sortDictWrappers(dictWrapperModels):null; + return CollUtil.isNotEmpty(dictWrapperModels)?sortDictWrappers(dictWrapperModels):dictWrapperModels; } diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/OptionsUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/OptionsUtil.java index 7a989cf1..23798689 100644 --- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/OptionsUtil.java +++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/OptionsUtil.java @@ -16,13 +16,14 @@ package org.opsli.core.utils; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.convert.Convert; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.opsli.api.base.result.ResultVo; import org.opsli.api.web.system.options.OptionsApi; import org.opsli.api.wrapper.system.options.OptionsModel; -import org.opsli.api.wrapper.system.other.crypto.OtherCryptoAsymmetricModel; import org.opsli.common.enums.OptionsType; import org.opsli.core.cache.local.CacheUtil; import org.opsli.core.msg.CoreMsg; @@ -42,6 +43,8 @@ import static org.opsli.common.constants.OrderConstants.UTIL_ORDER; * @Author: Parker * @CreateTime: 2020-09-19 20:03 * @Description: 参数工具类 + * + * Hash 永久缓存 */ @Slf4j @Order(UTIL_ORDER) @@ -50,7 +53,7 @@ import static org.opsli.common.constants.OrderConstants.UTIL_ORDER; public class OptionsUtil { /** 前缀 */ - public static final String PREFIX_CODE = "options:code:"; + public static final String PREFIX_CODE = "options:code"; /** 参数 Api */ private static OptionsApi optionsApi; @@ -71,36 +74,38 @@ public class OptionsUtil { /** * 根据 optionCode 获得参数 - * @param optionCode - * @return + * @param optionCode 参数编号 + * @return OptionsModel */ public static OptionsModel getOptionByCode(String optionCode){ // 缓存Key - String cacheKey = PREFIX_CODE + optionCode; + String cacheKey = PREFIX_CODE; + // 缓存Key + VALUE + String cacheKeyVal = cacheKey + ":" + optionCode; // 先从缓存里拿 - OptionsModel model = CacheUtil.getTimed(OptionsModel.class, cacheKey); + OptionsModel model = CacheUtil.getHash(OptionsModel.class, cacheKey, optionCode); if (model != null){ return model; } // 拿不到 -------- // 防止缓存穿透判断 - boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey); + boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKeyVal); if(hasNilFlag){ return null; } try { // 分布式加锁 - if(!DistributedLockUtil.lock(cacheKey)){ + if(!DistributedLockUtil.lock(cacheKeyVal)){ // 无法申领分布式锁 log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); return null; } // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 - model = CacheUtil.getTimed(OptionsModel.class, cacheKey); + model = CacheUtil.getHash(OptionsModel.class, cacheKey, optionCode); if (model != null){ return model; } @@ -110,13 +115,13 @@ public class OptionsUtil { if(resultVo.isSuccess()){ model = resultVo.getData(); // 存入缓存 - CacheUtil.put(cacheKey, model); + CacheUtil.putHash(cacheKey, optionCode, model); } }catch (Exception e){ log.error(e.getMessage(),e); }finally { // 释放锁 - DistributedLockUtil.unlock(cacheKey); + DistributedLockUtil.unlock(cacheKeyVal); } if(model == null){ @@ -133,19 +138,72 @@ public class OptionsUtil { * @return Map */ public static Map findAllOptions(){ - ResultVo> optionsApiAll = optionsApi.findAll(); - if(optionsApiAll == null || !optionsApiAll.isSuccess()){ - return null; + List optionsModels; + Map optionsModelMap; + + // 处理集合数据 + optionsModels = handleOptionsList( + CacheUtil.getHashAll(PREFIX_CODE)); + // 转换对象 + optionsModelMap = convertOptionsMap(optionsModels); + if(CollUtil.isNotEmpty(optionsModelMap)){ + return optionsModelMap; } - List optionsModels = optionsApiAll.getData(); - if(CollUtil.isEmpty(optionsModels)){ - return null; + // 防止缓存穿透判断 + boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_CODE); + if(hasNilFlag){ + return optionsModelMap; } - Map optionsModelMap = Maps.newHashMap(); - for (OptionsModel optionsModel : optionsModels) { - optionsModelMap.put(optionsModel.getOptionCode(), optionsModel); + try { + // 分布式加锁 + if(!DistributedLockUtil.lock(PREFIX_CODE)){ + // 无法申领分布式锁 + log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); + return optionsModelMap; + } + + // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 + // 处理集合数据 + optionsModels = handleOptionsList( + CacheUtil.getHashAll(PREFIX_CODE)); + // 转换对象 + optionsModelMap = convertOptionsMap(optionsModels); + if(CollUtil.isNotEmpty(optionsModelMap)){ + return optionsModelMap; + } + + // 数据库查询数据 + ResultVo> optionsApiAll = optionsApi.findAll(); + if(optionsApiAll.isSuccess()){ + // 处理数据 + optionsModelMap = convertOptionsMap(optionsApiAll.getData()); + if(CollUtil.isNotEmpty(optionsModelMap)){ + // 保存至缓存 + for (Map.Entry entry : optionsModelMap.entrySet()) { + String optionCode = entry.getKey(); + OptionsModel model = entry.getValue(); + CacheUtil.putHash(PREFIX_CODE, optionCode, model); + } + + // 返回数据 + return optionsModelMap; + } + } + }catch (Exception e){ + log.error(e.getMessage(),e); + return optionsModelMap; + }finally { + // 释放锁 + DistributedLockUtil.unlock(PREFIX_CODE); + } + + // 如果值还是 为空 则赋默认值 + if(CollUtil.isEmpty(optionsModelMap)){ + // 加入缓存防穿透 + // 设置空变量 用于防止穿透判断 + CacheUtil.putNilFlag(PREFIX_CODE); } return optionsModelMap; @@ -156,25 +214,30 @@ public class OptionsUtil { /** * 刷新参数 - 删就完了 - * @param option - * @return + * @param option 参数 + * @return boolean */ public static boolean refreshOption(OptionsModel option){ if(option == null || StringUtils.isEmpty(option.getOptionCode())){ return true; } + // 缓存Key + String cacheKey = PREFIX_CODE; + // 缓存Key + VALUE + String cacheKeyVal = cacheKey + ":" + option.getOptionCode(); + // 计数器 int count = 0; - OptionsModel model = CacheUtil.getTimed(OptionsModel.class, PREFIX_CODE + option.getOptionCode()); - boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_CODE + option.getOptionCode()); + OptionsModel model = CacheUtil.getHash(OptionsModel.class, cacheKey, option.getOptionCode()); + boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKeyVal); // 只要不为空 则执行刷新 if (hasNilFlag){ count++; // 清除空拦截 - boolean tmp = CacheUtil.delNilFlag(PREFIX_CODE + option.getOptionCode()); + boolean tmp = CacheUtil.delNilFlag(cacheKeyVal); if(tmp){ count--; } @@ -183,7 +246,7 @@ public class OptionsUtil { if(model != null){ count++; // 先删除 - boolean tmp = CacheUtil.del(PREFIX_CODE + option.getOptionCode()); + boolean tmp = CacheUtil.delHash(cacheKey, option.getOptionCode()); if(tmp){ count--; } @@ -192,11 +255,45 @@ public class OptionsUtil { return count == 0; } + /** + * 处理缓存参数数据 + * @param optionsMap List + * @return List + */ + public static List handleOptionsList(Map optionsMap){ + if(CollUtil.isEmpty(optionsMap)){ + return null; + } + List optionsModels = Lists.newArrayList(); + for (Map.Entry entry : optionsMap.entrySet()) { + OptionsModel convert = Convert.convert(OptionsModel.class, entry.getValue()); + optionsModels.add(convert); + } - // ===================================== + return optionsModels; + } + /** + * 转换参数数据 - Map + * @param optionsModels Map + * @return Map + */ + public static Map convertOptionsMap(List optionsModels){ + // 这里不管有没有 都返回一个集合 防止多做一步null处理 + Map optionsModelMap = Maps.newHashMap(); + + // List 转换 Map + if(CollUtil.isNotEmpty(optionsModels)){ + for (OptionsModel optionsModel : optionsModels) { + optionsModelMap.put(optionsModel.getOptionCode(), optionsModel); + } + } + return optionsModelMap; + } + + // ===================================== @Autowired public void setOptionsApi(OptionsApi optionsApi) { diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/SystemMsg.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/SystemMsg.java index c48aff20..172dec8e 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/SystemMsg.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/SystemMsg.java @@ -85,6 +85,7 @@ public enum SystemMsg implements BaseMsg { * 系统参数 */ EXCEPTION_OPTIONS_UNIQUE(20700,"参数编号重复,该角色已存在"), + EXCEPTION_OPTIONS_UPDATE(20701,"更新异常"), /** diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginRestController.java index 2ade1d87..29718550 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/login/web/LoginRestController.java @@ -22,20 +22,16 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.opsli.api.base.result.ResultVo; import org.opsli.api.wrapper.system.options.OptionsModel; -import org.opsli.api.wrapper.system.other.crypto.OtherCryptoAsymmetricModel; -import org.opsli.common.enums.CryptoAsymmetricType; -import org.opsli.common.enums.OptionsType; -import org.opsli.core.utils.ValidationUtil; import org.opsli.api.wrapper.system.tenant.TenantModel; import org.opsli.api.wrapper.system.user.UserModel; import org.opsli.common.annotation.InterfaceCrypto; import org.opsli.common.annotation.Limiter; import org.opsli.common.api.TokenThreadLocal; import org.opsli.common.enums.AlertType; +import org.opsli.common.enums.OptionsType; import org.opsli.common.exception.TokenException; import org.opsli.common.thread.refuse.AsyncProcessQueueReFuse; import org.opsli.common.utils.IPUtil; -import org.opsli.core.filters.aspect.InterfaceCryptoAop; import org.opsli.core.msg.TokenMsg; import org.opsli.core.security.shiro.realm.JwtRealm; import org.opsli.core.utils.*; @@ -201,19 +197,13 @@ public class LoginRestController { @GetMapping("/sys/publicKey") public ResultVo getPublicKey(){ - // 获得系统配置参数 - OptionsModel optionsModel = OptionsUtil.getOptionByCode(OptionsType.CRYPTO_ASYMMETRIC); - if(optionsModel != null){ - // 获得加密类型 - CryptoAsymmetricType cryptoType = CryptoAsymmetricType.getCryptoType( - optionsModel.getOptionValue()); - OtherCryptoAsymmetricModel cryptoAsymmetric = CryptoAsymmetricUtil.getCryptoAsymmetric(cryptoType); - if(cryptoAsymmetric != null){ - return ResultVo.success( - "操作成功!", - cryptoAsymmetric.getPublicKey() - ); - } + // 获得公钥 + OptionsModel option = OptionsUtil.getOptionByCode(OptionsType.CRYPTO_ASYMMETRIC_PUBLIC_KEY); + if(option != null){ + return ResultVo.success( + "操作成功!", + option.getOptionValue() + ); } // 失败 diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/service/ISysOptionsService.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/service/ISysOptionsService.java index f53a9a54..db891fb9 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/service/ISysOptionsService.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/service/ISysOptionsService.java @@ -24,6 +24,8 @@ import org.opsli.core.base.service.interfaces.CrudServiceInterface; import org.opsli.modulars.system.options.entity.SysOptions; import org.opsli.api.wrapper.system.options.OptionsModel; +import java.util.Map; + /** * @BelongsProject: opsli-boot @@ -36,4 +38,10 @@ import org.opsli.api.wrapper.system.options.OptionsModel; */ public interface ISysOptionsService extends CrudServiceInterface { + /** + * 更新参数 + * @param params + */ + void updateOptions(Map params); + } diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/service/impl/SysOptionsServiceImpl.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/service/impl/SysOptionsServiceImpl.java index 0a338879..2a0a5035 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/service/impl/SysOptionsServiceImpl.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/service/impl/SysOptionsServiceImpl.java @@ -20,6 +20,8 @@ package org.opsli.modulars.system.options.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import org.apache.commons.lang3.StringUtils; import org.opsli.api.wrapper.system.options.OptionsModel; import org.opsli.common.constants.MyBatisConstants; @@ -37,6 +39,7 @@ import org.springframework.transaction.annotation.Transactional; import java.util.Collections; import java.util.List; +import java.util.Map; /** @@ -95,6 +98,55 @@ public class SysOptionsServiceImpl extends CrudServiceImpl params) { + if(CollUtil.isEmpty(params)){ + // 更新异常 + throw new ServiceException(SystemMsg.EXCEPTION_OPTIONS_UPDATE); + } + + List optionsCode = Lists.newArrayList(); + optionsCode.addAll(params.keySet()); + + // 获得所有的原始内容 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("option_code", optionsCode); + List optionsList = this.findList(queryWrapper); + Map resourceDataDict = Maps.newHashMap(); + for (SysOptions option : optionsList) { + resourceDataDict.put(option.getOptionCode(), + transformT2M(option) + ); + } + + // 循环修改 + for (Map.Entry entry : params.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + + OptionsModel optionsModel = resourceDataDict.get(key); + if(optionsModel == null){ + // 更新异常 + throw new ServiceException(SystemMsg.EXCEPTION_OPTIONS_UPDATE); + } + + // 唯一验证 + Integer count = this.uniqueVerificationByCode(optionsModel); + if(count != null && count > 0){ + // 重复 + throw new ServiceException(SystemMsg.EXCEPTION_OPTIONS_UNIQUE); + } + + // 设置值 + optionsModel.setOptionValue(value); + optionsModel.setVersion(null); + + // 更新 + this.update(optionsModel); + } + } + @Override @Transactional(rollbackFor = Exception.class) public boolean delete(String id) { diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/web/SysOptionsRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/web/SysOptionsRestController.java index 78b37006..b576f47c 100644 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/web/SysOptionsRestController.java +++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/web/SysOptionsRestController.java @@ -27,7 +27,6 @@ import org.apache.shiro.authz.annotation.RequiresPermissions; import org.opsli.api.base.result.ResultVo; import org.opsli.api.web.system.options.OptionsApi; import org.opsli.api.wrapper.system.options.OptionsModel; -import org.opsli.api.wrapper.system.other.crypto.OtherCryptoAsymmetricModel; import org.opsli.common.annotation.ApiRestController; import org.opsli.common.annotation.EnableLog; import org.opsli.common.annotation.RequiresPermissionsCus; @@ -38,6 +37,7 @@ import org.opsli.core.persistence.Page; import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.WebQueryBuilder; import org.opsli.core.utils.CryptoAsymmetricUtil; +import org.opsli.core.utils.OptionsUtil; import org.opsli.modulars.system.options.entity.SysOptions; import org.opsli.modulars.system.options.service.ISysOptionsService; import org.springframework.web.multipart.MultipartHttpServletRequest; @@ -46,6 +46,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.Method; import java.util.List; +import java.util.Map; /** @@ -69,7 +70,7 @@ public class SysOptionsRestController extends BaseRestController get(OptionsModel model) { // 如果系统内部调用 则直接查数据库 @@ -87,7 +88,7 @@ public class SysOptionsRestController extends BaseRestController findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { @@ -105,7 +106,7 @@ public class SysOptionsRestController extends BaseRestController insert(OptionsModel model) { @@ -120,7 +121,7 @@ public class SysOptionsRestController extends BaseRestController update(OptionsModel model) { @@ -129,6 +130,21 @@ public class SysOptionsRestController extends BaseRestController updateOptions(Map params) { + // 调用修改方法 + IService.updateOptions(params); + return ResultVo.success("保存参数成功"); + } + /** * 系统参数 删除 @@ -136,7 +152,7 @@ public class SysOptionsRestController extends BaseRestController del(String id){ @@ -150,7 +166,7 @@ public class SysOptionsRestController extends BaseRestController delAll(String ids){ @@ -175,7 +191,7 @@ public class SysOptionsRestController extends BaseRestController importExcel(MultipartHttpServletRequest request) { @@ -205,7 +221,7 @@ public class SysOptionsRestController extends BaseRestController> findAllOptions() { + return ResultVo.success( + OptionsUtil.findAllOptions() + ); + } + + /** + * 系统参数 查询全部 List + * @return ResultVo + */ + @Override public ResultVo> findAll() { return ResultVo.success( WrapperUtil.transformInstance(IService.findAllList(), OptionsModel.class) @@ -249,6 +276,8 @@ public class SysOptionsRestController extends BaseRestController createCrypto(String type) { CryptoAsymmetricType cryptoType = CryptoAsymmetricType.getCryptoType(type); if(cryptoType == null){ diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/entity/OtherCryptoAsymmetric.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/entity/OtherCryptoAsymmetric.java deleted file mode 100644 index e782fe95..00000000 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/entity/OtherCryptoAsymmetric.java +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package org.opsli.modulars.system.other.crypto.entity; - - -import java.util.Date; -import com.baomidou.mybatisplus.annotation.FieldStrategy; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableLogic; -import com.fasterxml.jackson.annotation.JsonIgnore; -import lombok.AccessLevel; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.Setter; -import org.opsli.core.base.entity.BaseEntity; - -/** - * @BelongsProject: opsli-boot - * @BelongsPackage: org.opsli.modulars.system.other.crypto.entity - * @Author: Parker - * @CreateTime: 2021-02-10 17:09:34 - * @Description: 非对称加密 - */ -@Data -@EqualsAndHashCode(callSuper = false) -public class OtherCryptoAsymmetric extends BaseEntity { - - /** 加解密类别 */ - private String cryptoType; - - /** 公钥 */ - private String publicKey; - - /** 私钥 */ - private String privateKey; - - - // ======================================== - - - /** 创建人 */ - @JsonIgnore - @Setter(AccessLevel.NONE) - @TableField(exist = false) - private String createBy; - - /** 创建时间 */ - @JsonIgnore - @Setter(AccessLevel.NONE) - @TableField(exist = false) - private Date createTime; - - /** 更新人 */ - @JsonIgnore - @Setter(AccessLevel.NONE) - @TableField(exist = false) - private String updateBy; - - /** 更新时间 */ - @JsonIgnore - @Setter(AccessLevel.NONE) - @TableField(exist = false) - private Date updateTime; - - /** 乐观锁 版本 */ - @JsonIgnore - @Setter(AccessLevel.NONE) - @TableField(exist = false) - private Integer version; - - -} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/mapper/OtherCryptoAsymmetricMapper.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/mapper/OtherCryptoAsymmetricMapper.java deleted file mode 100644 index 635e4bf1..00000000 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/mapper/OtherCryptoAsymmetricMapper.java +++ /dev/null @@ -1,37 +0,0 @@ -/** -* Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com -*

-* Licensed under the Apache License, Version 2.0 (the "License"); you may not -* use this file except in compliance with the License. You may obtain a copy of -* the License at -*

-* http://www.apache.org/licenses/LICENSE-2.0 -*

-* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -* License for the specific language governing permissions and limitations under -* the License. -*/ - -package org.opsli.modulars.system.other.crypto.mapper; - - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -import org.opsli.modulars.system.other.crypto.entity.OtherCryptoAsymmetric; - - -/** -* @BelongsProject: opsli-boot -* @BelongsPackage: org.opsli.modulars.system.other.crypto.mapper -* @Author: Parker -* @CreateTime: 2021-02-10 17:09:34 -* @Description: 非对称加密 Mapper -*/ -@Mapper -public interface OtherCryptoAsymmetricMapper extends BaseMapper { - -} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/mapper/xml/OtherCryptoAsymmetricMapper.xml b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/mapper/xml/OtherCryptoAsymmetricMapper.xml deleted file mode 100644 index 76777710..00000000 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/mapper/xml/OtherCryptoAsymmetricMapper.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/service/IOtherCryptoAsymmetricService.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/service/IOtherCryptoAsymmetricService.java deleted file mode 100644 index adccdee4..00000000 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/service/IOtherCryptoAsymmetricService.java +++ /dev/null @@ -1,45 +0,0 @@ -/** -* Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com -*

-* Licensed under the Apache License, Version 2.0 (the "License"); you may not -* use this file except in compliance with the License. You may obtain a copy of -* the License at -*

-* http://www.apache.org/licenses/LICENSE-2.0 -*

-* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -* License for the specific language governing permissions and limitations under -* the License. -*/ - -package org.opsli.modulars.system.other.crypto.service; - - -import org.opsli.api.wrapper.system.other.crypto.OtherCryptoAsymmetricModel; -import org.opsli.common.enums.CryptoAsymmetricType; -import org.opsli.core.base.service.interfaces.CrudServiceInterface; - - - -import org.opsli.modulars.system.other.crypto.entity.OtherCryptoAsymmetric; - - -/** -* @BelongsProject: opsli-boot -* @BelongsPackage: org.opsli.modulars.system.other.crypto.service -* @Author: Parker -* @CreateTime: 2021-02-10 17:09:34 -* @Description: 非对称加密 Service -*/ -public interface IOtherCryptoAsymmetricService extends CrudServiceInterface { - - /*** - * 重置数据 - * @param type 枚举 - * @return OtherCryptoAsymmetricModel - */ - OtherCryptoAsymmetricModel reset(CryptoAsymmetricType type); - -} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/service/impl/OtherCryptoAsymmetricServiceImpl.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/service/impl/OtherCryptoAsymmetricServiceImpl.java deleted file mode 100644 index 6bc9dd61..00000000 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/service/impl/OtherCryptoAsymmetricServiceImpl.java +++ /dev/null @@ -1,192 +0,0 @@ -/** -* Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com -*

-* Licensed under the Apache License, Version 2.0 (the "License"); you may not -* use this file except in compliance with the License. You may obtain a copy of -* the License at -*

-* http://www.apache.org/licenses/LICENSE-2.0 -*

-* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -* License for the specific language governing permissions and limitations under -* the License. -*/ - -package org.opsli.modulars.system.other.crypto.service.impl; - - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.convert.Convert; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import org.apache.commons.lang3.StringUtils; -import org.opsli.api.wrapper.system.other.crypto.OtherCryptoAsymmetricModel; -import org.opsli.common.constants.MyBatisConstants; -import org.opsli.common.enums.CryptoAsymmetricType; -import org.opsli.common.exception.ServiceException; -import org.opsli.core.base.service.impl.CrudServiceImpl; -import org.opsli.core.msg.CoreMsg; -import org.opsli.core.utils.CryptoAsymmetricUtil; -import org.opsli.modulars.system.SystemMsg; -import org.opsli.modulars.system.other.crypto.entity.OtherCryptoAsymmetric; -import org.opsli.modulars.system.other.crypto.mapper.OtherCryptoAsymmetricMapper; -import org.opsli.modulars.system.other.crypto.service.IOtherCryptoAsymmetricService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Collections; -import java.util.List; - - -/** -* @BelongsProject: opsli-boot -* @BelongsPackage: org.opsli.modulars.system.other.crypto.service.impl -* @Author: Parker -* @CreateTime: 2021-02-10 17:09:34 -* @Description: 非对称加密 Service Impl -*/ -@Service -public class OtherCryptoAsymmetricServiceImpl extends CrudServiceImpl - implements IOtherCryptoAsymmetricService { - - @Autowired(required = false) - private OtherCryptoAsymmetricMapper mapper; - - - @Override - @Transactional(rollbackFor = Exception.class) - public OtherCryptoAsymmetricModel insert(OtherCryptoAsymmetricModel model) { - if(model == null){ - return null; - } - - // 唯一验证 - Integer count = this.uniqueVerificationByCode(model); - if(count != null && count > 0){ - // 重复 - throw new ServiceException(SystemMsg.EXCEPTION_OTHER_CRYPTO_UNIQUE); - } - - return super.insert(model); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public OtherCryptoAsymmetricModel update(OtherCryptoAsymmetricModel model) { - if(model == null){ - return null; - } - - // 唯一验证 - Integer count = this.uniqueVerificationByCode(model); - if(count != null && count > 0){ - // 重复 - throw new ServiceException(SystemMsg.EXCEPTION_OTHER_CRYPTO_UNIQUE); - } - - return super.update(model); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public boolean delete(String id) { - OtherCryptoAsymmetricModel model = super.get(id); - boolean ret = super.delete(id); - - if(ret){ - // 清除缓存 - this.clearCache(Collections.singletonList(model)); - } - return ret; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public boolean deleteAll(String[] ids) { - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.in(MyBatisConstants.FIELD_ID, Convert.toList(String.class, ids)); - List modelList = super.transformTs2Ms( - super.findList(queryWrapper) - ); - - // 清除缓存 - this.clearCache(modelList); - - return super.deleteAll(ids); - } - - /*** - * 重置数据 - * @param type 枚举 - * @return OtherCryptoAsymmetricModel - */ - @Transactional(rollbackFor = Exception.class) - @Override - public OtherCryptoAsymmetricModel reset(CryptoAsymmetricType type) { - if(type == null){ - return null; - } - - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("crypto_type", type.getCode()); - OtherCryptoAsymmetricModel model = super.transformT2M( - this.getOne(queryWrapper) - ); - - // 删除当前数据 并清空缓存 - this.delete(model); - // 重新获得缓存 如果当前库中没有该缓存 则自动创建 - return CryptoAsymmetricUtil.getCryptoAsymmetric(type); - } - - - // ======================= - - /** - * 唯一验证 - * @param model model - * @return Integer - */ - @Transactional(readOnly = true) - public Integer uniqueVerificationByCode(OtherCryptoAsymmetricModel model){ - if(model == null){ - return null; - } - QueryWrapper wrapper = new QueryWrapper<>(); - wrapper.eq("crypto_type", model.getCryptoType()); - - // 重复校验排除自身 - if(StringUtils.isNotEmpty(model.getId())){ - wrapper.notIn(MyBatisConstants.FIELD_ID, model.getId()); - } - - return super.count(wrapper); - } - - /** - * 清除缓存 - * @param modelList - */ - private void clearCache(List modelList){ - // 清空缓存 - if(CollUtil.isNotEmpty(modelList)){ - int cacheCount = 0; - for (OtherCryptoAsymmetricModel model : modelList) { - cacheCount++; - boolean tmp = CryptoAsymmetricUtil.refresh(model); - if(tmp){ - cacheCount--; - } - } - // 判断删除状态 - if(cacheCount != 0){ - // 删除缓存失败 - throw new ServiceException(CoreMsg.CACHE_DEL_EXCEPTION); - } - } - } - - -} diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/web/OtherCryptoAsymmetricRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/web/OtherCryptoAsymmetricRestController.java deleted file mode 100644 index c9826cbb..00000000 --- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/other/crypto/web/OtherCryptoAsymmetricRestController.java +++ /dev/null @@ -1,239 +0,0 @@ -/** -* Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com -*

-* Licensed under the Apache License, Version 2.0 (the "License"); you may not -* use this file except in compliance with the License. You may obtain a copy of -* the License at -*

-* http://www.apache.org/licenses/LICENSE-2.0 -*

-* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -* License for the specific language governing permissions and limitations under -* the License. -*/ - -package org.opsli.modulars.system.other.crypto.web; - - -import cn.hutool.core.util.ReflectUtil; -import cn.hutool.core.convert.Convert; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import org.opsli.api.web.system.other.crypto.OtherCryptoAsymmetricRestApi; -import org.opsli.api.wrapper.system.options.OptionsModel; -import org.opsli.api.wrapper.system.other.crypto.OtherCryptoAsymmetricModel; -import org.opsli.common.utils.WrapperUtil; -import org.opsli.core.base.service.interfaces.CrudServiceInterface; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import lombok.extern.slf4j.Slf4j; -import org.opsli.common.annotation.RequiresPermissionsCus; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.opsli.api.base.result.ResultVo; -import org.opsli.common.annotation.ApiRestController; -import org.opsli.common.annotation.EnableLog; -import org.opsli.core.base.controller.BaseRestController; -import org.opsli.core.persistence.Page; -import org.opsli.core.persistence.querybuilder.QueryBuilder; -import org.opsli.core.persistence.querybuilder.WebQueryBuilder; -import org.opsli.modulars.system.options.entity.SysOptions; -import org.springframework.web.multipart.MultipartHttpServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.lang.reflect.Method; - - -import org.opsli.modulars.system.other.crypto.entity.OtherCryptoAsymmetric; -import org.opsli.modulars.system.other.crypto.service.IOtherCryptoAsymmetricService; - - -/** -* @BelongsProject: opsli-boot - -* @BelongsPackage: org.opsli.modulars.system.other.crypto.web - -* @Author: Parker -* @CreateTime: 2021-02-10 17:09:34 -* @Description: 非对称加密 Controller -*/ -@Api(tags = "非对称加密") -@Slf4j - -@ApiRestController("/other/crypto") - -public class OtherCryptoAsymmetricRestController extends BaseRestController - implements OtherCryptoAsymmetricRestApi { - - - /** - * 非对称加密 查一条 - * @param model 模型 - * @return ResultVo - */ - @ApiOperation(value = "获得单条非对称加密", notes = "获得单条非对称加密 - ID") - @RequiresPermissions("other_crypto_select") - @Override - public ResultVo get(OtherCryptoAsymmetricModel model) { - // 如果系统内部调用 则直接查数据库 - if(model != null && model.getIzApi() != null && model.getIzApi()){ - model = IService.get(model); - } - return ResultVo.success(model); - } - - /** - * 非对称加密 查询分页 - * @param pageNo 当前页 - * @param pageSize 每页条数 - * @param request request - * @return ResultVo - */ - @ApiOperation(value = "获得分页数据", notes = "获得分页数据 - 查询构造器") - @RequiresPermissions("other_crypto_select") - @Override - public ResultVo findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) { - - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); - Page page = new Page<>(pageNo, pageSize); - page.setQueryWrapper(queryBuilder.build()); - page = IService.findPage(page); - - return ResultVo.success(page.getBootstrapData()); - } - - /** - * 非对称加密 新增 - * @param model 模型 - * @return ResultVo - */ - @ApiOperation(value = "新增非对称加密数据", notes = "新增非对称加密数据") - @RequiresPermissions("other_crypto_insert") - @EnableLog - @Override - public ResultVo insert(OtherCryptoAsymmetricModel model) { - // 调用新增方法 - IService.insert(model); - return ResultVo.success("新增非对称加密成功"); - } - - /** - * 非对称加密 修改 - * @param model 模型 - * @return ResultVo - */ - @ApiOperation(value = "修改非对称加密数据", notes = "修改非对称加密数据") - @RequiresPermissions("other_crypto_update") - @EnableLog - @Override - public ResultVo update(OtherCryptoAsymmetricModel model) { - // 调用修改方法 - IService.update(model); - return ResultVo.success("修改非对称加密成功"); - } - - - /** - * 非对称加密 删除 - * @param id ID - * @return ResultVo - */ - @ApiOperation(value = "删除非对称加密数据", notes = "删除非对称加密数据") - @RequiresPermissions("other_crypto_update") - @EnableLog - @Override - public ResultVo del(String id){ - IService.delete(id); - return ResultVo.success("删除非对称加密成功"); - } - - /** - * 非对称加密 批量删除 - * @param ids ID 数组 - * @return ResultVo - */ - @ApiOperation(value = "批量删除非对称加密数据", notes = "批量删除非对称加密数据") - @RequiresPermissions("other_crypto_update") - @EnableLog - @Override - public ResultVo delAll(String ids){ - String[] idArray = Convert.toStrArray(ids); - IService.deleteAll(idArray); - return ResultVo.success("批量删除非对称加密成功"); - } - - - /** - * 非对称加密 Excel 导出 - * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解 - * - * 导出时,Token认证和方法权限认证 全部都由自定义完成 - * 因为在 导出不成功时,需要推送错误信息, - * 前端直接走下载流,当失败时无法获得失败信息,即使前后端换一种方式后端推送二进制文件前端再次解析也是最少2倍的耗时 - * ,且如果数据量过大,前端进行渲染时直接会把浏览器卡死 - * 而直接开启socket接口推送显然是太过浪费资源了,所以目前采用Java最原始的手段 - * response 推送 javascript代码 alert 提示报错信息 - * - * @param request request - * @param response response - */ - @ApiOperation(value = "导出Excel", notes = "导出Excel") - @RequiresPermissionsCus("other_crypto_export") - @EnableLog - @Override - public void exportExcel(HttpServletRequest request, HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "exportExcel"); - QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap()); - super.excelExport(OtherCryptoAsymmetricRestApi.TITLE, queryBuilder.build(), response, method); - } - - /** - * 非对称加密 Excel 导入 - * 注:这里 RequiresPermissions 引入的是 Shiro原生鉴权注解 - * @param request 文件流 request - * @return ResultVo - */ - @ApiOperation(value = "导入Excel", notes = "导入Excel") - @RequiresPermissions("other_crypto_import") - @EnableLog - @Override - public ResultVo importExcel(MultipartHttpServletRequest request) { - return super.importExcel(request); - } - - /** - * 非对称加密 Excel 下载导入模版 - * 注:这里 RequiresPermissionsCus 引入的是 自定义鉴权注解 - * @param response response - */ - @ApiOperation(value = "导出Excel模版", notes = "导出Excel模版") - @RequiresPermissionsCus("other_crypto_import") - @Override - public void importTemplate(HttpServletResponse response) { - // 当前方法 - Method method = ReflectUtil.getMethodByName(this.getClass(), "importTemplate"); - super.importTemplate(OtherCryptoAsymmetricRestApi.TITLE, response, method); - } - - // ======================= - - - @Override - public ResultVo getByCryptoType(String cryptoType) { - QueryWrapper wrapper = new QueryWrapper<>(); - wrapper.eq("crypto_type", cryptoType); - OtherCryptoAsymmetric entity = IService.getOne(wrapper); - - return ResultVo.success( - WrapperUtil.transformInstance(entity, OtherCryptoAsymmetricModel.class) - ); - } - - @Override - public ResultVo insertInner(OtherCryptoAsymmetricModel model) { - // 调用新增方法 - IService.insert(model); - return ResultVo.success("新增非对称加密成功"); - } -}