diff --git a/src/main/java/com/example/demo/controller/coin/AuditController.java b/src/main/java/com/example/demo/controller/coin/AuditController.java index 1b7628a..bf1494c 100644 --- a/src/main/java/com/example/demo/controller/coin/AuditController.java +++ b/src/main/java/com/example/demo/controller/coin/AuditController.java @@ -6,6 +6,7 @@ import com.example.demo.config.interfac.Log; import com.example.demo.domain.entity.Admin; import com.example.demo.service.coin.AuditService; import com.example.demo.service.coin.TranslationService; +import com.example.demo.serviceImpl.coin.AuditServiceImpl; import com.github.pagehelper.PageInfo; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; @@ -17,7 +18,9 @@ import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.example.demo.domain.vo.coin.*; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @program: gold-java @@ -49,10 +52,21 @@ public class AuditController { //审核订单 @Log("审核订单") @PostMapping("audit") - public ResponseEntity auditOrder( - @RequestBody AuditRequest request) { - boolean result = auditService.auditOrder(request.getToken(), request.getOrderCode(), request.getAuditId(), request.getAction(), request.getRejectReason(),request.getPrice(),request.getLinkId()); - return ResponseEntity.ok(result); + public ResponseEntity> auditOrder(@RequestBody AuditRequest request) throws Exception { + boolean result = auditService.auditOrder(request.getToken(), request.getOrderCode(), request.getAuditId(), + request.getAction(), request.getRejectReason(), request.getPrice(), request.getLinkId() + ); + + Map resp = new HashMap<>(); + resp.put("success", result); + if (!result) { + resp.put("message", AuditServiceImpl.AuditContext.getFailMsg()); + } else { + resp.put("message", "审核成功"); + } + + AuditServiceImpl.AuditContext.clear(); // 必须清理 + return ResponseEntity.ok(resp); } //多条件查询充值审核订单列表 diff --git a/src/main/java/com/example/demo/domain/vo/coin/RefundAudit.java b/src/main/java/com/example/demo/domain/vo/coin/RefundAudit.java index ed8172b..d9c1ee2 100644 --- a/src/main/java/com/example/demo/domain/vo/coin/RefundAudit.java +++ b/src/main/java/com/example/demo/domain/vo/coin/RefundAudit.java @@ -6,6 +6,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import java.math.BigDecimal; import java.util.Date; import java.util.List; @@ -53,6 +54,9 @@ public class RefundAudit { private String rejectReason; //驳回理由 private Byte type; //类型 private Integer flag; //是否为员工号 0-员工号 1-非员工号 + private BigDecimal price; //原价 + private String linkId; //linkID + private Integer redDiff; //红包差额 金币 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") diff --git a/src/main/java/com/example/demo/exception/RedCheckException.java b/src/main/java/com/example/demo/exception/RedCheckException.java index 384b5c0..debf37a 100644 --- a/src/main/java/com/example/demo/exception/RedCheckException.java +++ b/src/main/java/com/example/demo/exception/RedCheckException.java @@ -1,5 +1,8 @@ package com.example.demo.exception; +import lombok.Getter; + +@Getter public class RedCheckException extends RuntimeException { private final int num; @@ -9,7 +12,4 @@ public class RedCheckException extends RuntimeException { this.num = num; } - public int getNum() { - return num; - } } \ No newline at end of file diff --git a/src/main/java/com/example/demo/service/Temporary/RedService.java b/src/main/java/com/example/demo/service/Temporary/RedService.java index 98a3d88..a5c75d1 100644 --- a/src/main/java/com/example/demo/service/Temporary/RedService.java +++ b/src/main/java/com/example/demo/service/Temporary/RedService.java @@ -29,8 +29,8 @@ public interface RedService { //判断红包是否退票情况 String checkRed(BigDecimal price,String linkId) throws Exception; - //修改订单状态 - void updateOrderStatus(String linkId) throws Exception; + //扣除金币抵扣红包 + String consumeRed(String linkId) throws Exception; //红包不足抵扣金额 Result updateRed(ConsumeUser consumeUser) throws Exception; } diff --git a/src/main/java/com/example/demo/service/coin/AuditService.java b/src/main/java/com/example/demo/service/coin/AuditService.java index 19a0b88..5f4a438 100644 --- a/src/main/java/com/example/demo/service/coin/AuditService.java +++ b/src/main/java/com/example/demo/service/coin/AuditService.java @@ -19,11 +19,11 @@ import java.math.BigDecimal; public interface AuditService { //审核订单并修改用户余额等 - boolean auditOrder(String token, String orderCode, Integer auditId, Integer action, String rejectReason, BigDecimal price, String linkId); + boolean auditOrder(String token, String orderCode, Integer auditId, Integer action, String rejectReason, BigDecimal price, String linkId) throws Exception; //多条件查询充值审核订单 PageInfo selectRechargeBy(Integer pageNum, Integer pageSize, RechargeAudit rechargeAudit); //多条件查询退款审核订单 - PageInfo selectRefundBy(Integer pageNum, Integer pageSize, RefundAudit refundAudit); + PageInfo selectRefundBy(Integer pageNum, Integer pageSize, RefundAudit refundAudit) ; //充值审核金币合计数 Gold sumRechargeGold(Integer pageNum, Integer pageSize, RechargeAudit rechargeAudit); //退款审核金币合计数 diff --git a/src/main/java/com/example/demo/serviceImpl/Temporary/RedServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/Temporary/RedServiceImpl.java index ff0db01..9bcf33f 100644 --- a/src/main/java/com/example/demo/serviceImpl/Temporary/RedServiceImpl.java +++ b/src/main/java/com/example/demo/serviceImpl/Temporary/RedServiceImpl.java @@ -57,12 +57,14 @@ public class RedServiceImpl implements RedService { @Value("${red.urllogin}") private String BASE_URL_LOGIN; private static final String BASE_URLDev = "http://af9c6249.natappfree.cc"; + private static final String BASE_URL_Margen = "http://pcc8496a.natappfree.cc"; private static final String PATH = "/api/coupon/IssueRechargeRedPacket"; private static final String PATHRED = "/api/coupon/getTotalDiscount"; private static final String BASE_URL = "http://localhost:8080"; private static final String PATHLIST = "/api/coupon/getRedPacket"; private static final String PATHLOGIN = "/api/user/toujiaoAppLogin"; private static final String PATH_REFUND = "/api/coupon/refundRedPacket"; + private static final String PATH_CHECK = "/api/coupon/checkRefundState"; private static final String CONSUME_PATH = "/api/coupon/updateCostRedPacket"; private static final HttpClient CLIENT = HttpClient.newHttpClient(); @@ -237,9 +239,7 @@ public class RedServiceImpl implements RedService { String body = "{\"order_id\":\"" + linkId + "\",\"amount\":" + price.divideToIntegralValue(BigDecimal.valueOf(100)).intValue() + "}"; // 构建 HttpRequest - HttpRequest request = HttpRequest.newBuilder() - // .uri(URI.create(BASE_URLDev + PATH_REFUND)) - .uri(URI.create("http://a4f24573.natappfree.cc/api/coupon/refundRedPacket")) + HttpRequest request = HttpRequest.newBuilder().uri(URI.create(BASE_URL_Margen+PATH_CHECK)) .header("Content-Type", "application/json") // ⭐ 透传 token,避免 JWT 过期问题 // .header("Authorization", authHeader) @@ -251,29 +251,31 @@ public class RedServiceImpl implements RedService { CLIENT.send(request, HttpResponse.BodyHandlers.ofString()); // HTTP 层校验 - if (resp.statusCode() != 200) { + if (resp.statusCode() != 200 ) { log.warn("红包接口 HTTP 异常,status:{},body:{}", resp.statusCode(), resp.body()); throw new RuntimeException("红包接口 HTTP 异常"); } - // 解析返回 JSON JsonNode root = objectMapper.readTree(resp.body()); int code = root.path("code").asInt(); + if (code == 400) { + // 400 状态码表示参数错误 + log.warn("该订单无法处理,status:{},body:{}", + resp.statusCode(), resp.body()); + throw new RuntimeException("该订单无法自动处理,请联系工作人员"); + } + boolean flag = root.path("data").path("flag").asBoolean(); - int num = root.path("data").path("num").asInt(); // ✅ 获取 num + int num = root.path("data").path("num").asInt(); // 获取 num // 业务判断 if (code == 200 && flag) { - //updateOrderStatus(linkId); return "success"; - } - - // 失败 同时抛出须补充的金币数 - throw new RedCheckException( - "红包校验失败,orderId=" + linkId, - num - ); + } else { // flag 为 false + throw new RedCheckException( + "红包校验失败,orderId=" + linkId, num); + } } catch (IOException | InterruptedException e) { log.error("调用红包接口失败,orderId:{}", linkId, e); throw new RuntimeException("调用红包接口异常", e); @@ -281,16 +283,36 @@ public class RedServiceImpl implements RedService { } + + // 扣除金币抵扣红包 @Override - public void updateOrderStatus(String linkId) throws Exception { + public String consumeRed(String linkId) throws Exception { try { - String body = JSON.toJSONString(java.util.Map.of("linkId", linkId)); - } - catch (Exception e) { - log.error("修改状态失败", e); - throw new Exception("系统异常"); + // 构造参数 + String body = "{\"order_id\":\"" + linkId + "}"; + // 构建 HttpRequest + HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(BASE_URL_Margen+PATH_REFUND)) + .header("Content-Type", "application/json") + .POST(HttpRequest.BodyPublishers.ofString(body)) + .build(); + // 发送请求 + HttpResponse resp = + CLIENT.send(request, HttpResponse.BodyHandlers.ofString()); + + // HTTP 层校验 + if (resp.statusCode() != 200 ) { + log.warn("红包接口 HTTP 异常,status:{},body:{}", + resp.statusCode(), resp.body()); + throw new RuntimeException("红包接口 HTTP 异常"); + } + } catch (IOException | InterruptedException e) { + log.error("调用红包接口失败,orderId:{}", linkId, e); + throw new RuntimeException("调用红包接口异常", e); } + return "success"; } + + @Transactional(rollbackFor = Exception.class) @Override public Result updateRed(ConsumeUser consumeUser) throws Exception { diff --git a/src/main/java/com/example/demo/serviceImpl/coin/AuditServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/coin/AuditServiceImpl.java index 2c0a6bd..09416ed 100644 --- a/src/main/java/com/example/demo/serviceImpl/coin/AuditServiceImpl.java +++ b/src/main/java/com/example/demo/serviceImpl/coin/AuditServiceImpl.java @@ -58,7 +58,7 @@ public class AuditServiceImpl implements AuditService { */ @Transactional(rollbackFor = Exception.class) @Override - public boolean auditOrder(String token, String orderCode, Integer auditId, Integer action,String rejectReason,BigDecimal price,String linkId) { + public boolean auditOrder(String token, String orderCode, Integer auditId, Integer action,String rejectReason,BigDecimal price,String linkId) throws Exception { UserGoldRecord order=auditMapper.selectOrderByOrderCode(orderCode); Date date =new Date(); //状态为0待审核或4第一次红包退款失败的订单才能审核 @@ -119,8 +119,6 @@ public class AuditServiceImpl implements AuditService { auditMapper.updateFirstRecharge(order.getJwcode());//设置首充时间为当前时间 } auditMapper.updateUserGold(update); - - //累充 try { BigDecimal sum = BigDecimal.valueOf( @@ -138,7 +136,6 @@ public class AuditServiceImpl implements AuditService { log.warn("精网号发送失败,主流程继续 | jwcode={}", order.getJwcode(), e); } - //erp增加充值数据 GoldTistV2.addCoinNew(order.getJwcode().toString(), 64, //充值永久金币 @@ -150,17 +147,23 @@ public class AuditServiceImpl implements AuditService { }else if (order.getType()==2) { //退款 //对非强制退款订单进行退红包校验 - if (order.getAuditStatus()!=4){ + if (order.getAuditStatus()!=4&&price!= null&&linkId!= null){ try { redService.checkRed(price, linkId); } catch (RedCheckException e) { // 业务失败(flag=false) int num = e.getNum(); - log.error("红包退票失败,还需扣除金币数: {}", num); + String logMsg = String.format( + "红包退票失败,orderId=%s,还需扣除金币数=%d", + linkId, num + ); + + log.error(logMsg); updateOrder.setAuditStatus(4); - updateOrder.setRedDiff(BigDecimal.valueOf(num)); + updateOrder.setRedDiff(BigDecimal.valueOf(num* 100L)); auditMapper.updateOrder(updateOrder); - throw e; // 或者包装后再抛 + AuditContext.setFailMsg(logMsg); + return false; } catch (Exception e) { // 网络异常 / 系统异常 log.error("红包接口调用异常", e); @@ -194,10 +197,8 @@ public class AuditServiceImpl implements AuditService { // 执行审核更新 redMapper.update(order.getJwcode(),type,order.getPrice()); }//金币充值退款 - - else if (oldOrder.getType()==0){ - int type = 1; + if(order.getTaskGold()==0){ //无任务金币统一走免费+永久 GoldTistV2.addCoinNew(order.getJwcode().toString(), 58, //退款免费+永久金币-充值 (double) (order.getFreeDecember()+order.getFreeJune()+order.getPermanentGold() ) /100, @@ -206,8 +207,11 @@ public class AuditServiceImpl implements AuditService { GoldTistV2.addCoinNew(order.getJwcode().toString(), 59, //退款任务+永久金币-充值 (double) (order.getTaskGold()+order.getPermanentGold() ) /100, order.getRemark(),(double) order.getPermanentGold() / 100, auditName, "退款金币充值");} + //额外扣金币抵扣红包 - if (order.getAuditStatus()==4){ + + if (order.getAuditStatus()==4&&price!= null&&linkId!= null){ + int type = 1; //红包充值累计 GoldUser user = userMapper.selectUser(order.getJwcode().toString()); // 检查用户余额是否足够抵扣红包差额 if (order.getRedDiff().compareTo(user.getNowSumGold()) > 0) { @@ -248,9 +252,13 @@ public class AuditServiceImpl implements AuditService { consumeUser.setAdminId(order.getAdminId()); consumeUser.setRemark(order.getRemark()); consumeUser.setPrice(order.getPrice()); - - } // 执行审核更新 - redMapper.update(order.getJwcode(),type,order.getPrice()); + // 执行金币抵扣红包 + redService.updateRed(consumeUser); + //link扣除已有红包 + redService.consumeRed(linkId); + // 执行审核更新 + redMapper.update(order.getJwcode(),type,order.getPrice()); + } } } @@ -381,4 +389,21 @@ public class AuditServiceImpl implements AuditService { gold.setTaskGolds(BigDecimal.valueOf(taskGoldSum)); return gold; } + public class AuditContext { + + private static final ThreadLocal FAIL_MSG = new ThreadLocal<>(); + + public static void setFailMsg(String msg) { + FAIL_MSG.set(msg); + } + + public static String getFailMsg() { + return FAIL_MSG.get(); + } + + public static void clear() { + FAIL_MSG.remove(); + } + } + }