doge преди 3 дни
родител
ревизия
32b4dfcb6c

+ 3 - 3
app/Constants/StepStatus.php

@@ -17,7 +17,7 @@ class StepStatus
     const CHOOSE_WITHDRAW_ADDRESS = 8;//选择 提现地址
 
     const INPUT_ADDRESS_TRC20 = 9;//输入 TRC20地址
-    const INPUT_ADDRESS_ALIAS = 10;//输入 地址别名
+    const LEGACY_INPUT_ADDRESS_ALIAS = 10;//兼容仍停留在旧步骤的会话
 
     const INPUT_JOIN_ROOM_ID = 11;//输入房间号加入房间
 
@@ -32,7 +32,7 @@ class StepStatus
     const QB_INPUT_BANK_NAME = 18;//输入 银行名称
     const QB_INPUT_CARD_NO = 19;//输入 银行卡号/支付宝账号
     const QB_INPUT_ACCOUNT = 20;//输入 姓名
-    const QB_INPUT_ALIAS = 22;//输入账号别名
+    const LEGACY_QB_INPUT_ALIAS = 22;//兼容仍停留在旧步骤的会话
 
     const INPUT_RECHARGE_SJ_MONEY = 21;//输入 三斤充值金额
 
@@ -40,4 +40,4 @@ class StepStatus
     const MY_INPUT_OLD_SECRET = 23;//输入原账号秘钥
     const MY_INPUT_SECRET_PASS = 24;//输入秘钥的查看密码
 
-}
+}

+ 0 - 5
app/Http/Controllers/api/Wallet.php

@@ -520,7 +520,6 @@ class Wallet extends BaseController
                 'bank_name' => 'nullable|string|max:255',
                 'payout_method' => 'nullable|string|in:' . implode(',', array_keys(WithdrawalDestination::MANUAL_METHODS)),
                 'qr_image' => 'nullable|string|max:255',
-                'alias' => 'nullable',
             ]);
             $member_id = request()->user->member_id;
             $destination = WithdrawalDestination::resolve($params['channel'], $params);
@@ -544,7 +543,6 @@ class Wallet extends BaseController
                     'card_no' => $destination['card_no'],
                     'bank_name' => $destination['bank_name'],
                     'qr_image' => $destination['qr_image'] ?? null,
-                    'alias' => $params['alias'] ?? '',
                 ])->save()) {
                     throw new Exception(lang('系统繁忙,请稍后重试!'));
                 }
@@ -615,14 +613,12 @@ class Wallet extends BaseController
             $params = request()->validate([
                 'id' => 'nullable|integer',
                 'address' => 'required',
-                'alias' => 'nullable',
             ]);
             $member_id = request()->user->member_id;
             if (!empty($params['id'])) {
                 $info = Address::where('id', $params['id'])->where('member_id', $member_id)->first();
                 if (empty($info)) throw new Exception(lang('找不到此记录'));
                 $info->address = $params['address'];
-                $info->alias = $params['alias'] ?? '';
                 $info->save();
             } else {
                 $count = Address::where('member_id', $member_id)->where('address', $params['address'])->count();
@@ -630,7 +626,6 @@ class Wallet extends BaseController
                 Address::create([
                     'member_id' => $member_id,
                     'address' => $params['address'],
-                    'alias' => $params['alias'] ?? '',
                 ]);
             }
 

+ 3 - 2
app/Models/Address.php

@@ -5,5 +5,6 @@ namespace App\Models;
 class Address extends BaseModel
 {
     protected $table = 'address';
-    protected $fillable = ['member_id', 'address', 'alias'];
-}
+    protected $fillable = ['member_id', 'address'];
+    protected $hidden = ['created_at', 'updated_at', 'alias'];
+}

+ 2 - 7
app/Models/Bank.php

@@ -18,7 +18,6 @@ use Laravel\Sanctum\HasApiTokens;
  * @property $bank_name
  * @property $account
  * @property $card_no
- * @property $alias
  *
  */
 class Bank extends BaseModel
@@ -26,7 +25,8 @@ class Bank extends BaseModel
 
 
     protected $table = 'banks';
-    protected $fillable = ['member_id', 'channel', 'bank_name', 'account', 'card_no', 'qr_image', 'alias'];
+    protected $fillable = ['member_id', 'channel', 'bank_name', 'account', 'card_no', 'qr_image'];
+    protected $hidden = ['created_at', 'updated_at', 'alias'];
 
     public function getId()
     {
@@ -59,11 +59,6 @@ class Bank extends BaseModel
 
     }
 
-    public function getAlias(): string
-    {
-        return $this->alias;
-    }
-
     public function getCardNo(): string
     {
         return $this->card_no;

+ 8 - 23
app/Services/QianBaoWithdrawService.php

@@ -130,7 +130,7 @@ class QianBaoWithdrawService
     public static function onMessage($chatId, $text, $messageId, $stepStatus): null|array
     {
         return match ($stepStatus) {
-            StepStatus::QB_INPUT_ALIAS => QianBaoWithdrawService::inputAliAs($chatId, $text, $messageId),
+            StepStatus::LEGACY_QB_INPUT_ALIAS => self::saveBank($chatId, $messageId, Cache::get("{$chatId}_QB_ACCOUNT")),
             StepStatus::INPUT_WITHDRAW_QB_MONEY => QianBaoWithdrawService::inputQbAmount($chatId, $text, $messageId),
             StepStatus::QB_INPUT_BANK_NAME => QianBaoWithdrawService::inputBankName($chatId, $text, $messageId),
             StepStatus::QB_INPUT_CARD_NO => QianBaoWithdrawService::inputCardNo($chatId, $text, $messageId),
@@ -220,7 +220,7 @@ class QianBaoWithdrawService
         $list = Bank::where('member_id', $chatId)->where('channel', $channel)->get();
         $keyboard = [];
         foreach ($list as $item) {
-            $keyboard[] = [['text' => $item->getAlias(), 'callback_data' => "withdrawAddress@@choose_qb_{$item->getId()}"]];
+            $keyboard[] = [['text' => $item->getCardNo(), 'callback_data' => "withdrawAddress@@choose_qb_{$item->getId()}"]];
         }
         $keyboard[] = [
             ['text' => "{$card}" . lang("管理"), 'callback_data' => "withdraw@@management_{$channel}"],
@@ -538,7 +538,7 @@ class QianBaoWithdrawService
 
         $keyboard = [];
         foreach ($list as $item) {
-            $keyboard[] = [['text' => $item->getAlias(), 'callback_data' => "withdrawAddress@@bank_detail{$item->getId()}"]];
+            $keyboard[] = [['text' => $item->getCardNo(), 'callback_data' => "withdrawAddress@@bank_detail{$item->getId()}"]];
         }
         if (count($list) < 5) {
             $keyboard[] = [
@@ -698,25 +698,10 @@ class QianBaoWithdrawService
         if ($account === '') {
             return ['chat_id' => $chatId, 'text' => lang('请输入真实姓名'), 'message_id' => $messageId];
         }
-        Cache::put("{$chatId}_QB_ACCOUNT", $account);
-        Cache::put(get_step_key($chatId), StepStatus::QB_INPUT_ALIAS);
-        $channel = Cache::get("{$chatId}_QB_WITHDRAW_CHANNEL");
-        $text = lang("请输入别名");
-        switch ($channel) {
-            case "DF005":
-            case "DF001":
-                $text = lang('请输入账号别名');
-                break;
-        }
-        return [
-            'chat_id' => $chatId,
-            'text' => $text,
-            'message_id' => $messageId,
-        ];
+        return self::saveBank($chatId, $messageId, $account);
     }
 
-    //输入别名,并保存到数据库
-    private static function inputAliAs($chatId, $alias, $messageId): array
+    private static function saveBank($chatId, $messageId, ?string $name): array
     {
         $channel = Cache::get("{$chatId}_QB_WITHDRAW_CHANNEL");
         $cardNo = Cache::get("{$chatId}_QB_WITHDRAW_CARD_NO");
@@ -724,21 +709,21 @@ class QianBaoWithdrawService
         if (!in_array($channel, ['DF001', 'DF002', 'DF005'], true)) {
             return ['chat_id' => $chatId, 'text' => lang('选择通道错误'), 'message_id' => $messageId];
         }
-        DB::transaction(function () use ($chatId, $channel, $cardNo, $bankName, $alias) {
+        DB::transaction(function () use ($chatId, $channel, $cardNo, $bankName, $name) {
             $user = User::where('member_id', $chatId)->lockForUpdate()->firstOrFail();
-            $account = WithdrawalName::bind($user, $channel, Cache::get("{$chatId}_QB_ACCOUNT"));
+            $account = WithdrawalName::bind($user, $channel, $name);
             $bank = Bank::create([
                 'member_id' => $chatId,
                 'account' => $account,
                 'channel' => $channel,
                 'card_no' => $cardNo,
                 'bank_name' => $bankName,
-                'alias' => $alias,
             ]);
             if (!$bank->exists) {
                 throw new Exception(lang('系统繁忙,请稍后重试!'));
             }
         });
+        Cache::delete("{$chatId}_QB_ACCOUNT");
         Cache::delete(get_step_key($chatId));
         return static::banks($chatId, $messageId, $channel);
     }

+ 13 - 33
app/Services/WithdrawService.php

@@ -103,8 +103,11 @@ class WithdrawService
             case StepStatus::INPUT_ADDRESS_TRC20:
                 $res = WithdrawService::inputAddress($chatId, $text, $messageId);
                 break;
-            case StepStatus::INPUT_ADDRESS_ALIAS:
-                $res = WithdrawService::inputAlias($chatId, $text, $messageId);
+            case StepStatus::LEGACY_INPUT_ADDRESS_ALIAS:
+                $address = Cache::get("{$chatId}_address");
+                $res = is_string($address) && $address !== ''
+                    ? self::inputAddress($chatId, $address, $messageId)
+                    : self::addAddress($chatId, $messageId);
                 break;
             default:
                 $res = null;
@@ -263,7 +266,6 @@ class WithdrawService
         $address = Address::where('id', $id)
             ->where('member_id', $chatId)->first();
         $text .= lang("地址") . ":{$address->address}\n";
-        $text .= lang("别名") . ":{$address->alias}";
 
         $keyboard = [
             [['text' => lang('❌删除该地址'), 'callback_data' => "withdrawAddress@@del{$id}"]],
@@ -279,27 +281,6 @@ class WithdrawService
     }
 
 
-    //输入别名
-    public static function inputAlias($chatId, $alias, $messageId)
-    {
-        if (mb_strlen($alias) > 20) {
-            return [
-                'chat_id' => $chatId,
-                'text' => lang("别名不能超过20个字,请重新输入"),
-                'reply_to_message_id' => $messageId,
-            ];
-        }
-        $address = Cache::get("{$chatId}_address");
-        $a = new Address();
-        $a->address = $address;
-        $a->alias = $alias;
-        $a->member_id = $chatId;
-        $a->save();
-        Cache::delete("{$chatId}_address");
-        Cache::delete(get_step_key($chatId));
-        return self::getAddress($chatId, $messageId);
-    }
-
     //用户输入TRC20地址
     public static function inputAddress($chatId, $address, $messageId)
     {
@@ -310,12 +291,11 @@ class WithdrawService
                 'reply_to_message_id' => $messageId,
             ];
         }
-        Cache::put("{$chatId}_address", $address);
-        Cache::put(get_step_key($chatId), StepStatus::INPUT_ADDRESS_ALIAS);
-        return [
-            'chat_id' => $chatId,
-            'text' => lang("请输入地址别名,便于区分多个地址"),
-        ];
+        Address::create(['member_id' => $chatId, 'address' => $address]);
+        Cache::delete("{$chatId}_address");
+        Cache::delete(get_step_key($chatId));
+
+        return self::getAddress($chatId, $messageId);
     }
 
     //添加地址
@@ -346,7 +326,7 @@ class WithdrawService
 
         $keyboard = [];
         foreach ($list as $item) {
-            $keyboard[] = [['text' => $item->alias, 'callback_data' => "withdrawAddress@@detail{$item->id}"]];
+            $keyboard[] = [['text' => $item->address, 'callback_data' => "withdrawAddress@@detail{$item->id}"]];
         }
         if (count($list) < 5) {
             $keyboard[] = [['text' => lang("➕ 添加地址"), 'callback_data' => "withdrawAddress@@add"]];
@@ -561,7 +541,7 @@ class WithdrawService
         $list = Address::where('member_id', $chatId)->get();
         $keyboard = [];
         foreach ($list as $item) {
-            $keyboard[] = [['text' => $item->alias, 'callback_data' => "withdrawAddress@@choose{$item->id}"]];
+            $keyboard[] = [['text' => $item->address, 'callback_data' => "withdrawAddress@@choose{$item->id}"]];
         }
         $keyboard[] = [
             ['text' => lang("🏠 地址管理"), 'callback_data' => "withdraw@@address"],
@@ -694,4 +674,4 @@ class WithdrawService
         }
 
     }
-}
+}

+ 70 - 1
tests/Integration/ApiCryptoTest.php

@@ -2,15 +2,19 @@
 
 namespace Tests\Integration;
 
+use App\Constants\StepStatus;
 use App\Http\Controllers\api\TelegramWebHook;
 use App\Services\ApiCryptoService;
+use App\Services\QianBaoWithdrawService;
 use App\Services\UserService;
+use App\Services\WithdrawService;
 use Illuminate\Contracts\Http\Kernel;
 use Illuminate\Database\Schema\Blueprint;
 use Illuminate\Foundation\Application;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\Facade;
 use Illuminate\Support\Facades\Route;
 use Illuminate\Support\Facades\Schema;
@@ -316,6 +320,63 @@ class ApiCryptoTest extends TestCase
         self::assertSame('{"code":0}', $this->send('/api/wallet/probe')->getContent());
     }
 
+    public function test_withdrawal_account_and_address_apis_ignore_and_hide_aliases(): void
+    {
+        $this->createWalletFixture();
+        $bank = $this->unwrap($this->sendEncrypted('/api/wallet/addBank', 'POST', [
+            'channel' => 'DF001', 'bank_name' => 'Fixture Bank', 'card_no' => '12345', 'account' => 'Fixture Name',
+            'alias' => 'ignored bank alias',
+        ], true));
+        self::assertSame(0, $bank['code']);
+        self::assertSame('', DB::table('banks')->value('alias'));
+        DB::table('banks')->update(['alias' => 'old bank alias']);
+        $bankList = $this->unwrap($this->sendEncrypted('/api/wallet/bankList', 'GET', (object) [], true));
+        self::assertSame('12345', $bankList['data']['list'][0]['card_no']);
+        self::assertArrayNotHasKey('alias', $bankList['data']['list'][0]);
+
+        $address = 'T' . str_repeat('A', 33);
+        $saved = $this->unwrap($this->sendEncrypted('/api/wallet/addAddress', 'POST', [
+            'address' => $address, 'alias' => 'ignored address alias',
+        ], true));
+        self::assertSame(0, $saved['code']);
+        self::assertNull(DB::table('address')->value('alias'));
+        DB::table('address')->update(['alias' => 'old address alias']);
+        $addresses = $this->unwrap($this->sendEncrypted('/api/wallet/address', 'GET', (object) [], true));
+        self::assertSame($address, $addresses['data']['list'][0]['address']);
+        self::assertArrayNotHasKey('alias', $addresses['data']['list'][0]);
+    }
+
+    public function test_telegram_saves_withdrawal_destinations_without_prompting_for_aliases(): void
+    {
+        $this->createWalletFixture();
+        Cache::put('42_QB_WITHDRAW_CHANNEL', 'DF001');
+        Cache::put('42_QB_WITHDRAW_BANK_NAME', 'Fixture Bank');
+        QianBaoWithdrawService::onMessage(42, '12345', 1, StepStatus::QB_INPUT_CARD_NO);
+        self::assertSame(StepStatus::QB_INPUT_ACCOUNT, Cache::get(get_step_key(42)));
+        $saved = QianBaoWithdrawService::onMessage(42, 'Fixture Name', 2, StepStatus::QB_INPUT_ACCOUNT);
+        $keyboard = json_decode($saved['reply_markup'], true)['inline_keyboard'];
+        self::assertSame('12345', $keyboard[0][0]['text']);
+        self::assertSame('', DB::table('banks')->where('card_no', '12345')->value('alias'));
+        self::assertNull(Cache::get(get_step_key(42)));
+
+        Cache::put('42_QB_WITHDRAW_CARD_NO', '67890');
+        Cache::put('42_QB_ACCOUNT', 'Fixture Name');
+        QianBaoWithdrawService::onMessage(42, 'ignored', 3, StepStatus::LEGACY_QB_INPUT_ALIAS);
+        self::assertSame('', DB::table('banks')->where('card_no', '67890')->value('alias'));
+
+        $address = 'T' . str_repeat('A', 33);
+        $saved = WithdrawService::onMessage(42, $address, 4, StepStatus::INPUT_ADDRESS_TRC20);
+        $keyboard = json_decode($saved['reply_markup'], true)['inline_keyboard'];
+        self::assertSame($address, $keyboard[0][0]['text']);
+        self::assertNull(Cache::get(get_step_key(42)));
+
+        $oldAddress = 'T' . str_repeat('B', 33);
+        Cache::put('42_address', $oldAddress);
+        WithdrawService::onMessage(42, 'ignored', 5, StepStatus::LEGACY_INPUT_ADDRESS_ALIAS);
+        self::assertTrue(DB::table('address')->where('address', $oldAddress)->exists());
+        self::assertSame(0, DB::table('address')->whereNotNull('alias')->count());
+    }
+
     public function test_cors_preflight_and_head(): void
     {
         Route::get('api/wallet/probe', fn () => response()->json(['code' => 0]));
@@ -509,9 +570,17 @@ class ApiCryptoTest extends TestCase
         });
         Schema::create('banks', function (Blueprint $table) {
             $table->id();
-            foreach (['member_id', 'channel', 'bank_name', 'account', 'card_no', 'alias'] as $field) {
+            foreach (['member_id', 'channel', 'bank_name', 'account', 'card_no'] as $field) {
                 $table->string($field);
             }
+            $table->string('alias')->default('');
+            $table->timestamps();
+        });
+        Schema::create('address', function (Blueprint $table) {
+            $table->id();
+            $table->string('member_id');
+            $table->string('address');
+            $table->string('alias')->nullable();
             $table->timestamps();
         });
         (require dirname(__DIR__, 2) . '/database/migrations/2026_11_06_140000_add_qr_image_to_withdrawal_destinations.php')->up();