支付相关
parent
e5bc14b9d7
commit
6da4776db7
|
|
@ -6,7 +6,6 @@ import lombok.Getter;
|
|||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.simpleframework.xml.Transient;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
|
@ -78,7 +77,7 @@ public class GoodsInfoEntity {
|
|||
private String memo;
|
||||
|
||||
/**
|
||||
* 计费方式 1-->入场计费 2-->出厂计费
|
||||
* 计费方式 in-->入场计费 out-->出场计费
|
||||
*/
|
||||
private String moneyWay;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -12,7 +12,8 @@ import lombok.RequiredArgsConstructor;
|
|||
@RequiredArgsConstructor
|
||||
public enum SettlementWay implements DictStr {
|
||||
MONTH("month", "月结"),
|
||||
BALANCE("balance", "余额")
|
||||
BALANCE("balance", "余额"),
|
||||
CASH("cash", "现付")
|
||||
;
|
||||
private final String val;
|
||||
private final String txt;
|
||||
|
|
|
|||
|
|
@ -72,4 +72,9 @@ public class OrderGoodsEntity {
|
|||
*/
|
||||
private BigDecimal taxRate;
|
||||
|
||||
/**
|
||||
* 计费方式 in-->入场计费 out-->出场计费
|
||||
*/
|
||||
private String moneyWay;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -274,6 +274,8 @@ public class OrderPagingResult {
|
|||
*/
|
||||
private MoneyStrategy moneyStrategy;
|
||||
|
||||
private String moneyWay;
|
||||
|
||||
/**
|
||||
* 计费配置 Id
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -117,9 +117,9 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
|
|||
.setAssignmentTransTime(transCompanyId == null ? null : LocalDateTime.now());
|
||||
this.save(orderInfoEntity);
|
||||
|
||||
if (transCompanyId != null) {
|
||||
/*if (transCompanyId != null) {
|
||||
settleForTransCompany(this.getById(orderInfoEntity.getId()), 0);
|
||||
}
|
||||
}*/
|
||||
|
||||
Long orderId = orderInfoEntity.getId();
|
||||
OrderCategory orderCategory = addOrderInfoParam.getOrderCategory();
|
||||
|
|
@ -629,16 +629,15 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
|
|||
Assert.isNull(orderInfo.getDriverId(), () -> Exceptions.clierr("当前订单已分配司机,无需重复分配"));
|
||||
Assert.isTrue(orderInfo.getOrderStatus() == OrderStatus.DaiPaiDan, () -> Exceptions.clierr("当前订单状态,无法分配司机"));
|
||||
// 查询订单及相关支付上下文
|
||||
/*PaymentContextResult ctx = paymentContext(orderInfo.getId());
|
||||
if (PaymentWay.COMPANY.getVal().equals(orderInfo.getPaymentCategory()) &&
|
||||
SettlementWay.BALANCE.getVal().equals(ctx.getSettlementWay())) {
|
||||
// 当该笔订单支付方式为公司支付,并且支付方式为余额支付时,需在分配之前查询当前清运公司余额是否充足,
|
||||
// 如果不足则提示余额不足,不允许在派司机
|
||||
PaymentContextResult ctx = paymentContext(orderInfo.getId());
|
||||
if (SettlementWay.BALANCE.getVal().equals(ctx.getSettlementWay())) {
|
||||
// 如果该笔订单的清运公司支付方式为余额支付时,需在分配之前查询当前清运公司余额是否充足,
|
||||
// 不足则提示余额不足,不允许在派司机
|
||||
if (ctx.getCompanyBalance().compareTo(BigDecimal.ZERO) < 0) {
|
||||
// 已经是负数,禁止再次支付
|
||||
throw Exceptions.clierr("公司账户余额不足");
|
||||
}
|
||||
}*/
|
||||
}
|
||||
baseMapper.busyDriver(driverId, Boolean.TRUE);
|
||||
|
||||
this.updateById(new OrderInfoEntity()
|
||||
|
|
@ -662,8 +661,8 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
|
|||
.setAssignmentTransTime(LocalDateTime.now())
|
||||
.setOrderStatus(OrderStatus.DaiPaiDan)
|
||||
);
|
||||
OrderInfoEntity orderInfoEntity = this.getById(orderInfoId);
|
||||
settleForTransCompany(orderInfoEntity, 0);
|
||||
// OrderInfoEntity orderInfoEntity = this.getById(orderInfoId);
|
||||
// settleForTransCompany(orderInfoEntity, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -709,15 +708,35 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
|
|||
Assert.isTrue(orderInfo.getAuditStatus() == AuditStatus.TongGuo, () -> Exceptions.clierr("当前订单未审核完成,无法开始运输"));
|
||||
Long orderInfoId = orderInfo.getId();
|
||||
|
||||
// 判断支付方式,如果为公司支付,在此处直接扣减
|
||||
// handleCompanyPay(orderInfo);
|
||||
OrderGoodsEntity entity = orderGoodsService.getById(orderInfo.getGoodsId());
|
||||
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()
|
||||
.setId(orderInfoId)
|
||||
.setCargoPhoto(startTransportOrderParam.getCargoPhoto())
|
||||
.setOrderStatus(OrderStatus.QingYunZhong)
|
||||
.setTransTime(LocalDateTime.now())
|
||||
);
|
||||
}
|
||||
|
||||
this.updateById(new OrderInfoEntity()
|
||||
.setId(orderInfoId)
|
||||
.setCargoPhoto(startTransportOrderParam.getCargoPhoto())
|
||||
.setOrderStatus(OrderStatus.QingYunZhong)
|
||||
.setTransTime(LocalDateTime.now())
|
||||
);
|
||||
Long truckId = orderInfo.getTruckId();
|
||||
Assert.notNull(truckId, () -> Exceptions.clierr("订单未分配车辆"));
|
||||
BizTruckEntity truckInfo = baseMapper.getTruckInfo(truckId);
|
||||
|
|
@ -751,8 +770,8 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
|
|||
|
||||
public void handleCompanyPay(OrderInfoEntity orderInfo) {
|
||||
PaymentContextResult ctx = paymentContext(orderInfo.getId());
|
||||
if (PaymentWay.COMPANY.getVal().equals(orderInfo.getPaymentCategory())) {
|
||||
// 验证资金账户信息
|
||||
if (!SettlementWay.CASH.getVal().equals(ctx.getSettlementWay())) {
|
||||
/*// 验证资金账户信息
|
||||
if (ctx.getCompanyAccountId() == null) {
|
||||
throw Exceptions.clierr("公司资金账户不存在");
|
||||
}
|
||||
|
|
@ -766,7 +785,7 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
|
|||
// 已经是负数,禁止再次支付
|
||||
throw Exceptions.clierr("公司账户余额不足");
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
BigDecimal oldBalance = ctx.getCompanyBalance();
|
||||
BigDecimal newBalance = oldBalance.subtract(ctx.getSettleMoney());
|
||||
|
|
@ -793,7 +812,6 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
|
|||
log.info("公司账户扣减成功,用户ID:{},扣减金额:{},余额:{} -> {},结算方式:{}",
|
||||
ctx.getCompanyUserId(), ctx.getSettleMoney(), oldBalance, newBalance, ctx.getSettlementWay());
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1040,7 +1058,25 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
|
|||
// 1) 复制“产品”到 order_expense_items;
|
||||
// 2) 从 expense_items_config 读取可用付费项并按 scope 过滤(all / customer_type=QiYe|GeTi / customer 包含 trans_company_id);
|
||||
// 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 {
|
||||
// 关闭 GPS
|
||||
BizTruckEntity truckInfo = baseMapper.getTruckInfo(truckId);
|
||||
|
|
@ -1056,10 +1092,8 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
|
|||
* 3. 合并集合,计算金额(total_money=quantity*unit_price,settle_money=total_money+discount_money+revise_money),批量入库
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void settleForTransCompany(OrderInfoEntity orderInfoEntity, Integer settleWeight) {
|
||||
public void settleForTransCompany(OrderInfoEntity orderInfoEntity, OrderGoodsEntity orderGoods, Integer settleWeight) {
|
||||
Long orderId = orderInfoEntity.getId();
|
||||
OrderGoodsEntity orderGoods = orderGoodsService.getById(orderInfoEntity.getGoodsId());
|
||||
Assert.notNull(orderGoods, () -> Exceptions.clierr("订单产品不存在"));
|
||||
|
||||
// 数量口径:计费策略=按车(Che) 时数量=1,否则数量=settleWeight
|
||||
int quantityByStrategy = (orderGoods.getMoneyStrategy() == MoneyStrategy.Che) ? 1 : settleWeight;
|
||||
|
|
|
|||
|
|
@ -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.exception.WxPayException;
|
||||
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.Exceptions;
|
||||
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.order.contant.PaymentStatus;
|
||||
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.order.pojo.entity.OrderExpenseItemsEntity;
|
||||
import com.njzscloud.supervisory.order.pojo.entity.OrderInfoEntity;
|
||||
|
|
@ -70,10 +68,9 @@ public class PaymentController {
|
|||
@PostMapping("/pay")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> pay(@RequestBody PaymentParam paymentParam) {
|
||||
// 入参校验:支付方式、订单ID、支付清单不能为空
|
||||
// 入参校验:结算金额、订单ID、支付清单不能为空
|
||||
if (paymentParam == null
|
||||
|| paymentParam.getOrderId() == null
|
||||
|| Strings.isNullOrEmpty(paymentParam.getPaymentCategory())
|
||||
|| paymentParam.getSettleTotalMoney() == null
|
||||
|| paymentParam.getSettleTotalMoney().signum() < 0
|
||||
|| paymentParam.getItems() == null) {
|
||||
|
|
@ -91,13 +88,6 @@ public class PaymentController {
|
|||
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()) {
|
||||
OrderExpenseItemsEntity entity = orderExpenseItemsService.getById(it.getId());
|
||||
|
|
@ -123,65 +113,35 @@ public class PaymentController {
|
|||
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("公司账户余额不足");
|
||||
}
|
||||
}
|
||||
try {
|
||||
// 构建微信支付请求
|
||||
String outTradeNo = generateOutTradeNo(ctx.getSn());
|
||||
WxPayUnifiedOrderRequest wxRequest = new WxPayUnifiedOrderRequest();
|
||||
wxRequest.setOutTradeNo(outTradeNo);
|
||||
wxRequest.setBody("订单支付-" + ctx.getSn());
|
||||
wxRequest.setTotalFee(ctx.getSettleMoney().multiply(new BigDecimal("100")).intValue()); // 转换为分
|
||||
wxRequest.setOpenid(getCurrentUserOpenid(paymentParam.getWxCode()));
|
||||
wxRequest.setTradeType("JSAPI");
|
||||
wxRequest.setSpbillCreateIp(RequestHolder.getClientIP());
|
||||
wxRequest.setNotifyUrl(properties.getNotifyUrl()); // 需要配置实际的回调地址
|
||||
|
||||
// 3. 更新订单支付状态为已支付
|
||||
// 调用微信支付服务
|
||||
WxPayMpOrderResult result = (WxPayMpOrderResult) wechatPayService.createJsapiOrder(wxRequest);
|
||||
|
||||
// 更新订单状态为待支付
|
||||
orderInfoService.lambdaUpdate()
|
||||
.eq(OrderInfoEntity::getId, paymentParam.getOrderId())
|
||||
.set(OrderInfoEntity::getPaymentStatus, PaymentStatus.YiZhiFu)
|
||||
.set(OrderInfoEntity::getPaymentCategory, paymentParam.getPaymentCategory())
|
||||
.set(OrderInfoEntity::getPayTime, LocalDateTime.now())
|
||||
.set(OrderInfoEntity::getPaymentStatus, PaymentStatus.WeiZhiFu)
|
||||
.set(OrderInfoEntity::getPaymentCategory, PaymentWay.WX.getVal())
|
||||
.set(OrderInfoEntity::getOutTradeNo, outTradeNo)
|
||||
.update();
|
||||
|
||||
log.info("订单支付成功,订单ID:{},支付方式:{},支付金额:{}",
|
||||
paymentParam.getOrderId(), paymentParam.getPaymentCategory(), ctx.getSettleMoney());
|
||||
} else if (PaymentWay.WX.getVal().equals(paymentParam.getPaymentCategory())) {
|
||||
try {
|
||||
// 构建微信支付请求
|
||||
String outTradeNo = generateOutTradeNo(ctx.getSn());
|
||||
WxPayUnifiedOrderRequest wxRequest = new WxPayUnifiedOrderRequest();
|
||||
wxRequest.setOutTradeNo(outTradeNo);
|
||||
wxRequest.setBody("订单支付-" + ctx.getSn());
|
||||
wxRequest.setTotalFee(ctx.getSettleMoney().multiply(new BigDecimal("100")).intValue()); // 转换为分
|
||||
wxRequest.setOpenid(getCurrentUserOpenid(paymentParam.getWxCode()));
|
||||
wxRequest.setTradeType("JSAPI");
|
||||
wxRequest.setSpbillCreateIp(RequestHolder.getClientIP());
|
||||
wxRequest.setNotifyUrl(properties.getNotifyUrl()); // 需要配置实际的回调地址
|
||||
log.info("微信支付订单创建成功(生产级SDK),订单ID:{},微信订单号:{}", paymentParam.getOrderId(), outTradeNo);
|
||||
|
||||
// 调用微信支付服务
|
||||
WxPayMpOrderResult result = (WxPayMpOrderResult) wechatPayService.createJsapiOrder(wxRequest);
|
||||
|
||||
// 更新订单状态为待支付
|
||||
orderInfoService.lambdaUpdate()
|
||||
.eq(OrderInfoEntity::getId, paymentParam.getOrderId())
|
||||
.set(OrderInfoEntity::getPaymentStatus, PaymentStatus.WeiZhiFu)
|
||||
.set(OrderInfoEntity::getPaymentCategory, paymentParam.getPaymentCategory())
|
||||
.set(OrderInfoEntity::getOutTradeNo, outTradeNo)
|
||||
.update();
|
||||
|
||||
log.info("微信支付订单创建成功(生产级SDK),订单ID:{},微信订单号:{}", paymentParam.getOrderId(), outTradeNo);
|
||||
|
||||
return R.success(result);
|
||||
} catch (WxPayException e) {
|
||||
log.error("微信支付订单创建失败,订单ID:{},错误信息:{}", paymentParam.getOrderId(), e.getMessage(), e);
|
||||
WxPayNotifyResponse.fail(e.getMessage());
|
||||
}
|
||||
return R.success(result);
|
||||
} catch (WxPayException e) {
|
||||
log.error("微信支付订单创建失败,订单ID:{},错误信息:{}", paymentParam.getOrderId(), e.getMessage(), e);
|
||||
WxPayNotifyResponse.fail(e.getMessage());
|
||||
}
|
||||
|
||||
return R.success();
|
||||
|
|
|
|||
|
|
@ -20,12 +20,6 @@ public class PaymentParam {
|
|||
*/
|
||||
private Long orderId;
|
||||
|
||||
|
||||
/**
|
||||
* 支付方式:wx / company
|
||||
*/
|
||||
private String paymentCategory;
|
||||
|
||||
/**
|
||||
* 结算总金额(必须 >= 0)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -140,10 +140,12 @@
|
|||
j.license_end_time,
|
||||
g.idcard trans_idcard,
|
||||
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
|
||||
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 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 biz_truck e ON e.id = a.truck_id
|
||||
LEFT JOIN biz_driver f ON f.id = a.driver_id
|
||||
|
|
|
|||
Loading…
Reference in New Issue