mirror of
https://gitee.com/lab1024/smart-admin.git
synced 2025-09-17 19:06:39 +08:00
commit
558d5c86ff
@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
@ -19,7 +21,10 @@ import java.time.LocalDateTime;
|
||||
*/
|
||||
@Data
|
||||
@TableName("t_category")
|
||||
public class CategoryEntity {
|
||||
public class CategoryEntity implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long categoryId;
|
||||
|
@ -3,6 +3,8 @@ package net.lab1024.sa.admin.module.business.category.domain.vo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -15,7 +17,10 @@ import java.util.List;
|
||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
||||
*/
|
||||
@Data
|
||||
public class CategoryTreeVO {
|
||||
public class CategoryTreeVO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "类目id")
|
||||
private Long categoryId;
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.lab1024.sa.admin.module.business.goods.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
|
||||
|
@ -3,6 +3,8 @@ package net.lab1024.sa.admin.module.system.department.domain.vo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
@ -15,7 +17,10 @@ import java.time.LocalDateTime;
|
||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
||||
*/
|
||||
@Data
|
||||
public class DepartmentVO {
|
||||
public class DepartmentVO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "部门id")
|
||||
private Long departmentId;
|
||||
|
@ -7,7 +7,7 @@ import jakarta.annotation.Resource;
|
||||
import net.lab1024.sa.base.common.controller.SupportBaseController;
|
||||
import net.lab1024.sa.base.common.domain.ResponseDTO;
|
||||
import net.lab1024.sa.base.constant.SwaggerTagConst;
|
||||
import net.lab1024.sa.base.module.support.cache.CacheService;
|
||||
import net.lab1024.sa.base.module.support.cache.service.CacheService;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
@ -1,18 +1,15 @@
|
||||
package net.lab1024.sa.base.common.json.deserializer;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.ObjectCodec;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.lab1024.sa.base.module.support.dict.domain.vo.DictValueVO;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 字典反序列化
|
||||
@ -27,7 +24,7 @@ import java.util.stream.Collectors;
|
||||
public class DictValueVoDeserializer extends JsonDeserializer<String> {
|
||||
|
||||
@Override
|
||||
public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
|
||||
public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
|
||||
List<String> list = new ArrayList<>();
|
||||
ObjectCodec objectCodec = jsonParser.getCodec();
|
||||
JsonNode listOrObjectNode = objectCodec.readTree(jsonParser);
|
||||
|
@ -68,7 +68,7 @@ public class FileConfig implements WebMvcConfigurer {
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "file.storage", name = {"mode"}, havingValue = "cloud")
|
||||
@ConditionalOnProperty(prefix = "file.storage", name = {"mode"}, havingValue = MODE_CLOUD)
|
||||
public AmazonS3 initAmazonS3() {
|
||||
ClientConfiguration clientConfig = new ClientConfiguration();
|
||||
clientConfig.setProtocol(Protocol.HTTPS);
|
||||
|
@ -33,7 +33,6 @@ public class RedisConfig {
|
||||
|
||||
@Bean
|
||||
public RedisTemplate<String, Object> redisTemplate() {
|
||||
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
|
||||
ObjectMapper om = new ObjectMapper();
|
||||
om.registerModule(new JavaTimeModule())
|
||||
.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false)
|
||||
@ -43,9 +42,11 @@ public class RedisConfig {
|
||||
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
|
||||
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
// enableDefaultTyping 官方已弃用 所以改为 activateDefaultTyping
|
||||
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
|
||||
jackson2JsonRedisSerializer.setObjectMapper(om);
|
||||
|
||||
// 由于在 SpringBoot3 中 jackson2JsonRedisSerializer.setObjectMapper 弃用,所以改为
|
||||
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(om, Object.class);
|
||||
|
||||
RedisTemplate<String, Object> template = new RedisTemplate<>();
|
||||
template.setConnectionFactory(factory);
|
||||
template.setKeySerializer(new StringRedisSerializer());
|
||||
|
@ -1,6 +1,6 @@
|
||||
package net.lab1024.sa.base.module.support.apiencrypt.advice;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.lab1024.sa.base.common.util.SmartStringUtil;
|
||||
@ -37,6 +37,9 @@ public class DecryptRequestAdvice extends RequestBodyAdviceAdapter {
|
||||
@Resource
|
||||
private ApiEncryptService apiEncryptService;
|
||||
|
||||
@Resource
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Override
|
||||
public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
|
||||
return methodParameter.hasMethodAnnotation(ApiDecrypt.class) || methodParameter.hasParameterAnnotation(ApiDecrypt.class) || methodParameter.getContainingClass().isAnnotationPresent(ApiDecrypt.class);
|
||||
@ -46,7 +49,7 @@ public class DecryptRequestAdvice extends RequestBodyAdviceAdapter {
|
||||
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
|
||||
try {
|
||||
String bodyStr = IOUtils.toString(inputMessage.getBody(), ENCODING);
|
||||
ApiEncryptForm apiEncryptForm = JSONObject.parseObject(bodyStr, ApiEncryptForm.class);
|
||||
ApiEncryptForm apiEncryptForm = objectMapper.readValue(bodyStr, ApiEncryptForm.class);
|
||||
if (SmartStringUtil.isEmpty(apiEncryptForm.getEncryptData())) {
|
||||
return inputMessage;
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.lab1024.sa.base.module.support.apiencrypt.advice;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
@ -30,7 +29,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
|
||||
|
||||
@Slf4j
|
||||
@ControllerAdvice
|
||||
public class EncryptResponseAdvice implements ResponseBodyAdvice<ResponseDTO> {
|
||||
public class EncryptResponseAdvice implements ResponseBodyAdvice<ResponseDTO<Object>> {
|
||||
|
||||
@Resource
|
||||
private ApiEncryptService apiEncryptService;
|
||||
@ -44,19 +43,18 @@ public class EncryptResponseAdvice implements ResponseBodyAdvice<ResponseDTO> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseDTO beforeBodyWrite(ResponseDTO body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
|
||||
if (body.getData() == null) {
|
||||
public ResponseDTO<Object> beforeBodyWrite(ResponseDTO<Object> body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
|
||||
if (body == null || body.getData() == null) {
|
||||
return body;
|
||||
}
|
||||
|
||||
String encrypt = null;
|
||||
try {
|
||||
encrypt = apiEncryptService.encrypt(objectMapper.writeValueAsString(body.getData()));
|
||||
String encrypt = apiEncryptService.encrypt(objectMapper.writeValueAsString(body.getData()));
|
||||
body.setData(encrypt);
|
||||
body.setDataType(DataTypeEnum.ENCRYPT.getValue());
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
body.setData(encrypt);
|
||||
body.setDataType(DataTypeEnum.ENCRYPT.getValue());
|
||||
return body;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
package net.lab1024.sa.base.module.support.cache.config;
|
||||
|
||||
import net.lab1024.sa.base.module.support.cache.service.CacheService;
|
||||
import net.lab1024.sa.base.module.support.cache.service.CaffeineCacheServiceImpl;
|
||||
import net.lab1024.sa.base.module.support.cache.service.RedisCacheServiceImpl;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 缓存配置
|
||||
*
|
||||
* @author zhoumingfa
|
||||
* @date 2025/03/28
|
||||
*/
|
||||
@Configuration
|
||||
public class CacheConfig {
|
||||
|
||||
private static final String REDIS_CACHE = "redis";
|
||||
private static final String CAFFEINE_CACHE = "caffeine";
|
||||
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = REDIS_CACHE)
|
||||
public CacheService redisCacheService() {
|
||||
return new RedisCacheServiceImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = CAFFEINE_CACHE)
|
||||
public CacheService caffeineCacheService() {
|
||||
return new CaffeineCacheServiceImpl();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package net.lab1024.sa.base.module.support.cache.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 缓存服务
|
||||
*
|
||||
* @Author 1024创新实验室: 罗伊
|
||||
* @Date 2021/10/11 20:07
|
||||
* @Wechat zhuoda1024
|
||||
* @Email lab1024@163.com
|
||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
||||
*/
|
||||
@Service
|
||||
public interface CacheService {
|
||||
|
||||
/**
|
||||
* 获取所有缓存名称
|
||||
*/
|
||||
List<String> cacheNames();
|
||||
|
||||
/**
|
||||
* 某个缓存下的所有 key
|
||||
*/
|
||||
List<String> cacheKey(String cacheName);
|
||||
|
||||
/**
|
||||
* 移除某个 key
|
||||
*/
|
||||
void removeCache(String cacheName);
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package net.lab1024.sa.base.module.support.cache;
|
||||
package net.lab1024.sa.base.module.support.cache.service;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import jakarta.annotation.Resource;
|
||||
@ -6,7 +6,6 @@ import net.lab1024.sa.base.constant.ReloadConst;
|
||||
import net.lab1024.sa.base.module.support.reload.core.annoation.SmartReload;
|
||||
import org.springframework.cache.caffeine.CaffeineCache;
|
||||
import org.springframework.cache.caffeine.CaffeineCacheManager;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@ -14,7 +13,7 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 缓存操作
|
||||
* caffeine 缓存实现
|
||||
*
|
||||
* @Author 1024创新实验室: 罗伊
|
||||
* @Date 2021/10/11 20:07
|
||||
@ -22,24 +21,23 @@ import java.util.stream.Collectors;
|
||||
* @Email lab1024@163.com
|
||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
||||
*/
|
||||
@Service
|
||||
public class CacheService {
|
||||
public class CaffeineCacheServiceImpl implements CacheService {
|
||||
|
||||
@Resource
|
||||
private CaffeineCacheManager caffeineCacheManager;
|
||||
|
||||
/**
|
||||
* 获取所有缓存名称
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public List<String> cacheNames() {
|
||||
return Lists.newArrayList(caffeineCacheManager.getCacheNames());
|
||||
}
|
||||
|
||||
/**
|
||||
* 某个缓存下的所有key
|
||||
*
|
||||
* 某个缓存下的所有 key
|
||||
*/
|
||||
@Override
|
||||
public List<String> cacheKey(String cacheName) {
|
||||
CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(cacheName);
|
||||
if (cache == null) {
|
||||
@ -50,10 +48,9 @@ public class CacheService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除某个key
|
||||
*
|
||||
* 移除某个 key
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void removeCache(String cacheName) {
|
||||
CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(cacheName);
|
||||
if (cache != null) {
|
@ -0,0 +1,86 @@
|
||||
package net.lab1024.sa.base.module.support.cache.service;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import jakarta.annotation.Resource;
|
||||
import net.lab1024.sa.base.constant.ReloadConst;
|
||||
import net.lab1024.sa.base.module.support.reload.core.annoation.SmartReload;
|
||||
import org.springframework.data.redis.cache.RedisCache;
|
||||
import org.springframework.data.redis.cache.RedisCacheManager;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* redis 缓存实现
|
||||
*
|
||||
* @author zhoumingfa
|
||||
* @date 2025/3/28
|
||||
*/
|
||||
public class RedisCacheServiceImpl implements CacheService {
|
||||
|
||||
@Resource
|
||||
private RedisCacheManager redisCacheManager;
|
||||
|
||||
@Resource
|
||||
private RedisConnectionFactory redisConnectionFactory;
|
||||
|
||||
/**
|
||||
* 获取所有缓存名称
|
||||
*/
|
||||
@Override
|
||||
public List<String> cacheNames() {
|
||||
return Lists.newArrayList(redisCacheManager.getCacheNames());
|
||||
}
|
||||
|
||||
/**
|
||||
* 某个缓存下的所有 key
|
||||
*/
|
||||
@Override
|
||||
public List<String> cacheKey(String cacheName) {
|
||||
RedisCache cache = (RedisCache) redisCacheManager.getCache(cacheName);
|
||||
if (cache == null) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
// 获取 Redis 连接
|
||||
RedisConnection connection = redisConnectionFactory.getConnection();
|
||||
// 根据指定的 key 模式获取所有匹配的键
|
||||
Set<byte[]> keys = connection.keyCommands().keys((cacheName + ":*").getBytes());
|
||||
|
||||
if (keys != null) {
|
||||
return keys.stream().map(key -> {
|
||||
String redisKey = StrUtil.str(key, "utf-8");
|
||||
// 从 Redis 键中提取出最后一个冒号后面的字符串作为真正的键
|
||||
return redisKey.substring(redisKey.lastIndexOf(":") + 1);
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
connection.close();
|
||||
return Lists.newArrayList(cacheName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除某个 key
|
||||
*/
|
||||
@Override
|
||||
public void removeCache(String cacheName) {
|
||||
RedisCache cache = (RedisCache) redisCacheManager.getCache(cacheName);
|
||||
if (cache != null) {
|
||||
cache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@SmartReload(ReloadConst.CACHE_SERVICE)
|
||||
public void clearAllCache() {
|
||||
Collection<String> cacheNames = redisCacheManager.getCacheNames();
|
||||
for (String name : cacheNames) {
|
||||
RedisCache cache = (RedisCache) redisCacheManager.getCache(name);
|
||||
if (cache != null) {
|
||||
cache.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -107,16 +107,14 @@ public class DictCacheService {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<DictValueVO> dictValueVOList = DICT_CACHE.get(valueCode);
|
||||
List<DictValueVO> dictValueVOList = DICT_CACHE.get(keyCode);
|
||||
if (CollectionUtils.isEmpty(dictValueVOList)) {
|
||||
return null;
|
||||
}
|
||||
Optional<DictValueVO> option = dictValueVOList.stream().filter(e->e.getValueCode().equals(valueCode)).findFirst();
|
||||
if(option.isPresent()){
|
||||
return option.get();
|
||||
}
|
||||
return null;
|
||||
return option.orElse(null);
|
||||
}
|
||||
|
||||
public String selectValueNameByValueCodeSplit(String keyCode, String valueCodes) {
|
||||
if (StrUtil.isEmpty(valueCodes)) {
|
||||
return "";
|
||||
|
@ -9,7 +9,7 @@
|
||||
<if test="query.searchWord != null and query.searchWord != '' ">
|
||||
AND (
|
||||
INSTR(feedback_content,#{query.searchWord})
|
||||
OR INSTR(create_name,#{query.searchWord})
|
||||
OR INSTR(user_name,#{query.searchWord})
|
||||
)
|
||||
</if>
|
||||
<if test="query.startDate != null">
|
||||
|
@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
@ -19,7 +20,9 @@ import java.time.LocalDateTime;
|
||||
*/
|
||||
@Data
|
||||
@TableName("t_category")
|
||||
public class CategoryEntity {
|
||||
public class CategoryEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long categoryId;
|
||||
|
@ -3,6 +3,7 @@ package net.lab1024.sa.admin.module.business.category.domain.vo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -15,7 +16,9 @@ import java.util.List;
|
||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
||||
*/
|
||||
@Data
|
||||
public class CategoryTreeVO {
|
||||
public class CategoryTreeVO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "类目id")
|
||||
private Long categoryId;
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.lab1024.sa.admin.module.business.goods.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
|
||||
|
@ -3,6 +3,7 @@ package net.lab1024.sa.admin.module.system.department.domain.vo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
@ -15,7 +16,9 @@ import java.time.LocalDateTime;
|
||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
||||
*/
|
||||
@Data
|
||||
public class DepartmentVO {
|
||||
public class DepartmentVO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "部门id")
|
||||
private Long departmentId;
|
||||
|
@ -6,7 +6,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
||||
import net.lab1024.sa.base.common.controller.SupportBaseController;
|
||||
import net.lab1024.sa.base.common.domain.ResponseDTO;
|
||||
import net.lab1024.sa.base.constant.SwaggerTagConst;
|
||||
import net.lab1024.sa.base.module.support.cache.CacheService;
|
||||
import net.lab1024.sa.base.module.support.cache.cache.service.CacheService;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
@ -1,18 +1,15 @@
|
||||
package net.lab1024.sa.base.common.json.deserializer;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.ObjectCodec;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.lab1024.sa.base.module.support.dict.domain.vo.DictValueVO;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 字典反序列化
|
||||
@ -27,7 +24,7 @@ import java.util.stream.Collectors;
|
||||
public class DictValueVoDeserializer extends JsonDeserializer<String> {
|
||||
|
||||
@Override
|
||||
public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
|
||||
public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
|
||||
List<String> list = new ArrayList<>();
|
||||
ObjectCodec objectCodec = jsonParser.getCodec();
|
||||
JsonNode listOrObjectNode = objectCodec.readTree(jsonParser);
|
||||
|
@ -68,7 +68,7 @@ public class FileConfig implements WebMvcConfigurer {
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "file.storage", name = {"mode"}, havingValue = "cloud")
|
||||
@ConditionalOnProperty(prefix = "file.storage", name = {"mode"}, havingValue = MODE_CLOUD)
|
||||
public AmazonS3 initAmazonS3() {
|
||||
ClientConfiguration clientConfig = new ClientConfiguration();
|
||||
clientConfig.setProtocol(Protocol.HTTPS);
|
||||
|
@ -1,6 +1,6 @@
|
||||
package net.lab1024.sa.base.module.support.apiencrypt.advice;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.lab1024.sa.base.common.util.SmartStringUtil;
|
||||
import net.lab1024.sa.base.module.support.apiencrypt.annotation.ApiDecrypt;
|
||||
@ -37,6 +37,9 @@ public class DecryptRequestAdvice extends RequestBodyAdviceAdapter {
|
||||
@Resource
|
||||
private ApiEncryptService apiEncryptService;
|
||||
|
||||
@Resource
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Override
|
||||
public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
|
||||
return methodParameter.hasMethodAnnotation(ApiDecrypt.class) || methodParameter.hasParameterAnnotation(ApiDecrypt.class) || methodParameter.getContainingClass().isAnnotationPresent(ApiDecrypt.class);
|
||||
@ -46,7 +49,7 @@ public class DecryptRequestAdvice extends RequestBodyAdviceAdapter {
|
||||
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
|
||||
try {
|
||||
String bodyStr = IOUtils.toString(inputMessage.getBody(), ENCODING);
|
||||
ApiEncryptForm apiEncryptForm = JSONObject.parseObject(bodyStr, ApiEncryptForm.class);
|
||||
ApiEncryptForm apiEncryptForm = objectMapper.readValue(bodyStr, ApiEncryptForm.class);
|
||||
if (SmartStringUtil.isEmpty(apiEncryptForm.getEncryptData())) {
|
||||
return inputMessage;
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.lab1024.sa.base.module.support.apiencrypt.advice;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -31,7 +30,7 @@ import javax.annotation.Resource;
|
||||
|
||||
@Slf4j
|
||||
@ControllerAdvice
|
||||
public class EncryptResponseAdvice implements ResponseBodyAdvice<ResponseDTO> {
|
||||
public class EncryptResponseAdvice implements ResponseBodyAdvice<ResponseDTO<Object>> {
|
||||
|
||||
@Resource
|
||||
private ApiEncryptService apiEncryptService;
|
||||
@ -45,19 +44,18 @@ public class EncryptResponseAdvice implements ResponseBodyAdvice<ResponseDTO> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseDTO beforeBodyWrite(ResponseDTO body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
|
||||
if (body.getData() == null) {
|
||||
public ResponseDTO<Object> beforeBodyWrite(ResponseDTO<Object> body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
|
||||
if (body == null || body.getData() == null) {
|
||||
return body;
|
||||
}
|
||||
|
||||
String encrypt = null;
|
||||
try {
|
||||
encrypt = apiEncryptService.encrypt(objectMapper.writeValueAsString(body.getData()));
|
||||
String encrypt = apiEncryptService.encrypt(objectMapper.writeValueAsString(body.getData()));
|
||||
body.setData(encrypt);
|
||||
body.setDataType(DataTypeEnum.ENCRYPT.getValue());
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
body.setData(encrypt);
|
||||
body.setDataType(DataTypeEnum.ENCRYPT.getValue());
|
||||
return body;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
package net.lab1024.sa.base.module.support.cache.cache.config;
|
||||
|
||||
import net.lab1024.sa.base.module.support.cache.cache.service.CacheService;
|
||||
import net.lab1024.sa.base.module.support.cache.cache.service.CaffeineCacheServiceImpl;
|
||||
import net.lab1024.sa.base.module.support.cache.cache.service.RedisCacheServiceImpl;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 缓存配置
|
||||
*
|
||||
* @author zhoumingfa
|
||||
* @date 2025/03/28
|
||||
*/
|
||||
@Configuration
|
||||
public class CacheConfig {
|
||||
|
||||
private static final String REDIS_CACHE = "redis";
|
||||
private static final String CAFFEINE_CACHE = "caffeine";
|
||||
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = REDIS_CACHE)
|
||||
public CacheService redisCacheService() {
|
||||
return new RedisCacheServiceImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = CAFFEINE_CACHE)
|
||||
public CacheService caffeineCacheService() {
|
||||
return new CaffeineCacheServiceImpl();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package net.lab1024.sa.base.module.support.cache.cache.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 缓存服务
|
||||
*
|
||||
* @Author 1024创新实验室: 罗伊
|
||||
* @Date 2021/10/11 20:07
|
||||
* @Wechat zhuoda1024
|
||||
* @Email lab1024@163.com
|
||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
||||
*/
|
||||
@Service
|
||||
public interface CacheService {
|
||||
|
||||
/**
|
||||
* 获取所有缓存名称
|
||||
*/
|
||||
List<String> cacheNames();
|
||||
|
||||
/**
|
||||
* 某个缓存下的所有 key
|
||||
*/
|
||||
List<String> cacheKey(String cacheName);
|
||||
|
||||
/**
|
||||
* 移除某个 key
|
||||
*/
|
||||
void removeCache(String cacheName);
|
||||
|
||||
}
|
@ -1,11 +1,10 @@
|
||||
package net.lab1024.sa.base.module.support.cache;
|
||||
package net.lab1024.sa.base.module.support.cache.cache.service;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import net.lab1024.sa.base.constant.ReloadConst;
|
||||
import net.lab1024.sa.base.module.support.reload.core.annoation.SmartReload;
|
||||
import org.springframework.cache.caffeine.CaffeineCache;
|
||||
import org.springframework.cache.caffeine.CaffeineCacheManager;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
@ -14,7 +13,7 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 缓存操作
|
||||
* caffeine 缓存实现
|
||||
*
|
||||
* @Author 1024创新实验室: 罗伊
|
||||
* @Date 2021/10/11 20:07
|
||||
@ -22,24 +21,23 @@ import java.util.stream.Collectors;
|
||||
* @Email lab1024@163.com
|
||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
||||
*/
|
||||
@Service
|
||||
public class CacheService {
|
||||
public class CaffeineCacheServiceImpl implements CacheService {
|
||||
|
||||
@Resource
|
||||
private CaffeineCacheManager caffeineCacheManager;
|
||||
|
||||
/**
|
||||
* 获取所有缓存名称
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public List<String> cacheNames() {
|
||||
return Lists.newArrayList(caffeineCacheManager.getCacheNames());
|
||||
}
|
||||
|
||||
/**
|
||||
* 某个缓存下的所有key
|
||||
*
|
||||
* 某个缓存下的所有 key
|
||||
*/
|
||||
@Override
|
||||
public List<String> cacheKey(String cacheName) {
|
||||
CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(cacheName);
|
||||
if (cache == null) {
|
||||
@ -50,10 +48,9 @@ public class CacheService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除某个key
|
||||
*
|
||||
* 移除某个 key
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void removeCache(String cacheName) {
|
||||
CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(cacheName);
|
||||
if (cache != null) {
|
@ -0,0 +1,86 @@
|
||||
package net.lab1024.sa.base.module.support.cache.cache.service;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import net.lab1024.sa.base.constant.ReloadConst;
|
||||
import net.lab1024.sa.base.module.support.reload.core.annoation.SmartReload;
|
||||
import org.springframework.data.redis.cache.RedisCache;
|
||||
import org.springframework.data.redis.cache.RedisCacheManager;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* redis 缓存实现
|
||||
*
|
||||
* @author zhoumingfa
|
||||
* @date 2025/3/28
|
||||
*/
|
||||
public class RedisCacheServiceImpl implements CacheService {
|
||||
|
||||
@Resource
|
||||
private RedisCacheManager redisCacheManager;
|
||||
|
||||
@Resource
|
||||
private RedisConnectionFactory redisConnectionFactory;
|
||||
|
||||
/**
|
||||
* 获取所有缓存名称
|
||||
*/
|
||||
@Override
|
||||
public List<String> cacheNames() {
|
||||
return Lists.newArrayList(redisCacheManager.getCacheNames());
|
||||
}
|
||||
|
||||
/**
|
||||
* 某个缓存下的所有 key
|
||||
*/
|
||||
@Override
|
||||
public List<String> cacheKey(String cacheName) {
|
||||
RedisCache cache = (RedisCache) redisCacheManager.getCache(cacheName);
|
||||
if (cache == null) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
// 获取 Redis 连接
|
||||
RedisConnection connection = redisConnectionFactory.getConnection();
|
||||
// 根据指定的 key 模式获取所有匹配的键
|
||||
Set<byte[]> keys = connection.keyCommands().keys((cacheName + ":*").getBytes());
|
||||
|
||||
if (keys != null) {
|
||||
return keys.stream().map(key -> {
|
||||
String redisKey = StrUtil.str(key, "utf-8");
|
||||
// 从 Redis 键中提取出最后一个冒号后面的字符串作为真正的键
|
||||
return redisKey.substring(redisKey.lastIndexOf(":") + 1);
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
connection.close();
|
||||
return Lists.newArrayList(cacheName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除某个 key
|
||||
*/
|
||||
@Override
|
||||
public void removeCache(String cacheName) {
|
||||
RedisCache cache = (RedisCache) redisCacheManager.getCache(cacheName);
|
||||
if (cache != null) {
|
||||
cache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@SmartReload(ReloadConst.CACHE_SERVICE)
|
||||
public void clearAllCache() {
|
||||
Collection<String> cacheNames = redisCacheManager.getCacheNames();
|
||||
for (String name : cacheNames) {
|
||||
RedisCache cache = (RedisCache) redisCacheManager.getCache(name);
|
||||
if (cache != null) {
|
||||
cache.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -107,16 +107,14 @@ public class DictCacheService {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<DictValueVO> dictValueVOList = DICT_CACHE.get(valueCode);
|
||||
List<DictValueVO> dictValueVOList = DICT_CACHE.get(keyCode);
|
||||
if (CollectionUtils.isEmpty(dictValueVOList)) {
|
||||
return null;
|
||||
}
|
||||
Optional<DictValueVO> option = dictValueVOList.stream().filter(e->e.getValueCode().equals(valueCode)).findFirst();
|
||||
if(option.isPresent()){
|
||||
return option.get();
|
||||
}
|
||||
return null;
|
||||
return option.orElse(null);
|
||||
}
|
||||
|
||||
public String selectValueNameByValueCodeSplit(String keyCode, String valueCodes) {
|
||||
if (StrUtil.isEmpty(valueCodes)) {
|
||||
return "";
|
||||
|
@ -9,7 +9,7 @@
|
||||
<if test="query.searchWord != null and query.searchWord != '' ">
|
||||
AND (
|
||||
INSTR(feedback_content,#{query.searchWord})
|
||||
OR INSTR(create_name,#{query.searchWord})
|
||||
OR INSTR(user_name,#{query.searchWord})
|
||||
)
|
||||
</if>
|
||||
<if test="query.startDate != null">
|
||||
|
@ -1,11 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<template v-for="(item, index) in options">
|
||||
<template v-if="values.includes(item.valueCode)">
|
||||
{{ item.valueName }}
|
||||
<span> </span>
|
||||
</template>
|
||||
</template>
|
||||
<span>{{ dictValueName }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -21,8 +16,11 @@
|
||||
// 当前的值
|
||||
value: [Number, String, Array],
|
||||
});
|
||||
const values = computed(() => {
|
||||
if (props.value === null || typeof props.value === 'undefined' || props.value === '') return [];
|
||||
return Array.isArray(props.value) ? props.value.map((item) => item.valueCode) : props.value.split(',');
|
||||
const dictValueName = computed(() => {
|
||||
if (props.value === null || typeof props.value === 'undefined' || props.value === '') return '';
|
||||
const valueCodeList = Array.isArray(props.value) ? props.value.map((item) => item.valueCode) : props.value.split(',');
|
||||
const valueNameList = props.options.filter((item) => valueCodeList.includes(item.valueCode)).map((item) => item.valueName);
|
||||
|
||||
return valueNameList.join(',');
|
||||
});
|
||||
</script>
|
||||
|
@ -120,7 +120,7 @@
|
||||
{{ text }}
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'place'">
|
||||
<DictPreview :options="descList.GOODS_PLACE" :value="text" />
|
||||
<DictPreview :options="descList['GOODS_PLACE']" :value="text" />
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'remark'">
|
||||
<span>{{ text ? text : '' }}</span>
|
||||
@ -199,7 +199,6 @@
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import TableOperator from '/@/components/support/table-operator/index.vue';
|
||||
import { TABLE_ID_CONST } from '/@/constants/support/table-id-const';
|
||||
import { GOODS_STATUS_ENUM } from '/@/constants/business/erp/goods-const';
|
||||
import DictSelect from '/@/components/support/dict-select/index.vue';
|
||||
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
|
||||
import _ from 'lodash';
|
||||
@ -236,7 +235,6 @@
|
||||
title: '商品状态',
|
||||
dataIndex: 'goodsStatus',
|
||||
resizable: true,
|
||||
sorter: true,
|
||||
filterOptions: {
|
||||
type: 'enum-select',
|
||||
enumName: 'GOODS_STATUS_ENUM',
|
||||
|
@ -56,7 +56,7 @@
|
||||
row-key="employeeId"
|
||||
bordered
|
||||
>
|
||||
<template #bodyCell="{ text, record, index, column }">
|
||||
<template #bodyCell="{ text, record, column }">
|
||||
<template v-if="column.dataIndex === 'administratorFlag'">
|
||||
<a-tag color="error" v-if="text">超管</a-tag>
|
||||
</template>
|
||||
|
@ -1,11 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<template v-for="(item, index) in options">
|
||||
<template v-if="values.includes(item.valueCode)">
|
||||
{{ item.valueName }}
|
||||
<span> </span>
|
||||
</template>
|
||||
</template>
|
||||
<span>{{ dictValueName }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -21,8 +16,11 @@
|
||||
// 当前的值
|
||||
value: [Number, String, Array],
|
||||
});
|
||||
const values = computed(() => {
|
||||
if (props.value === null || typeof props.value === 'undefined' || props.value === '') return [];
|
||||
return Array.isArray(props.value) ? props.value.map((item) => item.valueCode) : props.value.split(',');
|
||||
const dictValueName = computed(() => {
|
||||
if (props.value === null || typeof props.value === 'undefined' || props.value === '') return '';
|
||||
const valueCodeList = Array.isArray(props.value) ? props.value.map((item) => item.valueCode) : props.value.split(',');
|
||||
const valueNameList = props.options.filter((item) => valueCodeList.includes(item.valueCode)).map((item) => item.valueName);
|
||||
|
||||
return valueNameList.join(',');
|
||||
});
|
||||
</script>
|
||||
|
@ -120,7 +120,7 @@
|
||||
{{ text }}
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'place'">
|
||||
<DictPreview :options="descList.GOODS_PLACE" :value="text" />
|
||||
<DictPreview :options="descList['GOODS_PLACE']" :value="text" />
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'remark'">
|
||||
<span>{{ text ? text : '' }}</span>
|
||||
@ -234,7 +234,6 @@
|
||||
title: '商品状态',
|
||||
dataIndex: 'goodsStatus',
|
||||
resizable: true,
|
||||
sorter: true,
|
||||
filterOptions: {
|
||||
type: 'enum-select',
|
||||
enumName: 'GOODS_STATUS_ENUM',
|
||||
|
@ -56,7 +56,7 @@
|
||||
row-key="employeeId"
|
||||
bordered
|
||||
>
|
||||
<template #bodyCell="{ text, record, index, column }">
|
||||
<template #bodyCell="{ text, record, column }">
|
||||
<template v-if="column.dataIndex === 'administratorFlag'">
|
||||
<a-tag color="error" v-if="text">超管</a-tag>
|
||||
</template>
|
||||
|
@ -204,7 +204,7 @@ CREATE TABLE `t_dict_key` (
|
||||
-- ----------------------------
|
||||
-- Records of t_dict_key
|
||||
-- ----------------------------
|
||||
INSERT INTO `t_dict_key` VALUES (1, 'GODOS_PLACE', '商品产地', '商品产地的字典', 0, '2022-10-04 21:33:50', '2022-10-04 21:33:50');
|
||||
INSERT INTO `t_dict_key` VALUES (1, 'GOODS_PLACE', '商品产地', '商品产地的字典', 0, '2022-10-04 21:33:50', '2022-10-04 21:33:50');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_dict_value
|
||||
|
Loading…
Reference in New Issue
Block a user