diff --git a/mall-common/src/main/java/com/suisung/mall/common/exception/GlobalExceptionHandler.java b/mall-common/src/main/java/com/suisung/mall/common/exception/GlobalExceptionHandler.java index 71ddbcf0..ce493b0a 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/exception/GlobalExceptionHandler.java +++ b/mall-common/src/main/java/com/suisung/mall/common/exception/GlobalExceptionHandler.java @@ -6,11 +6,18 @@ import com.suisung.mall.common.api.ResultCode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.dao.DataAccessException; +import org.springframework.validation.BindException; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; import javax.servlet.http.HttpServletRequest; +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; import java.sql.SQLException; +import java.util.stream.Collectors; /** * 全局异常处理器 @@ -25,22 +32,62 @@ import java.sql.SQLException; @RestControllerAdvice public class GlobalExceptionHandler { private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); - private static final String UNKNOWN_LOCATION = "未知位置"; private static final String DB_ERROR_MSG = "数据库操作失败,请稍后重试"; - private static final String LOG_FORMAT = "业务异常 || URI={} || Method={} || Error={} || Location={}"; /** - * 获取异常发生位置信息 - * - * @param stackTrace 异常堆栈 - * @return 格式化的位置信息(类名.方法名 : 行号) + * 处理参数校验异常 */ - private String getExceptionLocation(StackTraceElement[] stackTrace) { - if (stackTrace == null || stackTrace.length == 0) { - return UNKNOWN_LOCATION; + @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class}) + public CommonResult handleValidationException(Exception e, HttpServletRequest req) { + String errorMessage; + + if (e instanceof MethodArgumentNotValidException) { + errorMessage = ((MethodArgumentNotValidException) e).getBindingResult().getFieldErrors().stream() + .map(FieldError::getDefaultMessage) + .collect(Collectors.joining("; ")); + } else { + errorMessage = ((BindException) e).getBindingResult().getFieldErrors().stream() + .map(FieldError::getDefaultMessage) + .collect(Collectors.joining("; ")); } - StackTraceElement first = stackTrace[0]; - return String.format("%s.%s:%d", first.getClassName(), first.getMethodName(), first.getLineNumber()); + + logError(req, "参数校验失败", e); + return CommonResult.validateFailed(errorMessage); + } + + /** + * 处理约束违反异常 + */ + @ExceptionHandler(ConstraintViolationException.class) + public CommonResult handleConstraintViolation(ConstraintViolationException e, HttpServletRequest req) { + String errorMessage = e.getConstraintViolations().stream() + .map(ConstraintViolation::getMessage) + .collect(Collectors.joining("; ")); + + logError(req, "约束违反异常", e); + return CommonResult.validateFailed(errorMessage); + } + + /** + * 处理参数类型不匹配异常 + */ + @ExceptionHandler(MethodArgumentTypeMismatchException.class) + public CommonResult handleMethodArgumentTypeMismatch(MethodArgumentTypeMismatchException e, HttpServletRequest req) { + String errorMessage = String.format("参数%s类型不匹配,需要%s类型,但接收到%s", + e.getName(), e.getRequiredType().getSimpleName(), e.getValue()); + + logError(req, "参数类型不匹配", e); + return CommonResult.validateFailed(errorMessage); + } + + /** + * 处理数字格式异常和其他参数异常 + */ + @ExceptionHandler({NumberFormatException.class, IllegalArgumentException.class}) + public CommonResult handleParameterException(Exception e, HttpServletRequest req) { + String errorMessage = e.getMessage(); + logError(req, "参数异常", e); + return CommonResult.validateFailed(errorMessage); } /** @@ -48,8 +95,7 @@ public class GlobalExceptionHandler { */ @ExceptionHandler({SQLException.class, DataAccessException.class, Exception.class}) public CommonResult handleSystemException(HttpServletRequest req, Exception e) { - String location = getExceptionLocation(e.getStackTrace()); - logger.error(LOG_FORMAT, req.getRequestURI(), req.getMethod(), e.getMessage(), location, e); + logError(req, e.getMessage(), e); if (e instanceof SQLException || e instanceof DataAccessException) { return CommonResult.failed(DB_ERROR_MSG); @@ -62,12 +108,22 @@ public class GlobalExceptionHandler { */ @ExceptionHandler(ApiException.class) public CommonResult handleApiException(HttpServletRequest req, ApiException e) { - String location = getExceptionLocation(e.getStackTrace()); - logger.error(LOG_FORMAT, - req.getRequestURI(), req.getMethod(), e.getErrorCode(), location, e); - + logError(req, e.getErrorCode() != null ? e.getErrorCode().getMessage() : e.getMessage(), e); return StrUtil.isNotBlank(e.getMessage()) ? CommonResult.failed(e.getMessage()) : CommonResult.failed(ResultCode.FAILED); } + + /** + * 记录错误日志 + */ + private void logError(HttpServletRequest req, String message, Exception e) { + StackTraceElement[] stackTrace = e.getStackTrace(); + String location = (stackTrace == null || stackTrace.length == 0) + ? "未知位置" + : String.format("%s.%s:%d", stackTrace[0].getClassName(), stackTrace[0].getMethodName(), stackTrace[0].getLineNumber()); + + logger.error("业务异常 || URI={} || Method={} || Error={} || Location={}", + req.getRequestURI(), req.getMethod(), message, location, e); + } } \ No newline at end of file diff --git a/mall-gateway/src/main/resources/application.yml b/mall-gateway/src/main/resources/application.yml index f0235133..8c4ef682 100644 --- a/mall-gateway/src/main/resources/application.yml +++ b/mall-gateway/src/main/resources/application.yml @@ -90,6 +90,7 @@ secure: - "/esProduct/**" - "/admin/oss/upload/**" - "/admin/shop/wxqrcode/common/wxurlscheme" + - "/mobile/shop/lakala/sign/ec/**" - "/mobile/**/**/test/case" - "/**/**/testcase" universal: diff --git a/mall-shop/pom.xml b/mall-shop/pom.xml index 06a6df00..3380cf21 100644 --- a/mall-shop/pom.xml +++ b/mall-shop/pom.xml @@ -273,6 +273,11 @@ 4.1.0 + + org.springframework.boot + spring-boot-starter-thymeleaf + + diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java index 429c18f8..42ae878b 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java @@ -13,6 +13,7 @@ import cn.hutool.json.JSONUtil; import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.service.impl.BaseControllerImpl; import com.suisung.mall.shop.lakala.service.LakalaApiService; +import com.suisung.mall.shop.lakala.service.LklLedgerEcService; import com.suisung.mall.shop.library.service.LibraryProductService; import com.suisung.mall.shop.message.service.MqMessageService; import com.suisung.mall.shop.message.service.PushMessageService; @@ -28,6 +29,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.util.Base64Utils; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.ModelAndView; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; @@ -71,6 +73,9 @@ public class LakalaController extends BaseControllerImpl { @Resource private MqMessageService mqMessageService; + @Resource + private LklLedgerEcService lklLedgerEcService; + @ApiOperation(value = "测试案例", notes = "测试案例") @RequestMapping(value = "/testcase", method = RequestMethod.POST) public Object testcase(@RequestBody JSONObject paramsJSON) { @@ -154,6 +159,26 @@ public class LakalaController extends BaseControllerImpl { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(resp); } + @ApiOperation(value = "跳转到拉卡拉签署合同链接", notes = "跳转到拉卡拉签署合同链接") + @RequestMapping(value = "/sign/ec/{code}", method = RequestMethod.GET) + public ModelAndView jumpToSignLklEcLink(@PathVariable Long code) { +// // 根据 code 值决定重定向到哪个 URL +// String resultUrl = lklLedgerEcService.getLklEcResultUrl(code); +// if (StrUtil.isBlank(resultUrl)) { +// return new RedirectView("https://mall.gpxscs.cn/mchapp"); +// } +// return new RedirectView(resultUrl); + + // 根据 code 值获取结果 URL + String resultUrl = lklLedgerEcService.getLklEcResultUrl(code); + + ModelAndView modelAndView = new ModelAndView("sign_lkl_ec"); + modelAndView.addObject("resultUrl", resultUrl); + + // 返回模板名称,渲染 sign_lkl_ec.html 页面 + return modelAndView; + } + @ApiOperation(value = "商户分账业务开通申请", notes = "商户分账业务开通申请") @RequestMapping(value = "/ledger/applyLedgerMer", method = RequestMethod.POST) public CommonResult ledgerApplyLedgerMer(@RequestBody JSONObject paramsJSON) { diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerEcService.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerEcService.java index c19c650a..b6b3954c 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerEcService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerEcService.java @@ -50,4 +50,12 @@ public interface LklLedgerEcService extends IBaseService { LklLedgerEc getByMchId(Long mchId, String ecStatus, Integer status); + /** + * 获取拉卡拉商户签署合同页面URL + * + * @param mchId + * @return + */ + String getLklEcResultUrl(Long mchId); + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerEcServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerEcServiceImpl.java index dc95704b..8c251d88 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerEcServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerEcServiceImpl.java @@ -135,4 +135,19 @@ public class LklLedgerEcServiceImpl extends BaseServiceImpl + + + + + 小发同城电子合同签署 + + + +
+
+

小发同城电子合同签署

+
+ +
+
+ +
+ +
+

恭喜!您的开店入驻申请已审核通过

+

请在24小时内完成电子合同签署

+ + + + + + + + + + +
+ 注意:链接有效期为24小时,逾期需重新提交申请。 +
+
+
+ + +
+ + + +