diff --git a/ant-design-vue-jeecg/src/components/layouts/UserLayout.vue b/ant-design-vue-jeecg/src/components/layouts/UserLayout.vue index 3e5e110..5f680af 100644 --- a/ant-design-vue-jeecg/src/components/layouts/UserLayout.vue +++ b/ant-design-vue-jeecg/src/components/layouts/UserLayout.vue @@ -16,7 +16,7 @@ <div class="footer"> <div class="copyright"> - Copyright © 2022 华恒焊接股份有限公司 + Copyright © 2023 华恒焊接股份有限公司 </div> </div> </div> diff --git a/huaheng-wms-core/src/main/java/org/jeecg/JeecgSystemApplication.java b/huaheng-wms-core/src/main/java/org/jeecg/JeecgSystemApplication.java index c6b2cb4..79a828b 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/JeecgSystemApplication.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/JeecgSystemApplication.java @@ -18,6 +18,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.env.Environment; @@ -28,6 +29,7 @@ import net.bytebuddy.asm.Advice.This; * 单体启动类(采用此类启动为单体模式) */ @Slf4j +@EnableCaching @SpringBootApplication @EnableAutoConfiguration(exclude = {MongoAutoConfiguration.class}) public class JeecgSystemApplication extends SpringBootServletInitializer { diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/LoginController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/LoginController.java index a9b604f..331390b 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/LoginController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/LoginController.java @@ -429,29 +429,28 @@ public class LoginController { } } + // 暂时移除唯一登录功能 // 删除相同用户名称对应的key - Collection<String> keys = redisTemplate.keys(CommonConstant.PREFIX_USER_TOKEN + "*"); - for (String key : keys) { - String token = (String)redisUtil.get(key); - LoginUser loginUser = sysBaseAPI.getUserByName(JwtUtil.getUsername(token)); - if (loginUser != null) { - if (oConvertUtils.isNotEmpty(username) && loginUser.getUsername().contains(username)) { - log.info("强制 " + sysUser.getRealname() + " 退出成功! "); - // 清空用户登录Token缓存 - redisUtil.del(token); - // 清空用户登录Token缓存 - redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token); - // 清空用户登录Shiro权限缓存 - redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId()); - // 清空用户的缓存信息(包括部门信息),例如sys:cache:user::<username> - redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername())); - // 调用shiro的logout - SecurityUtils.getSubject().logout(); - // - redisUtil.del(key); - } - } - } +// Collection<String> keys = redisTemplate.keys(CommonConstant.PREFIX_USER_TOKEN + "*"); +// for (String key : keys) { +// String token = (String)redisUtil.get(key); +// LoginUser loginUser = sysBaseAPI.getUserByName(JwtUtil.getUsername(token)); +// if (loginUser != null) { +// if (oConvertUtils.isNotEmpty(username) && loginUser.getUsername().contains(username)) { +// log.info("强制 " + sysUser.getRealname() + " 退出成功! "); +// // 清空用户登录Token缓存 +// redisUtil.del(token); +// // 清空用户登录Token缓存 +// redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token); +// // 清空用户登录Shiro权限缓存 +// redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId()); +// // 清空用户的缓存信息(包括部门信息),例如sys:cache:user::<username> +// redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername())); +// // 调用shiro的logout +// SecurityUtils.getSubject().logout(); +// } +// } +// } // update-end--Author:sunjianlei Date:20210802 for:获取用户租户信息 // 生成token String token = HuahengJwtUtil.sign(username, syspassword, warehouseCode); diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysUserOnlineController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysUserOnlineController.java index eb7e780..65f0e9f 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysUserOnlineController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysUserOnlineController.java @@ -136,8 +136,6 @@ public class SysUserOnlineController { redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId()); // 清空用户的缓存信息 redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername())); - // 真*清空Token - redisUtil.del(key); // 调用shiro的logout SecurityUtils.getSubject().logout(); return Result.ok("退出登录成功!"); diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/acs/controller/AcsController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/acs/controller/AcsController.java index 5580e89..1eb399d 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/acs/controller/AcsController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/acs/controller/AcsController.java @@ -6,13 +6,13 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import org.jeecg.common.api.vo.Result; -import org.jeecg.common.system.util.JwtUtil; import org.jeecg.modules.wms.api.acs.entity.AcsStatus; import org.jeecg.modules.wms.api.acs.service.IAcsService; -import org.jeecg.modules.wms.framework.aspectj.PassApiAuthentication; +import org.jeecg.modules.wms.config.address.service.IAddressService; import org.jeecg.modules.wms.framework.aspectj.lang.annotation.ApiLogger; import org.jeecg.modules.wms.framework.controller.HuahengBaseController; import org.jeecg.modules.wms.task.agvTask.service.IAgvTaskService; +import org.jeecg.utils.OkHttpUtils; import org.jeecg.utils.StringUtils; import org.jeecg.utils.constant.QuantityConstant; import org.springframework.transaction.annotation.Transactional; @@ -22,6 +22,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; +import com.alibaba.fastjson.JSON; + import io.swagger.annotations.ApiOperation; @RestController @@ -30,15 +32,22 @@ public class AcsController extends HuahengBaseController { @Resource private IAcsService acsService; + @Resource private IAgvTaskService agvTaskService; + @Resource + private IAddressService addressService; + // @PassApiAuthentication - @ApiLogger(apiName = "API接口第三方Token校验测试", from = "TEST") +// @ApiLogger(apiName = "API接口第三方Token校验测试", from = "TEST") @ResponseBody @PostMapping(value = "/testTokenCheck") public Result<?> testTokenCheck(@RequestBody Map<String, String> paramMap, HttpServletRequest request) { - return new Result<>(); + String url = "http://127.0.0.1:8080/wms/api/wms/acs/testTokenCheck"; + String body = OkHttpUtils.sendPostByJsonStr(url, JSON.toJSONString(paramMap)); +// String url = addressService.getUrlByParam(QuantityConstant.ADDRESS_AGV_TASK_ASSIGN); + return Result.ok(body); } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/acs/service/impl/AcsServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/acs/service/impl/AcsServiceImpl.java index 5ab2f0c..30ea8f9 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/acs/service/impl/AcsServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/acs/service/impl/AcsServiceImpl.java @@ -10,9 +10,9 @@ import org.jeecg.modules.wms.config.location.entity.Location; import org.jeecg.modules.wms.config.location.service.ILocationService; import org.jeecg.modules.wms.task.agvTask.entity.AgvTask; import org.jeecg.modules.wms.task.agvTask.service.IAgvTaskService; +import org.jeecg.utils.OkHttpUtils; import org.jeecg.utils.StringUtils; import org.jeecg.utils.constant.QuantityConstant; -import org.jeecg.utils.http.OkHttpUtils; import org.springframework.stereotype.Service; import com.alibaba.fastjson.JSON; diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/erp/service/impl/ErpServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/erp/service/impl/ErpServiceImpl.java index 087c8ef..91e5d7e 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/erp/service/impl/ErpServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/erp/service/impl/ErpServiceImpl.java @@ -38,9 +38,9 @@ import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail; import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader; import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentDetailService; import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentHeaderService; +import org.jeecg.utils.OkHttpUtils; import org.jeecg.utils.StringUtils; import org.jeecg.utils.constant.QuantityConstant; -import org.jeecg.utils.http.OkHttpUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/mes/servuce/impl/MesServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/mes/servuce/impl/MesServiceImpl.java index ca70e23..909c8c4 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/mes/servuce/impl/MesServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/mes/servuce/impl/MesServiceImpl.java @@ -33,9 +33,9 @@ import org.jeecg.modules.wms.task.taskHeader.entity.TaskDetail; import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader; import org.jeecg.modules.wms.task.taskHeader.service.ITaskDetailService; import org.jeecg.modules.wms.task.taskHeader.service.ITaskHeaderService; +import org.jeecg.utils.OkHttpUtils; import org.jeecg.utils.StringUtils; import org.jeecg.utils.constant.QuantityConstant; -import org.jeecg.utils.http.OkHttpUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/WcsServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/WcsServiceImpl.java index dba4ffc..28440d9 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/WcsServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/WcsServiceImpl.java @@ -35,9 +35,9 @@ import org.jeecg.modules.wms.task.taskHeader.entity.TaskDetail; import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader; import org.jeecg.modules.wms.task.taskHeader.service.ITaskDetailService; import org.jeecg.modules.wms.task.taskHeader.service.ITaskHeaderService; +import org.jeecg.utils.OkHttpUtils; import org.jeecg.utils.StringUtils; import org.jeecg.utils.constant.QuantityConstant; -import org.jeecg.utils.http.OkHttpUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/address/service/impl/AddressServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/address/service/impl/AddressServiceImpl.java index 24817b6..f4689a7 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/address/service/impl/AddressServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/address/service/impl/AddressServiceImpl.java @@ -6,6 +6,7 @@ import org.apache.commons.math3.analysis.function.Add; import org.jeecg.modules.wms.config.address.entity.Address; import org.jeecg.modules.wms.config.address.mapper.AddressMapper; import org.jeecg.modules.wms.config.address.service.IAddressService; +import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -20,6 +21,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; public class AddressServiceImpl extends ServiceImpl<AddressMapper, Address> implements IAddressService { @Override + @Cacheable(cacheNames = "getAddressByUrl#300", key = "#root.methodName + '_' + #url + '_' + #warehouseCode") public Address getAddressByUrl(String url, String warehouseCode) { LambdaQueryWrapper<Address> addressLambdaQueryWrapper = Wrappers.lambdaQuery(); addressLambdaQueryWrapper.eq(Address::getUrl, url).eq(Address::getWarehouseCode, warehouseCode).last(" limit 1"); @@ -28,6 +30,7 @@ public class AddressServiceImpl extends ServiceImpl<AddressMapper, Address> impl } @Override + @Cacheable(cacheNames = "getUrlByParam#300", key = "#root.methodName + '_' + #param + '_' + #warehouseCode + '_' + #zoneCode") public String getUrlByParam(String param, String warehouseCode, String zoneCode) { LambdaQueryWrapper<Address> addressLambdaQueryWrapper = Wrappers.lambdaQuery(); addressLambdaQueryWrapper.eq(Address::getParam, param).eq(Address::getWarehouseCode, warehouseCode).eq(Address::getZoneCode, zoneCode); @@ -39,7 +42,9 @@ public class AddressServiceImpl extends ServiceImpl<AddressMapper, Address> impl return url; } + /** #300 缓存300秒 */ @Override + @Cacheable(cacheNames = "getUrlByParam#300", key = "#root.methodName + '_' + #param") public String getUrlByParam(String param) { LambdaQueryWrapper<Address> addressLambdaQueryWrapper = Wrappers.lambdaQuery(); addressLambdaQueryWrapper.eq(Address::getParam, param); @@ -47,8 +52,6 @@ public class AddressServiceImpl extends ServiceImpl<AddressMapper, Address> impl if (address == null) { return null; } - String url = address.getUrl(); - return url; + return address.getUrl(); } - } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/impl/LocationServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/impl/LocationServiceImpl.java index 418ea67..957f0ac 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/impl/LocationServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/impl/LocationServiceImpl.java @@ -93,10 +93,13 @@ public class LocationServiceImpl extends ServiceImpl<LocationMapper, Location> i if (location == null) { return false; } + boolean success = false; // 如果这个托盘号已经在库位表里,那么不能再写入 - boolean success = havaContainerCodeInLocation(containerCode, warehouseCode); - if (success) { - throw new ServiceException("库位表已经存在这个容器号,不能再写入"); + if (StringUtils.isNotEmpty(containerCode)) { + success = havaContainerCodeInLocation(containerCode, warehouseCode); + if (success) { + throw new ServiceException("库位表已经存在这个容器号,不能再写入"); + } } location.setContainerCode(containerCode); location.setStatus(status); diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/ApiAuthenticationAspect.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/ApiAuthenticationAspect.java index ca2ded7..3086f1e 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/ApiAuthenticationAspect.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/ApiAuthenticationAspect.java @@ -10,6 +10,7 @@ import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; +import org.bouncycastle.crypto.RuntimeCryptoException; import org.jeecg.modules.wms.framework.aspectj.dto.RSA256Key; import org.jeecg.utils.HuahengJwtUtil; import org.springframework.beans.factory.annotation.Autowired; @@ -23,9 +24,11 @@ import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTVerificationException; import com.auth0.jwt.interfaces.DecodedJWT; +import com.baomidou.mybatisplus.extension.service.IService; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; import lombok.extern.slf4j.Slf4j; /** @@ -68,12 +71,16 @@ public class ApiAuthenticationAspect { ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); String token = request.getHeader("token"); + if (token == null) { + log.error("Authentication token is null"); + throw new RuntimeException("Authentication token is null"); + } try { Algorithm algorithm = Algorithm.RSA256(rsa256Key.getPublicKey(), rsa256Key.getPrivateKey()); JWTVerifier verifier = JWT.require(algorithm).withIssuer(HuahengJwtUtil.HUAHENG_SYSTEM_ID).build(); verifier.verify(token); } catch (JWTVerificationException e) { - log.error("TOKEN认证失败:{}", e.getMessage()); + log.error(e.getMessage()); throw e; } } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/ApiLogAspect.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/ApiLogAspect.java index e34bdd5..c00ac66 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/ApiLogAspect.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/ApiLogAspect.java @@ -27,6 +27,7 @@ import org.jeecg.modules.wms.config.address.service.IAddressService; import org.jeecg.modules.wms.framework.aspectj.lang.annotation.ApiLogger; import org.jeecg.modules.wms.monitor.apiLog.entity.ApiLog; import org.jeecg.modules.wms.monitor.apiLog.service.IApiLogService; +import org.jeecg.utils.HuahengJwtUtil; import org.jeecg.utils.ServletUtils; import org.jeecg.utils.SpringUtils; import org.jeecg.utils.StringUtils; @@ -239,47 +240,47 @@ public class ApiLogAspect { /** * 记录WMS调用第三方系统接口的请求信息 * 在OKHttpUtils.bodypost方法中直接调用本类static方法 + * @param apiLog **/ - public static ApiLog initApiLog(Request request, String body) { - ApiLog log = new ApiLog(); + public static void initApiLog(ApiLog apiLog, Request request, String body) { try { - log.setApiMethod(request.method()); - log.setUrl(request.url().toString()); - log.setRequestTime(new Date()); - parseUrl(log, request.url().url()); - log.setRequestHeader(request.headers().toString()); - log.setRequestBody(body); + apiLog.setApiMethod(request.method()); + apiLog.setUrl(request.url().toString()); + apiLog.setRequestTime(new Date()); + parseUrl(apiLog, request.url().url()); + apiLog.setRequestHeader(request.headers().toString()); + apiLog.setRequestBody(body); } catch (Exception e) { e.printStackTrace(); } - return log; } /** 记录响应头信息 **/ - public static void finishApiLog(ApiLog log, Response response, String body) { + public static void finishApiLog(ApiLog log, Response response, String responseBody) { try { - log.setResponseBody(body); log.setResponseTime(new Date()); Long duration = log.getResponseTime().getTime() - log.getRequestTime().getTime(); log.setDuration(duration.intValue()); + if (response == null) { + return; + } log.setHttpCode(response.code()); - - // 响应头 log.setResponseHeader(response.headers().toString()); - Result ajaxResult = null; + log.setResponseBody(responseBody); + Result result = null; try { - ajaxResult = JSON.parseObject(body, Result.class); + result = JSON.parseObject(responseBody, Result.class); } catch (Exception ex) { - body = JSON.parse(body).toString(); - ajaxResult = JSON.parseObject(body, Result.class); + responseBody = JSON.parse(responseBody).toString(); + result = JSON.parseObject(responseBody, Result.class); } - log.setRetCode(ajaxResult.getCode()); + log.setRetCode(result.getCode()); } catch (Exception e) { e.printStackTrace(); } finally { try { if (StringUtils.isNotEmpty(log.getResponseBody()) && log.getResponseBody().length() > 2001) { - log.setResponseBody(log.getResponseBody().substring(0, 2000) + "...\nResponseBodyLength:" + log.getResponseBody().length()); + log.setResponseBody(log.getResponseBody().substring(0, 2000) + "...\n"); } } catch (Exception e) { e.printStackTrace(); @@ -289,16 +290,16 @@ public class ApiLogAspect { } /** 根据url,从address表中判断调用的去向 **/ - public static void parseUrl(ApiLog log, URL url) { + public static void parseUrl(ApiLog apiLog, URL url) { try { String[] spList = url.toString().split("/"); String apiName = spList[spList.length - 1]; String ip = JeecgSystemApplication.getLocalHostExactAddress().getHostAddress(); - Address address = addressService.getAddressByUrl(url.toString(), QuantityConstant.DEFAULT_WAREHOUSE); - log.setApiName(apiName); - log.setRequestFrom("WMS"); - log.setIp(ip); - log.setResponseBy(address.getParam().toUpperCase()); + apiLog.setApiName(apiName); + apiLog.setRequestFrom(HuahengJwtUtil.HUAHENG_SYSTEM_ID); + apiLog.setIp(ip); +// Address address = addressService.getAddressByUrl(url.toString(), QuantityConstant.DEFAULT_WAREHOUSE); +// apiLog.setResponseBy(address.getParam().toUpperCase()); } catch (Exception e) { e.printStackTrace(); } @@ -398,7 +399,7 @@ public class ApiLogAspect { public static void setApiLogException(ApiLog log, Exception e) { try { String exception = ExceptionUtils.getFullStackTrace(e); - String shortExpInfo = e.getMessage() + "\n" + org.apache.commons.lang3.StringUtils.left(exception, 1000); + String shortExpInfo = e.getMessage() + "\n" + org.apache.commons.lang3.StringUtils.left(exception, 1000) + "..."; log.setException(shortExpInfo); } catch (Exception ex) { ex.printStackTrace(); @@ -408,7 +409,7 @@ public class ApiLogAspect { public static void setApiLogThrowable(ApiLog log, Throwable e) { try { String exception = ExceptionUtils.getFullStackTrace(e); - String shortExpInfo = e.getMessage() + "\n" + org.apache.commons.lang3.StringUtils.left(exception, 1000); + String shortExpInfo = e.getMessage() + "\n" + org.apache.commons.lang3.StringUtils.left(exception, 1000) + "..."; log.setException(shortExpInfo); } catch (Exception ex) { ex.printStackTrace(); diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/controller/HuahengBaseController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/controller/HuahengBaseController.java index d313b3b..83da530 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/controller/HuahengBaseController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/controller/HuahengBaseController.java @@ -5,7 +5,7 @@ import java.util.concurrent.TimeUnit; import javax.annotation.Nonnull; import org.jeecg.common.api.vo.Result; -import org.jeecg.utils.RedissonDistributedLocker; +import org.jeecg.utils.support.RedissonDistributedLocker; import org.springframework.beans.factory.annotation.Autowired; import cn.hutool.core.date.SystemClock; diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java index 03596a2..334c2be 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java @@ -135,9 +135,9 @@ public class ShipmentCombinationServiceImpl implements IShipmentCombinationServi } } if (over) { - return Result.OK("出库单已经配盘"); + return Result.OK("出库单已经配盘", null); } - return Result.OK("自动组盘成功"); + return Result.OK("自动组盘成功", null); } @Override @@ -210,7 +210,7 @@ public class ShipmentCombinationServiceImpl implements IShipmentCombinationServi throw new ServiceException(result.getMessage()); } } - return Result.OK("自动组盘成功"); + return Result.OK("自动组盘成功", null); } @Override diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/controller/TaskHeaderController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/controller/TaskHeaderController.java index c23117e..d4b9d78 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/controller/TaskHeaderController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/controller/TaskHeaderController.java @@ -25,6 +25,7 @@ import org.jeecg.modules.wms.config.port.entity.Port; import org.jeecg.modules.wms.config.port.service.IPortService; import org.jeecg.modules.wms.config.zone.entity.Zone; import org.jeecg.modules.wms.config.zone.service.IZoneService; +import org.jeecg.modules.wms.framework.aspectj.lang.annotation.ApiLogger; import org.jeecg.modules.wms.framework.controller.HuahengBaseController; import org.jeecg.modules.wms.task.taskHeader.entity.TaskDetail; import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader; @@ -648,4 +649,46 @@ public class TaskHeaderController extends HuahengBaseController { return Result.OK(portList); } + /** + * 修复空出的数据 + * @return + */ + @AutoLog(value = "修复空出的数据") + @PostMapping("/handleEmptyOut") + @ApiOperation("修复空出的数据") + @ResponseBody + @ApiLogger(apiName = "修复空出的数据", from = "WMS") + public Result handleEmptyOut(@RequestBody String taskNo) { + Result result = taskHeaderService.handleEmptyOut(taskNo); + return result; + } + + /** + * 修复重入的数据 + * @return + */ + @AutoLog(value = "修复重入的数据") + @PostMapping("/handleDoubleIn") + @ApiOperation("修复重入的数据") + @ResponseBody + @ApiLogger(apiName = "修复重入的数据", from = "WMS") + public Result handleDoubleIn(@RequestBody String taskNo) { + Result result = taskHeaderService.handleDoubleIn(taskNo); + return result; + } + + /** + * 修复取货错的数据 + * @return + */ + @AutoLog(value = "修复取货错的数据") + @PostMapping("handlePickupError") + @ApiOperation("修复取货错的数据") + @ResponseBody + @ApiLogger(apiName = "修复取货错的数据", from = "WMS") + public Result handlePickupError(@RequestBody String taskNo) { + Result result = taskHeaderService.handlePickupError(taskNo); + return result; + } + } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java index 04e56c2..7692399 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java @@ -2126,14 +2126,14 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea if (StringUtils.isNotEmpty(lastStatus)) { container.setStatus(lastStatus); // 解决空托盘组移库问题 } - if (StringUtils.isNotEmpty(fromLocationCode)) { - success = containerService.havaLocationCodeByContainer(fromLocationCode, warehouseCode); - if (success) { - throw new ServiceException("库位表已经存在这个容器号,不能再写入"); - } - } +// if (StringUtils.isNotEmpty(fromLocationCode)) { +// success = containerService.havaLocationCodeByContainer(fromLocationCode, warehouseCode); +// if (success) { +// throw new ServiceException("库位表已经存在这个容器号,不能再写入"); +// } +// } container.setLastStatus(QuantityConstant.EMPTY_STRING); - container.setLocationCode(fromLocationCode); +// container.setLocationCode(fromLocationCode); success = containerService.updateById(container); if (!success) { throw new ServiceException("取消任务时, 更新容器失败"); diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengJwtUtil.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengJwtUtil.java index 88a9e93..a1b3ec6 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengJwtUtil.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengJwtUtil.java @@ -28,7 +28,7 @@ public class HuahengJwtUtil { /** token失效时间 1天 */ public static final long EXPIRE_TIME = 24 * 60 * 60 * 1000; - public static final String HUAHENG_SYSTEM_ID = "HUAHENG-WMS4-4.0.1"; + public static final String HUAHENG_SYSTEM_ID = "HUAHENG-WMS4"; /** * 根据request中的token获取用户账号 diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/OkHttpUtils.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/OkHttpUtils.java new file mode 100644 index 0000000..1879e25 --- /dev/null +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/OkHttpUtils.java @@ -0,0 +1,279 @@ +package org.jeecg.utils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.parser.Feature; +import com.aliyun.oss.ServiceException; +import com.xkcoding.http.util.StringUtil; + +import antlr.StringUtils; +import cn.hutool.core.util.StrUtil; +import net.bytebuddy.asm.Advice.This; +import okhttp3.*; +import org.jeecg.modules.wms.framework.aspectj.ApiLogAspect; +import org.jeecg.modules.wms.monitor.apiLog.entity.ApiLog; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.messaging.support.ErrorMessage; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import javax.validation.constraints.NotNull; + +/** + * OkHttp发送请求 + * @author huaheng + * @Date 2022-5-30 + */ +public class OkHttpUtils { + + private static final Logger log = LoggerFactory.getLogger(OkHttpUtils.class); + + /** + * 最多重试次数 + */ + public final static int MAX_RENTRY_COUNT = 3; + + /** + * 最大连接时间(秒) + */ + public final static int CONNECTION_TIMEOUT = 1; + + /** + * 最大读取时间(秒) + */ + public final static int READ_TIMEOUT = 30; + + /** + * 最大写入时间(秒) + */ + public final static int WRITE_TIMEOUT = 30; + + /** + * JSON格式 + */ + public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8"); + /** + * OkHTTP线程池最大空闲线程数 + */ + public final static int MAX_IDLE_CONNECTIONS = 100; + /** + * OkHTTP线程池空闲线程存活时间(秒) + */ + public final static long KEEP_ALIVE_DURATION = 60; + + private static final String CONTENT_TYPE = "Content-Type"; + + /** 访问接口参数配置 */ + private final static OkHttpClient HTTP_CLIENT = + new OkHttpClient.Builder().connectTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS).readTimeout(READ_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS).addInterceptor(new OkHttpUtils.OkhttpInterceptor(MAX_RENTRY_COUNT)) // 过滤器,设置最大重试次数 + .retryOnConnectionFailure(false).connectionPool(new ConnectionPool(MAX_IDLE_CONNECTIONS, KEEP_ALIVE_DURATION, TimeUnit.SECONDS)).build(); + + /** + * 向指定 URL 发送GET方法的请求 + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式 + * @return 所代表远程资源的响应结果 + * @throws Exception + */ + public static String sendGet(String url, String param) { + Map<String, String> headers = new HashMap<String, String>(); + return sendGet(url, headers, param); + } + + /** + * 向指定 URL 发送GET方法的请求 + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式 + * @param headers 请求头 + * @return 所代表远程资源的响应结果 + * @throws Exception + */ + public static String sendGet(String url, Map<String, String> headers, String param) { + ApiLog apiLog = new ApiLog(); + Request.Builder builder = new Request.Builder(); + buildHeader(builder, headers); + Request request = builder.url(url + "?" + param).get().build(); + Response response = null; + String result = null; + try { + ApiLogAspect.initApiLog(apiLog, request, param); + response = HTTP_CLIENT.newCall(request).execute(); + result = response.body().string(); + } catch (Exception e) { + String errorString = + StrUtil.format("执行GET请求异常,url:{},header:{},param:{},errorMessage:{}", url, JSON.toJSONString(headers), param, e.getMessage()); + ApiLogAspect.setApiLogException(apiLog, e); + throw new RuntimeException(errorString, e); + } finally { + ApiLogAspect.finishApiLog(apiLog, response, result); + } + if (response.isSuccessful() && Objects.nonNull(response.body())) {// 调用成功 + log.info("执行GET请求成功,url:{},header:{},param:{},result:{}", url, JSON.toJSONString(headers), param, result); + } else { + String errorString = StrUtil.format("执行GET请求失败,url:{},header:{},param:{},responseCode:{},responseMessage:{}", url, + JSON.toJSONString(headers), param, response.code(), response.message()); + throw new ServiceException(errorString); + } + return result; + } + + /** + * 向指定 URL 发送POST方法的请求 + * @param url 发送请求的 URL + * @param param 请求参数,请求参数是 name1=value1&name2=value2 的形式 + * @return 远程资源的响应结果 + * @throws IOException + */ + public static String sendPost(String url, String param) throws IOException { + Map<String, String> headers = new HashMap<String, String>(); + return sendPost(url, headers, param); + } + + /** + * 向指定 URL 发送POST方法的请求 + * @param url 发送请求的 URL + * @param param 请求参数,请求参数是 name1=value1&name2=value2 的形式 + * @param headers 请求头 + * @return 远程资源的响应结果 + * @throws IOException + */ + public static String sendPost(String url, Map<String, String> headers, String param) { + ApiLog apiLog = new ApiLog(); + Request.Builder builder = new Request.Builder(); + buildHeader(builder, headers); + FormBody body = new FormBody.Builder().build(); + Request request = builder.url(url + "?" + param).post(body).build(); + Response response = null; + String result = null; + try { + ApiLogAspect.initApiLog(apiLog, request, param); + response = HTTP_CLIENT.newCall(request).execute(); + result = response.body().string(); + } catch (Exception e) { + String errorString = + StrUtil.format("执行POST请求异常,url:{},header:{},param:{},errorMessage:{}", url, JSON.toJSONString(headers), param, e.getMessage()); + ApiLogAspect.setApiLogException(apiLog, e); + throw new RuntimeException(errorString, e); + } finally { + ApiLogAspect.finishApiLog(apiLog, response, result); + } + if (response.isSuccessful() && Objects.nonNull(response.body())) {// 调用成功 + log.info("执行POST请求成功,url:{},header:{},param:{},result:{}", url, JSON.toJSONString(headers), param, result); + } else { + String errorString = StrUtil.format("执行POST请求失败,url:{},header:{},param:{},responseCode:{},responseMessage:{}", url, + JSON.toJSONString(headers), param, response.code(), response.message()); + throw new RuntimeException(errorString); + } + return result; + } + + public static String sendPostByJsonStr(String url, String jsonString) { + Map<String, String> headers = new HashMap<String, String>(); + return sendPostByJsonStr(url, headers, jsonString); + } + + /** + * JSONString形式发送POST请求 + * @throws Exception + * @throws IOException + */ + public static String sendPostByJsonStr(String url, Map<String, String> headers, String jsonString) { + ApiLog apiLog = new ApiLog(); + headers.put("Accept", "application/json");// 设置接收数据的格式 + headers.put("Content-Type", "application/json");// 设置发送数据的格式 + Request.Builder builder = new Request.Builder(); + buildHeader(builder, headers); + RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, jsonString); + Request request = builder.url(url).post(body).build(); + Response response = null; + String result = null; + try { + ApiLogAspect.initApiLog(apiLog, request, jsonString); + response = HTTP_CLIENT.newCall(request).execute(); + result = response.body().string(); + } catch (Exception e) { + String errorString = StrUtil.format("执行POST请求异常,url:{},header:{},param:{},errorMessage:{}", url, JSON.toJSONString(headers), jsonString, e.getMessage()); + ApiLogAspect.setApiLogException(apiLog, e); + throw new RuntimeException(errorString); + } finally { + ApiLogAspect.finishApiLog(apiLog, response, result); + } + if (response.isSuccessful() && Objects.nonNull(response.body())) {// 调用成功 + log.info("执行POST请求成功,url:{},header:{},param:{},result:{}", url, JSON.toJSONString(headers), jsonString, result); + } else { + String errorString = StrUtil.format("执行POST请求失败,url:{},header:{},param:{},responseCode:{},responseMessage:{}", url, + JSON.toJSONString(headers), jsonString, response.code(), response.message()); + throw new RuntimeException(errorString); + } + return result; + } + + /** + * 设置请求头 + * @param builder . + * @param headers 请求头 + */ + private static void buildHeader(Request.Builder builder, Map<String, String> headers) { + if (Objects.nonNull(headers) && headers.size() > 0) { + headers.forEach((k, v) -> { + if (Objects.nonNull(k) && Objects.nonNull(v)) { + builder.addHeader(k, v); + } + }); + } + } + + /** + * 支持嵌套泛型的POST请求 + * @param url 链接 + * @param json 请求json + * @param type 嵌套泛型 + * @return 响应对象, 可进行强转。 + * @throws Exception + */ + public static <T> T sendPostByJsonStr(String url, String jsonString, TypeReference<T> type) throws Exception { + String result = sendPostByJsonStr(url, jsonString); + if (Objects.nonNull(result) && Objects.nonNull(type)) { + return JSON.parseObject(result, type); + } + return null; + } + + public static class OkhttpInterceptor implements Interceptor { + // 最大重试次数 + private int maxRentry; + + public OkhttpInterceptor(int maxRentry) { + this.maxRentry = maxRentry; + } + + /** 递归 2次下发请求,如果仍然失败 则返回 null 但是 intercept must not return null. 返回 null 会报 IllegalStateException 异常 */ + public Response intercept(@NotNull Chain chain) throws IOException { + return retry(chain, 0); + } + + private Response retry(Chain chain, int retryCent) throws IOException { + Request request = chain.request(); + Response response = null; + try { + response = chain.proceed(request); + } catch (Exception e) { + if (maxRentry > retryCent) { + return retry(chain, retryCent + 1); + } + if (Objects.isNull(response)) { + throw e; + } + } + return response; + } + } +} diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/SecretKeyUtils.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/SecretKeyUtils.java index 713cf74..5aab3b7 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/SecretKeyUtils.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/SecretKeyUtils.java @@ -16,13 +16,9 @@ import java.util.Map; import org.jeecg.modules.wms.framework.aspectj.dto.RSA256Key; -import sun.misc.BASE64Decoder; -import sun.misc.BASE64Encoder; - /** * KeyPairGenerator https://www.jianshu.com/p/4de1ee0e7206 key的生成使用方法 */ -@SuppressWarnings("restriction") public class SecretKeyUtils { public static final String KEY_ALGORITHM = "RSA"; @@ -68,12 +64,12 @@ public class SecretKeyUtils { // 解码返回byte public static byte[] decryptBASE64(String key) throws Exception { - return (new BASE64Decoder()).decodeBuffer(key); + return Base64.getDecoder().decode(key); } // 编码返回字符串 public static String encryptBASE64(byte[] key) throws Exception { - return (new BASE64Encoder()).encodeBuffer(key); + return Base64.getEncoder().encodeToString(key); } // 使用KeyPairGenerator 生成公私钥,存放于map对象中 diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/StringUtils.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/StringUtils.java index fd6a744..cf3b904 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/StringUtils.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/StringUtils.java @@ -1,12 +1,11 @@ package org.jeecg.utils; -import org.apache.commons.lang.text.StrBuilder; -import org.jeecg.utils.support.StrFormatter; - import java.lang.reflect.Field; import java.util.Collection; import java.util.Map; +import org.apache.commons.lang.text.StrBuilder; + /** * 字符串工具类 * @author huaheng @@ -238,25 +237,6 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils { } /** - * 格式化文本, {} 表示占位符<br> - * 此方法只是简单将占位符 {} 按照顺序替换为参数<br> - * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br> - * 例:<br> - * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br> - * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br> - * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br> - * @param template 文本模板,被替换的部分用 {} 表示 - * @param params 参数值 - * @return 格式化后的文本 - */ - public static String format(String template, Object... params) { - if (isEmpty(params) || isEmpty(template)) { - return template; - } - return StrFormatter.format(template, params); - } - - /** * 驼峰首字符小写 */ public static String uncapitalize(String str) { diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/config/HuahengRedisConfig.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/config/HuahengRedisConfig.java new file mode 100644 index 0000000..214b6e6 --- /dev/null +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/config/HuahengRedisConfig.java @@ -0,0 +1,49 @@ +package org.jeecg.utils.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; + +import org.jeecg.utils.manager.RedisConfigCacheManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheManager; +import org.springframework.data.redis.cache.RedisCacheWriter; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializationContext; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +import java.time.Duration; + +@Slf4j +@Configuration +public class HuahengRedisConfig { + + @Bean + @Primary + public RedisCacheManager redisCacheManager(RedisConnectionFactory factory) { + ObjectMapper om = new ObjectMapper(); + RedisSerializer<String> redisSerializer = new StringRedisSerializer(); + Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); + // 解决查询缓存转换异常的问题 + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + jackson2JsonRedisSerializer.setObjectMapper(om); + // 配置序列化(解决乱码的问题) + RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMillis(-1)) + .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) + .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)).disableCachingNullValues(); + RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(factory); + + /* + * return RedisConfigCacheManager.builder(factory).withInitialCacheConfigurations().transactionAware().build(); + */ + return new RedisConfigCacheManager(cacheWriter, config); + } +} \ No newline at end of file diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengShiroConfig.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/config/HuahengShiroConfig.java index 8a80708..ed6c1e2 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengShiroConfig.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/config/HuahengShiroConfig.java @@ -1,4 +1,4 @@ -package org.jeecg.utils; +package org.jeecg.utils.config; import java.util.LinkedHashMap; import java.util.Map; diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/http/OkHttpUtils.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/http/OkHttpUtils.java deleted file mode 100644 index aa05386..0000000 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/http/OkHttpUtils.java +++ /dev/null @@ -1,233 +0,0 @@ -package org.jeecg.utils.http; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.TypeReference; -import com.alibaba.fastjson.parser.Feature; - -import net.bytebuddy.asm.Advice.This; -import okhttp3.*; -import org.jeecg.modules.wms.framework.aspectj.ApiLogAspect; -import org.jeecg.modules.wms.monitor.apiLog.entity.ApiLog; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.TimeUnit; - -import javax.validation.constraints.NotNull; - -/** - * OkHttp发送请求 - * @author huaheng - * @Date 2022-5-30 - */ -public class OkHttpUtils { - - private static final Logger log = LoggerFactory.getLogger(OkHttpUtils.class); - - /** - * 最多重试次数 - */ - public final static int MAX_RENTRY_COUNT = 3; - - /** - * 最大连接时间(秒) - */ - public final static int CONNECTION_TIMEOUT = 1; - - /** - * 最大读取时间(秒) - */ - public final static int READ_TIMEOUT = 30; - - /** - * 最大写入时间(秒) - */ - public final static int WRITE_TIMEOUT = 30; - - /** - * JSON格式 - */ - public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8"); - /** - * OkHTTP线程池最大空闲线程数 - */ - public final static int MAX_IDLE_CONNECTIONS = 100; - /** - * OkHTTP线程池空闲线程存活时间 - */ - public final static long KEEP_ALIVE_DURATION = 30L; - - private static final String CONTENT_TYPE = "Content-Type"; - - /** - * client 配置重试 - */ - private final static OkHttpClient HTTP_CLIENT = - new OkHttpClient.Builder().connectTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS).readTimeout(READ_TIMEOUT, TimeUnit.SECONDS) - .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS).addInterceptor(new OkHttpUtils.OkhttpInterceptor(MAX_RENTRY_COUNT)) // 过滤器,设置最大重试次数 - .retryOnConnectionFailure(false).connectionPool(new ConnectionPool(MAX_IDLE_CONNECTIONS, KEEP_ALIVE_DURATION, TimeUnit.MINUTES)).build(); - - /** - * 向指定 URL 发送GET方法的请求 - * @param url 发送请求的 URL //* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 - * @return 所代表远程资源的响应结果 - */ - public static String sendGet(String url, String param) { - ApiLog apiLog = null; - // headers 请求头 - Map<String, String> headers = new HashMap<>(); - // 请求URI - String urlNameString = url + "?" + param; - Request.Builder builder = new Request.Builder(); - buildHeader(builder, headers); - - Request request = builder.url(urlNameString).get().build(); - Response response = null; - String result = null; - try { - apiLog = ApiLogAspect.initApiLog(request, param); - response = HTTP_CLIENT.newCall(request).execute(); - if (response.isSuccessful() && Objects.nonNull(response.body())) { - result = response.body().string(); - log.info("执行GET请求,url:{},header:{},param:{} 成功,返回结果:{}", url, JSON.toJSONString(headers), param, result); - } - } catch (IOException e) { - log.error("执行GET请求,url:{},header:{},param:{} 失败!", url, JSON.toJSONString(headers), param, e); - ApiLogAspect.setApiLogException(apiLog, e); - } finally { - ApiLogAspect.finishApiLog(apiLog, response, result); - } - return result; - } - - /** - * 向指定 URL 发送POST方法的请求 - * @param url 发送请求的 URL - * @param param 请求参数,请求参数是 name1=value1&name2=value2 的形式。 - * @return 远程资源的响应结果 - * @throws IOException - */ - public static String sendPost(String url, String param) { - ApiLog apiLog = null; - FormBody.Builder builder = new FormBody.Builder(); - String urlNameString = url + "?" + param; - FormBody body = builder.build(); - Request request = new Request.Builder().url(urlNameString).post(body).build(); - Response response = null; - String result = null; - try { - apiLog = ApiLogAspect.initApiLog(request, param); - response = HTTP_CLIENT.newCall(request).execute(); - // 调用成功 - if (response.isSuccessful() && response.body() != null) { - result = response.body().string(); - log.info("执行GET请求,url:{},param:{} 成功,返回结果:{}", url, param, result); - } - } catch (IOException e) { - log.error("执行GET请求,url:{},param:{} 失败!", url, param, e); - ApiLogAspect.setApiLogException(apiLog, e); - } finally { - ApiLogAspect.finishApiLog(apiLog, response, result); - } - return result; - } - - /** JSONString形式发送POST请求 - * @throws IOException */ - public static String sendPostByJsonStr(String url, String json) { - ApiLog apiLog = null; - // using above json body as a input to post API call - RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, json); - // headers 请求头 - Map<String, String> headers = new HashMap<>(); - headers.put("Accept", "application/json");// 设置接收数据的格式 - headers.put("Content-Type", "application/json");// 设置发送数据的格式 - Request.Builder builder = new Request.Builder(); - buildHeader(builder, headers); - Request request = builder.url(url).post(body).build(); - Response response = null; - String result = null; - try { - apiLog = ApiLogAspect.initApiLog(request, json); - response = HTTP_CLIENT.newCall(request).execute(); - if (response.isSuccessful() && Objects.nonNull(response.body())) { - result = response.body().string(); - log.info("执行POST请求,url:{},header:{},param:{} 成功,返回结果:{}", url, JSON.toJSONString(headers), json, result); - } - } catch (IOException e) { - log.error("执行POST请求,url:{},header:{},param:{} 失败!", url, JSON.toJSONString(headers), json, e); - ApiLogAspect.setApiLogException(apiLog, e); - } finally { - ApiLogAspect.finishApiLog(apiLog, response, result); - } - return result; - } - - /** - * 设置请求头 - * @param builder . - * @param headers 请求头 - */ - private static void buildHeader(Request.Builder builder, Map<String, String> headers) { - if (Objects.nonNull(headers) && headers.size() > 0) { - headers.forEach((k, v) -> { - if (Objects.nonNull(k) && Objects.nonNull(v)) { - builder.addHeader(k, v); - } - }); - } - } - - /** - * 支持嵌套泛型的POST请求 - * @param url 链接 - * @param json 请求json - * @param type 嵌套泛型 - * @return 响应对象, 可进行强转。 - * @throws IOException - */ - public static <T> T sendPostByJsonStr(String url, String jsonString, TypeReference<T> type) throws IOException { - String result = sendPostByJsonStr(url, jsonString); - if (Objects.nonNull(result) && Objects.nonNull(type)) { - return JSON.parseObject(result, type); - } - return null; - } - - public static class OkhttpInterceptor implements Interceptor { - // 最大重试次数 - private int maxRentry; - - public OkhttpInterceptor(int maxRentry) { - this.maxRentry = maxRentry; - } - - @NotNull - @Override - public Response intercept(@NotNull Chain chain) throws IOException { - /* - * 递归 2次下发请求,如果仍然失败 则返回 null ,但是 intercept must not return null. 返回 null 会报 IllegalStateException 异常 - */ - return retry(chain, 0); - } - - private Response retry(Chain chain, int retryCent) { - Request request = chain.request(); - Response response = null; - try { - response = chain.proceed(request); - } catch (Exception e) { - if (maxRentry > retryCent) { - return retry(chain, retryCent + 1); - } - } - return response; - } - } - -} diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/CustomLogContextListener.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/listener/CustomLogContextListener.java index 46735d8..dfa74f5 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/CustomLogContextListener.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/listener/CustomLogContextListener.java @@ -1,4 +1,4 @@ -package org.jeecg.utils; +package org.jeecg.utils.listener; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/manager/RedisConfigCacheManager.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/manager/RedisConfigCacheManager.java new file mode 100644 index 0000000..ef1a19c --- /dev/null +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/manager/RedisConfigCacheManager.java @@ -0,0 +1,69 @@ +package org.jeecg.utils.manager; + +import java.time.Duration; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.data.redis.cache.CacheKeyPrefix; +import org.springframework.data.redis.cache.RedisCache; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheManager; +import org.springframework.data.redis.cache.RedisCacheWriter; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializationContext; + +import lombok.extern.slf4j.Slf4j; + +/** + * redis 配置类 + */ +@Slf4j +public class RedisConfigCacheManager extends RedisCacheManager { + + public RedisConfigCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) { + super(cacheWriter, defaultCacheConfiguration); + } + + public RedisConfigCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, String... initialCacheNames) { + super(cacheWriter, defaultCacheConfiguration, initialCacheNames); + } + + public RedisConfigCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, boolean allowInFlightCacheCreation, + String... initialCacheNames) { + super(cacheWriter, defaultCacheConfiguration, allowInFlightCacheCreation, initialCacheNames); + } + + public RedisConfigCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, + Map<String, RedisCacheConfiguration> initialCacheConfigurations) { + super(cacheWriter, defaultCacheConfiguration, initialCacheConfigurations); + } + + public RedisConfigCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, + Map<String, RedisCacheConfiguration> initialCacheConfigurations, boolean allowInFlightCacheCreation) { + super(cacheWriter, defaultCacheConfiguration, initialCacheConfigurations, allowInFlightCacheCreation); + } + + private static final RedisSerializationContext.SerializationPair<Object> DEFAULT_PAIR = + RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()); + + private static final CacheKeyPrefix DEFAULT_CACHE_KEY_PREFIX = cacheName -> cacheName + ":"; + + @Override + protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) { + final int lastIndexOf = StringUtils.lastIndexOf(name, '#'); + if (lastIndexOf > -1) { + final String ttl = StringUtils.substring(name, lastIndexOf + 1); + final Duration duration = Duration.ofSeconds(Long.parseLong(ttl)); + cacheConfig = cacheConfig.entryTtl(duration); + // 修改缓存key和value值的序列化方式 + cacheConfig = cacheConfig.computePrefixWith(DEFAULT_CACHE_KEY_PREFIX).serializeValuesWith(DEFAULT_PAIR); + final String cacheName = StringUtils.substring(name, 0, lastIndexOf); + return super.createRedisCache(cacheName, cacheConfig); + } else { + // 修改缓存key和value值的序列化方式 + cacheConfig = cacheConfig.computePrefixWith(DEFAULT_CACHE_KEY_PREFIX).serializeValuesWith(DEFAULT_PAIR); + return super.createRedisCache(name, cacheConfig); + } + // throw new RuntimeException("字符串中必须包含#号,#号后为过期时间, -1为永不过期"); + } +} \ No newline at end of file diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/RedissonDistributedLocker.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/support/RedissonDistributedLocker.java index 82d2210..a564ef5 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/RedissonDistributedLocker.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/support/RedissonDistributedLocker.java @@ -1,4 +1,4 @@ -package org.jeecg.utils; +package org.jeecg.utils.support; import java.util.concurrent.TimeUnit; diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/support/StrFormatter.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/support/StrFormatter.java deleted file mode 100644 index aa86bae..0000000 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/support/StrFormatter.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.jeecg.utils.support; - -import org.jeecg.utils.StringUtils; - -/** - * 字符串格式化 - * @author huaheng - */ -public class StrFormatter { - - public static final String EMPTY_JSON = "{}"; - public static final char C_BACKSLASH = '\\'; - public static final char C_DELIM_START = '{'; - public static final char C_DELIM_END = '}'; - - /** - * 格式化字符串<br> - * 此方法只是简单将占位符 {} 按照顺序替换为参数<br> - * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br> - * 例:<br> - * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br> - * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br> - * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br> - * @param strPattern 字符串模板 - * @param argArray 参数列表 - * @return 结果 - */ - public static String format(final String strPattern, final Object... argArray) { - if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray)) { - return strPattern; - } - final int strPatternLength = strPattern.length(); - - // 初始化定义好的长度以获得更好的性能 - StringBuilder sbuf = new StringBuilder(strPatternLength + 50); - - int handledPosition = 0; - int delimIndex;// 占位符所在位置 - for (int argIndex = 0; argIndex < argArray.length; argIndex++) { - delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition); - if (delimIndex == -1) { - if (handledPosition == 0) { - return strPattern; - } else { // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果 - sbuf.append(strPattern, handledPosition, strPatternLength); - return sbuf.toString(); - } - } else { - if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH) { - if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH) { - // 转义符之前还有一个转义符,占位符依旧有效 - sbuf.append(strPattern, handledPosition, delimIndex - 1); - sbuf.append(Convert.utf8Str(argArray[argIndex])); - handledPosition = delimIndex + 2; - } else { - // 占位符被转义 - argIndex--; - sbuf.append(strPattern, handledPosition, delimIndex - 1); - sbuf.append(C_DELIM_START); - handledPosition = delimIndex + 1; - } - } else { - // 正常占位符 - sbuf.append(strPattern, handledPosition, delimIndex); - sbuf.append(Convert.utf8Str(argArray[argIndex])); - handledPosition = delimIndex + 2; - } - } - } - // append the characters following the last {} pair. - // 加入最后一个占位符后所有的字符 - sbuf.append(strPattern, handledPosition, strPattern.length()); - - return sbuf.toString(); - } - -} diff --git a/huaheng-wms-core/src/main/resources/application-dev.yml b/huaheng-wms-core/src/main/resources/application-dev.yml index 6bcf0e0..4535301 100644 --- a/huaheng-wms-core/src/main/resources/application-dev.yml +++ b/huaheng-wms-core/src/main/resources/application-dev.yml @@ -276,6 +276,7 @@ logging: org.jeecg.common: WARN org.jeecg.modules: WARN org.jeecg.modules.wms: DEBUG + org.jeecg.config.shiro: INFO #swagger knife4j: #开启增强配置 diff --git a/huaheng-wms-core/src/main/resources/application-prod.yml b/huaheng-wms-core/src/main/resources/application-prod.yml index 269ad0f..f396120 100644 --- a/huaheng-wms-core/src/main/resources/application-prod.yml +++ b/huaheng-wms-core/src/main/resources/application-prod.yml @@ -265,6 +265,7 @@ logging: org.jeecg.common: WARN org.jeecg.modules: WARN org.jeecg.modules.wms: DEBUG + org.jeecg.config.shiro: INFO #swagger knife4j: #开启增强配置 diff --git a/huaheng-wms-core/src/main/resources/application.yml b/huaheng-wms-core/src/main/resources/application.yml index bc2e8c7..641bf07 100644 --- a/huaheng-wms-core/src/main/resources/application.yml +++ b/huaheng-wms-core/src/main/resources/application.yml @@ -6,4 +6,4 @@ spring: huaheng: system: - Id: HUAHENG-WMS4-4.0.1 + Id: HUAHENG-WMS4 diff --git a/huaheng-wms-core/src/main/resources/logback-spring.xml b/huaheng-wms-core/src/main/resources/logback-spring.xml index 1fe1103..6a72ece 100644 --- a/huaheng-wms-core/src/main/resources/logback-spring.xml +++ b/huaheng-wms-core/src/main/resources/logback-spring.xml @@ -2,7 +2,7 @@ <configuration debug="false"> <!-- 监听器,指定日志文件存放目录 --> - <contextListener class="org.jeecg.utils.CustomLogContextListener" /> + <contextListener class="org.jeecg.utils.listener.CustomLogContextListener" /> <!--定义日志文件的存储地址 --> <property name="LOG_HOME" value="${LOG_PATH}/logs" />