diff --git a/src/main/java/com/qs/serve/common/config/RedisConfig.java b/src/main/java/com/qs/serve/common/config/RedisConfig.java index ce7f564d..25874761 100644 --- a/src/main/java/com/qs/serve/common/config/RedisConfig.java +++ b/src/main/java/com/qs/serve/common/config/RedisConfig.java @@ -1,6 +1,13 @@ package com.qs.serve.common.config; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; @@ -16,8 +23,12 @@ import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.serializer.*; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.StringRedisSerializer; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import java.time.Duration; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; /** @@ -43,6 +54,19 @@ public class RedisConfig extends CachingConfigurerSupport{ .build(); } +// @Bean +// public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { +// JavaTimeModule module = new JavaTimeModule(); +// DateTimeFormatter formatter = new DateTimeFormatterBuilder() +// .appendPattern("yyyy-MM-dd HH:mm:ss").toFormatter(); +// module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter)); +// module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter)); +// ObjectMapper objectMapper = builder.createXmlMapper(false).build(); +// objectMapper.registerModule(new JavaTimeModule()); +// objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); +// return objectMapper; +// } + @Bean public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory){ RedisMessageListenerContainer container = new RedisMessageListenerContainer(); diff --git a/src/main/java/com/qs/serve/common/framework/annotations/RedisCacheable.java b/src/main/java/com/qs/serve/common/framework/annotations/RedisCacheable.java new file mode 100644 index 00000000..c4acc8a1 --- /dev/null +++ b/src/main/java/com/qs/serve/common/framework/annotations/RedisCacheable.java @@ -0,0 +1,35 @@ +package com.qs.serve.common.framework.annotations; + +import java.lang.annotation.*; + +/** + * 解决原有@CacheAble不支持独立失效策略场景 + * @author YenHex + * @since 2024/10/17 + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RedisCacheable { + + /** + * redis缓存前缀,默认类与方法名 + * @return + */ + String prefix() default ""; + + /** + * 过期时间 + * @return + */ + int expire() default 350; + + /** + * 缓存读取主键表达式 + * @return + */ + String expression() default ""; + + String SIMPLE_KEY = "#key"; + +} diff --git a/src/main/java/com/qs/serve/common/framework/aop/RedisCacheAspect.java b/src/main/java/com/qs/serve/common/framework/aop/RedisCacheAspect.java new file mode 100644 index 00000000..c0a52a3b --- /dev/null +++ b/src/main/java/com/qs/serve/common/framework/aop/RedisCacheAspect.java @@ -0,0 +1,135 @@ +package com.qs.serve.common.framework.aop; + +import com.baomidou.mybatisplus.core.toolkit.StringPool; +import com.qs.serve.common.framework.annotations.RedisCacheable; +import com.qs.serve.common.framework.redis.RedisService; +import com.qs.serve.common.util.JsonUtil; +import com.qs.serve.common.util.StringUtils; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * @author YenHex + * @since 2024/10/18 + */ +@Slf4j +@Aspect +@Component +@AllArgsConstructor +public class RedisCacheAspect { + + private final RedisService redisService; + + @Pointcut("@annotation(com.qs.serve.common.framework.annotations.RedisCacheable)") + public void PointCut() {} + + @Around("PointCut()") + public Object redisCacheAdvice(ProceedingJoinPoint joinPoint) throws Throwable { + Object[] args = joinPoint.getArgs(); + Signature signature = joinPoint.getSignature(); + MethodSignature methodSignature = ((MethodSignature) signature); + Method method = methodSignature.getMethod(); + RedisCacheable redisCacheable = AnnotatedElementUtils.findMergedAnnotation(method, RedisCacheable.class); + if(redisCacheable!=null){ + String prefix = StringUtils.hasText(redisCacheable.prefix()) ? redisCacheable.prefix() + : methodSignature.getDeclaringType().getName() +"."+ methodSignature.getMethod().getName()+"()"; + //构建表达式key + String pk = this.getPrimaryKey(methodSignature,redisCacheable,args); + String redisCacheKey = "RCache:" + prefix + (pk==null?"":pk); + Object result = redisService.get(redisCacheKey); + if(result!=null){ + return JsonUtil.jsonToMap(result.toString()); + } + result = joinPoint.proceed(args); + if(result!=null){ + redisService.set(redisCacheKey,JsonUtil.objectToJson(result),redisCacheable.expire(), TimeUnit.MILLISECONDS); + } + return result; + } + // 返回默认对象 + return joinPoint.proceed(args); + } + + public String getPrimaryKey(MethodSignature methodSignature,RedisCacheable annotation,Object[] args){ + String method = methodSignature.getDeclaringType().getName() + +"."+ methodSignature.getMethod().getName()+"()"; + final String expression = annotation.expression(); + //适配表达式读取key,key读取不到log.error,放行请求 + String primaryKey = null; + if(StringUtils.isNotEmpty(expression)){ + // + if(expression.equals(RedisCacheable.SIMPLE_KEY)&&args.length==1){ + return args[0].toString(); + } + List keys = new ArrayList<>(); + // 指定表名 + String tableName = null; + if(expression.contains(StringPool.DOT)){ + String[] keyArr = expression.split(StringPool.BACK_SLASH + StringPool.DOT); + for (String key : keyArr) { + if(key.contains(StringPool.DOLLAR)){ + tableName = key.replace(StringPool.DOLLAR,""); + continue; + } + keys.add(key); + } + }else { + keys.add(expression); + } + for (Object arg : args) { + // 跳过非指定的表名 + if(tableName!=null){ + String clazzName = arg.getClass().getSimpleName(); + if(!clazzName.equals(tableName)){ + continue; + } + } + // 读取key + primaryKey = getPrimaryKeyRecursion(keys, arg, 0); + } + if(primaryKey==null){ + log.error("LockSubmitAspect失效,方法:{} 无法读取主键:{}",method,expression); + } + } + return primaryKey; + } + + + /** + * 递归读取主键 + * @param keys + * @param arg + * @param startIndex + * @return + */ + private String getPrimaryKeyRecursion(List keys, Object arg, int startIndex) { + String key = keys.get(startIndex); + Map param = JsonUtil.jsonToMap(JsonUtil.objectToJson(arg)); + Object val = param.get(key); + if(val!=null){ + boolean isLast = startIndex + 1== keys.size(); + if(isLast){ + return val.toString(); + }else { + // 自调支持无限层级 + return getPrimaryKeyRecursion(keys, val, startIndex + 1 ); + } + } + return null; + } + +} diff --git a/src/main/java/com/qs/serve/modules/oms/controller/OmsOrderController.java b/src/main/java/com/qs/serve/modules/oms/controller/OmsOrderController.java index e11dc961..baca5314 100644 --- a/src/main/java/com/qs/serve/modules/oms/controller/OmsOrderController.java +++ b/src/main/java/com/qs/serve/modules/oms/controller/OmsOrderController.java @@ -178,7 +178,7 @@ public class OmsOrderController { @SysLog(module = SystemModule.BASE, title = "订单", biz = BizType.DELETE) public R deleteById(@PathVariable("id") Long id){ OmsOrder dbOmsOrder = omsOrderService.getById(id); - if(dbOmsOrder.getStatus().equals(0)&&dbOmsOrder.getCheckState().equals(0)){ + if(dbOmsOrder.getStatus().equals(0)&&dbOmsOrder.getCheckState().equals(0)&&dbOmsOrder.getOrderCheckState().equals(0)){ boolean result = omsOrderService.removeById(id); return R.isTrue(result); } diff --git a/src/main/java/com/qs/serve/modules/oms/service/OmsOrderPart1Service.java b/src/main/java/com/qs/serve/modules/oms/service/OmsOrderPart1Service.java index 06951992..3ccb5b19 100644 --- a/src/main/java/com/qs/serve/modules/oms/service/OmsOrderPart1Service.java +++ b/src/main/java/com/qs/serve/modules/oms/service/OmsOrderPart1Service.java @@ -20,6 +20,7 @@ public interface OmsOrderPart1Service { */ OmsOrder copyOrder(Long orderId); + boolean releaseInventory(Long orderId); /** * 校验sku合法性 diff --git a/src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderOptionsServiceImpl.java b/src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderOptionsServiceImpl.java index 705a7e77..ec575659 100644 --- a/src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderOptionsServiceImpl.java +++ b/src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderOptionsServiceImpl.java @@ -278,9 +278,9 @@ public class OmsOrderOptionsServiceImpl implements OmsOrderOptionsService { TbsSeeYonConst.OA_DATA_EXPIRE_ORDER_DR + omsOrder.getOrderSn() ,"获取条款申请流水号"); BigDecimal dr = null; - if(codeRs.getData()!=null){ + if(codeRs.getStatus()==200 && codeRs.getMsg()!=null){ try { - String oaRateId = codeRs.getData().toString(); + String oaRateId = codeRs.getMsg().toString(); dr = omsOrderMapper.getExpiredOrderRates(oaRateId); omsOrder.setDiscountRate(dr); } catch (Exception e) { diff --git a/src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderPart1ServiceImpl.java b/src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderPart1ServiceImpl.java index 317453ea..b5f2d94b 100644 --- a/src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderPart1ServiceImpl.java +++ b/src/main/java/com/qs/serve/modules/oms/service/impl/OmsOrderPart1ServiceImpl.java @@ -100,6 +100,7 @@ public class OmsOrderPart1ServiceImpl implements OmsOrderPart1Service { order.setUserName(user.getName()); order.setUserPhone(user.getMobile()); order.setCheckState(0); + order.setStatus(0); order.setOrderCheckState(OmsOrderCheckState.UnPublish.getCode()); order.setLatitudeFrom(orgOrder.getLatitudeFrom()); order.setOrderSource(orgOrder.getOrderSource()); @@ -124,6 +125,13 @@ public class OmsOrderPart1ServiceImpl implements OmsOrderPart1Service { return order; } + @Override + public boolean releaseInventory(Long orderId) { + // 释放库存 + + return false; + } + @Override public List verifySku(OmsVerifySkuParam param) { diff --git a/src/main/java/com/qs/serve/modules/vtb/controller/VtbVerificationBatchController.java b/src/main/java/com/qs/serve/modules/vtb/controller/VtbVerificationBatchController.java index 3a155f72..9251b1ed 100644 --- a/src/main/java/com/qs/serve/modules/vtb/controller/VtbVerificationBatchController.java +++ b/src/main/java/com/qs/serve/modules/vtb/controller/VtbVerificationBatchController.java @@ -1,6 +1,7 @@ package com.qs.serve.modules.vtb.controller; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.qs.serve.common.framework.annotations.RedisCacheable; import com.qs.serve.common.model.annotation.LimitSubmit; import com.qs.serve.common.model.annotation.SysLog; import com.qs.serve.common.model.dto.PageVo; @@ -200,7 +201,8 @@ public class VtbVerificationBatchController { * @return */ @GetMapping("/ListAffairs") - public R> pageMemberAffair(String targetId){ + @RedisCacheable(expression = RedisCacheable.SIMPLE_KEY,expire = 45*1000) + public Object pageMemberAffair(String targetId){ VtbVerificationBatch batch = vtbVerificationBatchService.getById(targetId); return vtbVerificationBatchOperationService.pageAffairV2(targetId,batch.getVtbBatchCode()); } diff --git a/src/main/java/com/qs/serve/modules/vtb/service/impl/VtbVerificationBatchOperationServiceImpl.java b/src/main/java/com/qs/serve/modules/vtb/service/impl/VtbVerificationBatchOperationServiceImpl.java index 8ab94bc7..520b70e4 100644 --- a/src/main/java/com/qs/serve/modules/vtb/service/impl/VtbVerificationBatchOperationServiceImpl.java +++ b/src/main/java/com/qs/serve/modules/vtb/service/impl/VtbVerificationBatchOperationServiceImpl.java @@ -24,6 +24,7 @@ import com.qs.serve.modules.vtb.mapper.VtbVerificationMapper; import com.qs.serve.modules.vtb.service.*; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.math.BigDecimal; @@ -64,6 +65,7 @@ public class VtbVerificationBatchOperationServiceImpl implements VtbVerification } @Override + @Async public Object doBacked(TbsAffairCommitBo param) { //退回 VtbVerificationBatch batch = vtbVerificationBatchService.getById(param.getTargetId()); @@ -88,6 +90,7 @@ public class VtbVerificationBatchOperationServiceImpl implements VtbVerification } @Override + @Async public Object doFinished(TbsAffairCommitBo param) { //完成 VtbVerificationBatch batch = vtbVerificationBatchService.getById(param.getTargetId()); @@ -111,6 +114,7 @@ public class VtbVerificationBatchOperationServiceImpl implements VtbVerification } @Override + @Async public Object doRefuse(TbsAffairCommitBo param) { VtbVerificationBatch batch = vtbVerificationBatchService.getById(param.getTargetId()); List verificationList = vtbVerificationBatchService.listVerifications(batch.getId()); @@ -127,6 +131,7 @@ public class VtbVerificationBatchOperationServiceImpl implements VtbVerification } @Override + @Async public void insertAddNodeLog(CtpAddNodeParam param, String affairId, SysUser sysUser) { //给加签添加审批日志 DataAffairCommitMapper dataAffairCommitMapper = SpringUtils.getBean(DataAffairCommitMapper.class); @@ -199,6 +204,7 @@ public class VtbVerificationBatchOperationServiceImpl implements VtbVerification } @Override + @Async public void buildAffairCommitData(TbsAffairCommitBo commitParam, String flag) { //常规的提交审批日志 String userId = AuthContextUtils.getSysUserId();