!62 Bug修复及细节优化

Merge pull request !62 from 大熊/master
This commit is contained in:
1024创新实验室 2025-03-29 15:49:56 +00:00 committed by Gitee
commit 558d5c86ff
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
38 changed files with 421 additions and 109 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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());

View File

@ -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;
}

View File

@ -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;
}
}

View File

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

View File

@ -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);
}

View File

@ -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) {

View File

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

View File

@ -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 "";

View File

@ -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">

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}
}

View File

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

View File

@ -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);
}

View File

@ -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) {

View File

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

View File

@ -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 "";

View File

@ -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">

View File

@ -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>

View File

@ -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',

View File

@ -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>

View File

@ -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>

View File

@ -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',

View File

@ -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>

View File

@ -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