@ -192,16 +192,24 @@ public class WalletPrerequisiteProjectionService {
private void ensureWallet ( SourceWallet source ) {
List < Wallet > existing = jdbc . query (
"SELECT wallet_id,user_id,wallet_type,central_bank_confirmation_signature " +
"SELECT wallet_id,user_id,wallet_type,central_bank_confirmation_signature ,balance,frozen_amount " +
"FROM digital_wallet WHERE wallet_id=? OR user_id=?" ,
( rs , row ) - > new Wallet ( rs . getString ( "wallet_id" ) , rs . getString ( "user_id" ) ,
rs . getString ( "wallet_type" ) , rs . getString ( "central_bank_confirmation_signature" ) ) ,
rs . getString ( "wallet_type" ) , rs . getString ( "central_bank_confirmation_signature" ) ,
rs . getBigDecimal ( "balance" ) , rs . getBigDecimal ( "frozen_amount" ) ) ,
source . walletId , source . userId ) ;
if ( ! existing . isEmpty ( ) ) {
if ( existing . size ( ) ! = 1 ) throw conflict ( "共享钱包标识或用户归属冲突" ) ;
validateWallet ( existing . get ( 0 ) , source ) ;
Wallet value = existing . get ( 0 ) ;
if ( ! isRetrainedUnusedWallet ( value , source ) ) {
validateWallet ( value , source ) ;
return ;
}
// Module 3 was redone after this wallet was first projected here, and the stale wallet
// was never actually used downstream, so retire it and let the fresh module 3 result
// through instead of surfacing a spurious "共享钱包与模块三最终结果不一致" conflict.
retireUnusedWalletChain ( value . walletId ) ;
}
try {
jdbc . update ( "INSERT INTO digital_wallet " +
"(wallet_id,user_id,wallet_type,status,balance,frozen_amount,central_bank_confirmation_signature," +
@ -213,6 +221,25 @@ public class WalletPrerequisiteProjectionService {
}
}
private boolean isRetrainedUnusedWallet ( Wallet value , SourceWallet source ) {
if ( ! source . userId . equals ( value . userId ) | | source . walletId . equals ( value . walletId ) ) return false ;
if ( value . balance . signum ( ) ! = 0 | | value . frozenAmount . signum ( ) ! = 0 ) return false ;
Integer usageCount = jdbc . queryForObject (
"SELECT (SELECT COUNT(*) FROM currency_exchange_order WHERE wallet_id=?) + " +
"(SELECT COUNT(*) FROM payment_order WHERE payer_wallet_id=? OR payee_wallet_id=?) + " +
"(SELECT COUNT(*) FROM wallet_balance_ledger WHERE wallet_id=?) + " +
"(SELECT COUNT(*) FROM payment_wallet_ledger WHERE wallet_id=?)" ,
Integer . class , value . walletId , value . walletId , value . walletId , value . walletId , value . walletId ) ;
return usageCount ! = null & & usageCount = = 0 ;
}
private void retireUnusedWalletChain ( String staleWalletId ) {
jdbc . update ( "DELETE FROM wallet_bank_binding WHERE wallet_id=?" , staleWalletId ) ;
jdbc . update ( "DELETE FROM wallet_contract WHERE wallet_id=?" , staleWalletId ) ;
jdbc . update ( "DELETE FROM wallet_certificate WHERE wallet_id=?" , staleWalletId ) ;
jdbc . update ( "DELETE FROM digital_wallet WHERE wallet_id=?" , staleWalletId ) ;
}
private void ensureCertificate ( SourceWallet source ) {
List < WalletCertificate > existing = jdbc . query (
"SELECT certificate_serial,wallet_id,public_key,central_bank_root_signature " +
@ -470,9 +497,13 @@ public class WalletPrerequisiteProjectionService {
private final String userId ;
private final String walletType ;
private final String finalSignature ;
private Wallet ( String walletId , String userId , String walletType , String finalSignature ) {
private final BigDecimal balance ;
private final BigDecimal frozenAmount ;
private Wallet ( String walletId , String userId , String walletType , String finalSignature ,
BigDecimal balance , BigDecimal frozenAmount ) {
this . walletId = walletId ; this . userId = userId ;
this . walletType = walletType ; this . finalSignature = finalSignature ;
this . balance = balance ; this . frozenAmount = frozenAmount ;
}
}