| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- <?php
- namespace App\Module\Blockchain\Models;
- use App\Module\Blockchain\Enums\TokenType;
- use Illuminate\Database\Eloquent\Model;
- use Illuminate\Database\Eloquent\Relations\HasMany;
- use Illuminate\Support\Facades\DB;
- use InvalidArgumentException;
- use Illuminate\Support\Facades\Cache;
- class BlockchainWallet extends Model
- {
- protected $table = 'blockchain_wallets';
- protected $fillable = [
- 'address',
- 'type',
- 'balance',
- 'balance_updated_at',
- 'status'
- ];
- protected $casts = [
- 'type' => TokenType::class,
- 'balance' => 'decimal:18',
- 'balance_updated_at' => 'datetime',
- 'status' => 'boolean'
- ];
- protected static function booted()
- {
- static::creating(function ($wallet) {
- if (!preg_match('/^0x[a-fA-F0-9]{40}$/', $wallet->address)) {
- throw new InvalidArgumentException('Invalid wallet address format');
- }
- });
- static::updating(function ($wallet) {
- if ($wallet->isDirty('balance')) {
- $wallet->balance_updated_at = now();
- }
- });
- }
- /**
- * 更新钱包余额
- * @param float $newBalance 新余额
- * @param array|null $syncData 同步数据
- */
- public function updateBalance(float $newBalance, ?array $syncData = null): void
- {
- DB::transaction(function () use ($newBalance, $syncData) {
- // 获取原始余额
- $oldBalance = $this->balance;
- // 更新钱包余额
- DB::table($this->table)
- ->where('id', $this->id)
- ->lockForUpdate()
- ->update([
- 'balance' => $newBalance,
- 'balance_updated_at' => now()
- ]);
- // 刷新模型
- $this->refresh();
- // 记录余额变更
- $logData = [
- 'wallet_id' => $this->id,
- 'old_balance' => $oldBalance,
- 'new_balance' => $newBalance,
- 'change_type' => 2, // 2=同步
- 'created_at' => now()
- ];
- // 如果有同步数据,添加到日志
- if ($syncData) {
- $logData['sync_block_number'] = $syncData['block_number'] ?? null;
- $logData['sync_tx_hash'] = $syncData['tx_hash'] ?? null;
- $logData['sync_timestamp'] = $syncData['timestamp'] ?? null;
- $logData['sync_data'] = json_encode($syncData);
- }
- DB::table('blockchain_wallet_balance_logs')->insert($logData);
- // 清除缓存
- $this->clearBalanceCache();
- });
- }
- public function transactions(): HasMany
- {
- return $this->hasMany(BlockchainTransaction::class, 'from_address', 'address');
- }
- public function receivedTransactions(): HasMany
- {
- return $this->hasMany(BlockchainTransaction::class, 'to_address', 'address');
- }
- public function getCachedBalance(): float
- {
- $cacheKey = "wallet_balance_{$this->address}_{$this->type->value}";
- return Cache::remember($cacheKey, config('blockchain.cache.balance_ttl', 300), function () {
- return $this->balance;
- });
- }
- /**
- * 清除余额缓存
- */
- protected function clearBalanceCache(): void
- {
- $cacheKey = "wallet_balance_{$this->address}_{$this->type->value}";
- Cache::forget($cacheKey);
- }
- }
|