Skip to content

全局搜索(開發文檔)

最後更新:2026-04-10

📖 功能說明請參考 全局搜索


架構

相關檔案

ViewController / ViewModel(3 個)
檔案說明
.../GlobalSearch/GlobalSearchViewController.swift搜索主頁
.../GlobalSearch/GlobalSearchViewModel.swift搜索 ViewModel
.../GlobalSearch/Shared/SearchHeader/GlobalSearchHeaderViewModel.swiftHeader ViewModel

基礎路徑:BBSport/Tab/

Service(3 個)
檔案說明
.../Section/SearchHistory/GlobalSearchHistoryService.swift搜索歷史
.../Section/HotSearch/GlobalSearchHotSearchService.swift熱門搜索
.../Section/Search/GlobalSearchService.swift搜索請求

基礎路徑:BBSport/Tab/GlobalSearch/

View(31 個)
檔案說明
.../Shared/SearchField/GlobalSearchField.swift搜索輸入框
.../Shared/SearchField/GlobalSearchFieldInputUseCase.swift輸入框 UseCase
.../Shared/SearchHeader/GlobalSearchHeaderView.swift搜索 Header
.../Shared/SelfSizingCollectionView.swift自適應 CollectionView
.../Shared/LeftAlignedCollectionViewFlowLayout.swift左對齊 Layout
.../Section/HotSearch/View/GlobalSearchHotSearchView.swift熱門搜索視圖
.../Section/Search/View/Match/GlobalSearchMatchResultView.swift賽事結果
.../Section/Search/View/Activity/GlobalSearchActivityResultView.swift活動結果
.../Section/Search/View/Disclosure/GlobalSearchDisclosureResultView.swift爆料結果
.../Section/Search/View/Game/GlobalSearchGameResultView.swift遊戲結果
.../Section/Search/View/Host/GlobalSearchHostResultView.swift主播結果
.../Section/Search/View/Empty/GlobalSearchEmptyResultCell.swift空結果
.../Section/SearchHistory/View/GlobalSearchHistoryView.swift搜索歷史
以及各 +ItemCell / +StateItem 擴展檔...

基礎路徑:BBSport/Tab/GlobalSearch/

Protocol / Model(5 個)
檔案說明
.../Protocol/GlobalSearchSectionService.swiftSection Service 協議
.../Protocol/GlobalSearchCellStateItem.swiftCell 狀態協議
.../Protocol/GlobalSearchSectionFooterStateItem.swiftFooter 狀態協議
.../Protocol/GlobalSearchSectionHeaderStateItem.swiftHeader 狀態協議
.../Section/Search/Model/GlobalSearchTab.swiftTab 分類 Model

基礎路徑:BBSport/Tab/GlobalSearch/


API

搜索流程


熱門搜索聯賽

POST api/forehead/data/user/global/search/hotLeague — urlForm — STAPI.GlobalSearchHotSearchRequest

無參數,靠 Header token/uid 認證。

Response: [League]

欄位型別說明
leagueIdString聯賽 ID
leagueNameString聯賽名稱
leagueLogoString聯賽 Logo URL
matches[Match]旗下賽事列表

Match 欄位:home(String), away(String), homeScore(Int?), awayScore(Int?), eventId(String), startEventDate(Double, 毫秒)


搜索結果

POST api/forehead/data/user/global/search — urlForm — STAPI.GlobalSearchRequest

參數型別必填說明
searchKeyString搜索關鍵字
showClientString固定 "2"(App 端)
tabIndexGlobalSearchTabTab 篩選(-1=全部)
sizeString固定 "10"

Response:

欄位型別說明
leagues[League]聯賽與賽事
liveHosts[LiveHost]主播列表(含 hasLive
gameVenues[Game]遊戲場館
activities[Activity]優惠活動
activityDisclosures[Disclosure]活動爆料
sportsMessages[SportsMessage]運動爆料/專家推薦
hasDataIndexString有資料的 Tab 索引(逗號分隔)

搜索子 Model 欄位

LiveHost(主播)
欄位型別說明
hasLiveInt是否開播(1=是、0=否)
idInt主播 ID
nameString主播名稱
photoIdString主播頭像圖片 URL
Activity(優惠活動)
欄位型別說明
startTimeDouble活動開始時間(毫秒)
endTimeDouble活動結束時間(毫秒)
idInt活動 ID
nameString活動名稱
pcImageStringBanner 圖片 URL
pcUrlString跳轉路徑
Disclosure(活動爆料)
欄位型別說明
h5UrlStringH5 跳轉連結
createTimeDouble創建時間(毫秒)
actIdInt跳轉連結 ID
idInt爆料 ID
isHotBool是否熱門
recommendedBool是否推薦
replyCountInt回覆數
thumbInt按讚數
titleString爆料標題
usernameString用戶名稱
titlePicString用戶稱號圖片
vipLevelInt用戶 VIP 等級
SportsMessage(運動爆料/專家推薦)
欄位型別說明
idInt爆料 ID
professorNameString專家名稱
sportsTitleString爆料標題
goldPriceInt金幣價格
sportsPlayString比賽玩法
openBackGoldInt黑單返金開關(1=開)
profileString頭像 URL
introductionString專家介紹
tagString編輯標籤
redContinuousInt連紅數
sportsIdInt賽事 ID
isBuyInt是否已購買(1=是)
resultInt爆料結果(0=未結束、1=紅、2=黑、3=和...)
isAttentionInt是否關注(1=是)
yieldRateString收益率(含%)
playDetails[PlayDetail]玩法細節(contentoddsselected
home / guestString主隊/客隊名稱
sportsNameString聯賽名稱
sportsTimeDouble開賽時間(毫秒)

搜索歷史

GlobalSearchHistoryService 使用 STPerUserStorage<[String]>(UserDefaults 封裝,每用戶獨立 key)儲存搜索歷史。

規則數值
最大儲存筆數20 筆
預設展示行數2 行,超過折疊,點擊「展開」查看全部
儲存方式STPerUserStorage(UserDefaults,key: GlobalSearchHistory.Key
重複處理重複關鍵字移到第一位,達上限時移除最舊一筆
清除彈出確認 Alert,確認後清除全部

實作重點

  • 三段 Service 架構:History(本地)、HotSearch(API 熱門)、Search(搜索)各自獨立建構 Section
  • Combine 驅動@Published loadState 驅動 UI;DispatchGroup 並發請求後統一更新
  • 防抖機制GlobalSearchFieldInputUseCase 控制輸入限制:最少 2 個字元 才觸發搜索,每次搜索間隔至少 2 秒requestTimeInterval = 2),超過 50 字元 無法輸入。非 debounce/throttle 實作,而是在 shouldRequestSearch() 中以 lastRequestTime 差值判斷
  • Tab 篩選GlobalSearchTab 支援全部/足球/籃球/網球等,filter(by:) 按球類過濾
  • CollectionView 自適應LeftAlignedCollectionViewFlowLayout 左對齊 + SelfSizingCollectionView 自動高度
  • 外部帶入搜索init(searchText:) 支援從其他頁面跳轉帶入初始關鍵字
  • 搜索失敗 UI:API 請求失敗時(onError callback),loadState 不更新為 .end,UI 保持 .searching 狀態。搜索有結果但特定分類無資料時顯示 GlobalSearchEmptyResultCell 空狀態。若搜索結果完全為空(isEmpty=true),則同時顯示空結果提示和歷史/熱門搜索區塊