perf: 优化部分工具代码,提高兼容性

pull/25/head
Parker 2 years ago
parent 1b7d7038ec
commit 0ce0f85821

@ -80,5 +80,7 @@ public final class RedisConstants {
/** Excel 导出 凭证 */
public static final String PREFIX_TMP_EXCEL_EXPORT_NAME = "kv#{}:excel-export:";
public static final String PREFIX_ID_INCR = "kv#{}:id_incr:";
private RedisConstants(){}
}

@ -15,6 +15,8 @@
*/
package org.opsli.core.autoconfigure.conf;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.extern.slf4j.Slf4j;
import org.opsli.common.annotation.ApiRestController;
import org.opsli.core.api.ApiRequestMappingHandlerMapping;
@ -23,6 +25,8 @@ import org.opsli.core.filters.interceptor.UserAuthInterceptor;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@ -87,4 +91,13 @@ public class SpringWebMvcConfig implements WebMvcConfigurer, WebMvcRegistrations
registry.addInterceptor(new UserAuthInterceptor());
WebMvcConfigurer.super.addInterceptors(registry);
}
@Bean
public MappingJackson2HttpMessageConverter getMappingJackson2HttpMessageConverter() {
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json()
.serializerByType(Long.class, ToStringSerializer.instance)
.serializerByType(Long.TYPE, ToStringSerializer.instance)
.build();
return new MappingJackson2HttpMessageConverter(objectMapper);
}
}

@ -0,0 +1,142 @@
package org.opsli.core.factory;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.opsli.common.constants.RedisConstants;
import org.opsli.core.cache.CacheUtil;
import org.opsli.core.utils.EnvPrefixTool;
import org.springframework.data.redis.core.RedisTemplate;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.concurrent.TimeUnit;
/**
*
*
* @author parker
* @date 2022/1/13 18:28
*/
@Slf4j
@AllArgsConstructor
public class CodeFactory {
/** 压缩秒格式 */
private final static String FORMAT_COMPRESS_SECOND = "yyyyMMddHHmmss";
/** 默认1分钟不会超过 10000个订单 */
private final static int TTL = 60;
/** 自增ID 前缀 */
private final static String INCR_PREFIX_BIZ = "biz_";
/**
*
* +2++++ 14 10000
*
* @param redisTemplate redisTemplate
* @param bizTag
* @return String
*/
public String generateSoleNo(RedisTemplate<String, String> redisTemplate, String bizTag){
if(null == redisTemplate){
throw new RuntimeException("RedisTemplate 为空");
}
// 格式化 业务号
final String formatBizTag = EnvPrefixTool.getEnvBizTag(bizTag);
LocalDateTime localDateTime = LocalDateTime.now();
// 当前时间 到日
String formatDate = DateUtil.format(DateUtil.date(localDateTime), "yyyyMMdd");
// 日期前缀
String prefixDate = StrUtil.sub(formatDate, 2, formatDate.length());
// 已走过秒
int secondCount = (int) (getTimeMillsSecond(localDateTime)/1000 - getTimeMillsDay(localDateTime)/1000);
String prefixSecond = StrUtil.fillBefore(String.valueOf(secondCount), '0', 5);
// 获得自增ID
String incrementId = getIncrementId(redisTemplate, INCR_PREFIX_BIZ, formatBizTag);
return formatBizTag + prefixDate + prefixSecond
+ incrementId;
}
/**
* UUID
*
* @return String
*/
public String generateUUID(){
return StrUtil.uuid();
}
/**
* ID
* @param redisTemplate redisTemplate
* @param prefix
* @param tag
* @return long
*/
private String getIncrementId(RedisTemplate<String, String> redisTemplate, String prefix, String tag) {
// 自增ID
Long incrementId;
// 缓存Key
String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_ID_INCR)
+ prefix + tag;
// 判断是否存在
incrementId = redisTemplate.opsForValue().increment(cacheKey);
if(null == incrementId){
throw new RuntimeException("Redis 生成自增ID 失败");
}
Long expire = redisTemplate.getExpire(cacheKey, TimeUnit.SECONDS);
if(null == expire || expire < 0){
// 设置 60 秒失效
redisTemplate.expire(cacheKey, TTL, TimeUnit.SECONDS);
}
// 不足4位补0, 超过4位返回原始值
return StrUtil.fillBefore(String.valueOf(incrementId), '0', 4);
}
/**
*
*
* @return long
*/
private static long getTimeMillsDay(LocalDateTime localDateTime) {
LocalDate localDate = localDateTime.toLocalDate();
return LocalDateTime.of(
localDate.getYear(), localDate.getMonth(),
localDate.getDayOfMonth(), 0,
0, 0)
.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
/**
*
*
* @return long
*/
private static long getTimeMillsSecond(LocalDateTime localDateTime) {
LocalDate localDate = localDateTime.toLocalDate();
LocalTime localTime = localDateTime.toLocalTime();
return LocalDateTime.of(
localDate.getYear(), localDate.getMonth(),
localDate.getDayOfMonth(), localTime.getHour(),
localTime.getMinute(), localTime.getSecond())
.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
}

@ -30,12 +30,14 @@ import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.opsli.api.wrapper.system.user.UserOrgRefModel;
import org.opsli.common.constants.MyBatisConstants;
import org.opsli.common.enums.DictType;
import org.opsli.core.utils.UserUtil;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.function.Consumer;
/**
* MyBatis
@ -110,84 +112,61 @@ public class MybatisAutoFillInterceptor implements Interceptor {
return;
}
// 排除字段
List<String> existField = Lists.newArrayList();
// 当前时间
Date currDate = DateUtil.date();
final Object argObj = arg;
// 字段缓存 减少每次更新 反射
Field[] fields = ENTITY_FIELD_MAP.get(arg.getClass());
if(fields == null){
fields = ReflectUtil.getFields(arg.getClass());
ENTITY_FIELD_MAP.put(arg.getClass(), fields);
}
for (Field f : fields) {
// 判断是否是排除字段
if(existField.contains(f.getName())){
continue;
}
// 如果设置为忽略字段 则直接跳过不处理
TableField tableField = f.getAnnotation(TableField.class);
if(tableField != null){
boolean exist = tableField.exist();
if(!exist){
existField.add(f.getName());
continue;
}
}
switch (f.getName()) {
// 处理字段
loopHandlerField(argObj, (fieldName)->{
switch (fieldName) {
// 创建人、更新人
case MyBatisConstants.FIELD_CREATE_BY:
case MyBatisConstants.FIELD_UPDATE_BY:
// 如果创建人 为空则进行默认赋值
Object createOrUpdateValue = ReflectUtil.getFieldValue(arg, f.getName());
Object createOrUpdateValue = ReflectUtil.getFieldValue(argObj, fieldName);
if(StringUtils.isBlank(Convert.toStr(createOrUpdateValue))){
BeanUtil.setProperty(arg, f.getName(), UserUtil.getUser().getId());
BeanUtil.setProperty(argObj, fieldName, UserUtil.getUser().getId());
}
break;
// 创建日期、更新日期
case MyBatisConstants.FIELD_CREATE_TIME:
case MyBatisConstants.FIELD_UPDATE_TIME:
BeanUtil.setProperty(arg, f.getName(), currDate);
BeanUtil.setProperty(argObj, fieldName, currDate);
break;
// 乐观锁
case MyBatisConstants.FIELD_OPTIMISTIC_LOCK:
BeanUtil.setProperty(arg, f.getName(), 0);
BeanUtil.setProperty(argObj, fieldName, DictType.NO_YES_NO.getValue());
break;
// 逻辑删除
case MyBatisConstants.FIELD_DELETE_LOGIC:
BeanUtil.setProperty(arg, f.getName(), MyBatisConstants.LOGIC_NOT_DELETE_VALUE);
BeanUtil.setProperty(argObj, fieldName, MyBatisConstants.LOGIC_NOT_DELETE_VALUE);
break;
// 多租户设置
case MyBatisConstants.FIELD_TENANT:
// 2020-12-05 修复当前租户可能为空字符串报错问题
// 如果租户ID 为空则进行默认赋值
Object tenantValue = ReflectUtil.getFieldValue(arg, f.getName());
Object tenantValue = ReflectUtil.getFieldValue(argObj, fieldName);
if(StringUtils.isBlank(Convert.toStr(tenantValue))){
BeanUtil.setProperty(arg, f.getName(), UserUtil.getTenantId());
BeanUtil.setProperty(argObj, fieldName, UserUtil.getTenantId());
}
break;
// 组织机构设置
case MyBatisConstants.FIELD_ORG_GROUP:
// 如果组织IDs 为空则进行默认赋值
Object orgValue = ReflectUtil.getFieldValue(arg, f.getName());
Object orgValue = ReflectUtil.getFieldValue(argObj, fieldName);
if(StringUtils.isBlank(Convert.toStr(orgValue))){
UserOrgRefModel userOrgRefModel =
UserUtil.getUserDefOrgByUserId(UserUtil.getUser().getId());
if(null != userOrgRefModel){
String orgIds = userOrgRefModel.getOrgIds();
BeanUtil.setProperty(arg, f.getName(), orgIds);
BeanUtil.setProperty(argObj, fieldName, orgIds);
}
}
break;
default:
break;
}
}
});
}
/**
@ -199,23 +178,53 @@ public class MybatisAutoFillInterceptor implements Interceptor {
return;
}
// 排除字段
List<String> existField = Lists.newArrayList();
// 2020-09-19
// 修改这儿 有可能会拿到一个 MapperMethod需要特殊处理
if (arg instanceof MapperMethod.ParamMap) {
MapperMethod.ParamMap<?> paramMap = (MapperMethod.ParamMap<?>) arg;
if (paramMap.containsKey(ET)) {
arg = paramMap.get(ET);
} else {
arg = paramMap.get("param1");
}
arg = paramMap.containsKey(ET)
? paramMap.get(ET)
: paramMap.get("param1");
if (arg == null) {
return;
}
}
// 当前时间
Date currDate = DateUtil.date();
final Object argObj = arg;
// 处理字段
loopHandlerField(argObj, (fieldName)->{
switch (fieldName) {
// 更新人
case MyBatisConstants.FIELD_UPDATE_BY:
// 如果更新人 为空则进行默认赋值
Object updateValue = ReflectUtil.getFieldValue(argObj, fieldName);
if(StringUtils.isBlank(Convert.toStr(updateValue))){
BeanUtil.setProperty(argObj, fieldName, UserUtil.getUser().getId());
}
break;
// 更新日期
case MyBatisConstants.FIELD_UPDATE_TIME:
BeanUtil.setProperty(argObj, fieldName, currDate);
break;
default:
break;
}
});
}
/**
*
*
* @param arg
* @param callback
*/
private void loopHandlerField(Object arg, Consumer<String> callback){
// 排除字段
List<String> existField = Lists.newArrayList();
// 字段缓存 减少每次更新 反射
Field[] fields = ENTITY_FIELD_MAP.get(arg.getClass());
if(fields == null){
@ -225,36 +234,21 @@ public class MybatisAutoFillInterceptor implements Interceptor {
for (Field f : fields) {
// 判断是否是排除字段
if(existField.contains(f.getName())){
if (existField.contains(f.getName())) {
continue;
}
// 如果设置为忽略字段 则直接跳过不处理
TableField tableField = f.getAnnotation(TableField.class);
if(tableField != null){
boolean exist = tableField.exist();
if(!exist){
if (tableField != null) {
if (!tableField.exist()) {
existField.add(f.getName());
continue;
}
}
switch (f.getName()) {
// 更新人
case MyBatisConstants.FIELD_UPDATE_BY:
// 如果更新人 为空则进行默认赋值
Object updateValue = ReflectUtil.getFieldValue(arg, f.getName());
if(StringUtils.isBlank(Convert.toStr(updateValue))){
BeanUtil.setProperty(arg, f.getName(), UserUtil.getUser().getId());
}
break;
// 更新日期
case MyBatisConstants.FIELD_UPDATE_TIME:
BeanUtil.setProperty(arg, f.getName(), DateUtil.date());
break;
default:
break;
}
// 回调函数
callback.accept(f.getName());
}
}

@ -0,0 +1,60 @@
package org.opsli.core.utils;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
/**
*
*
* @author Parker
* @date 2022-11-16 6:52 PM
**/
@Slf4j
public final class EnvPrefixTool {
/**
*
* @param bizTag
* @return String
*/
public static String getEnvBizTag(String bizTag){
String activeProfile = StrUtil.blankToDefault(
SpringUtil.getActiveProfile(), EnvPrefixEnums.PROD.name());
try {
EnvPrefixEnums envPrefixEnums = EnvPrefixEnums.valueOf(activeProfile.toUpperCase());
return envPrefixEnums.getPrefix()+bizTag;
}catch (Exception e){
log.error("获取环境异常 => {}", e.getMessage(), e);
}
return bizTag;
}
/**
*
*/
@Getter
@AllArgsConstructor
private enum EnvPrefixEnums{
/** 本地环境 */
LOCAL("LOCAL_"),
/** 开发环境 */
DEV("DEV_"),
/** 测试环境 */
TEST("TEST_"),
/** 生产环境 */
PROD("");
/** 前缀 */
private final String prefix;
}
}
Loading…
Cancel
Save