fix:不绑定饭卡也可以充值

This commit is contained in:
dzc committed 2026-08-29 18:29:10 +08:00
1 parent c11d70ccac
commit 93dc377bb1
3 files changed
+61 -3

No files matched your search

@@ -332,7 +332,12 @@ public class ThirdAppPlusServiceImpl implements ThirdAppPlusService {
}
/**
* 小程序支付
* 根据业务类型解析可信金额与收款商户,并创建 App 或小程序第三方支付订单。
* 监护代充值会重新校验目标钱包、有效监护关系和人员身份,但实体饭卡未绑定或未激活不影响余额充值。
*
* @param userId 当前付款用户 ID
* @param dto 支付业务、平台及业务单号;可信金额由对应业务记录覆盖
* @return 第三方支付单号与客户端拉起支付所需参数
*/
@Override
public ThirdMiniAppPayVo miniPay(Long userId, ThirdMiniAppPayDto dto) {
@@ -375,7 +380,13 @@ public class ThirdAppPlusServiceImpl implements ThirdAppPlusService {
}
R<com.bsd.pjcloud.wallet.api.vo.WalletManageVo> walletResult = remoteWalletService.getWalletById(recharge.getWalletId());
WalletManageEntity wallet = walletResult == null || !walletResult.isOk() ? null : walletResult.getData();
if (wallet == null || ObjectUtil.isEmpty(wallet.getCardNumber()) || ObjectUtil.notEqual(wallet.getStatus(), WalleCardStatusEnum.ACTIVE.getCode()) || ObjectUtil.equals(wallet.getIsFreeze(), YesNoEnum.YES.getCode())) {
// 代充值实际增加的是钱包余额,未绑定或未激活实体饭卡不应阻止支付;挂失、锁卡、销卡及冻结仍拒绝。
boolean walletSupportsRecharge = wallet != null
&& !ObjectUtil.equals(wallet.getIsFreeze(), YesNoEnum.YES.getCode())
&& (StrUtil.isBlank(wallet.getStatus())
|| ObjectUtil.equals(wallet.getStatus(), WalleCardStatusEnum.NONE_ACTIVE.getCode())
|| ObjectUtil.equals(wallet.getStatus(), WalleCardStatusEnum.ACTIVE.getCode()));
if (!walletSupportsRecharge) {
throw new RuntimeException("目标饭卡当前不可充值");
}
R<List<Long>> relationResult = remoteUserRelationService.listActiveGuardianWardUserIds(userId);
@@ -9,6 +9,7 @@ import com.bsd.pjcloud.admin.api.feign.RemoteTokenService;
import com.bsd.pjcloud.admin.api.feign.RemoteUserRelationService;
import com.bsd.pjcloud.admin.api.feign.RemoteUserService;
import com.bsd.pjcloud.app.api.feign.RemoteAppUserService;
import com.bsd.pjcloud.common.core.constant.enums.MerchantTypeEnum;
import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.hard.api.feign.RemoteHardOrderService;
@@ -27,12 +28,14 @@ import com.bsd.pjcloud.thirdparty.service.*;
import com.bsd.pjcloud.thirdparty.vo.appplus.pay.ThirdOrderCodePayStatusVo;
import com.bsd.pjcloud.thirdparty.vo.appplus.pay.ThirdOrderCodePayVo;
import com.bsd.pjcloud.thirdparty.vo.appplus.pay.wechat.ThirdMiniWechatRefundQueryVo;
import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargeEntity;
import com.bsd.pjcloud.wallet.api.entity.mch.MchPaySettingEntity;
import com.bsd.pjcloud.wallet.api.feign.RemoteMchService;
import com.bsd.pjcloud.wallet.api.feign.RemoteWalletRechargePackageService;
import com.bsd.pjcloud.wallet.api.feign.RemoteWalletRechargeService;
import com.bsd.pjcloud.wallet.api.feign.RemoteWalletService;
import com.bsd.pjcloud.wallet.api.vo.MchManageVo;
import com.bsd.pjcloud.wallet.api.vo.WalletManageVo;
import com.bsd.pjcloud.wallet.api.vo.mch.MchPaySettingVo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
@@ -663,6 +666,48 @@ class ThirdAppPlusServiceImplOrderCodePayTest {
Assertions.assertEquals(hardOrder.getPayPrice(), payDtoCaptor.getValue().getAmount());
}
/**
* 新建且未绑定实体饭卡的钱包即使未写入绑定状态仍可接收余额充值,支付创建阶段不得再次要求卡号或激活状态。
*/
@Test
void guardianWardMiniPayShouldAllowUnboundInactiveCard() {
ThirdMiniRemotePayDto payRequest = new ThirdMiniRemotePayDto();
payRequest.setUserId(10L);
payRequest.setBizId("8001");
payRequest.setBizType(ThirdPayOrderBizTypeEnum.GUARDIAN_WARD_WALLET_RECHARGE);
payRequest.setMiniPlatformType(AppPlusPlatformTypeEnum.ALI_PAY);
WalletRechargeEntity recharge = new WalletRechargeEntity();
recharge.setId(8001L);
recharge.setWalletId(20L);
recharge.setPackageId(30L);
recharge.setPayStatus(false);
recharge.setPayPrice(1000);
WalletManageVo wallet = new WalletManageVo();
wallet.setId(20L);
wallet.setUserId(11L);
wallet.setDeptId(12L);
wallet.setCardNumber(null);
wallet.setStatus(null);
wallet.setIsFreeze(YesNoEnum.NO.getCode());
MchManageVo targetMerchant = enabledAliPayMerchant();
when(remoteWalletRechargeService.getRechargeById(8001L)).thenReturn(R.ok(recharge));
when(remoteWalletService.getWalletById(20L)).thenReturn(R.ok(wallet));
when(remoteUserRelationService.listActiveGuardianWardUserIds(10L)).thenReturn(R.ok(List.of(11L)));
when(remoteMchService.getViewsMchByDeptId(12L,
List.of(MerchantTypeEnum.FARMER, MerchantTypeEnum.CANTEEN)))
.thenReturn(R.ok(targetMerchant));
when(thirdMiniAppAliPayService.appPay(any(), any())).thenReturn("signed-order");
service.miniPay(payRequest.getUserId(), payRequest);
ArgumentCaptor<ThirdAppPlusPayDto> payDtoCaptor = ArgumentCaptor.forClass(ThirdAppPlusPayDto.class);
verify(thirdMiniAppAliPayService).appPay(payDtoCaptor.capture(), any());
Assertions.assertEquals(1000, payDtoCaptor.getValue().getAmount());
Assertions.assertEquals(88L, payDtoCaptor.getValue().getMchId());
}
/**
* 验证微信退款 PROCESSING 不提前推进本地订单终态。
*/
@@ -637,7 +637,9 @@ public class WalletRechargeServiceImpl extends ServiceImpl<WalletRechargeMapper,
if (ObjectUtil.equals(wallet.getIsFreeze(), YesNoEnum.YES.getCode())) {
return "饭卡已冻结";
}
boolean cardStatusSupportsRecharge = ObjectUtil.equals(wallet.getStatus(), WalleCardStatusEnum.NONE_ACTIVE.getCode())
// 新建但尚未绑定实体卡的钱包可能没有写入绑定状态,空状态与“未激活”均表示可接收余额充值。
boolean cardStatusSupportsRecharge = StrUtil.isBlank(wallet.getStatus())
|| ObjectUtil.equals(wallet.getStatus(), WalleCardStatusEnum.NONE_ACTIVE.getCode())
|| ObjectUtil.equals(wallet.getStatus(), WalleCardStatusEnum.ACTIVE.getCode());
if (!cardStatusSupportsRecharge) {
return cardStatusName(wallet.getStatus()) + ",暂不可充值";