fix(mobile-app): 修复多账号切换后账号列表只显示一个的问题

- phone_login_page: 登录成功后添加账号到多账号列表
- import_mnemonic_page: 恢复账号后添加到多账号列表
- sms_verify_page: 短信验证登录后添加账号到多账号列表

问题原因:多个登录入口没有调用 addAccount() 将账号添加到列表

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2025-12-27 11:12:50 -08:00
parent a8261e110a
commit 1694f37e91
7 changed files with 364 additions and 1 deletions

View File

@ -428,7 +428,19 @@
"Bash(dir /b \"c:\\\\Users\\\\dong\\\\Desktop\\\\rwadurian\")", "Bash(dir /b \"c:\\\\Users\\\\dong\\\\Desktop\\\\rwadurian\")",
"Bash(git commit -m \"$\\(cat <<''EOF''\nfix\\(reward-service\\): 权益分配memo显示触发用户ID\n\n所有权益类型的memo现在统一显示\"来自用户xxx的认种\"格式:\n- 省团队权益来自用户xxx的认种\n- 省区域权益来自用户xxx的认种\n- 市团队权益来自用户xxx的认种\n- 市区域权益来自用户xxx的认种\n- 社区权益来自用户xxx的认种\n\n修改前只显示\"xx权益已激活\",现在与分享权益格式保持一致\n\n🤖 Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")", "Bash(git commit -m \"$\\(cat <<''EOF''\nfix\\(reward-service\\): 权益分配memo显示触发用户ID\n\n所有权益类型的memo现在统一显示\"来自用户xxx的认种\"格式:\n- 省团队权益来自用户xxx的认种\n- 省区域权益来自用户xxx的认种\n- 市团队权益来自用户xxx的认种\n- 市区域权益来自用户xxx的认种\n- 社区权益来自用户xxx的认种\n\n修改前只显示\"xx权益已激活\",现在与分享权益格式保持一致\n\n🤖 Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
"Bash(echo \"请运行以下命令查看 D25122600005 的认种记录:\n\ndocker exec -it rwa-postgres psql -U rwa_user -d rwa_planting -c \"\"\nSELECT order_no, account_sequence, tree_count, status, created_at\nFROM planting_orders\nWHERE account_sequence = ''D25122600005''\nORDER BY created_at DESC;\n\"\"\")", "Bash(echo \"请运行以下命令查看 D25122600005 的认种记录:\n\ndocker exec -it rwa-postgres psql -U rwa_user -d rwa_planting -c \"\"\nSELECT order_no, account_sequence, tree_count, status, created_at\nFROM planting_orders\nWHERE account_sequence = ''D25122600005''\nORDER BY created_at DESC;\n\"\"\")",
"Bash(git commit -m \"$\\(cat <<''EOF''\nfix\\(wallet-service\\): 修复社区权益根据 targetId 正确分配\n\n问题社区权益\\(COMMUNITY_RIGHT\\)无论 targetId 是什么,都强制分配到\n总部账户 S0000000001导致社区授权人无法在流水明细中看到社区权益。\n\n修复\n- 将 allocateToHeadquartersCommunity 方法重命名为 allocateCommunityRight\n- 根据 targetId 判断分配目标:\n - D 开头(用户账户): 分配到社区授权人账户\n - S 开头或 ''1''(系统账户): 分配到总部社区账户\n- 更新流水备注以区分用户分配和总部分配\n\n🤖 Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")" "Bash(git commit -m \"$\\(cat <<''EOF''\nfix\\(wallet-service\\): 修复社区权益根据 targetId 正确分配\n\n问题社区权益\\(COMMUNITY_RIGHT\\)无论 targetId 是什么,都强制分配到\n总部账户 S0000000001导致社区授权人无法在流水明细中看到社区权益。\n\n修复\n- 将 allocateToHeadquartersCommunity 方法重命名为 allocateCommunityRight\n- 根据 targetId 判断分配目标:\n - D 开头(用户账户): 分配到社区授权人账户\n - S 开头或 ''1''(系统账户): 分配到总部社区账户\n- 更新流水备注以区分用户分配和总部分配\n\n🤖 Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
"Bash(git commit -m \"$\\(cat <<''EOF''\nfeat\\(mobile-app\\): 优化流水明细筛选选项\n\n- 将\"奖励转可结算\"改为\"分享收益\",更准确描述分享权益\n- 新增\"权益收入\"筛选项\\(SYSTEM_ALLOCATION\\),用于筛选:\n - 社区权益\n - 市/省团队权益\n - 市/省区域权益\n\n🤖 Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
"Bash(chcp 65001)",
"Bash(cmd /c \"chcp 65001 && python -c \"\"import openpyxl; import sys; sys.stdout.reconfigure\\(encoding=''utf-8''\\); wb = openpyxl.load_workbook\\(r''c:\\\\Users\\\\dong\\\\Desktop\\\\rwadurian\\\\榴莲皇后数据.xlsx''\\); print\\(''Sheets:'', wb.sheetnames\\); sheet = wb.active; print\\(''Rows:'', sheet.max_row, ''Cols:'', sheet.max_column\\); [print\\(f''Row {i}:'', row\\) for i, row in enumerate\\(sheet.iter_rows\\(max_row=5, values_only=True\\), 1\\)]\"\"\")",
"Bash(node scripts/batch-register.js:*)",
"Bash(node batch-register.js:*)",
"Bash(git commit -m \"$\\(cat <<''EOF''\nfeat\\(mobile-app\\): 隐藏\"我的团队\"功能,需秘密点击解锁\n\n- 默认隐藏\"我的团队\"树形组件\n- 在\"团队种植数\"区域连续点击19次后显示\n- 点击间隔超过1秒自动重置计数器\n- 退出页面后状态自动重置\n\n🤖 Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
"Bash(git commit -m \"$\\(cat <<''EOF''\nrefactor\\(mobile-app\\): 修改\"我的\"页面文案\n\n- \"直推人数\" → \"引荐\"\n- \"个人种植数\" → \"个人种植树\"\n- \"团队种植数\" → \"团队种植树\"\n- \"直推列表\" → \"引荐列表\"\n\n🤖 Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
"Bash(git commit -m \"$\\(cat <<''EOF''\nrefactor\\(mobile-app\\): 修改\"我的团队\"文案为\"我的同僚\"\n\n- \"我的团队\" → \"我的同僚\"\n- \"暂无团队成员\" → \"暂无同僚\"\n\n🤖 Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
"Bash(npx jest --testPathPattern=\"referral\" --passWithNoTests)",
"Bash(npx jest --testPathPattern=\"wallet\" --passWithNoTests)",
"Bash(git commit -m \"$\\(cat <<''EOF''\nrefactor\\(mobile-app\\): 修改\"我的\"页面文案\n\n- \"个人种植树\" → \"本人种植树\"\n- 引荐列表中 \"个人/团队\" → \"本人/同僚\"\n\n🤖 Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
"Bash(git commit -m \"$\\(cat <<''EOF''\nfeat\\(identity-service\\): 增强钱包生成可靠性确保100%生成成功\n\n核心改进\n- 基于数据库扫描代替Redis扫描防止状态丢失后无法重试\n- 指数退避策略\\(1分钟→60分钟\\),无时间限制持续重试\n- 分布式锁保护,防止多实例/并发重复触发\n- getWalletStatus API 检测失败状态并自动触发重试\n\n修改内容\n- RedisService: 添加 tryLock/unlock 分布式锁方法\n- UserAccountRepository: 添加 findUsersWithIncompleteWallets 查询\n- getWalletStatus: 增强状态检测,失败/超时时自动触发重试\n- WalletRetryTask: 完全重写,基于数据库驱动+指数退避\n\n🤖 Generated with [Claude Code]\\(https://claude.com/claude-code\\)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")"
], ],
"deny": [], "deny": [],
"ask": [] "ask": []

View File

@ -0,0 +1,184 @@
[
{
"i": 1,
"phone": "14052927714",
"seq": "D25122700001",
"code": "PHQZKV",
"inviter": "SEED01",
"wallet": {
"kava": "0x345b8839b942f841e76ee103b4c7089d704acbfd",
"dst": "dst1u5dmj4h3u087mlc36r5njx24eqmq5m20nc2r9t",
"bsc": "0x345b8839b942f841e76ee103b4c7089d704acbfd"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMCIsImFjY291bnRTZXF1ZW5jZSI6IkQyNTEyMjcwMDAwMSIsImRldmljZUlkIjoiZGV2LTE3NjY3NzcyODU3NjQiLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNzY2Nzc3Mjg2LCJleHAiOjE3NjY3ODQ0ODZ9.KV34psoB-uig1wiSUsKG9mE1BVNOBMTaxq7wwXk46r4"
},
{
"i": 2,
"phone": "18027595478",
"seq": "D25122700002",
"code": "JUEG1A",
"inviter": "PHQZKV",
"wallet": {
"kava": "0xe4c66acff372d084433984228773ad07932f8205",
"dst": "dst18etce0jkll3kfs8fxj5e6tneqlnx9cmx5l8wzz",
"bsc": "0xe4c66acff372d084433984228773ad07932f8205"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMSIsImFjY291bnRTZXF1ZW5jZSI6IkQyNTEyMjcwMDAwMiIsImRldmljZUlkIjoiZGV2LTE3NjY3NzczMTY3NjIiLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNzY2Nzc3MzE3LCJleHAiOjE3NjY3ODQ1MTd9.5_PF-8of02cPrXqrHWk67eHW77Nr6vBtvNONDs2_eUo"
},
{
"i": 3,
"phone": "17862239357",
"seq": "D25122700003",
"code": "DVRBF0",
"inviter": "JUEG1A",
"wallet": {
"kava": "0x3ff86b1f8e81df00e680fccaa075cce3853864a6",
"dst": "dst1umw0d6ncxwqy2072jmtwc5fcd69sczsrju5eeq",
"bsc": "0x3ff86b1f8e81df00e680fccaa075cce3853864a6"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMiIsImFjY291bnRTZXF1ZW5jZSI6IkQyNTEyMjcwMDAwMyIsImRldmljZUlkIjoiZGV2LTE3NjY3NzczNDEyNDIiLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNzY2Nzc3MzQxLCJleHAiOjE3NjY3ODQ1NDF9.H6oQNKoV9LVdP-2tEEzfgj0ShThQqcs9hgUjrAumD6I"
},
{
"i": 4,
"phone": "19297857036",
"seq": "D25122700004",
"code": "2UEPMU",
"inviter": "DVRBF0",
"wallet": {
"kava": "0x0f533a8c69d4217c66cb6c971d8e40fb2fcdda75",
"dst": "dst1cxjk6hwnftegk45h0xzsjlrruqgwvxjsh65wg7",
"bsc": "0x0f533a8c69d4217c66cb6c971d8e40fb2fcdda75"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMyIsImFjY291bnRTZXF1ZW5jZSI6IkQyNTEyMjcwMDAwNCIsImRldmljZUlkIjoiZGV2LTE3NjY3NzczNzA3MDMiLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNzY2Nzc3MzcxLCJleHAiOjE3NjY3ODQ1NzF9.2LUwgMITQvohGzloegEFpNWfKb8DCtrIVy6xTyBzn-8"
},
{
"i": 5,
"phone": "15320937126",
"seq": "D25122700005",
"code": "5J8V3C",
"inviter": "2UEPMU",
"wallet": {
"kava": "0xde2b2fbf8a4c9a1b10a9b6a16978eafa2737538e",
"dst": "dst18sdgdrmvnwhh2sdq4dswhw3lmhjcqp4gwdhf26",
"bsc": "0xde2b2fbf8a4c9a1b10a9b6a16978eafa2737538e"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxNCIsImFjY291bnRTZXF1ZW5jZSI6IkQyNTEyMjcwMDAwNSIsImRldmljZUlkIjoiZGV2LTE3NjY3Nzc0NDg1NzIiLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNzY2Nzc3NDQ5LCJleHAiOjE3NjY3ODQ2NDl9.HzJWZWEmUoXlPJ6A5IMrGKslWfKcVpIQY_PSdNrPKE4"
},
{
"i": 6,
"phone": "19355687135",
"seq": "D25122700006",
"code": "3O9FCJ",
"inviter": "5J8V3C",
"wallet": {
"kava": "0x0c2ca44714fefb4071b7edd9809824cb3647cff8",
"dst": "dst1nt2au5cjl97kysgejjqnph77zh95ll23jgga7z",
"bsc": "0x0c2ca44714fefb4071b7edd9809824cb3647cff8"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxNSIsImFjY291bnRTZXF1ZW5jZSI6IkQyNTEyMjcwMDAwNiIsImRldmljZUlkIjoiZGV2LTE3NjY3Nzc1MjYyMzciLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNzY2Nzc3NTI2LCJleHAiOjE3NjY3ODQ3MjZ9.m-F-CK8U4eO5WYCljq0r3AOqvaxgEebp1is6DuYFVQg"
},
{
"i": 7,
"phone": "18059815900",
"seq": "D25122700007",
"code": "4RQGK4",
"inviter": "3O9FCJ",
"wallet": {
"kava": "0x604853c11307a1eed056ab740dd8b4739d57deb3",
"dst": "dst1pwjr4xeayfn04et6lqxhltn84ck52rl033vkxr",
"bsc": "0x604853c11307a1eed056ab740dd8b4739d57deb3"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxNiIsImFjY291bnRTZXF1ZW5jZSI6IkQyNTEyMjcwMDAwNyIsImRldmljZUlkIjoiZGV2LTE3NjY3Nzc1NTcxODIiLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNzY2Nzc3NTU3LCJleHAiOjE3NjY3ODQ3NTd9.I3S5R52fgzVf7nLbYrXZw3-WQBY_RYdrBLYsCPiyxaQ"
},
{
"i": 8,
"phone": "18476247786",
"seq": "D25122700008",
"code": "GO0DHS",
"inviter": "4RQGK4",
"wallet": {
"kava": "0xd97f33f0507fd94ee6aed4631193becb5400d47f",
"dst": "dst190dxd7cn0cq6mjrtetzn7cfh0muyv5h7ess6xp",
"bsc": "0xd97f33f0507fd94ee6aed4631193becb5400d47f"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxNyIsImFjY291bnRTZXF1ZW5jZSI6IkQyNTEyMjcwMDAwOCIsImRldmljZUlkIjoiZGV2LTE3NjY3Nzc1ODE2MjEiLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNzY2Nzc3NTgyLCJleHAiOjE3NjY3ODQ3ODJ9.8xgV-o-9fUVDtktks0acjRlZpTZ6KjZqH7nKBgYIkpQ"
},
{
"i": 9,
"phone": "14264197292",
"seq": "D25122700009",
"code": "PQZEYG",
"inviter": "GO0DHS",
"wallet": {
"kava": "0xce1b26b410e53c7d278633058f325f8b975adf15",
"dst": "dst16sksskyr5fv9r0j900un9kvqzjyl207nfklewe",
"bsc": "0xce1b26b410e53c7d278633058f325f8b975adf15"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxOCIsImFjY291bnRTZXF1ZW5jZSI6IkQyNTEyMjcwMDAwOSIsImRldmljZUlkIjoiZGV2LTE3NjY3Nzc2MTI1MzQiLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNzY2Nzc3NjEzLCJleHAiOjE3NjY3ODQ4MTN9.mtx2xe8pGDNEAHcj5etePV74qWq5rIZndu32LAaJTRM"
},
{
"i": 10,
"phone": "13214866463",
"seq": "D25122700010",
"code": "W8FP57",
"inviter": "PQZEYG",
"wallet": {
"kava": "0xc47e127874232ab99456d4b04d2ada0834d6f850",
"dst": "dst1y0acpufm7w0gcf8nulw7ukz6guf8zd7dypxrap",
"bsc": "0xc47e127874232ab99456d4b04d2ada0834d6f850"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxOSIsImFjY291bnRTZXF1ZW5jZSI6IkQyNTEyMjcwMDAxMCIsImRldmljZUlkIjoiZGV2LTE3NjY3Nzc2NDM0NTYiLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNzY2Nzc3NjQzLCJleHAiOjE3NjY3ODQ4NDN9.HxJIUnUJLUq67D-AXLAkjIvT4E9iOgq4TYSXq07wE58"
},
{
"i": 11,
"phone": "18420065907",
"seq": "D25122700011",
"code": "WEGSDK",
"inviter": "W8FP57",
"wallet": {
"kava": "0x8ffe3fdb54c1af21bcd5df17667fd09f6487f9f2",
"dst": "dst1ujjydyar0l0d8krp7mxfvf5g47m0m2gdw4v5tk",
"bsc": "0x8ffe3fdb54c1af21bcd5df17667fd09f6487f9f2"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIyMCIsImFjY291bnRTZXF1ZW5jZSI6IkQyNTEyMjcwMDAxMSIsImRldmljZUlkIjoiZGV2LTE3NjY3Nzc2NjU2MzMiLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNzY2Nzc3NjY2LCJleHAiOjE3NjY3ODQ4NjZ9.8s-NKcmkZF5nM6TvqWAFEa6LukM6Ov6tR2dQedt48tg"
},
{
"i": 12,
"phone": "19542401963",
"seq": "D25122700012",
"code": "SLN8Y7",
"inviter": "WEGSDK",
"wallet": {
"kava": "0x01d7f0eec627c24ea72ed0a3c1ba87528dc6b265",
"dst": "dst1wd30zj03z2emqhpzewrwnm70p6c8ll56z2f8av",
"bsc": "0x01d7f0eec627c24ea72ed0a3c1ba87528dc6b265"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIyMSIsImFjY291bnRTZXF1ZW5jZSI6IkQyNTEyMjcwMDAxMiIsImRldmljZUlkIjoiZGV2LTE3NjY3Nzc2OTY2MDIiLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNzY2Nzc3Njk3LCJleHAiOjE3NjY3ODQ4OTd9.TlZ3e8A3Zwl0ORdetLSGAD8ZxfqVQiGAHaiarSvgyCs"
},
{
"i": 13,
"phone": "16807660295",
"seq": "D25122700013",
"code": "HZXFFL",
"inviter": "SLN8Y7",
"wallet": {
"kava": "0xab334497c564518990c73e6ae450802ab815c0c2",
"dst": "dst1ypl3cf38zs5dwdfxjgg006m2f7zcj6mqkf8ktc",
"bsc": "0xab334497c564518990c73e6ae450802ab815c0c2"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIyMiIsImFjY291bnRTZXF1ZW5jZSI6IkQyNTEyMjcwMDAxMyIsImRldmljZUlkIjoiZGV2LTE3NjY3Nzc3Mjc1ODMiLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNzY2Nzc3NzI4LCJleHAiOjE3NjY3ODQ5Mjh9.e6vhB7NudLxARynW8XwGcHGeZnEufSBafPTsgiXALKo"
},
{
"i": 14,
"phone": "19266490703",
"seq": "D25122700014",
"code": "4RTM9B",
"inviter": "HZXFFL",
"wallet": {
"kava": "0xd259dbd13804f587d9c158b4053ab950af92d12c",
"dst": "dst16ue0dkca0jt5ceu3v4865f07lfyvxku4n63dl3",
"bsc": "0xd259dbd13804f587d9c158b4053ab950af92d12c"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIyMyIsImFjY291bnRTZXF1ZW5jZSI6IkQyNTEyMjcwMDAxNCIsImRldmljZUlkIjoiZGV2LTE3NjY3Nzc3NTg1NDEiLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNzY2Nzc3NzU5LCJleHAiOjE3NjY3ODQ5NTl9.G8phCWhNiNycZ4FhXpTLT0u07H_FTtP23Tj-V8hf8eQ"
}
]

View File

@ -0,0 +1,85 @@
/**
* 批量注册账号脚本
*
* node batch-register.js [数量] [初始推荐码]
*
* 输出保存到当前目录 accounts.json
*/
const fs = require('fs');
const path = require('path');
const COUNT = parseInt(process.argv[2]) || 14;
const START_CODE = process.argv[3] || 'SEED01';
const API = 'https://rwaapi.szaiai.com/api/v1';
const PASSWORD = 'Test123456';
const OUTPUT_FILE = path.join(__dirname, 'accounts.json');
function randomPhone() {
return '1' + (Math.floor(Math.random() * 7) + 3) + Array(9).fill(0).map(() => Math.floor(Math.random() * 10)).join('');
}
async function waitWallet(token) {
for (let i = 0; i < 30; i++) {
const res = await fetch(`${API}/user/wallet`, {
headers: { 'Authorization': `Bearer ${token}` }
});
if (res.ok) {
const d = (await res.json()).data;
if (d?.status?.toUpperCase() === 'READY') return d.walletAddresses;
}
process.stdout.write('.');
await new Promise(r => setTimeout(r, 2000));
}
return null; // 超时返回null不抛错
}
async function register(code, i) {
const phone = randomPhone();
console.log(`\n[${i}] ${phone} <- ${code}`);
const res = await fetch(`${API}/user/register-without-sms-verify`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
phoneNumber: phone,
password: PASSWORD,
deviceId: `dev-${Date.now()}`,
inviterReferralCode: code
})
});
if (!res.ok) throw new Error(await res.text());
const d = (await res.json()).data;
console.log(` -> ${d.userSerialNum} | ${d.referralCode}`);
process.stdout.write(' 钱包');
const wallet = await waitWallet(d.accessToken);
console.log(wallet ? ' OK' : ' 超时');
return { i, phone, seq: d.userSerialNum, code: d.referralCode, inviter: code, wallet, token: d.accessToken };
}
async function main() {
console.log(`注册 ${COUNT} 个账号,起始码: ${START_CODE}\n`);
const list = [];
let code = START_CODE;
for (let i = 1; i <= COUNT; i++) {
if (i > 1) {
console.log('\n等待10秒...');
await new Promise(r => setTimeout(r, 10000));
}
const acc = await register(code, i);
list.push(acc);
code = acc.code;
fs.writeFileSync(OUTPUT_FILE, JSON.stringify(list, null, 2));
}
console.log(`\n完成,最后推荐码: ${code}`);
console.log(`保存到: ${OUTPUT_FILE}`);
}
main();

View File

@ -3,6 +3,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import '../../../../core/di/injection_container.dart'; import '../../../../core/di/injection_container.dart';
import '../../../../core/services/multi_account_service.dart';
import '../../../../routes/route_paths.dart'; import '../../../../routes/route_paths.dart';
/// - /// -
@ -104,6 +105,21 @@ class _ImportMnemonicPageState extends ConsumerState<ImportMnemonicPage> {
if (!mounted) return; if (!mounted) return;
//
final multiAccountService = ref.read(multiAccountServiceProvider);
await multiAccountService.addAccount(
AccountSummary(
userSerialNum: response.userSerialNum,
username: response.username,
avatarSvg: response.avatarSvg,
createdAt: DateTime.now(),
),
);
await multiAccountService.setCurrentAccountId(response.userSerialNum);
debugPrint('[ImportMnemonicPage] 已添加到多账号列表');
if (!mounted) return;
// //
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(

View File

@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import '../../../../core/di/injection_container.dart'; import '../../../../core/di/injection_container.dart';
import '../../../../core/services/multi_account_service.dart';
import '../../../../routes/route_paths.dart'; import '../../../../routes/route_paths.dart';
import '../providers/auth_provider.dart'; import '../providers/auth_provider.dart';
@ -104,6 +105,38 @@ class _PhoneLoginPageState extends ConsumerState<PhoneLoginPage> {
debugPrint('[PhoneLoginPage] 登录成功 - accountSequence: ${response.accountSequence}'); debugPrint('[PhoneLoginPage] 登录成功 - accountSequence: ${response.accountSequence}');
if (!mounted) return;
//
try {
final profile = await accountService.getMyProfile();
final multiAccountService = ref.read(multiAccountServiceProvider);
await multiAccountService.addAccount(
AccountSummary(
userSerialNum: response.accountSequence,
username: profile['nickname'] as String? ?? '用户${response.accountSequence}',
avatarSvg: profile['avatarSvg'] as String?,
avatarUrl: profile['avatarUrl'] as String?,
createdAt: DateTime.now(),
),
);
await multiAccountService.setCurrentAccountId(response.accountSequence);
debugPrint('[PhoneLoginPage] 已添加到多账号列表');
} catch (e) {
debugPrint('[PhoneLoginPage] 获取用户资料失败,使用默认信息: $e');
// 使使
final multiAccountService = ref.read(multiAccountServiceProvider);
await multiAccountService.addAccount(
AccountSummary(
userSerialNum: response.accountSequence,
username: '用户${response.accountSequence}',
createdAt: DateTime.now(),
),
);
await multiAccountService.setCurrentAccountId(response.accountSequence);
}
if (mounted) { if (mounted) {
// //
await ref.read(authProvider.notifier).checkAuthStatus(); await ref.read(authProvider.notifier).checkAuthStatus();

View File

@ -6,6 +6,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import '../../../../core/di/injection_container.dart'; import '../../../../core/di/injection_container.dart';
import '../../../../core/services/account_service.dart'; import '../../../../core/services/account_service.dart';
import '../../../../core/services/multi_account_service.dart';
import '../../../../routes/route_paths.dart'; import '../../../../routes/route_paths.dart';
import 'set_password_page.dart'; import 'set_password_page.dart';
@ -221,6 +222,38 @@ class _SmsVerifyPageState extends ConsumerState<SmsVerifyPage> {
if (!mounted) return; if (!mounted) return;
//
try {
final profile = await accountService.getMyProfile();
final multiAccountService = ref.read(multiAccountServiceProvider);
await multiAccountService.addAccount(
AccountSummary(
userSerialNum: response.accountSequence,
username: profile['nickname'] as String? ?? '用户${response.accountSequence}',
avatarSvg: profile['avatarSvg'] as String?,
avatarUrl: profile['avatarUrl'] as String?,
createdAt: DateTime.now(),
),
);
await multiAccountService.setCurrentAccountId(response.accountSequence);
debugPrint('[SmsVerifyPage] 已添加到多账号列表');
} catch (e) {
debugPrint('[SmsVerifyPage] 获取用户资料失败,使用默认信息: $e');
// 使使
final multiAccountService = ref.read(multiAccountServiceProvider);
await multiAccountService.addAccount(
AccountSummary(
userSerialNum: response.accountSequence,
username: '用户${response.accountSequence}',
createdAt: DateTime.now(),
),
);
await multiAccountService.setCurrentAccountId(response.accountSequence);
}
if (!mounted) return;
// //
context.go(RoutePaths.mining); context.go(RoutePaths.mining);
} }

BIN
榴莲皇后数据.xlsx Normal file

Binary file not shown.