fix market ranking state and quote rendering
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import {
|
||||
CardData,
|
||||
RankItem,
|
||||
RecommendFuturesItem,
|
||||
} from './MarketRankingModels';
|
||||
|
||||
export function cardDataToContracts(cardData: CardData): RecommendFuturesItem[] {
|
||||
return cardData.tableList.map((item: RankItem): RecommendFuturesItem => ({
|
||||
contract_code: item.code,
|
||||
contract_name: item.name,
|
||||
market: item.market,
|
||||
}));
|
||||
}
|
||||
|
||||
export function contractsToPlaceholderCardData(contracts: RecommendFuturesItem[]): CardData {
|
||||
const cardData: CardData = {
|
||||
tableList: contracts.map((contract: RecommendFuturesItem): RankItem => ({
|
||||
code: contract.contract_code,
|
||||
market: contract.market,
|
||||
name: contract.contract_name,
|
||||
})),
|
||||
};
|
||||
return cardData;
|
||||
}
|
||||
@@ -6,17 +6,23 @@ import {
|
||||
RankItem, RecommendFuturesItem, TabMetric,
|
||||
} from './MarketRankingModels';
|
||||
import { MarketRankingDataFetcher } from './MarketRankingDataFetcher';
|
||||
import {
|
||||
cardDataToContracts,
|
||||
contractsToPlaceholderCardData,
|
||||
} from './MarketRankingDataMapper';
|
||||
import { MarketRankingHqRequestClient } from '../node/clients/MarketRankingHqRequestClient';
|
||||
import { formatGreatNumber, formatPercent, formatPrice, riseFallColor } from '../common/NumberFormat';
|
||||
import { AllCardsCard } from '../node/model/AiDiagnosisNodeModel';
|
||||
import { PERIOD_RANGES, TAB_METRICS } from './MarketRankingConstant';
|
||||
import { enableDarkMode } from '@kernel/theme_manager';
|
||||
import { EmitterConstants, GlobalContext, HXLog, jumpToQuote } from 'biz_common';
|
||||
import { QuoteCustomSettingManager, StandardPriceType } from 'biz_quote';
|
||||
import { EmitterConstants, GlobalContext, jumpToQuote } from 'biz_common';
|
||||
import { RouterUtil } from '../util/RouterUtil';
|
||||
|
||||
const NORMAL_SIZE = 3;
|
||||
const MAX_SIZE = 5;
|
||||
const UNFOLDED_STORAGE_KEY = 'firstPageMarketRankingUnfolded';
|
||||
|
||||
PersistentStorage.persistProp<boolean>(UNFOLDED_STORAGE_KEY, false);
|
||||
|
||||
@Component
|
||||
export struct MarketRankingNodeComponent {
|
||||
@@ -29,13 +35,14 @@ export struct MarketRankingNodeComponent {
|
||||
@State cardConfig: AllCardsCard | undefined = undefined;
|
||||
@State cardData: CardData = { tableList: [] };
|
||||
private contracts: RecommendFuturesItem[] = [];
|
||||
private tabDataCache: Map<string, CardData> = new Map<string, CardData>();
|
||||
// 区分加载中和暂无数据,与 HotListNodeComponent 的 dataReady 约定保持一致
|
||||
@State dataReady: boolean = false;
|
||||
|
||||
// Tab 与展开状态
|
||||
@State primaryIdx: number = 0;
|
||||
@State secondaryIdx: number = 0;
|
||||
@State unfolded: boolean = false;
|
||||
@StorageLink(UNFOLDED_STORAGE_KEY) unfolded: boolean = false;
|
||||
|
||||
// Tab 滚动区域状态
|
||||
@State tabViewportWidth: number = 0;
|
||||
@@ -53,8 +60,6 @@ export struct MarketRankingNodeComponent {
|
||||
private hqUnsubscribe: (() => void) | undefined;
|
||||
private hqSubscriptionVersion: number = 0;
|
||||
private isTcpEventSubscribed: boolean = false;
|
||||
private lastStandardPriceType: StandardPriceType =
|
||||
QuoteCustomSettingManager.getInstance().getStandardPriceType();
|
||||
private tcpReconnectListener = (): void => {
|
||||
if (!this.canUseHq()) {
|
||||
return;
|
||||
@@ -114,19 +119,9 @@ export struct MarketRankingNodeComponent {
|
||||
return;
|
||||
}
|
||||
this.subscribeTcpNetStatus();
|
||||
this.syncStandardPriceType();
|
||||
this.restartCurrentSubscription();
|
||||
}
|
||||
|
||||
private syncStandardPriceType(): void {
|
||||
const currentStandardPriceType: StandardPriceType =
|
||||
QuoteCustomSettingManager.getInstance().getStandardPriceType();
|
||||
if (this.lastStandardPriceType !== currentStandardPriceType) {
|
||||
HXLog.d('MarketRankingNodeComponent', 'Standard price type changed, resubscribe');
|
||||
this.lastStandardPriceType = currentStandardPriceType;
|
||||
}
|
||||
}
|
||||
|
||||
private subscribeTcpNetStatus(): void {
|
||||
if (this.isTcpEventSubscribed || !this.canUseHq()) {
|
||||
return;
|
||||
@@ -185,11 +180,21 @@ export struct MarketRankingNodeComponent {
|
||||
}
|
||||
const requestVersion: number = this.dataRequestVersion + 1;
|
||||
this.dataRequestVersion = requestVersion;
|
||||
// 切换 Tab 后立即清理旧列表,避免新请求返回前闪现上一 Tab 的数据。
|
||||
const cacheKey: string = this.getTabCacheKey(primaryIdx, secondaryIdx);
|
||||
const cachedData: CardData | undefined = this.tabDataCache.get(cacheKey);
|
||||
this.stopSubscribeHq();
|
||||
this.contracts = [];
|
||||
this.cardData = { tableList: [] };
|
||||
this.dataReady = false;
|
||||
if (cachedData !== undefined) {
|
||||
this.cardData = cachedData;
|
||||
this.contracts = cardDataToContracts(cachedData);
|
||||
this.dataReady = true;
|
||||
if (this.firstPageVisible) {
|
||||
this.subscribeHq(primaryIdx, secondaryIdx);
|
||||
}
|
||||
} else {
|
||||
this.contracts = [];
|
||||
this.cardData = { tableList: [] };
|
||||
this.dataReady = false;
|
||||
}
|
||||
try {
|
||||
const contracts = await MarketRankingDataFetcher
|
||||
.getInstance()
|
||||
@@ -198,14 +203,11 @@ export struct MarketRankingNodeComponent {
|
||||
return;
|
||||
}
|
||||
this.contracts = contracts;
|
||||
this.cardData = {
|
||||
tableList: contracts.map((contract: RecommendFuturesItem): RankItem => ({
|
||||
code: contract.contract_code,
|
||||
market: contract.market,
|
||||
name: contract.contract_name,
|
||||
})),
|
||||
};
|
||||
if (cachedData === undefined) {
|
||||
this.cardData = contractsToPlaceholderCardData(contracts);
|
||||
}
|
||||
this.dataReady = true;
|
||||
this.tabDataCache.set(cacheKey, this.cardData);
|
||||
if (this.firstPageVisible) {
|
||||
this.subscribeHq(primaryIdx, secondaryIdx);
|
||||
}
|
||||
@@ -213,8 +215,10 @@ export struct MarketRankingNodeComponent {
|
||||
if (!this.isCurrentDataRequest(requestVersion, primaryIdx, secondaryIdx)) {
|
||||
return;
|
||||
}
|
||||
this.contracts = [];
|
||||
this.cardData = { tableList: [] };
|
||||
if (cachedData === undefined) {
|
||||
this.contracts = [];
|
||||
this.cardData = { tableList: [] };
|
||||
}
|
||||
this.dataReady = true;
|
||||
}
|
||||
}
|
||||
@@ -235,6 +239,7 @@ export struct MarketRankingNodeComponent {
|
||||
primaryIdx === this.primaryIdx &&
|
||||
secondaryIdx === this.secondaryIdx) {
|
||||
this.cardData = cardData;
|
||||
this.tabDataCache.set(this.getTabCacheKey(primaryIdx, secondaryIdx), cardData);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -266,6 +271,14 @@ export struct MarketRankingNodeComponent {
|
||||
secondaryIdx === this.secondaryIdx;
|
||||
}
|
||||
|
||||
private getTabCacheKey(primaryIdx: number, secondaryIdx: number): string {
|
||||
const metric: TabMetric = TAB_METRICS[primaryIdx];
|
||||
if (metric.hasChildren) {
|
||||
return `${metric.id}_${PERIOD_RANGES[secondaryIdx].id}`;
|
||||
}
|
||||
return `${metric.id}`;
|
||||
}
|
||||
|
||||
// ==================== 页面跳转 ====================
|
||||
|
||||
// 对齐 futures-homepage jumpToFenShi,跳转客户端行情分时页。
|
||||
@@ -357,26 +370,24 @@ export struct MarketRankingNodeComponent {
|
||||
})
|
||||
|
||||
// 展开/收起按钮,样式对齐 HotListNodeComponent 的展开/收起按钮
|
||||
if (this.cardData.tableList.length > NORMAL_SIZE) {
|
||||
Row() {
|
||||
Text(this.unfolded
|
||||
? $r('app.string.hotlist_collapse')
|
||||
: $r('app.string.hotlist_expand'))
|
||||
.fontColor($r('app.color.elements_text_tertiary'))
|
||||
.fontSize(12)
|
||||
.height(16)
|
||||
.width('100%')
|
||||
.textAlign(TextAlign.Center)
|
||||
}
|
||||
.width(40)
|
||||
.height(20)
|
||||
.borderRadius(10)
|
||||
.backgroundColor($r('app.color.elements_button_bg_disable_02'))
|
||||
.margin({ left: 8 })
|
||||
.onClick(() => {
|
||||
this.unfolded = !this.unfolded;
|
||||
})
|
||||
Row() {
|
||||
Text(this.unfolded
|
||||
? $r('app.string.hotlist_collapse')
|
||||
: $r('app.string.hotlist_expand'))
|
||||
.fontColor($r('app.color.elements_text_tertiary'))
|
||||
.fontSize(12)
|
||||
.height(16)
|
||||
.width('100%')
|
||||
.textAlign(TextAlign.Center)
|
||||
}
|
||||
.width(40)
|
||||
.height(20)
|
||||
.borderRadius(10)
|
||||
.backgroundColor($r('app.color.elements_button_bg_disable_02'))
|
||||
.margin({ left: 8 })
|
||||
.onClick(() => {
|
||||
this.toggleUnfolded();
|
||||
})
|
||||
|
||||
Blank()
|
||||
}
|
||||
@@ -540,7 +551,6 @@ export struct MarketRankingNodeComponent {
|
||||
}
|
||||
.width('100%')
|
||||
.height(this.emptyHeight())
|
||||
.margin({ top: 10 })
|
||||
.alignItems(HorizontalAlign.Center)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
}
|
||||
@@ -581,6 +591,8 @@ export struct MarketRankingNodeComponent {
|
||||
)
|
||||
}
|
||||
.width('100%')
|
||||
.height(this.emptyHeight())
|
||||
.animation({ duration: 180, curve: Curve.EaseInOut })
|
||||
}
|
||||
|
||||
@Builder
|
||||
@@ -626,6 +638,10 @@ export struct MarketRankingNodeComponent {
|
||||
|
||||
// ==================== 展示计算 ====================
|
||||
|
||||
private toggleUnfolded(): void {
|
||||
this.unfolded = !this.unfolded;
|
||||
}
|
||||
|
||||
private showTabGradient(): boolean {
|
||||
const maxOffset = this.tabContentWidth - this.tabViewportWidth;
|
||||
return maxOffset > 0 && this.tabScrollOffset < maxOffset;
|
||||
|
||||
Reference in New Issue
Block a user