Appearance
BBSport-New 架構知識庫
最後更新:2026-04-09
專案概覽
BBSport 是由 SEEKTOP 開發的 iOS 體育博彩平台應用程式。使用 UIKit 搭配部分 Combine / RxSwift 進行響應式程式設計,採用 MVVM 架構模式。專案支援多個體育數據供應商(FBSport 極速體育、DBSport DB體育、LeisuSport 雷速體育)以及自家平台 API(STAPI)。
目錄結構
BBSport/
├── API/ # 所有網路請求層
│ ├── APILayer/ # 底層 API 基礎設施
│ │ └── STApiManager/
│ │ ├── Adapters/ # 請求攔截器(Token、DeviceInfo、CachePolicy)
│ │ ├── Decision/ # 回應處理決策(StatusCode、Log)
│ │ └── Protocol/ # 協議定義(BaseResponse、ParseResponse)
│ ├── STAPI/ # 平台主要 API(自家後端)
│ │ ├── User/ # 用戶相關(登入、地址、銀行卡、Profile)
│ │ ├── Chat/ # 聊天室相關
│ │ ├── Bet/ # 投注相關
│ │ ├── Recharge/ # 充值相關
│ │ ├── Transfer/ # 轉帳相關
│ │ ├── Withdraw/ # 提款相關
│ │ ├── Task/ # 任務相關
│ │ ├── Activity/ # 活動相關
│ │ ├── Sport/ # 體育菜單 / 賽事排行
│ │ ├── Game/ # GameJump(平台登入跳轉)
│ │ ├── GlobalSearch/ # 全局搜索
│ │ ├── Settings/ # 系統設定
│ │ ├── Notice/ # 通知相關
│ │ ├── Feedback/ # 意見回饋
│ │ ├── CapitalDetail/ # 資金明細
│ │ └── WelfareCenter/ # 福利中心
│ ├── DBSportAPI/ # DB體育 API(OB平台)
│ │ ├── Sport/ # 賽事列表、聯賽、收藏
│ │ └── Bet/ # 最新盤口、投注限額
│ ├── FBSportAPI/ # 極速體育 API(FB)
│ │ ├── Bet/ # 計算投注、預約投注
│ │ ├── MatchResult/ # 賽果列表
│ │ └── Settle/ # 提前結算
│ ├── UPSportAPI/ # UP/BB 體育 API(雷速)
│ │ ├── Sport/ # 賽事列表
│ │ ├── Bet/ # 投注計算、單關/串關
│ │ ├── MatchResult/ # 賽果列表
│ │ ├── Settle/ # 提前結算
│ │ ├── Repository/ # 資料倉庫
│ │ └── Domain/ # Domain 管理
│ └── LeisuSportAPI/ # 雷速體育 API(賽事詳情數據)
│
└── Tab/ # 各 Tab 功能模組
├── 广场/ # 廣場 Tab(直播、活動)
│ ├── Activity/ # 活動列表
│ ├── FullScreenLive/ # 全螢幕直播
│ └── Stream/ # 主播流(StreamerViewController)
├── 我的/ # 我的 Tab(會員中心)
│ ├── Home/ # 我的首頁
│ └── Mine/
│ ├── Login_Register/ # 登入 / 注冊
│ ├── Recharge/ # 充值
│ ├── UserInfo/ # 個人資料 / 銀行卡 / 提款地址
│ ├── MiddleMenu/ # 福利中心等
│ ├── SportMenu/ # 賽事成績
│ ├── SystemSet/ # 系統設定
│ └── Tasks/ # 每日任務
├── 游戏/ # 遊戲 Tab
│ └── Amuse/
│ ├── Lottery/ # 彩票(大廳、開獎、投注)
│ └── API/ # 轉盤活動 API
└── GlobalSearch/ # 全局搜索 TabTabBar 結構
TabBar 根控制器:/Users/user/Work/bbsport-new/BBSport/Tab/Tabbar/MainViewController.swift
| Tab 索引 | 名稱 | 路由常數 | 對應目錄 |
|---|---|---|---|
| 0 | 廣場 | GetNewsViewController | Tab/广场/ |
| 1 | 遊戲 | GetBBHomeViewController | Tab/游戏/ |
| 2 | 體育(預設) | OpenEventList(menu=6, sport=1) | Tab/体育/ |
| 3 | 注單(需登入) | OpenEventList(menu=5, sport=1) | Tab/注单/ |
| 4 | 我的 | GetUserInfoVC | Tab/我的/ |
Tab 預設選擇邏輯:
- 上次使用娛樂遊戲(
GameStatusManager.shared.savedGameType == .bbAmuse)→ 預設 Tab 1(遊戲) - 從廣場點擊登入(
PUSHBYNEWSUserDefaults = true)→ 預設 Tab 0(廣場) - 其他情況 → 預設 Tab 2(體育)
廣場 Tab icon 特殊邏輯: icon 分兩段動畫,Transition(一次性)+ Loop(持續)。Loop 動畫依「是否直播中(isOnLive)」+ 「是否選中」決定圖示版本。
API 命名空間
| 命名空間 | 說明 | Host 類型 |
|---|---|---|
STAPI | 平台自家後端 | .main = 主 API 網域 |
DBSportAPI | DB體育(OB盤) | .sport = 體育服務, .main = 主 API |
FBSportAPI | 極速體育(FB) | 動態 host(透過 GameJump 取得) |
UPSportAPI | UP/BB 體育(雷速) | 動態 host(透過 GameJump 取得) |
LeisuSportAPI | 雷速體育(賽事詳情數據) | 獨立域名 |
彩票 | 彩票模組(Moya 獨立網路層) | MLLTJumpManager.shared.baseUrl(動態) |
HttpService | Legacy 請求(OC 橋接層) | 共用 STAPI 域名 |
架構模式
MVVM
- ViewController / View(C/V):負責 UI 渲染、手勢、動畫
- ViewModel(VM):負責業務邏輯、狀態管理、API 調用
- Model(M):資料結構,以
STAutoCodable提供自動解碼
響應式框架
- Combine:新模組(GlobalSearch、部分 StreamerViewModel)
- RxSwift:舊模組(WelfareCentreViewModel、StreamerViewController)
- Callback / Closure:登入流程、部分服務層
網路層
所有 API Request 均遵守 STAPIRequest / FBSportAPIRequest / DBSportAPIRequest 協議,透過對應的 API 結構體 .send { } 發送請求。
請求 Adapter(自動附加):
STRequestTokenAdapter— 附加 TokenSTRequestDeviceInfoAdapter— 附加裝置資訊STRequestCachePolicyAdapter— 快取策略
回應 Decision:
STBadResponseStatusCodeDecision— HTTP 狀態碼錯誤處理STPostLogDecision— 記錄請求日誌
命名規則
| 前綴 | 說明 |
|---|---|
BB | BBSport 專案相關(如 BBMineViewModel) |
ST | SeekTop 共用元件(如 STLoginViewController) |
ML | 彩票模組(如 MLLotteryMainViewController) |
IF | 底層 IF 框架(如 IFUserModel、IFLoginService) |
OB | DB體育(OB平台)Model(如 OBEventModel) |
FB | 極速體育 Model(如 FBCalculateBetsDataModel) |
設計模式
- Protocol-Oriented:
GlobalSearchSectionService、STBaseResponseProtocol、CryptoProtocol - Extension 分割:大型 ViewController 拆分為多個 extension 檔案(如
StreamerViewController+BallView.swift) - AutoDecode:自家
@AutoDecodeProperty Wrapper,帶預設值的自動解碼 - STAutoCodable:遵守
Codable的自動實作 Protocol
已知跨模組依賴
IFUserModel.sharedInstance()— 全局使用者 SingletonIFLoginService— 登入服務(跨多模組調用)STNotify— 全局通知中心(STNotify.logged、STNotify.specifiedTab等)IFCommonUtil/IFUICommonUtil— 工具類MGJRouterBackup— 頁面路由跳轉GameStatusManager.shared— 各平台登入 Token / 選中平台 / 登入狀態管理GameBalanceManager— 餘額查詢與平台間轉帳
體育平台類型(GameType)
| GameType | 說明 | 賽事/投注 API | 登入方式 |
|---|---|---|---|
.fbSport | 極速體育(FB) | FBSportAPI | STAPI.GameJumpRequest(body: .init(gameId: fbSportChannelID)) |
.dbSport | OB 體育(DB) | DBSportAPI | STAPI.GameJumpRequest(body: .init(gameId: dbSportChannelID)) |
.upSport | 雷速體育(UP/BB) | UPSportAPI | STAPI.GameJumpRequest(body: .init(gameId: upSportChannelID)) |
.bbSport | .upSport 的 alias,同一平台 | — | — |
.sicBo | 骰寶(LiveGame) | STAPI | — |
三個體育平台登入機制相同,都透過
STAPI.GameJumpRequest取得 token 和 apiSrc host,差別只在 channelId 和儲存位置(fbHost/upHost)。
Polling(輪詢)機制
統一入口:STStartPolling(type:queue:block:) / STStopPolling(type:)
使用 STPollingType 枚舉管理輪詢任務類型:
| PollingType | 說明 | 頻率 |
|---|---|---|
.sportList(plat:playType: .inPlay) | 賽事列表(滾球) | 5 秒 |
.sportList(plat:playType: .favorite) | 收藏賽事 | 5 秒 |
.sportList(plat:playType: .today) | 今日賽事 | 30 秒 |
.sportList(plat:playType: .early) | 早盤賽事 | 60 秒 |
.sportHomeBanner | 首頁 Banner | 61 秒 |
.sportEventLiveInfo | 賽事直播資訊 | 61 秒 |
.sportMenus | 體育選單 | 20 秒 |
.sportEventPlan | 賽事計劃 | 60 秒 |
.streamer | 主播狀態 | 20 秒 |
.sicBoBetsTask | 骰寶賠率任務 | 自訂 |
全局通知(STNotify)重要清單
| 通知名稱 | 觸發時機 |
|---|---|
STNotify.logged | 登入成功 |
STNotify.logout | 登出 |
STNotify.logoutThisPlantForm | 平台強制登出 |
STNotify.specifiedTab | 切換至指定 Tab(object: Int) |
STNotify.clearWindowMaskView | 清除浮層(關閉投注視窗等) |
STNotify.fbRefreshSettlementBetList | 刷新注單列表 |
STNotify.fbRefreshBetResult | 輪詢更新投注結果 |
STNotify.seriePassBetChange | 串關投注狀態變更(清除選中) |
STNotify.updateBetCanWinAmount | 更新可贏額顯示 |
STNotify.betResponseConst | 投注 API 有回應 |
STNotify.commonDeleteBetEvent | 刪除投注項 → 關閉投注視窗 |
STNotify.NIGHT_PATTERN_OPEN | 夜間模式切換 |
STNotify.receivedWinResultPush | 收到中獎 Push 通知 |
STNotify.getOnLiveState | 廣場開始直播 |
STNotify.getOffLiveState | 廣場結束直播 |
STNotify.getRedWD / getNoRedWD | 未讀消息紅點狀態變更 |
STNotify.cancelOrder | 撤銷充值訂單 |