package com.ruoyi.system.controller; import com.alibaba.fastjson2.JSONObject; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.ControllerUtil.BalancePayUtil; import com.ruoyi.system.ControllerUtil.GenerateCustomCode; import com.ruoyi.system.ControllerUtil.OrderUtil; import com.ruoyi.system.ControllerUtil.WXsendMsgUtil; import com.ruoyi.system.ControllerUtil.WechatPayUtil; import com.ruoyi.system.domain.*; import com.ruoyi.system.service.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import java.math.BigDecimal; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 支付回调控制器 * * 处理各种支付场景的微信支付回调通知 * 所有回调接口都以api开头,符合项目规范 * * @author Mr. Zhang Pan * @date 2025-06-16 * @version 1.0 */ @RestController public class PayNotifyController extends BaseController { private static final Logger logger = LoggerFactory.getLogger(PayNotifyController.class); @Autowired private WechatPayUtil wechatPayUtil; @Autowired private IGoodsOrderService goodsOrderService; @Autowired private IOrderService orderService; @Autowired private IOrderLogService orderLogService; @Autowired private IUsersService usersService; @Autowired private IServiceGoodsService serviceGoodsService; @Autowired private ISiteConfigService siteConfigService; @Autowired private IIntegralLogService integralLogService; @Autowired private IPayMoneyLogService payMoneyLogService; @Autowired private IWorkerLevelService workerLevelService; @Autowired private IWorkerMarginLogService workerMarginLogService; @Autowired private IWorkerMoneyLogService workerMoneyLogService; @Autowired private IUserMemberRechargeLogService userMemberRechargeLogService; @Autowired private IUserMemberRechargeProgramService userMemberRechargeProgramService; @Autowired private IUserMemnerConsumptionLogService userMemnerConsumptionLogService; @Autowired private IUserGroupBuyingService userGroupBuyingService; @Autowired private IUsersPayBeforService usersPayBeforService; @Autowired private IUserUseSecondaryCardService userUseSecondaryCardService; /** * 商品支付回调接口 * * @param request HTTP请求对象 * @return XML格式响应给微信服务器 * * 处理商品订单的支付成功回调: * 1. 验证支付签名 * 2. 更新商品订单支付状态 * 3. 更新订单支付时间和交易号 * 4. 处理库存扣减等业务逻辑 */ @PostMapping(value = "/api/goods/pay/notify") public String apiGoodsPayNotify(HttpServletRequest request) { try { logger.info("收到商品支付回调通知,开始处理..."); // 1. 使用WechatPayUtil处理支付回调 Map notifyResult = wechatPayUtil.handlePayNotify(request); // 2. 检查处理结果 boolean success = (Boolean) notifyResult.get("success"); String message = (String) notifyResult.get("message"); if (!success) { logger.error("商品支付回调处理失败:{}", message); return buildFailResponse("商品支付回调处理失败"); } // 3. 获取支付信息 Map paymentInfo = (Map) notifyResult.get("paymentInfo"); String outTradeNo = (String) paymentInfo.get("outTradeNo"); String transactionId = (String) paymentInfo.get("transactionId"); String totalFee = (String) paymentInfo.get("totalFee"); // 4. 查询对应的商品订单 GoodsOrder goodsOrder = new GoodsOrder(); goodsOrder.setMainOrderId(outTradeNo); List goodsOrderslist = goodsOrderService.selectGoodsOrderList(goodsOrder); // if (!goodsOrderslist.isEmpty()) { // logger.error("商品订单不存在,订单号:{}", outTradeNo); // return buildFailResponse("商品订单不存在"); // } // // 5. 检查订单状态,避免重复处理 // if (goodsOrder.getStatus() != null && goodsOrder.getStatus() == 2L) { // logger.info("商品订单已支付,订单号:{}", outTradeNo); // return buildSuccessResponse(); // } long uid = Long.parseLong("0"); // 6. 更新商品订单状态 for (GoodsOrder goodsOrderData : goodsOrderslist){ uid= goodsOrderData.getUid(); goodsOrderData.setStatus(2L); // 2:已支付 goodsOrderData.setPayTime(new Date()); goodsOrderData.setTransactionId(transactionId); int updateResult = goodsOrderService.updateGoodsOrder(goodsOrderData); ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(goodsOrderData.getProductId()); Users userinfo = usersService.selectUsersById(goodsOrderData.getUid()); WXsendMsgUtil.sendUserForMoneySuccess(userinfo.getOpenid(),goodsOrder,serviceGoods); } // if (updateResult <= 0) { // logger.error("更新商品订单状态失败,订单号:{}", outTradeNo); // return buildFailResponse("更新订单状态失败"); // } Users users =usersService.selectUsersById(uid); // 7. 处理商品订单支付成功后的业务逻辑 handleGoodsPaymentSuccess(users,outTradeNo, paymentInfo); //8向客户推送微信消息 //sendWechatMessage(users,outTradeNo); logger.info("商品支付回调处理成功,订单号:{}", outTradeNo); return buildSuccessResponse(); } catch (Exception e) { logger.error("商品支付回调处理异常:", e); return buildFailResponse("商品支付回调处理异常"); } } /** * 拼团支付的回调接口 * * @param request HTTP请求对象 * @return XML格式响应给微信服务器 *IUserGroupBuyingService userGroupBuyingService; * 处理商品订单的支付成功回调: * 1. 验证支付签名 * 2. 更新商品订单支付状态 * 3. 更新订单支付时间和交易号 * 4. 处理库存扣减等业务逻辑 */ @PostMapping(value = "/api/group/pay/notify") public String apigroupPayNotify(HttpServletRequest request) { try { logger.info("收到商品支付回调通知,开始处理..."); // 1. 使用WechatPayUtil处理支付回调 Map notifyResult = wechatPayUtil.handlePayNotify(request); // 2. 检查处理结果 boolean success = (Boolean) notifyResult.get("success"); String message = (String) notifyResult.get("message"); if (!success) { logger.error("商品支付回调处理失败:{}", message); return buildFailResponse("商品支付回调处理失败"); } // 3. 获取支付信息 Map paymentInfo = (Map) notifyResult.get("paymentInfo"); String outTradeNo = (String) paymentInfo.get("outTradeNo"); String transactionId = (String) paymentInfo.get("transactionId"); String totalFee = (String) paymentInfo.get("totalFee"); UserGroupBuying userGroupBuying = userGroupBuyingService.selectUserGroupBuyingById(Long.valueOf(outTradeNo)); if (userGroupBuying!=null){ userGroupBuying.setStatus(1L); userGroupBuying.setTransactionId(transactionId); userGroupBuying.setPaytime(new Date()); //userGroupBuying.setMoney(userGroupBuying.getMoney()); userGroupBuyingService.updateUserGroupBuying(userGroupBuying); // Order order = new Order(); // order.setType(1L); // order.setMainOrderId(GenerateCustomCode.generCreateOrder("B")); // order.setOrderId(userGroupBuying.getOrderid()); // order.setTransactionId(transactionId); // order.setCreateType(1L); // order // order // order // order // order // order // order // order // order // order } //最后无论如何平台流水需要添加,让平台看到流水和账目 PayMoneyLog payMoneyLog = new PayMoneyLog(); payMoneyLog.setOid(Long.valueOf(userGroupBuying.getId())); payMoneyLog.setOrderId(userGroupBuying.getOrderid()); payMoneyLog.setUid(Long.valueOf(userGroupBuying.getUid())); payMoneyLog.setUname(userGroupBuying.getUname()); payMoneyLog.setPrice(userGroupBuying.getMoney()); payMoneyLog.setMark("拼团支付"); payMoneyLog.setPayTime(new Date()); payMoneyLogService.insertPayMoneyLog(payMoneyLog); //sendWechatMessage(users,outTradeNo); logger.info("商品支付回调处理成功,订单号:{}", outTradeNo); return buildSuccessResponse(); } catch (Exception e) { logger.error("商品支付回调处理异常:", e); return buildFailResponse("商品支付回调处理异常"); } } /** * 拼团支付的回调接口 * * @param request HTTP请求对象 * @return XML格式响应给微信服务器 *IUserGroupBuyingService userGroupBuyingService; * 处理商品订单的支付成功回调: * 1. 验证支付签名 * 2. 更新商品订单支付状态 * 3. 更新订单支付时间和交易号 * 4. 处理库存扣减等业务逻辑 */ @PostMapping(value = "/api/order/amount/paydata/notify") public String apiorderamountpaydatanotify(HttpServletRequest request) { try { logger.info("收到商品支付回调通知,开始处理..."); // 1. 使用WechatPayUtil处理支付回调 Map notifyResult = wechatPayUtil.handlePayNotify(request); // 2. 检查处理结果 boolean success = (Boolean) notifyResult.get("success"); String message = (String) notifyResult.get("message"); if (!success) { logger.error("商品支付回调处理失败:{}", message); return buildFailResponse("商品支付回调处理失败"); } // 3. 获取支付信息 Map paymentInfo = (Map) notifyResult.get("paymentInfo"); String outTradeNo = (String) paymentInfo.get("outTradeNo"); String transactionId = (String) paymentInfo.get("transactionId"); String totalFee = (String) paymentInfo.get("totalFee"); UsersPayBefor usersPayBefor = usersPayBeforService.selectUsersPayBeforByOrderId(outTradeNo); if (usersPayBefor!=null){ usersPayBefor.setStatus(2L); usersPayBefor.setPaytime(new Date()); usersPayBefor.setPaycode(transactionId); usersPayBeforService.updateUsersPayBefor(usersPayBefor); } Users users = null; if (usersPayBefor != null) { users = usersService.selectUsersById(usersPayBefor.getUid()); } //订单回调处理,拼团创建订单,其他订单修改状态 OrderUtil.prepayCallback(usersPayBefor, users); // //最后无论如何平台流水需要添加,让平台看到流水和账目 PayMoneyLog payMoneyLog = new PayMoneyLog(); if (usersPayBefor != null) { payMoneyLog.setOid(usersPayBefor.getId()); } payMoneyLog.setOrderId(usersPayBefor.getOrderid()); payMoneyLog.setUid(usersPayBefor.getUid()); if (users != null) { payMoneyLog.setUname(users.getName()); } payMoneyLog.setPrice(usersPayBefor.getWxmoney()); payMoneyLog.setMark("订单支付"); payMoneyLog.setPayTime(new Date()); payMoneyLogService.insertPayMoneyLog(payMoneyLog); //sendWechatMessage(users,outTradeNo); logger.info("商品支付回调处理成功,订单号:{}", outTradeNo); return buildSuccessResponse(); } catch (Exception e) { logger.error("商品支付回调处理异常:", e); return buildFailResponse("商品支付回调处理异常"); } } /** * 拼团支付的回调接口 * * @param request HTTP请求对象 * @return XML格式响应给微信服务器 *IUserGroupBuyingService userGroupBuyingService; * 处理商品订单的支付成功回调: * 1. 验证支付签名 * 2. 更新商品订单支付状态 * 3. 更新订单支付时间和交易号 * 4. 处理库存扣减等业务逻辑 */ @PostMapping(value = "/api/order/amount/paydata/zuhenotify") public String apiorderamountpaydatazuhenotify(HttpServletRequest request) { try { logger.info("收到商品支付回调通知,开始处理..."); // 1. 使用WechatPayUtil处理支付回调 Map notifyResult = wechatPayUtil.handlePayNotify(request); // 2. 检查处理结果 boolean success = (Boolean) notifyResult.get("success"); String message = (String) notifyResult.get("message"); if (!success) { logger.error("商品支付回调处理失败:{}", message); return buildFailResponse("商品支付回调处理失败"); } // 3. 获取支付信息 Map paymentInfo = (Map) notifyResult.get("paymentInfo"); String outTradeNo = (String) paymentInfo.get("outTradeNo"); String transactionId = (String) paymentInfo.get("transactionId"); String totalFee = (String) paymentInfo.get("totalFee"); UsersPayBefor usersPayBefor = usersPayBeforService.selectUsersPayBeforByOrderId(outTradeNo); // 组合支付:微信支付回调后自动扣余额 if (usersPayBefor != null && usersPayBefor.getYemoney() != null && usersPayBefor.getYemoney().compareTo(BigDecimal.ZERO) > 0) { Users user = usersService.selectUsersById(usersPayBefor.getUid()); Map balanceResult = BalancePayUtil.processBalancePayment( user.getId(), usersPayBefor.getYemoney(), "订单组合支付-余额部分" + usersPayBefor.getYemoney() + "元", usersPayBefor.getOrderid() ); if (balanceResult == null || !Boolean.TRUE.equals(balanceResult.get("success"))) { OrderUtil.prepayCallback(usersPayBefor, user); String errorMsg = balanceResult != null ? (String) balanceResult.get("message") : "余额支付失败"; logger.error("组合支付余额部分扣款失败:{}", errorMsg); return buildFailResponse("组合支付余额部分扣款失败: " + errorMsg); } } if (usersPayBefor!=null){ usersPayBefor.setStatus(2L); usersPayBefor.setPaytime(new Date()); usersPayBefor.setPaycode(transactionId); usersPayBeforService.updateUsersPayBefor(usersPayBefor); } Users users = null; if (usersPayBefor != null) { users = usersService.selectUsersById(usersPayBefor.getUid()); } //订单回调处理,拼团创建订单,其他订单修改状态 OrderUtil.prepayCallback(usersPayBefor, users); // //最后无论如何平台流水需要添加,让平台看到流水和账目 PayMoneyLog payMoneyLog = new PayMoneyLog(); if (usersPayBefor != null) { payMoneyLog.setOid(usersPayBefor.getId()); } payMoneyLog.setOrderId(usersPayBefor.getOrderid()); payMoneyLog.setUid(usersPayBefor.getUid()); if (users != null) { payMoneyLog.setUname(users.getName()); } payMoneyLog.setPrice(usersPayBefor.getWxmoney()); payMoneyLog.setMark("订单支付"); payMoneyLog.setPayTime(new Date()); payMoneyLogService.insertPayMoneyLog(payMoneyLog); //sendWechatMessage(users,outTradeNo); logger.info("商品支付回调处理成功,订单号:{}", outTradeNo); return buildSuccessResponse(); } catch (Exception e) { logger.error("商品支付回调处理异常:", e); return buildFailResponse("商品支付回调处理异常"); } } /** * 用户支付接口 * * @param request HTTP请求对象 * @return XML格式响应给微信服务器 *IUserMemberRechargeLogService userMemberRechargeLogService; * 处理商品订单的支付成功回调: * 1. 验证支付签名 * 2. 更新商品订单支付状态 * 3. 更新订单支付时间和交易号 * 4. 处理库存扣减等业务逻辑 */ @PostMapping(value = "/api/recharge/pay/notify") public String apirechargePayNotify(HttpServletRequest request) { try { logger.info("支付回调通知,开始处理..."); // 1. 使用WechatPayUtil处理支付回调 Map notifyResult = wechatPayUtil.handlePayNotify(request); // 2. 检查处理结果 boolean success = (Boolean) notifyResult.get("success"); String message = (String) notifyResult.get("message"); if (!success) { logger.error("支付回调处理失败:{}", message); return buildFailResponse("商品支付回调处理失败"); } // 3. 获取支付信息 Map paymentInfo = (Map) notifyResult.get("paymentInfo"); String outTradeNo = (String) paymentInfo.get("outTradeNo"); String transactionId = (String) paymentInfo.get("transactionId"); String totalFee = (String) paymentInfo.get("totalFee"); UserMemberRechargeLog userMemberRechargeLog = userMemberRechargeLogService.selectUserMemberRechargeLogById(Integer.parseInt(outTradeNo)); if (userMemberRechargeLog!=null){ Users users =usersService.selectUsersById(Long.valueOf(userMemberRechargeLog.getUid())); if (users!=null){ userMemberRechargeLog.setPaytype(1); userMemberRechargeLog.setTransactionId(transactionId); userMemberRechargeLogService.updateUserMemberRechargeLog(userMemberRechargeLog); //成功之后就要给大哥加流水,确保大哥的账户流水里面有这条充值的记录,如果购买了会员下一步扣除就可以 UserMemnerConsumptionLog newuserMemnerConsumptionLog = new UserMemnerConsumptionLog(); newuserMemnerConsumptionLog.setUid(Math.toIntExact(users.getId())); newuserMemnerConsumptionLog.setConsumptiontype(3); newuserMemnerConsumptionLog.setConsumptiontime(new Date()); newuserMemnerConsumptionLog.setConsumptionmoney(userMemberRechargeLog.getComemoney()); newuserMemnerConsumptionLog.setReamk("用户充值"+userMemberRechargeLog.getInmoney()+"实际到账"+userMemberRechargeLog.getComemoney()); newuserMemnerConsumptionLog.setBeformoney(users.getBalance()); newuserMemnerConsumptionLog.setAftermoney(users.getBalance().add(userMemberRechargeLog.getComemoney())); newuserMemnerConsumptionLog.setNowmoney(users.getBalance().add(userMemberRechargeLog.getComemoney())); newuserMemnerConsumptionLog.setType(1); userMemnerConsumptionLogService.insertUserMemnerConsumptionLog(newuserMemnerConsumptionLog); users.setBalance(users.getBalance().add(userMemberRechargeLog.getComemoney())); usersService.updateUsers(users); WXsendMsgUtil.sendUserPayMoney(users.getOpenid(),"充值成功",totalFee,"1","充值成功"); //如果是会员包年充值就需要先充值后消费,形成一个用户余额不变动,但是用户的流水里面需要提现出用户的这次消费情况 if (userMemberRechargeLog.getIsmember()==1){ UserMemnerConsumptionLog userMemnerConsumptionLog = new UserMemnerConsumptionLog(); userMemnerConsumptionLog.setUid(Math.toIntExact(users.getId())); userMemnerConsumptionLog.setConsumptiontype(2); userMemnerConsumptionLog.setConsumptiontime(new Date()); userMemnerConsumptionLog.setConsumptionmoney(userMemberRechargeLog.getComemoney()); userMemnerConsumptionLog.setReamk("会员包年扣减"); userMemnerConsumptionLog.setBeformoney(users.getBalance()); userMemnerConsumptionLog.setAftermoney(users.getBalance().subtract(userMemberRechargeLog.getComemoney())); userMemnerConsumptionLog.setNowmoney(users.getBalance().subtract(userMemberRechargeLog.getComemoney())); userMemnerConsumptionLog.setType(2); userMemnerConsumptionLogService.insertUserMemnerConsumptionLog(userMemnerConsumptionLog); if (userMemberRechargeLog.getIsmember() == 1) { // 会员包年充值 if (users.getIsmember() == 1 && users.getMemberEnd() != null) { // 续费会员:在原有会员结束时间基础上加一年 Calendar calendar = Calendar.getInstance(); calendar.setTime(users.getMemberEnd()); calendar.add(Calendar.YEAR, 1); users.setMemberEnd(calendar.getTime()); } else if (users.getIsmember() == 0) { // 新会员:会员开始时间为当前,结束时间为一年后 users.setMemberBegin(new Date()); Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); calendar.add(Calendar.YEAR, 1); users.setMemberEnd(calendar.getTime()); } users.setIsmember(1); users.setBalance(users.getBalance().subtract(userMemberRechargeLog.getComemoney())); usersService.updateUsers(users); } } //WXsendMsgUtil.sendUserForMoneySuccess(users.getOpenid(),userMemberRechargeLog,users); } } Users users1 =usersService.selectUsersById(Long.valueOf(userMemberRechargeLog.getUid())); //最后无论如何平台流水需要添加,让平台看到流水和账目 PayMoneyLog payMoneyLog = new PayMoneyLog(); payMoneyLog.setOid(Long.valueOf(userMemberRechargeLog.getId())); payMoneyLog.setOrderId(userMemberRechargeLog.getOrderid()); payMoneyLog.setUid(Long.valueOf(userMemberRechargeLog.getUid())); payMoneyLog.setUname(users1.getName()); payMoneyLog.setPrice(userMemberRechargeLog.getInmoney()); payMoneyLog.setMark(userMemberRechargeLog.getReamk()); payMoneyLog.setPayTime(new Date()); payMoneyLogService.insertPayMoneyLog(payMoneyLog); //sendWechatMessage(users,outTradeNo); logger.info("用户支付回调处理成功,订单号:{}", outTradeNo); return buildSuccessResponse(); } catch (Exception e) { logger.error("商品支付回调处理异常:", e); return buildFailResponse("商品支付回调处理异常"); } } /** * 上门费支付回调接口 * * @param request HTTP请求对象 * @return XML格式响应给微信服务器 * * 处理上门费的支付成功回调: * 1. 验证支付签名 * 2. 更新订单日志中的上门费支付状态 * 3. 更新订单状态为已支付上门费 * 4. 通知师傅可以开始上门服务 */ @PostMapping(value = "/api/door/fee/pay/notify") public String apiDoorFeePayNotify(HttpServletRequest request) { try { logger.info("收到上门费支付回调通知,开始处理..."); // 1. 使用WechatPayUtil处理支付回调 Map notifyResult = wechatPayUtil.handlePayNotify(request); // 2. 检查处理结果 boolean success = (Boolean) notifyResult.get("success"); String message = (String) notifyResult.get("message"); if (!success) { logger.error("上门费支付回调处理失败:{}", message); return buildFailResponse("上门费支付回调处理失败"); } // 3. 获取支付信息 Map paymentInfo = (Map) notifyResult.get("paymentInfo"); String outTradeNo = (String) paymentInfo.get("outTradeNo"); String transactionId = (String) paymentInfo.get("transactionId"); String totalFee = (String) paymentInfo.get("totalFee"); // 4. 查询对应的订单日志(上门费记录) OrderLog orderLog = orderLogService.selectOrderLogById(Long.parseLong(outTradeNo)); if (orderLog == null) { logger.error("上门费订单记录不存在,订单号:{}", outTradeNo); return buildFailResponse("上门费订单记录不存在"); } // 5. 检查支付状态,避免重复处理 if (orderLog.getPaid() != null && orderLog.getPaid() == 2L) { logger.info("上门费已支付,订单号:{}", outTradeNo); return buildSuccessResponse(); } // 6. 更新上门费支付状态 orderLog.setPaid(2L); // 1:已支付 orderLog.setWorkerCost(new BigDecimal(totalFee)); orderLog.setPayTime(System.currentTimeMillis()/1000); //orderLog.setUpdateTime(new Date()); int updateResult = orderLogService.updateOrderLog(orderLog); logger.error("更新上门费支付状态失败,订单号:{}", outTradeNo); if (updateResult <= 0) { logger.error("更新上门费支付状态失败,订单号:{}", outTradeNo); return buildFailResponse("更新上门费支付状态失败"); } // // 7. 更新主订单状态 Order mainOrder = orderService.selectOrderByOrderId(orderLog.getOrderId()); Users users = usersService.selectUsersById(mainOrder.getUid()); // if (mainOrder != null) { // // 更新订单状态,表示上门费已支付 // JSONObject logJson = new JSONObject(); // logJson.put("type", 3); // logJson.put("doorFeePaid", true); // mainOrder.setLogJson(logJson.toJSONString()); // mainOrder.setJsonStatus(4); // 4:已支付上门费,可以出发上门 // orderService.updateOrder(mainOrder); // } // 8. 处理上门费支付成功后的业务逻辑 handleDoorFeePaymentSuccess(orderLog, paymentInfo); // 2. 处理积分奖励 handleIntegralReward(users, paymentInfo, "付款赠送积分"); //微信推送给师傅用户已支付上门费String openid, Order order, ServiceGoods serviceGoods Users worker=usersService.selectUsersById(mainOrder.getWorkerId()); if (worker != null){ ServiceGoods serviceGoods = serviceGoodsService.selectServiceGoodsById(mainOrder.getProductId()); if (serviceGoods != null){ WXsendMsgUtil.sendUserPayDoorMoneyForWorker(worker.getOpenid(),mainOrder,serviceGoods); } } logger.info("上门费支付回调处理成功,订单号:{}", outTradeNo); return buildSuccessResponse(); } catch (Exception e) { logger.error("上门费支付回调处理异常:", e); return buildFailResponse("上门费支付回调处理异常"); } } /** * 定金支付回调接口 * * @param request HTTP请求对象 * @return XML格式响应给微信服务器 * * 处理定金的支付成功回调: * 1. 验证支付签名 * 2. 更新订单日志中的定金支付状态 * 3. 更新订单状态为已支付定金 * 4. 记录定金支付时间和交易号 */ @PostMapping(value = "/api/deposit/pay/notify") public String apiDepositPayNotify(HttpServletRequest request) { try { logger.info("收到定金支付回调通知,开始处理..."); // 1. 使用WechatPayUtil处理支付回调 Map notifyResult = wechatPayUtil.handlePayNotify(request); // 2. 检查处理结果 boolean success = (Boolean) notifyResult.get("success"); String message = (String) notifyResult.get("message"); if (!success) { logger.error("定金支付回调处理失败:{}", message); return buildFailResponse("定金支付回调处理失败"); } // 3. 获取支付信息 Map paymentInfo = (Map) notifyResult.get("paymentInfo"); String outTradeNo = (String) paymentInfo.get("outTradeNo"); String transactionId = (String) paymentInfo.get("transactionId"); String totalFee = (String) paymentInfo.get("totalFee"); // 4. 查询对应的订单日志(定金记录) OrderLog orderLog = orderLogService.selectOrderLogById(Long.parseLong(outTradeNo)); if (orderLog == null) { logger.error("定金订单记录不存在,订单号:{}", outTradeNo); return buildFailResponse("定金订单记录不存在"); } // 5. 检查定金支付状态,避免重复处理 if (orderLog.getDepPaid() != null && orderLog.getDepPaid() == 2) { logger.info("定金已支付,订单号:{}", outTradeNo); return buildSuccessResponse(); } // 6. 更新定金支付状态 orderLog.setDepPaid(2); // 1:已支付 orderLog.setDepPayTime(System.currentTimeMillis()/1000); // orderLog.setUpdateTime(new Date()); int updateResult = orderLogService.updateOrderLog(orderLog); if (updateResult <= 0) { logger.error("更新定金支付状态失败,订单号:{}", outTradeNo); return buildFailResponse("更新定金支付状态失败"); } // // 7. 更新主订单状态 Order mainOrder = orderService.selectOrderByOrderId(orderLog.getOrderId()); // if (mainOrder != null) { // // 更新订单状态,表示定金已支付 // JSONObject logJson = new JSONObject(); // logJson.put("type", 4); // logJson.put("depositPaid", true); // mainOrder.setLogJson(logJson.toJSONString()); // orderService.updateOrder(mainOrder); // } // 8. 处理定金支付成功后的业务逻辑 Users users = usersService.selectUsersById(mainOrder.getUid()); handleDepositPaymentSuccess(users,orderLog, paymentInfo); logger.info("定金支付回调处理成功,订单号:{}", outTradeNo); return buildSuccessResponse(); } catch (Exception e) { logger.error("定金支付回调处理异常:", e); return buildFailResponse("定金支付回调处理异常"); } } /** * 订单金额支付回调接口 * * @param request HTTP请求对象 * @return XML格式响应给微信服务器 * * 处理订单总金额的支付成功回调: * 1. 验证支付签名 * 2. 更新服务订单支付状态 * 3. 更新订单支付时间和交易号 * 4. 处理订单支付完成后的业务逻辑 */ @PostMapping(value = "/api/order/amount/pay/notify") public String apiOrderAmountPayNotify(HttpServletRequest request) { try { logger.info("收到订单金额支付回调通知,开始处理..."); // 1. 使用WechatPayUtil处理支付回调 Map notifyResult = wechatPayUtil.handlePayNotify(request); // 2. 检查处理结果 boolean success = (Boolean) notifyResult.get("success"); String message = (String) notifyResult.get("message"); if (!success) { logger.error("订单金额支付回调处理失败:{}", message); return buildFailResponse("订单金额支付回调处理失败"); } // 3. 获取支付信息 Map paymentInfo = (Map) notifyResult.get("paymentInfo"); String outTradeNo = (String) paymentInfo.get("outTradeNo"); String transactionId = (String) paymentInfo.get("transactionId"); String totalFee = (String) paymentInfo.get("totalFee"); // 4. 查询对应的服务订单 Order order = orderService.selectOrderByOrderId(outTradeNo); if (order == null) { logger.error("服务订单不存在,订单号:{}", outTradeNo); return buildFailResponse("服务订单不存在"); } // 5. 检查订单支付状态,避免重复处理 if (order.getStatus() != null && order.getStatus() == 2L) { logger.info("订单已支付,订单号:{}", outTradeNo); return buildSuccessResponse(); } //更新最新的一条日志信息 OrderLog orderLog = orderLogService.selectDataTheFirstNew(order.getId()); orderLog.setPayTime(System.currentTimeMillis()/1000); orderLog.setPaid(2L); orderLogService.updateOrderLog(orderLog); // 6. 更新订单支付状态 order.setStatus(4L); // 2:已支付 order.setTransactionId(transactionId); order.setPayTime(new Date()); //order.setUpdateTime(new Date()); // 计算实际支付金额(分转换为元) BigDecimal paidAmount = new BigDecimal(totalFee).divide(new BigDecimal(100)); order.setPayPrice(paidAmount); int updateResult = orderService.updateOrder(order); if (updateResult <= 0) { logger.error("更新订单支付状态失败,订单号:{}", outTradeNo); return buildFailResponse("更新订单支付状态失败"); } // 7. 处理订单支付成功后的业务逻辑 handleOrderAmountPaymentSuccess(order, paymentInfo); calculateCommissionAndRecord(order.getOrderId(),order.getWorkerId()); //calculateCommissionMoney(order.getOrderId(), order.getUid(),order.getWorkerId()); logger.info("订单金额支付回调处理成功,订单号:{}", outTradeNo); return buildSuccessResponse(); } catch (Exception e) { logger.error("订单金额支付回调处理异常:", e); return buildFailResponse("订单金额支付回调处理异常"); } } /** * 处理商品支付成功后的业务逻辑 */ private void handleGoodsPaymentSuccess(Users users,String outTradeNo, Map paymentInfo) { try { // 1. 记录支付成功日志 logger.info("商品订单支付成功,订单号:{},支付金额:{}", outTradeNo, paymentInfo.get("totalFee")); // 2. 处理积分奖励 handleIntegralReward(users, paymentInfo, "下单赠送积分"); // 3. 记录支付记录 recordPaymentLog(outTradeNo, paymentInfo,"支付订单金额"); } catch (Exception e) { logger.error("处理商品支付成功业务逻辑异常:", e); } } /** * 处理上门费支付成功后的业务逻辑 */ private void handleDoorFeePaymentSuccess(OrderLog orderLog, Map paymentInfo) { try { // 1. 记录支付成功日志 logger.info("上门费支付成功,订单号:{},支付金额:{}", orderLog.getLogOrderId(), paymentInfo.get("totalFee")); // 2. 获取主订单信息以获取用户信息 Order mainOrder = orderService.selectOrderByOrderId(orderLog.getOrderId()); if (mainOrder != null) { // 3. 上门费支付不赠送积分(按照PHP逻辑) logger.info("上门费支付不赠送积分"); recordPaymentLogones(orderLog.getOid(), orderLog.getLogOrderId(),mainOrder.getUid(),mainOrder.getUname(), paymentInfo, "支付上门费"); //// // 4. 记录支付记录 // recordPaymentLog(orderLog.getOid(), orderLog.getLogOrderId(), // mainOrder.getUid(), mainOrder.getUname(), paymentInfo, "支付" + mainOrder.getProductName() + "上门费"); } } catch (Exception e) { logger.error("处理上门费支付成功业务逻辑异常:", e); } } /** * 处理定金支付成功后的业务逻辑 */ private void handleDepositPaymentSuccess(Users users,OrderLog orderLog, Map paymentInfo) { try { // 1. 记录支付成功日志 logger.info("定金支付成功,订单号:{},支付金额:{}", orderLog.getDepLogId(), paymentInfo.get("totalFee")); // 2. 获取主订单信息以获取用户信息 Order mainOrder = orderService.selectOrderByOrderId(orderLog.getOrderId()); if (mainOrder != null) { // 2. 处理积分奖励 handleIntegralReward(users, paymentInfo, "支付赠送积分"); // long oid,String orderid,long uid,String uname,Map paymentInfo, String description // 3. 记录支付记录 recordPaymentLogones(orderLog.getOid(), orderLog.getOrderId(),users.getId(),users.getName(), paymentInfo,"支付定金金额"); // // 3. 处理积分奖励 // handleIntegralReward(orderLog.getDepLogId(), mainOrder.getUid(), // mainOrder.getUname(), paymentInfo, "支付定金赠送积分"); // 4. 记录支付记录 // recordPaymentLog(orderLog.getOid(), orderLog.getDepLogId(), // mainOrder.getUid(), mainOrder.getUname(), paymentInfo, "支付" + mainOrder.getProductName() + "服务定金"); } } catch (Exception e) { logger.error("处理定金支付成功业务逻辑异常:", e); } } /** * 处理订单金额支付成功后的业务逻辑 */ private void handleOrderAmountPaymentSuccess(Order order, Map paymentInfo) { try { // 1. 记录支付成功日志 logger.info("订单金额支付成功,订单号:{},支付金额:{}", order.getOrderId(), paymentInfo.get("totalFee")); // 2. 更新订单状态为已完成 order.setStatus(4L); // 4:已结束 orderService.updateOrder(order); // 3. 处理积分奖励(复杂逻辑:考虑定金支付情况) handleOrderAmountIntegralReward(order, paymentInfo); // 4. 记录支付记录 // recordPaymentLog(order.getId(), order.getOrderId(), // order.getUid(), order.getUname(), paymentInfo, "支付" + order.getProductName() + "服务尾款"); recordPaymentLogones(order.getId(),order.getOrderId(),order.getUid(),order.getUname(), paymentInfo, "订单尾款支付"); } catch (Exception e) { logger.error("处理订单金额支付成功业务逻辑异常:", e); } } /** * 构建成功响应XML */ private String buildSuccessResponse() { return ""; } /** * 构建失败响应XML */ private String buildFailResponse(String message) { return ""; } /** * 根据订单号查找商品订单 */ private GoodsOrder findGoodsOrderByOrderId(String orderId) { GoodsOrder queryOrder = new GoodsOrder(); queryOrder.setOrderId(orderId); List orderList = goodsOrderService.selectGoodsOrderList(queryOrder); return orderList.isEmpty() ? null : orderList.get(0); } /** * 根据日志订单号查找订单日志 */ private OrderLog findOrderLogByLogId(String logId) { OrderLog queryLog = new OrderLog(); queryLog.setLogId(logId); List logList = orderLogService.selectOrderLogList(queryLog); return logList.isEmpty() ? null : logList.get(0); } /** * 根据定金订单号查找订单日志 */ private OrderLog findOrderLogByDepLogId(String depLogId) { OrderLog queryLog = new OrderLog(); queryLog.setDepLogId(depLogId); List logList = orderLogService.selectOrderLogList(queryLog); return logList.isEmpty() ? null : logList.get(0); } /** * 处理积分奖励 * * @param paymentInfo 支付信息 * @param description 描述 */ private void handleIntegralReward(Users users,Map paymentInfo, String description) { try { // 1. 查询系统配置 config_one SiteConfig siteConfigQuery = new SiteConfig(); siteConfigQuery.setName("config_one"); List configList = siteConfigService.selectSiteConfigList(siteConfigQuery); if (configList.isEmpty()) { logger.warn("未找到config_one配置,跳过积分奖励"); return; } SiteConfig config = configList.get(0); String configValue = config.getValue(); if (StringUtils.isEmpty(configValue)) { logger.warn("config_one配置值为空,跳过积分奖励"); return; } // 2. 解析JSON获取integral值(积分配置) Integer integral = null; try { JSONObject configJson = JSONObject.parseObject(configValue); integral = configJson.getInteger("integral"); } catch (Exception e) { logger.error("解析config_one配置失败:", e); return; } if (integral == null || integral <= 0) { logger.warn("integral配置无效,跳过积分奖励"); return; } // 3. 计算积分 String totalFeeStr = (String) paymentInfo.get("totalFee"); if (StringUtils.isEmpty(totalFeeStr)) { logger.warn("支付金额为空,跳过积分奖励"); return; } // 支付金额单位为分,转换为元 BigDecimal payAmount = new BigDecimal(totalFeeStr).divide(new BigDecimal(100)); // 计算积分:实际支付金额除以integral,向下取整 long integralReward = payAmount.divide(new BigDecimal(integral), 0, BigDecimal.ROUND_DOWN).longValue(); // 4. 如果积分大于1,则添加积分记录 if (integralReward >= 1) { IntegralLog integralLog = new IntegralLog(); integralLog.setOrderId(GenerateCustomCode.generCreateOrder("ESTB")); integralLog.setTitle("支付获得积分"); integralLog.setMark(description + "获得积分奖励"); integralLog.setUid(users.getId()); integralLog.setUname(users.getName()); integralLog.setType(1L); // 1:增加 integralLog.setNum(integralReward); integralLog.setCreatedAt(new Date()); integralLog.setUpdatedAt(new Date()); int result = integralLogService.insertIntegralLog(integralLog); if (result > 0) { logger.info("用户{}通过{}获得{}积分", users.getName(), description, integralReward); } else { logger.error("添加积分记录失败,订单号:{}", integralLog.getOrderId()); } } else { logger.info("订单{}积分奖励小于1,不予奖励",""); } } catch (Exception e) { logger.error("处理积分奖励异常,订单号:{},异常信息:", "", e); } } /** * 记录支付记录单条 * * @param paymentInfo 支付信息 * @param description 描述 */ private void recordPaymentLogones(long oid,String orderid,long uid,String uname,Map paymentInfo, String description) { try { String totalFeeStr = (String) paymentInfo.get("totalFee"); if (StringUtils.isEmpty(totalFeeStr)) { logger.warn("支付金额为空,跳过支付记录"); return; } PayMoneyLog payMoneyLog = new PayMoneyLog(); payMoneyLog.setOid(oid); payMoneyLog.setOrderId(orderid); payMoneyLog.setUid(uid); payMoneyLog.setUname(uname); payMoneyLog.setPrice(new BigDecimal(totalFeeStr)); payMoneyLog.setMark(description); payMoneyLog.setPayTime(new Date()); payMoneyLogService.insertPayMoneyLog(payMoneyLog); logger.info("用户{}的{}支付记录已保存,金额:{}元", uname, description, totalFeeStr); // 支付金额单位为分,转换为元 // BigDecimal payAmount = new BigDecimal(totalFeeStr).divide(new BigDecimal(100)); } catch (Exception e) { logger.error("记录支付记录异常,订单号:{},异常信息:", oid, e); } } /** * 记录支付记录多条 * * @param paymentInfo 支付信息 * @param description 描述 */ private void recordPaymentLog(String outTradeNo,Map paymentInfo, String description) { try { String totalFeeStr = (String) paymentInfo.get("totalFee"); if (StringUtils.isEmpty(totalFeeStr)) { logger.warn("支付金额为空,跳过支付记录"); return; } // 4. 查询对应的商品订单 GoodsOrder goodsOrder = new GoodsOrder(); goodsOrder.setMainOrderId(outTradeNo); List goodsOrderslist = goodsOrderService.selectGoodsOrderList(goodsOrder); if (!goodsOrderslist.isEmpty()) { for (GoodsOrder goodsOrderdata : goodsOrderslist){ PayMoneyLog payMoneyLog = new PayMoneyLog(); payMoneyLog.setOid(goodsOrderdata.getId()); payMoneyLog.setOrderId(goodsOrderdata.getOrderId()); payMoneyLog.setUid(goodsOrderdata.getUid()); payMoneyLog.setUname(goodsOrderdata.getUname()); payMoneyLog.setPrice(goodsOrderdata.getTotalPrice()); payMoneyLog.setMark(description); payMoneyLog.setPayTime(new Date()); payMoneyLogService.insertPayMoneyLog(payMoneyLog); logger.info("用户{}的{}支付记录已保存,金额:{}元", goodsOrderdata.getUname(), description, goodsOrderdata.getTotalPrice()); } } // 支付金额单位为分,转换为元 // BigDecimal payAmount = new BigDecimal(totalFeeStr).divide(new BigDecimal(100)); } catch (Exception e) { logger.error("记录支付记录异常,订单号:{},异常信息:", outTradeNo, e); } } /** * 处理订单总金额的积分奖励(考虑定金情况) * * @param order 订单信息 * @param paymentInfo 支付信息 */ private void handleOrderAmountIntegralReward(Order order, Map paymentInfo) { try { // 1. 查询系统配置 config_one SiteConfig siteConfigQuery = new SiteConfig(); siteConfigQuery.setName("config_one"); List configList = siteConfigService.selectSiteConfigList(siteConfigQuery); if (configList.isEmpty()) { logger.warn("未找到config_one配置,跳过积分奖励"); return; } SiteConfig config = configList.get(0); String configValue = config.getValue(); if (StringUtils.isEmpty(configValue)) { logger.warn("config_one配置值为空,跳过积分奖励"); return; } // 2. 解析JSON获取integral值 Integer integral = null; try { JSONObject configJson = JSONObject.parseObject(configValue); integral = configJson.getInteger("integral"); } catch (Exception e) { logger.error("解析config_one配置失败:", e); return; } if (integral == null || integral <= 0) { logger.warn("integral配置无效,跳过积分奖励"); return; } // 3. 查询是否有定金记录 OrderLog orderLogQuery = new OrderLog(); orderLogQuery.setOrderId(order.getOrderId()); List orderLogList = orderLogService.selectOrderLogList(orderLogQuery); BigDecimal totalPrice = BigDecimal.ZERO; OrderLog depositLog = null; // 查找定金记录 for (OrderLog log : orderLogList) { if (log.getDeposit() != null && log.getDeposit().compareTo(BigDecimal.ZERO) > 0) { depositLog = log; break; } } // 4. 根据定金情况计算积分基数 if (depositLog != null && depositLog.getDepPaid() != null) { if (depositLog.getDepPaid() == 1) { // 定金未支付/没有定金,直接支付总金额 totalPrice = depositLog.getPrice(); } else if (depositLog.getDepPaid() == 2) { // 定金已支付,计算尾款 totalPrice = depositLog.getPrice().subtract(depositLog.getDeposit()); } } else { // 没有定金,使用订单总金额 totalPrice = order.getPayPrice(); } // 5. 计算积分 long integralReward = totalPrice.divide(new BigDecimal(integral), 0, BigDecimal.ROUND_DOWN).longValue(); // 6. 如果积分大于0,则添加积分记录 if (integralReward > 0) { IntegralLog integralLog = new IntegralLog(); integralLog.setOrderId(order.getOrderId()); integralLog.setTitle("支付服务费用赠送积分"); integralLog.setMark(order.getProductName() + "服务费用"); integralLog.setUid(order.getUid()); integralLog.setUname(order.getUname()); integralLog.setType(1L); // 1:增加 integralLog.setNum(integralReward); integralLog.setCreatedAt(new Date()); integralLog.setUpdatedAt(new Date()); int result = integralLogService.insertIntegralLog(integralLog); if (result > 0) { logger.info("用户{}通过服务费用支付获得{}积分", order.getUname(), integralReward); } else { logger.error("添加积分记录失败,订单号:{}", order.getOrderId()); } } else { logger.info("订单{}服务费用积分奖励为0,不予奖励", order.getOrderId()); } } catch (Exception e) { logger.error("处理订单总金额积分奖励异常,订单号:{},异常信息:", order.getOrderId(), e); } } public Map calculateCommissionAndRecord( String orderId, Long workerId ) { Map result = new HashMap<>(); BigDecimal totalCommission = BigDecimal.ZERO; // 师傅最终佣金 BigDecimal margin = BigDecimal.ZERO; // 质保金 BigDecimal reduction = BigDecimal.ZERO; // 优惠金额 BigDecimal servicePrice = BigDecimal.ZERO; // 服务费用 BigDecimal materialPrice = BigDecimal.ZERO; // 材料费用(如有可补充) BigDecimal doorPrice = BigDecimal.ZERO; // 上门费 BigDecimal cr = BigDecimal.ZERO; // 师傅等级分佣比例 logger.info("【分佣计算】开始计算,orderId={}, workerId={}", orderId, workerId); // 1. 查询订单日志(type=2,5,paid=2,give_up=null) OrderLog orderLogQuery = new OrderLog(); orderLogQuery.setOrderId(orderId); List orderLogList = orderLogService.selectOrderLogList(orderLogQuery); logger.info("【分佣计算】查询订单日志完成,日志数量={}", orderLogList.size()); // 2. 查询订单和商品 Order order = orderService.selectOrderByOrderId(orderId); logger.info("【分佣计算】查询订单完成,order={}", order != null ? order.getId() : null); ServiceGoods product = null; if (order != null && order.getProductId() != null) { product = serviceGoodsService.selectServiceGoodsById(order.getProductId()); logger.info("【分佣计算】查询商品完成,productId={}", product != null ? product.getId() : null); } // 3. 查询师傅信息 Users worker = usersService.selectUsersById(workerId); logger.info("【分佣计算】查询师傅信息完成,worker={}", worker != null ? worker.getId() : null); // 4. 计算各项费用 for (OrderLog log : orderLogList) { logger.info("【分佣计算】处理日志,logId={}, type={}, workerCost={}, reductionPrice={}", log.getId(), log.getType(), log.getWorkerCost(), log.getReductionPrice()); if (log.getType() != null && log.getType().intValue() == 5) { // type=5 评估报价 WorkerLevel levelInfo = workerLevelService.selectWorkerLevelByLevel(Long.valueOf(worker.getLevel())); logger.info("【分佣计算】查询师傅等级,level={}, cr={}", worker.getLevel(), levelInfo != null ? levelInfo.getCr() : null); if (levelInfo != null && levelInfo.getCr() != null) { cr = new BigDecimal(levelInfo.getCr()).divide(new BigDecimal(100)); } // 师傅分佣 BigDecimal commission = log.getWorkerCost().multiply(cr).setScale(2, BigDecimal.ROUND_HALF_UP); totalCommission = totalCommission.add(commission); logger.info("【分佣计算】type=5,分佣金额={}, 当前总佣金={}", commission, totalCommission); // 服务费用 servicePrice = log.getWorkerCost().add(log.getReductionPrice() != null ? log.getReductionPrice() : BigDecimal.ZERO); logger.info("【分佣计算】type=5,服务费用={}", servicePrice); } if (log.getType() != null && log.getType().intValue() == 2) { // type=2 上门费 totalCommission = totalCommission.add(log.getWorkerCost()); doorPrice = log.getWorkerCost(); logger.info("【分佣计算】type=2,上门费={}, 当前总佣金={}", doorPrice, totalCommission); } if (log.getReductionPrice() != null) { reduction = reduction.add(log.getReductionPrice()); logger.info("【分佣计算】累计优惠金额={}", reduction); } } // 5. 判断是否需要扣除质保金 if (product != null && product.getMargin() != null && worker != null && worker.getMargin() != null && product.getMargin().compareTo(worker.getMargin()) > 0) { logger.info("【分佣计算】需要扣除质保金,商品margin={}, 师傅margin={}", product.getMargin(), worker.getMargin()); // 查系统配置 SiteConfig config = siteConfigService.selectSiteConfigByName("config_one"); BigDecimal marginPercent = BigDecimal.ZERO; if (config != null && config.getValue() != null) { try { JSONObject json = JSONObject.parseObject(config.getValue()); if (json.containsKey("margin")) { marginPercent = new BigDecimal(json.getString("margin")).divide(new BigDecimal(100)); } } catch (Exception e) { logger.error("【分佣计算】解析质保金配置异常", e); } } margin = totalCommission.multiply(marginPercent).setScale(2, BigDecimal.ROUND_HALF_UP); logger.info("【分佣计算】初步计算质保金={}, 配置比例={}", margin, marginPercent); // 超过质保金,则扣少点 if (worker.getMargin().add(margin).compareTo(product.getMargin()) > 0) { margin = product.getMargin().subtract(worker.getMargin()); logger.info("【分佣计算】质保金超限,实际扣除={}", margin); } // 插入质保金明细 WorkerMarginLog marginLog = new WorkerMarginLog(); marginLog.setOid(order.getId()); marginLog.setUid(workerId); marginLog.setOrderId(order != null ? order.getOrderId() : null); marginLog.setPrice(margin); workerMarginLogService.insertWorkerMarginLog(marginLog); logger.info("【分佣计算】插入质保金明细完成"); } // 6. 计算最终佣金 BigDecimal finalCommission = totalCommission.subtract(margin); logger.info("【分佣计算】最终佣金={}", finalCommission); // 7. 更新师傅账户(佣金、佣金总额、质保金) if (worker != null) { BigDecimal newCommission = (worker.getCommission() != null ? worker.getCommission() : BigDecimal.ZERO).add(finalCommission); BigDecimal newTotalComm = (worker.getTotalComm() != null ? worker.getTotalComm() : BigDecimal.ZERO).add(finalCommission); BigDecimal newMargin = (worker.getMargin() != null ? worker.getMargin() : BigDecimal.ZERO).add(margin); worker.setCommission(newCommission); worker.setTotalComm(newTotalComm); worker.setMargin(newMargin); usersService.updateUsers(worker); logger.info("【分佣计算】更新师傅账户完成,commission={}, total_comm={}, margin={}", newCommission, newTotalComm, newMargin); } // 8. 插入师傅金额记录 WorkerMoneyLog moneyLog = new WorkerMoneyLog(); moneyLog.setWorkerId(workerId); moneyLog.setOid(order.getId()); moneyLog.setOrderId(order != null ? order.getOrderId() : null); moneyLog.setPrice(finalCommission); moneyLog.setType(1); // 1=收入 moneyLog.setServicePrice(servicePrice); moneyLog.setReductionPrice(reduction); int bfb=cr.multiply(new BigDecimal(100)).intValue(); moneyLog.setCr(bfb); // 百分比 moneyLog.setMergin(margin); moneyLog.setDoorPrice(doorPrice); moneyLog.setStatus(1);//锁单 moneyLog.setStatusType(0);//后台锁定 moneyLog.setBeginlook(new Date()); //7天锁单 LocalDateTime ldt = LocalDateTime.now().plusDays(7); Date end = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant()); moneyLog.setEndlook(end); moneyLog.setLookday(7); moneyLog.setLookMoney(finalCommission); workerMoneyLogService.insertWorkerMoneyLog(moneyLog); logger.info("【分佣计算】插入师傅金额记录完成"); // 9. 组装返回 result.put("commission", finalCommission); // 师傅最终佣金 result.put("margin", margin); // 质保金 result.put("service_price", servicePrice); // 服务费用 result.put("material_price", materialPrice); // 材料费用(如有可补充) result.put("reduction", reduction); // 优惠金额 result.put("door_price", doorPrice); // 上门费 result.put("cr", cr); // 师傅分佣比例 // 10. 公式说明 result.put("formula", "最终佣金 = (服务项目金额 * 师傅等级分佣比例 + 上门费) - 质保金\n" + "质保金 = 总佣金 * 配置质保金比例,且不超过商品margin-师傅margin\n" + "服务费用 = 评估报价worker_cost + reduction_price\n" + "上门费 = type=2的worker_cost\n" + "优惠金额 = 所有reduction_price之和"); logger.info("【分佣计算】计算结束,返回结果={}", result); return result; } // /** // * 分佣 // * // // * @return 商品标题 // */ // public Map calculateCommissionMoney(String orderId,long oid, Long workerId // ) { // // 结果 // Map result = new HashMap<>(); // BigDecimal totalPrice = BigDecimal.ZERO; // BigDecimal margin = BigDecimal.ZERO; // BigDecimal reduction = BigDecimal.ZERO; // BigDecimal servicePrice = BigDecimal.ZERO; // BigDecimal doorPrice = BigDecimal.ZERO; // // // 1. 查询订单日志 // OrderLog orderLogQuery = new OrderLog(); // orderLogQuery.setOrderId(orderId); // List orderLogList = orderLogService.selectOrderLogList(orderLogQuery); // //List orderLogList = orderLogService.selectOrderLogListByWorker(orderId, workerId); // // // 2. 查询订单和商品 // Order order = orderService.selectOrderById(oid); // ServiceGoods product = null; // if (order != null && order.getProductId() != null) { // product = serviceGoodsService.selectServiceGoodsById(order.getProductId()); // } // // // 3. 查询师傅信息 // Users worker = usersService.selectUsersById(workerId); // // // 4. 计算佣金、上门费、优惠金额 // for (OrderLog log : orderLogList) { // BigDecimal workerCost =new BigDecimal(0); // if (log.getWorkerCost() != null) { // workerCost = log.getWorkerCost(); // } // if (log.getType() != null && log.getType().intValue() == 5) { // // type=5 评估报价 // WorkerLevel levelInfo = workerLevelService.selectWorkerLevelByLevel(Long.valueOf(worker.getLevel())); // BigDecimal cr = (levelInfo != null && levelInfo.getCr() != null) ? new BigDecimal(levelInfo.getCr()).divide(new BigDecimal(100)) : BigDecimal.ZERO; // totalPrice = totalPrice.add(workerCost.multiply(cr).setScale(2, BigDecimal.ROUND_HALF_UP)); // servicePrice = workerCost.add(log.getReductionPrice() != null ? log.getReductionPrice() : BigDecimal.ZERO); // } // if (log.getType() != null && log.getType().intValue() == 2) { // // type=2 上门费 // totalPrice = totalPrice.add(log.getWorkerCost()); // doorPrice = log.getWorkerCost(); // } // if (log.getReductionPrice() != null) { // reduction = reduction.add(log.getReductionPrice()); // } // } // // // 5. 判断是否需要扣除质保金 // if (product != null && product.getMargin() != null && worker != null && worker.getMargin() != null // && product.getMargin().compareTo(worker.getMargin()) > 0) { // // 查系统配置 // SiteConfig config = siteConfigService.selectSiteConfigByName("config_one"); // BigDecimal marginPercent = BigDecimal.ZERO; // if (config != null && config.getValue() != null) { // try { // JSONObject json = JSONObject.parseObject(config.getValue()); // if (json.containsKey("margin")) { // marginPercent = new BigDecimal(json.getString("margin")).divide(new BigDecimal(100)); // } // } catch (Exception ignore) {} // } // margin = totalPrice.multiply(marginPercent).setScale(2, BigDecimal.ROUND_HALF_UP); // // 超过质保金,则扣少点 // if (worker.getMargin().add(margin).compareTo(product.getMargin()) > 0) { // margin = product.getMargin().subtract(worker.getMargin()); // } // // 插入质保金明细 // WorkerMarginLog marginLog = new WorkerMarginLog(); // marginLog.setOid(order.getId()); // marginLog.setUid(workerId); // marginLog.setOrderId(order != null ? order.getOrderId() : null); // marginLog.setPrice(margin); //// marginLog.setCreatedAt(new Date()); //// marginLog.setUpdatedAt(new Date()); // workerMarginLogService.insertWorkerMarginLog(marginLog); // //修改师傅质保金和分佣情况 // worker.setCommission(totalPrice); // // hpinnworkerzhe.setTotalComm(); // } // // // 6. 返回 // result.put("commission", totalPrice); // result.put("margin", margin); // result.put("reduction", reduction); // result.put("service_price", servicePrice); // result.put("door_price", doorPrice); // return result; // } /** * 获取商品标题 * * @param goodsOrder 商品订单 * @return 商品标题 */ private String getGoodsTitle(GoodsOrder goodsOrder) { try { // 这里应该查询商品信息,简化处理返回商品名称或默认值 if (goodsOrder.getProductName() != null) { return goodsOrder.getProductName(); } return "商品"; } catch (Exception e) { logger.error("获取商品标题异常:", e); return "商品"; } } /** * 次卡微信支付回调接口 * @param request HTTP请求对象 * @return XML格式响应给微信服务器 * 逻辑: * 1. 验证支付签名 * 2. 查询次卡使用记录(orderId) * 3. 修改为可用状态 */ @PostMapping("/api/secondary/card/paydata/notify") public String secondaryCardPayDataNotify(HttpServletRequest request) { try { logger.info("收到次卡微信支付回调通知,开始处理..."); // 1. 使用WechatPayUtil处理支付回调 Map notifyResult = wechatPayUtil.handlePayNotify(request); // 2. 检查处理结果 boolean success = (Boolean) notifyResult.get("success"); String message = (String) notifyResult.get("message"); if (!success) { logger.error("次卡支付回调处理失败:{}", message); return buildFailResponse("次卡支付回调处理失败"); } // 3. 获取支付信息 Map paymentInfo = (Map) notifyResult.get("paymentInfo"); String outTradeNo = (String) paymentInfo.get("outTradeNo"); // 订单号 String transactionId = (String) paymentInfo.get("transactionId"); String totalFee = (String) paymentInfo.get("totalFee"); // 4. 查询次卡使用记录 UserUseSecondaryCard useCard = userUseSecondaryCardService.selectUserUseSecondaryCardByorderId(outTradeNo); if (useCard == null) { logger.error("未找到次卡使用记录,订单号:{}", outTradeNo); return buildFailResponse("未找到次卡使用记录"); } // 5. 修改为可用状态(假设status=1为可用) useCard.setStatus(1L); useCard.setUpdatedAt(new Date()); useCard.setTransactionId(transactionId); userUseSecondaryCardService.updateUserUseSecondaryCard(useCard); logger.info("次卡支付回调处理成功,订单号:{}", outTradeNo); return buildSuccessResponse(); } catch (Exception e) { logger.error("次卡支付回调处理异常:", e); return buildFailResponse("次卡支付回调处理异常"); } } }