Files
biz_firstpage/src/main/ets/node/view/FourEntryListNodeComponent.ets
T
clz af0025ce38 Initial commit: @b2c/first_page HarmonyOS stage-mode HAR
## Repository
- HarmonyOS stage-mode HAR module, consumed by host app
- No standalone build — hvigorw, oh_modules, and ../biz_quote absent here

## Architecture
### Feed Cards
- FirstPage.createNodeView dispatches cards by FirstPageConstant.KEY_*
- Card config from first_page_cards_config.json loaded by FirstPageCardsConfigLoader
- Public entrypoint: Index.ets

### Market Ranking (src/main/ets/market-ranking/)
- HTTP: MarketRankingDataFetcher fetches recommend_futures contracts
- HQ: MarketRankingHqRequestClient subscribes via 4106/frame 2201/scenario qht_qihuo_sort
- TCP reconnect rebuilds subscription from original HTTP contract list
- Async callbacks guarded by request/subscription versions

### Other Cards
- HotList, CommodityOptions, AiDiagnosis, AiRiseFall, SelfSelectedStock, CustomEntryList, FourEntryList
- Each has DataFetcher + HQ request client + NodeComponent

## Key Changes (from CardHarmonyOS reference)
- Added MetricId, PeriodId, SortOrder enums (MarketRankingModels.ets)
- Replaced string comparisons with enum switches in thirdColumnTitle/Value/Color
- Removed redundant undefined guards in thirdColumnColor/priceColor, delegated to riseFallColor
- Inlined priceColor(), use riseFallColor directly
- Tab bar Stack.height(30), Alignment.End (reverted from 46/TopEnd)
- Name column fontWeight removed (default regular)
2026-07-26 01:13:28 +08:00

82 lines
2.3 KiB
Plaintext

import { StringUtils } from 'hxutil';
import { FirstPageNodeModel } from '../../datacenter/model/FirstPageNodeModel';
import { EntryListNodeModel } from '../model/EntryListNodeModel';
import { RouterUtil } from '../../util/RouterUtil';
/**
* 首页四宫格节点
* @author wubingsong@myhexin.com
*/
@Component
export struct FourEntryListNodeComponent {
nodeModel: FirstPageNodeModel | null = null
@State
private isNodeShow: boolean = false
@State
private entryListNodeModelArr: EntryListNodeModel[] | null = null
private static COLUMN_COUNT = 4
aboutToAppear(): void {
if (this.nodeModel != null) {
let extraData = this.nodeModel.extraData
if (StringUtils.isNotEmpty(extraData)) {
let entryListNodes = JSON.parse(extraData) as EntryListNodeModel[]
if (entryListNodes) {
if (entryListNodes.length > FourEntryListNodeComponent.COLUMN_COUNT) {
this.entryListNodeModelArr = entryListNodes.slice(0, FourEntryListNodeComponent.COLUMN_COUNT)
} else {
this.entryListNodeModelArr = entryListNodes
}
if (this.entryListNodeModelArr.length > 0) {
this.isNodeShow = true
}
}
}
}
}
build() {
Column() {
List({ initialIndex: 0 }) {
ForEach(this.entryListNodeModelArr, (item: EntryListNodeModel) => {
ListItem() {
this.createItem(item)
}
}, (item: EntryListNodeModel) => item.id.toString())
}
.width("100%")
.height('auto')
.lanes(FourEntryListNodeComponent.COLUMN_COUNT)
.alignListItem(ListItemAlign.Center)
.scrollBar(BarState.Off)
.visibility(this.isNodeShow ? Visibility.Visible : Visibility.None)
}
.width("100%")
.height(80)
.backgroundImageSize(ImageSize.FILL)
}
@Builder
createItem(item: EntryListNodeModel) {
Column() {
Image(item.imgUrl)
.width(40)
.height(40)
Text(item.title)
.margin( { top : 4 })
.fontColor($r('app.color.color_333333'))
.maxLines(1)
.minFontSize(9)
.maxFontSize(14)
.fontSize(14)
}
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.height(80)
.onClick(() => {
RouterUtil.jumpPage(item.jumpUrl)
})
}
}