接口加密优化为在线配置

v1.4.1
Parker 5 years ago
parent 6e9ad77ec4
commit da41a11e32

@ -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<String, String> params);
/**
*
* @param id ID
@ -150,6 +160,13 @@ public interface OptionsApi {
@GetMapping("/getByCode")
ResultVo<OptionsModel> getByCode(String optionCode);
/**
*
* @return ResultVo
*/
@GetMapping("/findAllOptions")
ResultVo<Map<String, OptionsModel>> findAllOptions();
/**
*
* @return ResultVo

@ -1,162 +0,0 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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<OtherCryptoAsymmetricModel> 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
*
* socketJava
* 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<OtherCryptoAsymmetricModel> getByCryptoType(String optionCode);
// ===================
/**
*
* @param model
* @return ResultVo
*/
ResultVo<?> insertInner(@RequestBody OtherCryptoAsymmetricModel model);
}

@ -1,72 +0,0 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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;
}

@ -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<String, Object> getHashAll(final String key){
try {
// 缓存 Key
String cacheKey = CacheUtil.handleKey(CacheType.EDEN_HASH, key);
Map<String, Object> retMap = Maps.newHashMap();
// 如果本地缓存找不到该缓存 则去远端缓存拉去缓存
Map<Object, Object> allCache = redisPlugin.hGetAll(cacheKey);
if(CollUtil.isEmpty(allCache)){
return retMap;
}
for (Map.Entry<Object, Object> 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 =========================

@ -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<OtherCryptoAsymmetricModel> 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(){}
}

@ -229,72 +229,65 @@ public class DictUtil {
// 缓存Key
String cacheKey = DictConstants.CACHE_PREFIX_NAME + typeCode;
List<DictWrapper> dictWrapperModels;
// 处理集合数据
List<DictWrapper> 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<List<DictDetailModel>> resultVo = dictDetailApi.findListByTypeCode(typeCode);
if(resultVo.isSuccess()){
List<DictDetailModel> 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<List<DictDetailModel>> resultVo = dictDetailApi.findListByTypeCode(typeCode);
if(resultVo.isSuccess()){
List<DictDetailModel> 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<DictWrapper> handleDictList(Map<Object, Object> dictMap, String typeCode){
if(CollUtil.isEmpty(dictMap)){
return null;
}
public static List<DictWrapper> handleDictList(Map<String, Object> dictMap, String typeCode){
List<DictWrapper> dictWrapperModels = Lists.newArrayList();
for (Map.Entry<Object, Object> 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<String, Object> 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;
}

@ -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<String, OptionsModel> findAllOptions(){
ResultVo<List<OptionsModel>> optionsApiAll = optionsApi.findAll();
if(optionsApiAll == null || !optionsApiAll.isSuccess()){
return null;
List<OptionsModel> optionsModels;
Map<String, OptionsModel> optionsModelMap;
// 处理集合数据
optionsModels = handleOptionsList(
CacheUtil.getHashAll(PREFIX_CODE));
// 转换对象
optionsModelMap = convertOptionsMap(optionsModels);
if(CollUtil.isNotEmpty(optionsModelMap)){
return optionsModelMap;
}
List<OptionsModel> optionsModels = optionsApiAll.getData();
if(CollUtil.isEmpty(optionsModels)){
return null;
// 防止缓存穿透判断
boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_CODE);
if(hasNilFlag){
return optionsModelMap;
}
Map<String, OptionsModel> 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<List<OptionsModel>> optionsApiAll = optionsApi.findAll();
if(optionsApiAll.isSuccess()){
// 处理数据
optionsModelMap = convertOptionsMap(optionsApiAll.getData());
if(CollUtil.isNotEmpty(optionsModelMap)){
// 保存至缓存
for (Map.Entry<String, OptionsModel> 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<OptionsModel> handleOptionsList(Map<String, Object> optionsMap){
if(CollUtil.isEmpty(optionsMap)){
return null;
}
List<OptionsModel> optionsModels = Lists.newArrayList();
for (Map.Entry<String, Object> 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<String, OptionsModel> convertOptionsMap(List<OptionsModel> optionsModels){
// 这里不管有没有 都返回一个集合 防止多做一步null处理
Map<String, OptionsModel> 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) {

@ -85,6 +85,7 @@ public enum SystemMsg implements BaseMsg {
*
*/
EXCEPTION_OPTIONS_UNIQUE(20700,"参数编号重复,该角色已存在"),
EXCEPTION_OPTIONS_UPDATE(20701,"更新异常"),
/**

@ -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()
);
}
// 失败

@ -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<SysOptions, OptionsModel> {
/**
*
* @param params
*/
void updateOptions(Map<String, String> params);
}

@ -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<SysOptionsMapper, Sys
return model;
}
@Transactional(rollbackFor = Exception.class)
@Override
public void updateOptions(Map<String, String> params) {
if(CollUtil.isEmpty(params)){
// 更新异常
throw new ServiceException(SystemMsg.EXCEPTION_OPTIONS_UPDATE);
}
List<String> optionsCode = Lists.newArrayList();
optionsCode.addAll(params.keySet());
// 获得所有的原始内容
QueryWrapper<SysOptions> queryWrapper = new QueryWrapper<>();
queryWrapper.in("option_code", optionsCode);
List<SysOptions> optionsList = this.findList(queryWrapper);
Map<String, OptionsModel> resourceDataDict = Maps.newHashMap();
for (SysOptions option : optionsList) {
resourceDataDict.put(option.getOptionCode(),
transformT2M(option)
);
}
// 循环修改
for (Map.Entry<String, String> 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) {

@ -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<SysOptions, Opt
* @return ResultVo
*/
@ApiOperation(value = "获得单条系统参数", notes = "获得单条系统参数 - ID")
@RequiresPermissions("sys_options_select")
@RequiresPermissions("system_options_select")
@Override
public ResultVo<OptionsModel> get(OptionsModel model) {
// 如果系统内部调用 则直接查数据库
@ -87,7 +88,7 @@ public class SysOptionsRestController extends BaseRestController<SysOptions, Opt
* @return ResultVo
*/
@ApiOperation(value = "获得分页数据", notes = "获得分页数据 - 查询构造器")
@RequiresPermissions("sys_options_select")
@RequiresPermissions("system_options_select")
@Override
public ResultVo<?> findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) {
@ -105,7 +106,7 @@ public class SysOptionsRestController extends BaseRestController<SysOptions, Opt
* @return ResultVo
*/
@ApiOperation(value = "新增系统参数数据", notes = "新增系统参数数据")
@RequiresPermissions("sys_options_insert")
@RequiresPermissions("system_options_insert")
@EnableLog
@Override
public ResultVo<?> insert(OptionsModel model) {
@ -120,7 +121,7 @@ public class SysOptionsRestController extends BaseRestController<SysOptions, Opt
* @return ResultVo
*/
@ApiOperation(value = "修改系统参数数据", notes = "修改系统参数数据")
@RequiresPermissions("sys_options_update")
@RequiresPermissions("system_options_update")
@EnableLog
@Override
public ResultVo<?> update(OptionsModel model) {
@ -129,6 +130,21 @@ public class SysOptionsRestController extends BaseRestController<SysOptions, Opt
return ResultVo.success("修改系统参数成功");
}
/**
*
* @param params Map
* @return ResultVo
*/
@ApiOperation(value = "修改系统参数数据", notes = "修改系统参数数据")
@RequiresPermissions("system_options_update")
@EnableLog
@Override
public ResultVo<?> updateOptions(Map<String, String> params) {
// 调用修改方法
IService.updateOptions(params);
return ResultVo.success("保存参数成功");
}
/**
*
@ -136,7 +152,7 @@ public class SysOptionsRestController extends BaseRestController<SysOptions, Opt
* @return ResultVo
*/
@ApiOperation(value = "删除系统参数数据", notes = "删除系统参数数据")
@RequiresPermissions("sys_options_update")
@RequiresPermissions("system_options_update")
@EnableLog
@Override
public ResultVo<?> del(String id){
@ -150,7 +166,7 @@ public class SysOptionsRestController extends BaseRestController<SysOptions, Opt
* @return ResultVo
*/
@ApiOperation(value = "批量删除系统参数数据", notes = "批量删除系统参数数据")
@RequiresPermissions("sys_options_update")
@RequiresPermissions("system_options_update")
@EnableLog
@Override
public ResultVo<?> delAll(String ids){
@ -175,7 +191,7 @@ public class SysOptionsRestController extends BaseRestController<SysOptions, Opt
* @param response response
*/
@ApiOperation(value = "导出Excel", notes = "导出Excel")
@RequiresPermissionsCus("sys_options_export")
@RequiresPermissionsCus("system_options_export")
@EnableLog
@Override
public void exportExcel(HttpServletRequest request, HttpServletResponse response) {
@ -192,7 +208,7 @@ public class SysOptionsRestController extends BaseRestController<SysOptions, Opt
* @return ResultVo
*/
@ApiOperation(value = "导入Excel", notes = "导入Excel")
@RequiresPermissions("sys_options_import")
@RequiresPermissions("system_options_import")
@EnableLog
@Override
public ResultVo<?> importExcel(MultipartHttpServletRequest request) {
@ -205,7 +221,7 @@ public class SysOptionsRestController extends BaseRestController<SysOptions, Opt
* @param response response
*/
@ApiOperation(value = "导出Excel模版", notes = "导出Excel模版")
@RequiresPermissionsCus("sys_options_import")
@RequiresPermissionsCus("system_options_import")
@Override
public void importTemplate(HttpServletResponse response) {
// 当前方法
@ -237,6 +253,17 @@ public class SysOptionsRestController extends BaseRestController<SysOptions, Opt
* @return ResultVo
*/
@Override
public ResultVo<Map<String, OptionsModel>> findAllOptions() {
return ResultVo.success(
OptionsUtil.findAllOptions()
);
}
/**
* List
* @return ResultVo
*/
@Override
public ResultVo<List<OptionsModel>> findAll() {
return ResultVo.success(
WrapperUtil.transformInstance(IService.findAllList(), OptionsModel.class)
@ -249,6 +276,8 @@ public class SysOptionsRestController extends BaseRestController<SysOptions, Opt
* @return ResultVo
*/
@Override
@ApiOperation(value = "创建加密 公私钥", notes = "创建加密 公私钥")
@RequiresPermissions("system_options_update")
public ResultVo<?> createCrypto(String type) {
CryptoAsymmetricType cryptoType = CryptoAsymmetricType.getCryptoType(type);
if(cryptoType == null){

@ -1,86 +0,0 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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;
}

@ -1,37 +0,0 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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<OtherCryptoAsymmetric> {
}

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.opsli.modulars.system.other.crypto.mapper.OtherCryptoAsymmetricMapper">
</mapper>

@ -1,45 +0,0 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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<OtherCryptoAsymmetric, OtherCryptoAsymmetricModel> {
/***
*
* @param type
* @return OtherCryptoAsymmetricModel
*/
OtherCryptoAsymmetricModel reset(CryptoAsymmetricType type);
}

@ -1,192 +0,0 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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<OtherCryptoAsymmetricMapper, OtherCryptoAsymmetric, OtherCryptoAsymmetricModel>
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<OtherCryptoAsymmetric> queryWrapper = new QueryWrapper<>();
queryWrapper.in(MyBatisConstants.FIELD_ID, Convert.toList(String.class, ids));
List<OtherCryptoAsymmetricModel> 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<OtherCryptoAsymmetric> 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<OtherCryptoAsymmetric> 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<OtherCryptoAsymmetricModel> 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);
}
}
}
}

@ -1,239 +0,0 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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<OtherCryptoAsymmetric, OtherCryptoAsymmetricModel, IOtherCryptoAsymmetricService>
implements OtherCryptoAsymmetricRestApi {
/**
*
* @param model
* @return ResultVo
*/
@ApiOperation(value = "获得单条非对称加密", notes = "获得单条非对称加密 - ID")
@RequiresPermissions("other_crypto_select")
@Override
public ResultVo<OtherCryptoAsymmetricModel> 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<OtherCryptoAsymmetric> queryBuilder = new WebQueryBuilder<>(entityClazz, request.getParameterMap());
Page<OtherCryptoAsymmetric, OtherCryptoAsymmetricModel> 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
*
* socketJava
* 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<OtherCryptoAsymmetric> 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<OtherCryptoAsymmetricModel> getByCryptoType(String cryptoType) {
QueryWrapper<OtherCryptoAsymmetric> 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("新增非对称加密成功");
}
}
Loading…
Cancel
Save