Appearance
登入與注冊
最後更新:2026-04-09
功能說明
提供使用者帳號密碼登入、手機驗證碼登入、新用戶注冊、忘記密碼找回、Face ID 生物辨識快速登入等功能。未登入狀態下可以「隨便逛逛」進入 App 瀏覽,也可直接聯繫客服。登入後自動恢復上次的個人設定(賠率偏好、推播設定等)。
使用者流程
登入流程
- 進入 App,若 token 過期或手動登出,自動彈出登入頁(全螢幕覆蓋)
- 頁面頂部顯示背景圖,底部有帳號/密碼輸入區(
LoginView) - 使用者可切換「帳號密碼」或「手機驗證碼」登入方式(
STTabSelectView) - 帳號密碼登入:輸入帳號 + 密碼,點擊登入
- 手機驗證碼登入:輸入手機號,點擊取得驗證碼,輸入驗證碼
- 登入成功 →
IFLoginService.setUpChangeWindows()刷新主視窗 - 若曾開啟 Face ID,3小時內未操作則改用 Face ID 驗證
自動登入邏輯
- 條件:已勾選「記住密碼」+ 非手機登入 + 有本地帳號密碼
- 在 3 小時內:直接使用本地帳密靜默重新登入
- 超過 3 小時:觸發 Face ID 驗證(若已開啟),否則彈出登入頁
注冊流程
- 登入頁點擊「立即注冊」→ 跳轉至
RegisterViewController - 填寫使用者名稱 + 密碼
- 可選填設置暱稱、頭像
- 注冊成功後可開啟 Face ID 設定(
BBSetFaceIDViewController)
找回密碼
- 點擊「忘記密碼」或底部「聯繫客服 > 自助找回密碼」
FindPasswordViewController→ 輸入手機號 →SendMessageViewController發送驗證碼- 驗證通過後進入
ChangePaawordViewController設置新密碼
訪客模式(隨便逛逛)
- 登入頁底部左側顯示「隨便逛逛」按鈕(
guangGuangBtn),帶有圖示troll_around - 點擊後直接呼叫
IFLoginService.setUpChangeWindows()關閉登入頁,進入主畫面 - 訪客狀態下
IFUserModel.isLoginThisPlatform = false,可瀏覽 App 但無法進行需登入的操作(投注、充值等) - 關閉登入頁時若非已登入狀態,
isManualLoginOut設為true
頁面跳轉
- 登入頁底部「立即注冊」→
RegisterViewController - 登入頁底部「忘記密碼」→
FindPasswordViewController FindPasswordViewController→SendMessageViewController→ChangePaawordViewController- 注冊成功 →
BBSetFaceIDViewController(Face ID 設定) - 登入成功 → 主視窗刷新(
IFLoginService.setUpChangeWindows()) - 「隨便逛逛」→ 關閉登入頁進入主視窗
技術視角(開發看這裡)
相關檔案
| 類型 | 檔案路徑 |
|---|---|
| ViewController(登入) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Login/C/STLoginViewController.swift |
| ViewController(注冊) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Register/C/RegisterViewController.swift |
| ViewController(找回密碼) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/FindPassword/C/FindPasswordViewController.swift |
| ViewController(修改密碼) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/FindPassword/C/ChangePaawordViewController.swift |
| ViewController(發送驗證碼) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/FindPassword/C/SendMessageViewController.swift |
| ViewController(綁定帳號) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Login/C/BindingAccountViewController.swift |
| ViewController(設定帳號) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Login/C/SetAccountViewController.swift |
| ViewController(Face ID 設定) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Register/C/BBSetFaceIDViewController.swift |
| Service(登入管理) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Manager/STLoginManager.swift |
| Service(登入 UI) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Manager/STNewLoginUIManager.swift |
| Service(客服) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Manager/CustomerChatManager.swift |
| Service(OC 登入核心) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/IFLoginService.m |
| Service(OC 模組路由) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/ModuleApi.m |
| Service(HTTP 請求橋接) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Helpers/HttpService.swift |
| Helper(帳號儲存) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/SavedAccountManager.swift |
| Helper(常數定義) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Manager/BBNewCommonConstant.swift |
| View(登入主視圖) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Login/V/LoginView.swift |
| View(帳號密碼輸入) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Login/V/LoginUserNameView.swift |
| View(手機驗證碼輸入) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Login/V/LoginPhoneCodeView.swift |
| View(帳號列表) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Login/V/MLAllUserNameView.swift |
| ViewController(維護模式) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Maind/BBMaintain/BBMaintainViewController.swift |
| API(帳密登入) | /Users/user/Work/bbsport-new/BBSport/API/STAPI/User/Login/STAPI+UsernameLoginRequest.swift |
| API(登入二次驗證) | /Users/user/Work/bbsport-new/BBSport/API/STAPI/User/Login/STAPI+LoginCheckRequest.swift |
| API(心跳) | /Users/user/Work/bbsport-new/BBSport/API/STAPI/User/Login/STAPI+LoginHeartbeatRequest.swift |
| API(驗證碼 ID) | /Users/user/Work/bbsport-new/BBSport/API/STAPI/User/Login/STAPI+LoginCaptchaIdRequest.swift |
| API(體驗金) | /Users/user/Work/bbsport-new/BBSport/API/STAPI/User/Login/STAPI+ExperienceCashRequest.swift |
| API(更新登入紀錄) | /Users/user/Work/bbsport-new/BBSport/API/STAPI/User/Login/STAPI+UpdateLoginRecordRequest.swift |
| API(重發二次驗證碼) | /Users/user/Work/bbsport-new/BBSport/API/STAPI/STAPI+ResendLoginRequest.swift |
| 路由註冊 Header(OC) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/ModuleApi.h |
| View(登入基礎視圖) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Login/V/LoginBaseView.swift |
| View(帳號 Cell) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Login/V/MLUsernameTableViewCell.swift |
| View(登入背景播放器) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Login/V/BBLoginAvPlayer.swift |
| ViewController(找回密碼基類) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/FindPassword/C/BaseRegisterViewController.swift |
| ViewController(設定暱稱) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Register/C/RegSetNickNameViewController.swift |
| View(注冊主視圖) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Register/V/RegisterView.swift |
| View(帳號密碼注冊) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Register/V/RegisterByUserNameView.swift |
| View(設定帳密視圖) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Register/V/SetUserNameAndPasswordView.swift |
| View(設定頭像暱稱) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Register/V/SetHeadImageAndNickNameView.swift |
| View(注冊成功基礎) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Register/V/RegSuccessSetBaseView.swift |
| View(頭像選擇器) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Maind/BBInfoAvatarPicker.swift |
| ViewModel(頭像選擇器) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Maind/BBInfoAvatarPickerViewModel.swift |
| Model(頭像 Cell) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Maind/BBLoginInfoAvatarImageCellModel.swift |
| View(Tab 切換) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Maind/STTabSelectView.swift |
| View(倒計時按鈕) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Maind/STNewTimeButton.swift |
| View(訊息提示) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Manager/BBShowMessageView.swift |
| View(裝置資訊) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Maind/DeviceInformationView.swift |
| WebView(登入內嵌) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Maind/BBNewBackWebViewController.swift |
| 網路偵測 Header(OC) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Maind/ErrorInternetVC/InternetManager.h |
| 網路偵測實作(OC) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Maind/ErrorInternetVC/InternetManager.m |
| 網路錯誤頁 Header(OC) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Maind/ErrorInternetVC/NetErrorViewController.h |
| 網路錯誤頁實作(OC) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Maind/ErrorInternetVC/NetErrorViewController.m |
| 網路可達性 Header(OC) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Maind/ErrorInternetVC/Reachability.h |
| 網路可達性實作(OC) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Maind/ErrorInternetVC/Reachability.m |
| UI 工廠 Header(OC) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Manager/BBLoginUIFactory.h |
| UI 工廠實作(OC) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Manager/BBLoginUIFactory.m |
| UI 工廠基類 Header(OC) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Manager/BBUIFactory.h |
| UI 工廠基類實作(OC) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Manager/BBUIFactory.m |
| 手勢擴展 Header(OC) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Manager/UITapGestureRecognizer+Extand.h |
| 手勢擴展實作(OC) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Manager/UITapGestureRecognizer+Extand.m |
| Model(版本資訊 Header) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Model/STVersionInfoModel.h |
| Model(版本資訊實作) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Model/STVersionInfoModel.m |
| Protocol(主頁) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Protocol/BBMaindProtocol.swift |
| Protocol(域名探測) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Protocol/FindFastProtocol.swift |
| Protocol(狀態列樣式) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Protocol/STStatusBarStyleProtocol.swift |
| LiveChat VC Header(OC) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Maind/ChatLiveViewController.h |
| LiveChat VC 實作(OC) | /Users/user/Work/bbsport-new/BBSport/Tab/我的/Mine/Login_Register/登录注册/Maind/ChatLiveViewController.m |
| Config(API 路徑映射) | /Users/user/Work/bbsport-new/BBSport/STUIKit/STFoundation/Network/Basebusinesscomponent/Classes/URL/ThisPlatformRequestAction.swift |
API
登入 / 注冊 / 驗證碼 API(本平台)
| 功能說明 | 來源 | Endpoint | Method | 主要參數 |
|---|---|---|---|---|
| 帳號密碼登入(v2) | STAPI UsernameLoginRequest | api/forehead/user/login/username/v2 | POST urlForm | username, password, lotNumber, captchaOutput, passToken, genTime |
| 手機驗證碼登入 | OC ThisPlatformRequestAction.loginMobileGl | api/forehead/user/login/submit/validate/mobile/code/v2 | POST | mobile, telArea, code, (滑動驗證參數) |
| 登入二次驗證(異常設備) | STAPI LoginCheckRequest | api/forehead/user/login/abnormal/device/login/check | POST urlForm | accessToken, code |
| 重發二次驗證碼 | STAPI ResendLoginRequest | api/forehead/user/login/abnormal/device/login/resend | POST urlForm | accessToken |
| 登入心跳(60s 輪詢) | STAPI LoginHeartbeatRequest | api/forehead/user/login/heartbeat | POST urlForm | 無(使用本地 KEY_TOKEN) |
| 取得驗證碼 ID | STAPI LoginCaptchaIdRequest | api/forehead/user/login/captchaOutput/id | POST urlForm | telArea, mobile |
| 手機登入取得驗證碼(含滑動驗證) | OC ThisPlatformRequestAction.loginCodeGl | api/forehead/user/login/code/v2 | POST | mobile, telArea, lotNumber, captchaOutput, passToken, genTime |
| 取得手機驗證碼(通用) | OC ThisPlatformRequestAction.mobileCode | api/forehead/user/mobile/code | POST | mobile, telArea, type |
| 用戶名注冊(v2) | OC ThisPlatformRequestAction.registerUserNameGl | api/forehead/user/register/username/v2 | POST | username, password, inviterCode, (滑動驗證參數) |
| 手機號注冊 | OC ThisPlatformRequestAction.registerMobile | api/forehead/user/register/mobile | POST | mobile, telArea, code, username, password |
| 注冊取得驗證碼(v2) | OC ThisPlatformRequestAction.registerCode | api/forehead/user/register/code/v2 | POST | mobile, telArea, (滑動驗證參數) |
| 驗證注冊用戶名 | OC ThisPlatformRequestAction.registerUserNameValidate | api/forehead/user/register/username/validate | POST | username, telArea |
| 驗證手機驗證碼 | OC ThisPlatformRequestAction.registerCodeValidate | api/forehead/user/register/code/validate | POST | mobile, telArea, code |
| 綁定帳號 | OC ThisPlatformRequestAction.bindingAccount | api/forehead/user/login/submit/bind/or/create | POST | telArea, mobile, accessToken, operationType, password, username |
| 忘記密碼取得綁定資訊(v2) | OC ThisPlatformRequestAction.forgetInfoGl | api/forehead/user/forget/info/v2 | POST | username, (滑動驗證參數) |
| 忘記密碼發送驗證碼 | OC ThisPlatformRequestAction.forgetCodeOld | api/forehead/user/forget/get/validate/code | POST | accessToken, type |
| 忘記密碼重設密碼 | OC ThisPlatformRequestAction.forgetResetPasswordGl | api/forehead/user/forget/submit/reset/password | POST | accessToken, code, type, password |
其他相關 API
| 功能說明 | 來源 | Endpoint | Method | 主要參數 |
|---|---|---|---|---|
| 取得使用者識別碼 | STAPI | api/forehead/user/security/get/user/valid/code | POST json | 無 |
| 重置使用者識別碼 | STAPI | api/forehead/user/security/submit/reset/user/valid/code | POST json | 無 |
| 取得使用者安全資訊 | STAPI | api/forehead/user/security/load/info | POST | 無 |
| 取得體驗金 | STAPI | api/forehead/activity/welfare/experienceCash/list | POST | 無 |
| 取得賠率設定 | OC ThisPlatformRequestAction.gl_cfg_get | api/forehead/system/cfg/get?collect=UserConfig | GET | 無 |
GameJump API(
game/jump、game/jump/preCheck)已移至 場館登入
Token / Session 管理機制
存儲位置
| Key | 說明 | 儲存方式 |
|---|---|---|
KEY_TOKEN | 登入 Token,用於心跳保活及 API 認證 | UserDefaults |
KEY_UID | 使用者 ID | UserDefaults |
TOKENTIME | Token 過期時間(由伺服器下發 tokenExpireTime) | UserDefaults |
KEY_USERNAME | 帳號名稱 | UserDefaults(OC #define)及 Swift 常數 |
KEY_PASSWORD | 密碼 | UserDefaults(OC #define)及 Swift 常數 |
KEY_REMEMBER / isRememberPassword | 是否記住密碼 | UserDefaults |
loginTime | 上次登入成功的時間戳(毫秒) | UserDefaults |
isManualLoginOut | 是否手動登出 | UserDefaults |
phoneNumberLogin / isPhoneLogin | 是否使用手機驗證碼登入 | UserDefaults |
isOpenFaceId + username | 該帳號是否開啟 Face ID | UserDefaults(key 包含帳號名) |
loginFirst | 是否首次登入(用於 Face ID 引導彈窗) | UserDefaults |
Accounts | 已儲存帳號列表 | UserDefaults(@UserDefaultCodable,SavedAccountManager) |
Caches/UserInfo.plist | 完整登入回應快取(NSKeyedArchiver 序列化) | 檔案(Caches 目錄) |
Token 生命週期
- 登入成功:
logonDataProcessing解析伺服器回應,呼叫IFUserModel.refreshUserInfo將token存入KEY_TOKEN、Id存入KEY_UID、tokenExpireTime存入TOKENTIME - 心跳保活:登入成功後啟動
NSTimer,每 60 秒呼叫一次loginHeartBeat,帶KEY_TOKEN請求api/forehead/user/login/heartbeat,成功後refreshUserInfo更新使用者資料 - 自動登入判斷:
STLoginManager.canAutoLoginAuto()檢查isRememberPassword=true+isPhoneLogin=false+KEY_USERNAME/KEY_PASSWORD非空;再用loginTime判斷距離上次登入是否小於 3 小時(3 * 60 * 60 * 1000毫秒) - 登出清除:
userKillOut()移除KEY_TOKEN、KEY_UID、KEY_WITHDRAW_TIP,清空IFUserModel
Refresh Token 機制
本專案無獨立的 refresh token 流程。取而代之的是:
- 心跳每 60 秒 call 一次保持 token 有效
- 本平台 token 失效時(收到
STNotify.logoutThisPlantForm通知),STLoginManager.setupLoginOut使用本地帳密自動重新登入 - 各體育平台 token 失效時,由 GameJump 機制重新登入(詳見 場館登入)
資料模型
IFUserModel(全局使用者 Singleton)
| 欄位 | 說明 |
|---|---|
isLoginThisPlatform | 是否已登入本平台 |
isShowingLoginVC | 是否正在展示登入頁(防止重複彈出) |
isThisPlatformLogining | 是否正在登入流程中 |
token | 登入 Token |
Id | 使用者 ID |
oddsOBID / oddsSTID / oddsUPID | 各平台賠率類型偏好 |
nearGameID | 上次進入的遊戲類型 |
headUrl | 頭像 URL |
SavedAccountManager(帳號管理 Singleton)
| 欄位 | 說明 |
|---|---|
accounts: [Account] | 已儲存帳號列表(@UserDefaultCodable("Accounts")) |
Account.username | 帳號名稱 |
Account.password | 密碼(若未勾選「記住密碼」則為空字串) |
- 登入成功時
append新帳號(自動去重) MLAllUserNameView以 TableView 展示已儲存帳號列表,最多顯示 5 個(超出可滾動)- 選中帳號自動填入帳號密碼欄位;可滑動刪除帳號
STAPI.UserSecurityInfoRequest.Response
| 欄位 | 說明 |
|---|---|
mobile | 手機號(脫敏) |
cardCount | 已綁銀行卡數量 |
usdtCount | USDT 地址數量 |
withdrawVal | 提款驗證是否已完成 |
錯誤場景處理
API 回應碼判斷
IFLoginService.vailtedDataWithResponse: 統一檢查回應:
code == 1:成功code != 1:失敗,顯示message(除「您所在地區訪問受限制」外,均以BBShowMessageView提示)code == 500001:特殊登入失敗碼,回傳response["data"]供上層處理
滑動驗證碼觸發
code == 20003或code == 200025:伺服器要求滑動驗證,LoginUserNameView/LoginPhoneCodeView記錄self.code,下次登入時先啟動VerifyCodeManager.shared.start取得滑動驗證結果(lotNumber、captchaOutput、passToken、genTime),再帶入登入 API
異常設備二次驗證
- 帳密登入成功後,若回應包含
accessToken+areaCode+mobile,代表偵測到異常設備 - 彈出
BBSendMsgCodeView讓使用者輸入簡訊驗證碼 - 呼叫
IFLoginService.loginCheck(accessToken, code:)完成二次驗證 - 可透過
STAPI.ResendLoginRequest重發驗證碼
帳號密碼為空
userName.length <= 0或passWord.length <= 0:直接STLoading.stop()返回,不發送請求- 前端額外檢查:
LoginUserNameView以STHud.showTopToast提示「請輸入帳號」/「請輸入密碼」
維護 / 強更
logonDataProcessing中檢查userModel.isMainUpdate或GameMaintenanceManager.shared.app.isGameMaintenance- 若正在維護或強更,設定
isManualLoginOut = true並直接 return,不完成登入
網路錯誤
IFLoginService.commonRequestWithActionType的 failure callback:呼叫setupError:→BBShowMessageView顯示錯誤訊息 +STLoading.stop()- 登入頁有網路偵測功能(
listenNetWorkingStatus),無網路時顯示紅色提示條redNetView,點擊跳轉NetErrorViewController
手機驗證碼錯誤
- 區號為空:
BBShowMessageView提示「區號不能為空」 - 驗證碼為空:
BBShowMessageView提示「請輸入驗證碼」 - 手機號格式不正確:由
IFCheckUtil.checkPhoneNumber:region:/ylCheckPhoneNumber:region:檢查
實作重點
自動登入判斷邏輯(
STLoginManager):canAutoLoginAuto()檢查本地是否有帳密 + 勾選記住密碼;3小時門檻以loginTimeUserDefaults 記錄;Face ID 路徑:BBFaceIdLoginService.login成功後才重新調用loginService登出流程(
userKillOut):若為橫屏狀態先強制退出全螢幕;清除IFUserModel資料;發送STNotify.clearWindowMaskView清除浮層;發送STNotify.specifiedTab切換至預設 Tab;清除 TOKEN / UID UserDefaults登入成功資料處理(
logonDataProcessing):- 將整個 response 用
NSKeyedArchiver序列化存入Caches/UserInfo.plist(供 TOKEN 登入使用) IFUserModel.refreshUserInfo更新使用者資訊並存KEY_TOKEN/KEY_UID/TOKENTIME- 觸發版本更新檢查
- 儲存
gameJumpConfig到IFMainSwitch(場館登入用,詳見 場館登入) - 啟動心跳 Timer(60 秒)
- 將整個 response 用
TOKEN 登入(冷啟動):
ModuleApi.load註冊LoginByToken路由 → 從Caches/UserInfo.plist讀取快取登入回應 → 直接呼叫logonDataProcessing+loginHeartBeat+uploadLoginCount手機驗證碼登入後處理:不儲存密碼(
removeObject(forKey: PassWord)),不記住密碼(removeObject(forKey: isRememberPassword)),isPhoneLogin = true;若回應為字串(新用戶),跳轉SetAccountViewController設定帳號維護模式:
BBMaintainViewController/BBMaintainView— 後台設定維護時展示客服整合:登入頁底部「聯繫客服」按鈕,呼叫
CustomerChatManager.shared.openChat開啟客服選單,含多線路選項(自助找回密碼、主線客服、次線客服)多帳號切換:
SavedAccountManager以@UserDefaultCodable("Accounts")儲存帳號密碼列表;MLAllUserNameView以下拉列表展示;選中自動填入、可刪除;新帳號自動去重追加Face ID 引導:登入成功後若
loginFirst = false且未開啟 Face ID 且已記住密碼,STLoginManager.presentFaceIdOverlayIfNeeded彈出STFaceIdOverlay引導開啟
API 呼叫流程
App 啟動自動登入流程請見 App 啟動
帳號密碼登入
用戶點擊登入按鈕 (LoginUserNameView.loginBtnClick)
├─ 驗證: 帳號密碼已填寫?
│
├─ VerifyCodeManager.shared.start() → 滑動驗證碼 (CAPTCHA v4)
│ └─ 回傳: lotNumber, captchaOutput, passToken, genTime
│
└─ [API 1] POST api/forehead/user/login/username/v2
│ Body: username, password, lotNumber, captchaOutput, passToken, genTime
│
├─ code 20003/200025 → 重試驗證碼
│
├─ 含 accessToken+areaCode+mobile (異常設備)
│ ├─ [API 2] POST api/forehead/user/login/abnormal/device/login/resend → 發送簡訊
│ └─ 用戶輸入驗證碼
│ └─ [API 3] POST api/forehead/user/login/abnormal/device/login/check
│
└─ 直接成功
├─ [API 4] readUserSaveInfo() → 取得用戶賠率設定
├─ [API 5] getTitleId() → 取得用戶稱號
├─ [API 6] POST api/forehead/user/setting/auto/login/record → 更新登入紀錄
└─ setupTimer() → 每 60 秒心跳
└─ [API 7] POST api/forehead/user/login/heartbeat (持續)註冊新帳號
用戶點擊註冊 (RegisterByUserNameView.registerBtnClick)
├─ 驗證: 帳號(6-16字) + 密碼(8-20字)
├─ VerifyCodeManager.shared.start() → 滑動驗證碼
│
└─ [API] IFLoginService.glUserNameRegister
│ Body: username, password, inviterCode(選填), proxyHost(選填),
│ lotNumber, captchaOutput, passToken, genTime
│
└─ 成功 → 儲存帳密 → readUserSaveInfo() + getTitleId()
→ setUpChangeWindows() → 進入主畫面Token 刷新 (心跳)
登入成功後啟動 Timer (每 60 秒)
└─ [API] POST api/forehead/user/login/heartbeat
│ Headers: token, uid (由 STRequestTokenAdapter 自動附加)
└─ 成功 → refreshUserInfo() 更新用戶資訊