af0025ce38
## 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)
153 lines
3.9 KiB
Plaintext
153 lines
3.9 KiB
Plaintext
import { HXUtils, StockMarketUtil } from "@b2c/lib_baseui";
|
|
import { NumberUtils } from "hxutil";
|
|
|
|
export interface SelfSelectedStockModel {
|
|
id: string;
|
|
stockCode: string;
|
|
stockName: string;
|
|
currentPrice: number;
|
|
changeAmount: number;
|
|
changePercent: number;
|
|
updateTime?: number;
|
|
}
|
|
|
|
export interface SelfSelectedStockModelMock {
|
|
code: string;
|
|
name: string;
|
|
price: number;
|
|
change: number;
|
|
percent: number;
|
|
}
|
|
|
|
export interface StockGroupModel {
|
|
id: string;
|
|
groupName: string;
|
|
stocks: SelfSelectedStockModel[];
|
|
isSelected: boolean;
|
|
}
|
|
|
|
|
|
const HQ_DATA_INVALID = "--"
|
|
|
|
@Observed
|
|
export class SwiperHqDataItemModel extends Array<GridHqDataItemModel>{}
|
|
|
|
@Observed
|
|
export class GridHqDataItemModel extends Array<HQDataItemModel>{}
|
|
|
|
/**
|
|
* 行情自定义数据结构
|
|
*/
|
|
@Observed
|
|
export class HQDataItemModel{
|
|
name:string = HQ_DATA_INVALID
|
|
code:string = HQ_DATA_INVALID
|
|
showCode:string = HQ_DATA_INVALID
|
|
market:string = "0"
|
|
price:string = HQ_DATA_INVALID
|
|
riseFail:string = HQ_DATA_INVALID //涨跌幅
|
|
priceRise:string = HQ_DATA_INVALID
|
|
nameColor:ResourceColor = 0
|
|
priceColor:ResourceColor = 0
|
|
riseFailColor:ResourceColor = 0
|
|
priceRiseColor:ResourceColor = 0
|
|
showAddImage:boolean = false
|
|
/**
|
|
* -1:跌,1:涨,0:不变
|
|
*/
|
|
riseFailFlag:number = 0
|
|
|
|
priceChange:boolean = false
|
|
|
|
|
|
|
|
constructor(stockCode?:string,stockMarket?:string,stockName?:string) {
|
|
this.code = stockCode??HQ_DATA_INVALID
|
|
this.market = stockMarket??HQ_DATA_INVALID
|
|
this.name = stockName??HQ_DATA_INVALID
|
|
this.showCode = stockCode??HQ_DATA_INVALID
|
|
}
|
|
|
|
copyFrom(dataItemModel:HQDataItemModel){
|
|
this.name = dataItemModel.name
|
|
const market = dataItemModel.market
|
|
const showCodeTemp = dataItemModel.showCode
|
|
if ((StockMarketUtil.isOption(market+"") || StockMarketUtil.isFutureTL(market+"")) && HXUtils.isValidContractData(showCodeTemp+"")) {
|
|
this.showCode = showCodeTemp
|
|
}else{
|
|
this.showCode = this.code
|
|
}
|
|
|
|
this.riseFailFlag = this.getRiseFailFlag(dataItemModel.price,this.price)
|
|
this.priceChange = this.riseFailFlag != 0
|
|
this.price = dataItemModel.price
|
|
this.riseFail = dataItemModel.riseFail
|
|
this.priceRise = dataItemModel.priceRise
|
|
this.riseFailColor = dataItemModel.riseFailColor
|
|
this.riseFailColor = dataItemModel.riseFailColor
|
|
}
|
|
|
|
getMapKey():string{
|
|
return this.code+"_"+this.market
|
|
}
|
|
|
|
|
|
|
|
private getRiseFailFlag(newPrice:string,lastPrice:string){
|
|
let ret = 0
|
|
if (newPrice == lastPrice){
|
|
return ret
|
|
}
|
|
if (NumberUtils.isNumeric(newPrice) && NumberUtils.isNumeric(lastPrice)) {
|
|
const newPriceNumber = parseFloat(newPrice)
|
|
const lastPriceNumber = parseFloat(lastPrice)
|
|
if (newPriceNumber == lastPriceNumber) {
|
|
ret = 0
|
|
}else {
|
|
ret = newPriceNumber > lastPriceNumber ? 1:-1
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
copy():HQDataItemModel{
|
|
let copyDataItemModel = new HQDataItemModel(this.code,this.market,this.name)
|
|
copyDataItemModel.showCode = this.showCode
|
|
copyDataItemModel.price = this.price
|
|
copyDataItemModel.riseFail = this.riseFail
|
|
copyDataItemModel.priceRise = this.priceRise
|
|
copyDataItemModel.nameColor = this.nameColor
|
|
copyDataItemModel.riseFailColor = this.riseFailColor
|
|
copyDataItemModel.priceRiseColor = this.priceRiseColor
|
|
copyDataItemModel.showAddImage = this.showAddImage
|
|
copyDataItemModel.priceChange = this.priceChange
|
|
copyDataItemModel.riseFailFlag = this.riseFailFlag
|
|
return copyDataItemModel
|
|
}
|
|
}
|
|
|
|
export class GridDataSource implements IDataSource{
|
|
private dataArray:HQDataItemModel[] = []
|
|
|
|
constructor(data:HQDataItemModel[]) {
|
|
this.dataArray = data
|
|
}
|
|
totalCount(): number {
|
|
return this.dataArray.length
|
|
}
|
|
|
|
getData(index: number): HQDataItemModel {
|
|
return this.dataArray[index]
|
|
}
|
|
|
|
registerDataChangeListener(listener: DataChangeListener): void {
|
|
|
|
}
|
|
|
|
unregisterDataChangeListener(listener: DataChangeListener): void {
|
|
|
|
}
|
|
|
|
}
|
|
|