微信资金明细

master
ljw 2026-01-08 15:55:12 +08:00
parent 9869fe9f73
commit a85135e428
9 changed files with 146 additions and 3 deletions

View File

@ -0,0 +1,19 @@
package com.njzscloud.supervisory.money.contant;
import com.njzscloud.common.core.ienum.DictStr;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
*
* @author ljw
*/
@Getter
@RequiredArgsConstructor
public enum MoneyDetailType implements DictStr {
COMPANY("company", "企业"),
WX("wx", "微信");
private final String val;
private final String txt;
}

View File

@ -0,0 +1,21 @@
package com.njzscloud.supervisory.money.contant;
import com.njzscloud.common.core.ienum.DictStr;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* payment_status
*
*/
@Getter
@RequiredArgsConstructor
public enum PayStatus implements DictStr {
PENDING("PENDING", "待支付"),
PAID("PAID", "已支付"),
REFUNDING("REFUNDING", "待退款"),
REFUNDED("REFUNDED", "已退款"),
;
private final String val;
private final String txt;
}

View File

@ -2,6 +2,8 @@ package com.njzscloud.supervisory.money.pojo.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.njzscloud.supervisory.money.contant.MoneyChangeCategory;
import com.njzscloud.supervisory.money.contant.MoneyDetailType;
import com.njzscloud.supervisory.money.contant.PayStatus;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@ -18,7 +20,7 @@ import java.time.LocalDateTime;
@Setter
@ToString
@Accessors(chain = true)
@TableName("money_change_detail")
@TableName(value = "money_change_detail", autoResultMap = true)
public class MoneyChangeDetailEntity {
/**
@ -32,6 +34,16 @@ public class MoneyChangeDetailEntity {
*/
private Long userId;
/**
*
*/
private MoneyDetailType type;
/**
*
*/
private PayStatus status;
/**
* id
*/

View File

@ -8,6 +8,7 @@ import com.njzscloud.common.mp.support.PageParam;
import com.njzscloud.common.mp.support.PageResult;
import com.njzscloud.common.security.util.SecurityUtil;
import com.njzscloud.supervisory.biz.pojo.result.SearchCompanyResult;
import com.njzscloud.supervisory.money.contant.MoneyDetailType;
import com.njzscloud.supervisory.money.mapper.MoneyChangeDetailMapper;
import com.njzscloud.supervisory.money.pojo.entity.MoneyChangeDetailEntity;
import com.njzscloud.supervisory.money.pojo.result.MoneyChangeDetailExportResult;
@ -27,6 +28,7 @@ import java.util.Map;
/**
*
* @author ljw
*/
@Slf4j
@Service
@ -59,6 +61,16 @@ public class MoneyChangeDetailService extends ServiceImpl<MoneyChangeDetailMappe
this.removeBatchByIds(ids);
}
/**
* ID
*/
public MoneyChangeDetailEntity getByOrderIdAndType(Long orderId, MoneyDetailType type) {
return this.lambdaQuery()
.eq(MoneyChangeDetailEntity::getOrderId, orderId)
.eq(MoneyChangeDetailEntity::getType, type)
.one();
}
/**
*
*/

View File

@ -37,6 +37,8 @@ public class PaymentContextResult {
private BigDecimal settleMoney;
private Long driverUserId;
}

View File

@ -12,10 +12,12 @@ import com.njzscloud.common.core.ex.ExceptionMsg;
import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.common.core.utils.R;
import com.njzscloud.common.security.ex.UserLoginException;
import com.njzscloud.common.security.util.SecurityUtil;
import com.njzscloud.common.wechat.WechatUtil;
import com.njzscloud.common.wechat.param.Code2SessionParam;
import com.njzscloud.common.wechat.result.Code2SessionResult;
import com.njzscloud.supervisory.device.service.DeviceInfoService;
import com.njzscloud.supervisory.money.contant.PayStatus;
import com.njzscloud.supervisory.order.contant.MoneyWay;
import com.njzscloud.supervisory.order.contant.OrderStatus;
import com.njzscloud.supervisory.order.contant.PaymentStatus;
@ -28,6 +30,10 @@ import com.njzscloud.supervisory.order.pojo.result.PaymentContextResult;
import com.njzscloud.supervisory.order.service.OrderExpenseItemsService;
import com.njzscloud.supervisory.order.service.OrderGoodsService;
import com.njzscloud.supervisory.order.service.OrderInfoService;
import com.njzscloud.supervisory.money.service.MoneyChangeDetailService;
import com.njzscloud.supervisory.money.contant.MoneyChangeCategory;
import com.njzscloud.supervisory.money.contant.MoneyDetailType;
import com.njzscloud.supervisory.money.pojo.entity.MoneyChangeDetailEntity;
import com.njzscloud.supervisory.wxPay.config.WxPayProperties;
import com.njzscloud.supervisory.wxPay.dto.RefundRequestDto;
import com.njzscloud.supervisory.wxPay.param.PaymentParam;
@ -63,6 +69,7 @@ public class PaymentController {
private final WxPayProperties properties;
private final OrderGoodsService orderGoodsService;
private final PaymentService paymentService;
private final MoneyChangeDetailService moneyChangeDetailService;
/**
* 使SDK
@ -115,6 +122,13 @@ public class PaymentController {
throw Exceptions.clierr("结算总金额与实际总金额不一致");
}
// 检查是否已存在资金明细记录
MoneyChangeDetailEntity existingDetail = moneyChangeDetailService.getByOrderIdAndType(
paymentParam.getOrderId(), MoneyDetailType.WX);
if (existingDetail != null && PayStatus.PAID.equals(existingDetail.getStatus())) {
throw Exceptions.clierr("该订单已支付,无需重复支付");
}
try {
// 构建微信支付请求
String outTradeNo = generateOutTradeNo(ctx.getSn());
@ -140,6 +154,28 @@ public class PaymentController {
.set(OrderInfoEntity::getOutTradeNo, outTradeNo)
.update();
// 创建或更新资金明细
if (existingDetail == null) {
// 新建资金明细
MoneyChangeDetailEntity newDetail = new MoneyChangeDetailEntity();
newDetail.setType(MoneyDetailType.WX);
newDetail.setStatus(PayStatus.PENDING);
newDetail.setOrderId(paymentParam.getOrderId());
newDetail.setUserId(SecurityUtil.currentUserId());
// 扣款为负数
newDetail.setDelta(ctx.getSettleMoney().negate());
newDetail.setMoneyChangeCategory(MoneyChangeCategory.DingDanKouKuan);
newDetail.setMemo("微信支付订单:" + outTradeNo);
moneyChangeDetailService.save(newDetail);
} else {
// 更新现有资金明细状态为待支付
existingDetail.setStatus(PayStatus.PENDING);
existingDetail.setUserId(SecurityUtil.currentUserId());
existingDetail.setDelta(ctx.getSettleMoney().negate());
existingDetail.setMemo("微信支付订单:" + outTradeNo);
moneyChangeDetailService.updateById(existingDetail);
}
log.info("微信支付订单创建成功生产级SDK订单ID{},微信订单号:{}", paymentParam.getOrderId(), outTradeNo);
return R.success(result);
@ -223,6 +259,15 @@ public class PaymentController {
.setOrderStatus(out ? OrderStatus.YiWanCheng : null)
.setPayTime(LocalDateTime.now())
);
// 更新资金明细状态为已支付
MoneyChangeDetailEntity payDetail = moneyChangeDetailService.getByOrderIdAndType(entity.getId(), MoneyDetailType.WX);
if (payDetail != null) {
payDetail.setStatus(PayStatus.PAID);
moneyChangeDetailService.updateById(payDetail);
log.info("支付回调资金明细状态更新为已支付订单ID{}", entity.getId());
}
if (out) {
DeviceInfoService.open(orderSn);
}
@ -313,6 +358,15 @@ public class PaymentController {
.set(OrderInfoEntity::getRefundMoney, entity.getSettleMoney())
.set(OrderInfoEntity::getRefundTime, LocalDateTime.now())
.update();
// 更新资金明细状态为已退款
MoneyChangeDetailEntity refundDetail = moneyChangeDetailService.getByOrderIdAndType(entity.getId(), MoneyDetailType.WX);
if (refundDetail != null) {
refundDetail.setStatus(PayStatus.REFUNDED);
moneyChangeDetailService.updateById(refundDetail);
log.info("退款回调资金明细状态更新为已退款订单ID{}", entity.getId());
}
log.info("退款回调处理成功,订单号:{}", orderSn);
String responseXml = WxPayNotifyResponse.success("OK");
log.info("准备返回给微信的退款回调XML响应: {}", responseXml);

View File

@ -3,6 +3,8 @@ package com.njzscloud.supervisory.wxPay.service.impl;
import cn.hutool.core.util.IdUtil;
import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.supervisory.money.contant.MoneyChangeCategory;
import com.njzscloud.supervisory.money.contant.MoneyDetailType;
import com.njzscloud.supervisory.money.contant.PayStatus;
import com.njzscloud.supervisory.money.pojo.entity.MoneyAccountEntity;
import com.njzscloud.supervisory.money.pojo.entity.MoneyChangeDetailEntity;
import com.njzscloud.supervisory.money.service.MoneyAccountService;
@ -43,6 +45,7 @@ public class PaymentServiceImpl implements PaymentService {
refundRequest.getOrderId(), ctx.getOiPayWay(), isChange);
// 根据支付方式处理退款
if (SettlementWay.CASH.getVal().equals(ctx.getOiPayWay())) {
//微信退款 生成退款单号
String orderSn = IdUtil.getSnowflake(0, 0).nextIdStr();
// 微信退全款
@ -56,6 +59,19 @@ public class PaymentServiceImpl implements PaymentService {
refundRequest.getOrderId(), refundRequest.getOutTradeNo(), orderSn, money, notifyUrl);
String refundId = wechatPayService.refund(refundRequest.getOutTradeNo(), orderSn, money, money, notifyUrl);
log.info("微信退款申请成功退款ID{}", refundId);
// 新建退款资金明细
MoneyChangeDetailEntity newRefundDetail = new MoneyChangeDetailEntity()
.setType(MoneyDetailType.WX)
.setStatus(PayStatus.REFUNDING)
.setOrderId(refundRequest.getOrderId())
.setUserId(ctx.getDriverUserId())
// 退款为正数
.setDelta(refundRequest.getRefundAmount())
.setMoneyChangeCategory(MoneyChangeCategory.DingDanTuiKuan)
.setMemo("微信退款订单:" + orderSn);
moneyChangeDetailService.save(newRefundDetail);
} else if (SettlementWay.MONTH.getVal().equals(ctx.getOiPayWay()) || SettlementWay.BALANCE.getVal().equals(ctx.getOiPayWay())) {
// 公司退款
processCompanyRefund(refundRequest, ctx);
@ -98,7 +114,8 @@ public class PaymentServiceImpl implements PaymentService {
.setOrderId(orderId)
.setMoneyAccountId(companyAccount.getId())
.setOldMoney(oldBalance)
.setDelta(refundAmount) // 扣减为负数
// 扣减为负数
.setDelta(refundAmount)
.setNewMoney(newBalance)
.setMoneyChangeCategory(MoneyChangeCategory.DingDanTuiKuan)
.setMemo(reason);

View File

@ -7,6 +7,8 @@
SELECT
mcd.id,
mcd.user_id,
mcd.type,
mcd.status,
mcd.money_account_id,
mcd.old_money,
mcd.delta,
@ -96,6 +98,9 @@
<if test="entity.endTime != null">
AND mcd.create_time &lt;= #{entity.endTime}
</if>
<if test="entity.type != null">
AND mcd.type &lt;= #{entity.type}
</if>
</where>
ORDER BY
mcd.create_time DESC

View File

@ -338,7 +338,8 @@
bc.settlement_way,
sua.wechat_openid,
a.refund_money,
a.settle_money
a.settle_money,
bd.user_id AS driver_user_id
FROM order_info a
LEFT JOIN biz_company bc ON bc.id = a.trans_company_id
LEFT JOIN money_account ma1 ON ma1.station_id = a.trans_company_id