Compare commits

..

2 Commits

Author SHA1 Message Date
ljw f3e5f3bba0 Merge branch 'master' of https://git.njzscloud.com/lzq/njzscloud 2025-10-22 16:09:16 +08:00
ljw 6da4776db7 支付相关 2025-10-22 16:09:10 +08:00
9 changed files with 116 additions and 100 deletions

View File

@ -6,7 +6,6 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import org.simpleframework.xml.Transient;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -78,7 +77,7 @@ public class GoodsInfoEntity {
private String memo; private String memo;
/** /**
* 1--> 2--> * in--> out-->
*/ */
private String moneyWay; private String moneyWay;

View File

@ -0,0 +1,19 @@
package com.njzscloud.supervisory.order.contant;
import com.njzscloud.common.core.ienum.DictStr;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* money_way
*
*/
@Getter
@RequiredArgsConstructor
public enum MoneyWay implements DictStr {
IN("in", "入场计费"),
OUT("out", "出场计费"),
;
private final String val;
private final String txt;
}

View File

@ -12,7 +12,8 @@ import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor @RequiredArgsConstructor
public enum SettlementWay implements DictStr { public enum SettlementWay implements DictStr {
MONTH("month", "月结"), MONTH("month", "月结"),
BALANCE("balance", "余额") BALANCE("balance", "余额"),
CASH("cash", "现付")
; ;
private final String val; private final String val;
private final String txt; private final String txt;

View File

@ -72,4 +72,9 @@ public class OrderGoodsEntity {
*/ */
private BigDecimal taxRate; private BigDecimal taxRate;
/**
* in--> out-->
*/
private String moneyWay;
} }

View File

@ -274,6 +274,8 @@ public class OrderPagingResult {
*/ */
private MoneyStrategy moneyStrategy; private MoneyStrategy moneyStrategy;
private String moneyWay;
/** /**
* Id * Id
*/ */

View File

@ -117,9 +117,9 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
.setAssignmentTransTime(transCompanyId == null ? null : LocalDateTime.now()); .setAssignmentTransTime(transCompanyId == null ? null : LocalDateTime.now());
this.save(orderInfoEntity); this.save(orderInfoEntity);
if (transCompanyId != null) { /*if (transCompanyId != null) {
settleForTransCompany(this.getById(orderInfoEntity.getId()), 0); settleForTransCompany(this.getById(orderInfoEntity.getId()), 0);
} }*/
Long orderId = orderInfoEntity.getId(); Long orderId = orderInfoEntity.getId();
OrderCategory orderCategory = addOrderInfoParam.getOrderCategory(); OrderCategory orderCategory = addOrderInfoParam.getOrderCategory();
@ -629,16 +629,15 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
Assert.isNull(orderInfo.getDriverId(), () -> Exceptions.clierr("当前订单已分配司机,无需重复分配")); Assert.isNull(orderInfo.getDriverId(), () -> Exceptions.clierr("当前订单已分配司机,无需重复分配"));
Assert.isTrue(orderInfo.getOrderStatus() == OrderStatus.DaiPaiDan, () -> Exceptions.clierr("当前订单状态,无法分配司机")); Assert.isTrue(orderInfo.getOrderStatus() == OrderStatus.DaiPaiDan, () -> Exceptions.clierr("当前订单状态,无法分配司机"));
// 查询订单及相关支付上下文 // 查询订单及相关支付上下文
/*PaymentContextResult ctx = paymentContext(orderInfo.getId()); PaymentContextResult ctx = paymentContext(orderInfo.getId());
if (PaymentWay.COMPANY.getVal().equals(orderInfo.getPaymentCategory()) && if (SettlementWay.BALANCE.getVal().equals(ctx.getSettlementWay())) {
SettlementWay.BALANCE.getVal().equals(ctx.getSettlementWay())) { // 如果该笔订单的清运公司支付方式为余额支付时,需在分配之前查询当前清运公司余额是否充足,
// 当该笔订单支付方式为公司支付,并且支付方式为余额支付时,需在分配之前查询当前清运公司余额是否充足, // 不足则提示余额不足,不允许在派司机
// 如果不足则提示余额不足,不允许在派司机
if (ctx.getCompanyBalance().compareTo(BigDecimal.ZERO) < 0) { if (ctx.getCompanyBalance().compareTo(BigDecimal.ZERO) < 0) {
// 已经是负数,禁止再次支付 // 已经是负数,禁止再次支付
throw Exceptions.clierr("公司账户余额不足"); throw Exceptions.clierr("公司账户余额不足");
} }
}*/ }
baseMapper.busyDriver(driverId, Boolean.TRUE); baseMapper.busyDriver(driverId, Boolean.TRUE);
this.updateById(new OrderInfoEntity() this.updateById(new OrderInfoEntity()
@ -662,8 +661,8 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
.setAssignmentTransTime(LocalDateTime.now()) .setAssignmentTransTime(LocalDateTime.now())
.setOrderStatus(OrderStatus.DaiPaiDan) .setOrderStatus(OrderStatus.DaiPaiDan)
); );
OrderInfoEntity orderInfoEntity = this.getById(orderInfoId); // OrderInfoEntity orderInfoEntity = this.getById(orderInfoId);
settleForTransCompany(orderInfoEntity, 0); // settleForTransCompany(orderInfoEntity, 0);
return true; return true;
} }
@ -709,15 +708,35 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
Assert.isTrue(orderInfo.getAuditStatus() == AuditStatus.TongGuo, () -> Exceptions.clierr("当前订单未审核完成,无法开始运输")); Assert.isTrue(orderInfo.getAuditStatus() == AuditStatus.TongGuo, () -> Exceptions.clierr("当前订单未审核完成,无法开始运输"));
Long orderInfoId = orderInfo.getId(); Long orderInfoId = orderInfo.getId();
// 判断支付方式,如果为公司支付,在此处直接扣减 OrderGoodsEntity entity = orderGoodsService.getById(orderInfo.getGoodsId());
// handleCompanyPay(orderInfo); Assert.notNull(entity, () -> Exceptions.clierr("产品不存在"));
if (MoneyWay.IN.getVal().equals(entity.getMoneyWay())) {
// 当计费方式为入场计费时,并且是需要公司支付,我们需要再此次添加订单付费项,并计算好费用
settleForTransCompany(orderInfo, entity, 0);
// 处理公司支付
handleCompanyPay(orderInfo);
// 更新订单支付状态为已支付
this.updateById(new OrderInfoEntity()
.setId(orderInfoId)
.setCargoPhoto(startTransportOrderParam.getCargoPhoto())
.setOrderStatus(OrderStatus.QingYunZhong)
.setTransTime(LocalDateTime.now())
.setPaymentStatus(PaymentStatus.YiZhiFu)
.setPaymentCategory(PaymentWay.COMPANY.getVal())
.setPayTime(LocalDateTime.now())
);
} else {
this.updateById(new OrderInfoEntity() this.updateById(new OrderInfoEntity()
.setId(orderInfoId) .setId(orderInfoId)
.setCargoPhoto(startTransportOrderParam.getCargoPhoto()) .setCargoPhoto(startTransportOrderParam.getCargoPhoto())
.setOrderStatus(OrderStatus.QingYunZhong) .setOrderStatus(OrderStatus.QingYunZhong)
.setTransTime(LocalDateTime.now()) .setTransTime(LocalDateTime.now())
); );
}
Long truckId = orderInfo.getTruckId(); Long truckId = orderInfo.getTruckId();
Assert.notNull(truckId, () -> Exceptions.clierr("订单未分配车辆")); Assert.notNull(truckId, () -> Exceptions.clierr("订单未分配车辆"));
BizTruckEntity truckInfo = baseMapper.getTruckInfo(truckId); BizTruckEntity truckInfo = baseMapper.getTruckInfo(truckId);
@ -751,8 +770,8 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
public void handleCompanyPay(OrderInfoEntity orderInfo) { public void handleCompanyPay(OrderInfoEntity orderInfo) {
PaymentContextResult ctx = paymentContext(orderInfo.getId()); PaymentContextResult ctx = paymentContext(orderInfo.getId());
if (PaymentWay.COMPANY.getVal().equals(orderInfo.getPaymentCategory())) { if (!SettlementWay.CASH.getVal().equals(ctx.getSettlementWay())) {
// 验证资金账户信息 /*// 验证资金账户信息
if (ctx.getCompanyAccountId() == null) { if (ctx.getCompanyAccountId() == null) {
throw Exceptions.clierr("公司资金账户不存在"); throw Exceptions.clierr("公司资金账户不存在");
} }
@ -766,7 +785,7 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
// 已经是负数,禁止再次支付 // 已经是负数,禁止再次支付
throw Exceptions.clierr("公司账户余额不足"); throw Exceptions.clierr("公司账户余额不足");
} }
} }*/
BigDecimal oldBalance = ctx.getCompanyBalance(); BigDecimal oldBalance = ctx.getCompanyBalance();
BigDecimal newBalance = oldBalance.subtract(ctx.getSettleMoney()); BigDecimal newBalance = oldBalance.subtract(ctx.getSettleMoney());
@ -793,7 +812,6 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
log.info("公司账户扣减成功用户ID{},扣减金额:{},余额:{} -> {},结算方式:{}", log.info("公司账户扣减成功用户ID{},扣减金额:{},余额:{} -> {},结算方式:{}",
ctx.getCompanyUserId(), ctx.getSettleMoney(), oldBalance, newBalance, ctx.getSettlementWay()); ctx.getCompanyUserId(), ctx.getSettleMoney(), oldBalance, newBalance, ctx.getSettlementWay());
} }
} }
@ -1040,7 +1058,25 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
// 1) 复制“产品”到 order_expense_items // 1) 复制“产品”到 order_expense_items
// 2) 从 expense_items_config 读取可用付费项并按 scope 过滤all / customer_type=QiYe|GeTi / customer 包含 trans_company_id // 2) 从 expense_items_config 读取可用付费项并按 scope 过滤all / customer_type=QiYe|GeTi / customer 包含 trans_company_id
// 3) 合并集合,计算 total_money 与 settle_money并批量落库。 // 3) 合并集合,计算 total_money 与 settle_money并批量落库。
// settleForTransCompany(orderInfoEntity, settleWeight); OrderGoodsEntity entity = orderGoodsService.getById(orderInfoEntity.getGoodsId());
Assert.notNull(entity, () -> Exceptions.clierr("产品不存在"));
// 出厂付费
if (MoneyWay.OUT.getVal().equals(entity.getMoneyWay())) {
// 计算费用
settleForTransCompany(orderInfoEntity, entity, settleWeight);
// 扣费
handleCompanyPay(orderInfoEntity);
// 更新订单支付状态为已支付
this.updateById(new OrderInfoEntity()
.setId(orderInfoEntity.getId())
.setPaymentStatus(PaymentStatus.YiZhiFu)
.setPaymentCategory(PaymentWay.COMPANY.getVal())
.setPayTime(LocalDateTime.now())
);
}
} finally { } finally {
// 关闭 GPS // 关闭 GPS
BizTruckEntity truckInfo = baseMapper.getTruckInfo(truckId); BizTruckEntity truckInfo = baseMapper.getTruckInfo(truckId);
@ -1056,10 +1092,8 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
* 3. total_money=quantity*unit_pricesettle_money=total_money+discount_money+revise_money * 3. total_money=quantity*unit_pricesettle_money=total_money+discount_money+revise_money
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void settleForTransCompany(OrderInfoEntity orderInfoEntity, Integer settleWeight) { public void settleForTransCompany(OrderInfoEntity orderInfoEntity, OrderGoodsEntity orderGoods, Integer settleWeight) {
Long orderId = orderInfoEntity.getId(); Long orderId = orderInfoEntity.getId();
OrderGoodsEntity orderGoods = orderGoodsService.getById(orderInfoEntity.getGoodsId());
Assert.notNull(orderGoods, () -> Exceptions.clierr("订单产品不存在"));
// 数量口径:计费策略=按车(Che) 时数量=1否则数量=settleWeight // 数量口径:计费策略=按车(Che) 时数量=1否则数量=settleWeight
int quantityByStrategy = (orderGoods.getMoneyStrategy() == MoneyStrategy.Che) ? 1 : settleWeight; int quantityByStrategy = (orderGoods.getMoneyStrategy() == MoneyStrategy.Che) ? 1 : settleWeight;

View File

@ -8,7 +8,6 @@ import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.service.WxPayService;
import com.google.common.base.Strings;
import com.njzscloud.common.core.ex.ExceptionMsg; import com.njzscloud.common.core.ex.ExceptionMsg;
import com.njzscloud.common.core.ex.Exceptions; import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.common.core.utils.R; import com.njzscloud.common.core.utils.R;
@ -23,7 +22,6 @@ import com.njzscloud.supervisory.money.service.MoneyAccountService;
import com.njzscloud.supervisory.money.service.MoneyChangeDetailService; import com.njzscloud.supervisory.money.service.MoneyChangeDetailService;
import com.njzscloud.supervisory.order.contant.PaymentStatus; import com.njzscloud.supervisory.order.contant.PaymentStatus;
import com.njzscloud.supervisory.order.contant.PaymentWay; import com.njzscloud.supervisory.order.contant.PaymentWay;
import com.njzscloud.supervisory.order.contant.SettlementWay;
import com.njzscloud.supervisory.wxPay.dto.RefundRequestDto; import com.njzscloud.supervisory.wxPay.dto.RefundRequestDto;
import com.njzscloud.supervisory.order.pojo.entity.OrderExpenseItemsEntity; import com.njzscloud.supervisory.order.pojo.entity.OrderExpenseItemsEntity;
import com.njzscloud.supervisory.order.pojo.entity.OrderInfoEntity; import com.njzscloud.supervisory.order.pojo.entity.OrderInfoEntity;
@ -70,10 +68,9 @@ public class PaymentController {
@PostMapping("/pay") @PostMapping("/pay")
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public R<?> pay(@RequestBody PaymentParam paymentParam) { public R<?> pay(@RequestBody PaymentParam paymentParam) {
// 入参校验:支付方式、订单ID、支付清单不能为空 // 入参校验:结算金额、订单ID、支付清单不能为空
if (paymentParam == null if (paymentParam == null
|| paymentParam.getOrderId() == null || paymentParam.getOrderId() == null
|| Strings.isNullOrEmpty(paymentParam.getPaymentCategory())
|| paymentParam.getSettleTotalMoney() == null || paymentParam.getSettleTotalMoney() == null
|| paymentParam.getSettleTotalMoney().signum() < 0 || paymentParam.getSettleTotalMoney().signum() < 0
|| paymentParam.getItems() == null) { || paymentParam.getItems() == null) {
@ -91,13 +88,6 @@ public class PaymentController {
throw Exceptions.clierr("支付清单项不合法id/名称/金额)"); throw Exceptions.clierr("支付清单项不合法id/名称/金额)");
} }
// 校验支付方式
if (paymentParam.getPaymentCategory() == null ||
!(PaymentWay.WX.getVal().equals(paymentParam.getPaymentCategory()) ||
PaymentWay.COMPANY.getVal().equals(paymentParam.getPaymentCategory()))) {
throw Exceptions.clierr("支付方式不合法");
}
// 校验数据库中结算金额是否与请求一致 // 校验数据库中结算金额是否与请求一致
for (PaymentItemParam it : paymentParam.getItems()) { for (PaymentItemParam it : paymentParam.getItems()) {
OrderExpenseItemsEntity entity = orderExpenseItemsService.getById(it.getId()); OrderExpenseItemsEntity entity = orderExpenseItemsService.getById(it.getId());
@ -123,35 +113,6 @@ public class PaymentController {
throw Exceptions.clierr("结算总金额与实际总金额不一致"); throw Exceptions.clierr("结算总金额与实际总金额不一致");
} }
// 根据支付方式处理
if (PaymentWay.COMPANY.getVal().equals(paymentParam.getPaymentCategory())) {
// 公司支付:根据订单 trans_company_id -> biz_company.user_id -> money_account
if (null == ctx.getTransCompanyId()) {
throw Exceptions.clierr("订单未关联清运公司,无法公司支付");
}
// 根据结算方式判断是否需要检查余额
if (SettlementWay.BALANCE.getVal().equals(ctx.getSettlementWay())) {
// 余额结算:允许本次支付后余额为负数,但仅限于余额首次变为负数
if (ctx.getCompanyBalance() == null) {
ctx.setCompanyBalance(BigDecimal.ZERO);
}
if (ctx.getCompanyBalance().compareTo(BigDecimal.ZERO) < 0) {
// 已经是负数,禁止再次支付
throw Exceptions.clierr("公司账户余额不足");
}
}
// 3. 更新订单支付状态为已支付
orderInfoService.lambdaUpdate()
.eq(OrderInfoEntity::getId, paymentParam.getOrderId())
.set(OrderInfoEntity::getPaymentStatus, PaymentStatus.YiZhiFu)
.set(OrderInfoEntity::getPaymentCategory, paymentParam.getPaymentCategory())
.set(OrderInfoEntity::getPayTime, LocalDateTime.now())
.update();
log.info("订单支付成功订单ID{},支付方式:{},支付金额:{}",
paymentParam.getOrderId(), paymentParam.getPaymentCategory(), ctx.getSettleMoney());
} else if (PaymentWay.WX.getVal().equals(paymentParam.getPaymentCategory())) {
try { try {
// 构建微信支付请求 // 构建微信支付请求
String outTradeNo = generateOutTradeNo(ctx.getSn()); String outTradeNo = generateOutTradeNo(ctx.getSn());
@ -171,7 +132,7 @@ public class PaymentController {
orderInfoService.lambdaUpdate() orderInfoService.lambdaUpdate()
.eq(OrderInfoEntity::getId, paymentParam.getOrderId()) .eq(OrderInfoEntity::getId, paymentParam.getOrderId())
.set(OrderInfoEntity::getPaymentStatus, PaymentStatus.WeiZhiFu) .set(OrderInfoEntity::getPaymentStatus, PaymentStatus.WeiZhiFu)
.set(OrderInfoEntity::getPaymentCategory, paymentParam.getPaymentCategory()) .set(OrderInfoEntity::getPaymentCategory, PaymentWay.WX.getVal())
.set(OrderInfoEntity::getOutTradeNo, outTradeNo) .set(OrderInfoEntity::getOutTradeNo, outTradeNo)
.update(); .update();
@ -182,7 +143,6 @@ public class PaymentController {
log.error("微信支付订单创建失败订单ID{},错误信息:{}", paymentParam.getOrderId(), e.getMessage(), e); log.error("微信支付订单创建失败订单ID{},错误信息:{}", paymentParam.getOrderId(), e.getMessage(), e);
WxPayNotifyResponse.fail(e.getMessage()); WxPayNotifyResponse.fail(e.getMessage());
} }
}
return R.success(); return R.success();
} }

View File

@ -20,12 +20,6 @@ public class PaymentParam {
*/ */
private Long orderId; private Long orderId;
/**
* wx / company
*/
private String paymentCategory;
/** /**
* >= 0 * >= 0
*/ */

View File

@ -140,10 +140,12 @@
j.license_end_time, j.license_end_time,
g.idcard trans_idcard, g.idcard trans_idcard,
g.idcard_start_time trans_idcard_start_time, g.idcard_start_time trans_idcard_start_time,
g.idcard_end_time trans_idcard_end_time g.idcard_end_time trans_idcard_end_time,
gi.money_way
FROM order_info a FROM order_info a
LEFT JOIN order_cargo_place b ON b.id = a.cargo_place_id LEFT JOIN order_cargo_place b ON b.id = a.cargo_place_id
LEFT JOIN order_goods c ON c.id = a.goods_id LEFT JOIN order_goods c ON c.id = a.goods_id
LEFT JOIN goods_info gi ON gi.id = c.origin_goods_id
LEFT JOIN order_car_in_out d ON d.id = a.car_in_out_id LEFT JOIN order_car_in_out d ON d.id = a.car_in_out_id
LEFT JOIN biz_truck e ON e.id = a.truck_id LEFT JOIN biz_truck e ON e.id = a.truck_id
LEFT JOIN biz_driver f ON f.id = a.driver_id LEFT JOIN biz_driver f ON f.id = a.driver_id