add AI pick card
This commit is contained in:
@@ -0,0 +1,746 @@
|
||||
import { emitter } from '@kit.BasicServicesKit';
|
||||
import { enableDarkMode } from '@kernel/theme_manager';
|
||||
import { EmitterConstants, GlobalContext, jumpToQuote } from 'biz_common';
|
||||
import { AiPickDataFetcher } from './AiPickDataFetcher';
|
||||
import { AiPickHqRequestClient } from '../node/clients/AiPickHqRequestClient';
|
||||
import {
|
||||
CardData,
|
||||
PickContractItem,
|
||||
PickStrategy,
|
||||
PickTabData,
|
||||
} from './AiPickModels';
|
||||
import {
|
||||
cellColor,
|
||||
cellValue,
|
||||
formatColName,
|
||||
getUniqueContracts,
|
||||
} from './AiPickUtils';
|
||||
import {
|
||||
EMPTY_IMAGE_DARK,
|
||||
EMPTY_IMAGE_LIGHT,
|
||||
MAX_ITEMS,
|
||||
} from './AiPickConstant';
|
||||
import { AllCardsCard } from '../node/model/AiDiagnosisNodeModel';
|
||||
import { RouterUtil } from '../util/RouterUtil';
|
||||
import { getResourceString } from '../util/ResourceUtil';
|
||||
|
||||
interface StrategyDescParams {
|
||||
tabIdx: number;
|
||||
}
|
||||
|
||||
const TAB_BAR_HEIGHT = 30;
|
||||
const STRATEGY_DESC_HEIGHT = 86;
|
||||
const TABLE_HEADER_HEIGHT = 40;
|
||||
const TABLE_ROW_HEIGHT = 45;
|
||||
const TABLE_HEIGHT = TABLE_HEADER_HEIGHT + TABLE_ROW_HEIGHT * MAX_ITEMS;
|
||||
const CUSTOM_STRATEGY_HEIGHT = 30;
|
||||
const MAIN_CONTENT_HEIGHT =
|
||||
TAB_BAR_HEIGHT + STRATEGY_DESC_HEIGHT + TABLE_HEIGHT + CUSTOM_STRATEGY_HEIGHT;
|
||||
const NO_CONTRACT_HEIGHT = STRATEGY_DESC_HEIGHT + TABLE_HEIGHT;
|
||||
|
||||
@Component
|
||||
export struct AiPickNodeComponent {
|
||||
@Link @Watch('onRefreshTriggerChange') refreshTrigger: number;
|
||||
@Consume('firstPageVisible') @Watch('onFirstPageVisibleChange')
|
||||
firstPageVisible: boolean = true;
|
||||
@StorageProp(enableDarkMode) isDarkMode: boolean = false;
|
||||
|
||||
@State cardConfig: AllCardsCard | undefined = undefined;
|
||||
@State cardData: CardData = { tabs: [] };
|
||||
@State dataReady: boolean = false;
|
||||
@State tabIdx: number = 0;
|
||||
@State tabViewportWidth: number = 0;
|
||||
@State tabContentWidth: number = 0;
|
||||
@State tabScrollOffset: number = 0;
|
||||
@State showExplainSheet: boolean = false;
|
||||
|
||||
private isComponentActive: boolean = false;
|
||||
private dataRequestVersion: number = 0;
|
||||
private hqSubscriptionVersion: number = 0;
|
||||
private hqUnsubscribe: (() => void) | undefined;
|
||||
private isTcpEventSubscribed: boolean = false;
|
||||
private tcpReconnectListener = (): void => {
|
||||
if (!this.canUseHq()) {
|
||||
return;
|
||||
}
|
||||
setTimeout((): void => {
|
||||
if (this.canUseHq()) {
|
||||
this.restartSubscription();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
aboutToAppear(): void {
|
||||
this.isComponentActive = true;
|
||||
this.updateCardConfig();
|
||||
if (this.firstPageVisible) {
|
||||
this.subscribeTcpNetStatus();
|
||||
}
|
||||
this.updateCardData();
|
||||
}
|
||||
|
||||
aboutToDisappear(): void {
|
||||
this.isComponentActive = false;
|
||||
this.dataRequestVersion += 1;
|
||||
this.stopSubscribeHq();
|
||||
this.unSubscribeTcpNetStatus();
|
||||
}
|
||||
|
||||
onRefreshTriggerChange(): void {
|
||||
if (!this.isComponentActive) {
|
||||
return;
|
||||
}
|
||||
this.updateCardConfig();
|
||||
this.updateCardData();
|
||||
}
|
||||
|
||||
onFirstPageVisibleChange(): void {
|
||||
if (!this.isComponentActive) {
|
||||
return;
|
||||
}
|
||||
if (!this.firstPageVisible) {
|
||||
this.stopSubscribeHq();
|
||||
this.unSubscribeTcpNetStatus();
|
||||
return;
|
||||
}
|
||||
this.subscribeTcpNetStatus();
|
||||
if (this.cardData.tabs.length > 0) {
|
||||
this.subscribeHq();
|
||||
} else {
|
||||
this.updateCardData();
|
||||
}
|
||||
}
|
||||
|
||||
private updateCardConfig(): void {
|
||||
this.cardConfig = AiPickDataFetcher.getInstance().fetchCardConfig();
|
||||
}
|
||||
|
||||
private async updateCardData(): Promise<void> {
|
||||
if (!this.isComponentActive) {
|
||||
return;
|
||||
}
|
||||
const requestVersion: number = this.dataRequestVersion + 1;
|
||||
this.dataRequestVersion = requestVersion;
|
||||
this.stopSubscribeHq();
|
||||
if (this.cardData.tabs.length === 0) {
|
||||
this.dataReady = false;
|
||||
}
|
||||
try {
|
||||
const tabs: PickTabData[] =
|
||||
await AiPickDataFetcher.getInstance().fetchCardData();
|
||||
if (!this.isCurrentDataRequest(requestVersion)) {
|
||||
return;
|
||||
}
|
||||
const nextTabs: PickTabData[] = this.mergeCachedQuotes(tabs);
|
||||
if (this.tabIdx >= nextTabs.length) {
|
||||
this.tabIdx = 0;
|
||||
}
|
||||
this.cardData = { tabs: nextTabs };
|
||||
this.dataReady = true;
|
||||
if (nextTabs.length > 0 && this.firstPageVisible) {
|
||||
this.subscribeHq();
|
||||
}
|
||||
} catch {
|
||||
if (!this.isCurrentDataRequest(requestVersion)) {
|
||||
return;
|
||||
}
|
||||
this.dataReady = true;
|
||||
if (this.cardData.tabs.length > 0 && this.firstPageVisible) {
|
||||
this.subscribeHq();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private mergeCachedQuotes(tabs: PickTabData[]): PickTabData[] {
|
||||
const cachedContracts: PickContractItem[] = getUniqueContracts(this.cardData);
|
||||
const cachedMap: Map<string, PickContractItem> =
|
||||
new Map<string, PickContractItem>();
|
||||
cachedContracts.forEach((item: PickContractItem): void => {
|
||||
cachedMap.set(`${item.contract}_${item.market}`, item);
|
||||
});
|
||||
return tabs.map((tab: PickTabData): PickTabData => {
|
||||
const items: PickContractItem[] =
|
||||
tab.items.map((item: PickContractItem): PickContractItem => {
|
||||
const cachedItem: PickContractItem | undefined =
|
||||
cachedMap.get(`${item.contract}_${item.market}`);
|
||||
const nextItem: PickContractItem = {
|
||||
contract: item.contract,
|
||||
market: item.market,
|
||||
name: item.name,
|
||||
price: cachedItem?.price,
|
||||
priceChg: cachedItem?.priceChg,
|
||||
isMain: item.isMain,
|
||||
extraFields: item.extraFields,
|
||||
};
|
||||
return nextItem;
|
||||
});
|
||||
const nextTab: PickTabData = {
|
||||
strategy: tab.strategy,
|
||||
items: items,
|
||||
keysList: tab.keysList,
|
||||
fieldList: tab.fieldList,
|
||||
};
|
||||
return nextTab;
|
||||
});
|
||||
}
|
||||
|
||||
private subscribeHq(): void {
|
||||
this.stopSubscribeHq();
|
||||
if (!this.canUseHq() || this.cardData.tabs.length === 0) {
|
||||
return;
|
||||
}
|
||||
const subscriptionVersion: number = this.hqSubscriptionVersion;
|
||||
this.hqUnsubscribe = AiPickHqRequestClient.getInstance().subscribeHq(
|
||||
this.cardData,
|
||||
(cardData: CardData): void => {
|
||||
if (this.canUseHq() &&
|
||||
subscriptionVersion === this.hqSubscriptionVersion) {
|
||||
this.cardData = cardData;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
private stopSubscribeHq(): void {
|
||||
this.hqSubscriptionVersion += 1;
|
||||
if (this.hqUnsubscribe !== undefined) {
|
||||
this.hqUnsubscribe();
|
||||
this.hqUnsubscribe = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private restartSubscription(): void {
|
||||
if (this.cardData.tabs.length > 0) {
|
||||
this.subscribeHq();
|
||||
} else if (this.dataReady) {
|
||||
this.updateCardData();
|
||||
}
|
||||
}
|
||||
|
||||
private subscribeTcpNetStatus(): void {
|
||||
if (this.isTcpEventSubscribed || !this.canUseHq()) {
|
||||
return;
|
||||
}
|
||||
this.isTcpEventSubscribed = true;
|
||||
emitter.on(
|
||||
{ eventId: EmitterConstants.NETWORK_TCP_RECONNECT },
|
||||
this.tcpReconnectListener,
|
||||
);
|
||||
}
|
||||
|
||||
private unSubscribeTcpNetStatus(): void {
|
||||
if (!this.isTcpEventSubscribed) {
|
||||
return;
|
||||
}
|
||||
this.isTcpEventSubscribed = false;
|
||||
emitter.off(
|
||||
EmitterConstants.NETWORK_TCP_RECONNECT,
|
||||
this.tcpReconnectListener,
|
||||
);
|
||||
}
|
||||
|
||||
private canUseHq(): boolean {
|
||||
return this.isComponentActive && this.firstPageVisible;
|
||||
}
|
||||
|
||||
private isCurrentDataRequest(requestVersion: number): boolean {
|
||||
return this.isComponentActive && requestVersion === this.dataRequestVersion;
|
||||
}
|
||||
|
||||
private showTabGradient(): boolean {
|
||||
const maxOffset: number = this.tabContentWidth - this.tabViewportWidth;
|
||||
return maxOffset > 0 && this.tabScrollOffset < maxOffset;
|
||||
}
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
this.buildTitleBar()
|
||||
if (this.cardData.tabs.length > 0) {
|
||||
this.buildMainContent()
|
||||
} else {
|
||||
this.buildEmptyState()
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.backgroundColor($r('app.color.surface_layer1_foreground'))
|
||||
.borderRadius(4)
|
||||
.padding({ left: 10, right: 10, bottom: 10 })
|
||||
.bindSheet(this.showExplainSheet, this.buildExplainSheetContent, {
|
||||
height: SheetSize.FIT_CONTENT,
|
||||
dragBar: true,
|
||||
showClose: false,
|
||||
maskColor: $r('app.color.mask_level2'),
|
||||
onDisappear: () => {
|
||||
this.showExplainSheet = false;
|
||||
},
|
||||
radius: {
|
||||
topLeft: 10,
|
||||
topRight: 10,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@Builder
|
||||
buildTitleBar() {
|
||||
Row() {
|
||||
Row({ space: 4 }) {
|
||||
Text(this.cardConfig?.card_title.value || $r('app.string.ai_pick_title'))
|
||||
.fontSize(18)
|
||||
.fontWeight(500)
|
||||
.fontColor($r('app.color.elements_text_primary_02'))
|
||||
.maxLines(1)
|
||||
|
||||
if ((this.cardConfig?.card_url.android ?? '') !== '' ||
|
||||
(this.cardConfig?.card_url.ios ?? '') !== '') {
|
||||
Image($r('app.media.icon_arrow_forward_20'))
|
||||
.width(20)
|
||||
.height(20)
|
||||
.fillColor($r('app.color.elements_icon_primary_02'))
|
||||
}
|
||||
}
|
||||
.height('100%')
|
||||
.alignItems(VerticalAlign.Center)
|
||||
.onClick(() => {
|
||||
this.jumpToCardTitle();
|
||||
})
|
||||
|
||||
if ((this.cardConfig?.explain_message ?? '') !== '') {
|
||||
Image($r('app.media.icon_info_24'))
|
||||
.width(16)
|
||||
.height(16)
|
||||
.fillColor($r('app.color.elements_icon_tertiary'))
|
||||
.margin({ left: 8 })
|
||||
.onClick(() => {
|
||||
this.showExplainSheet = true;
|
||||
})
|
||||
}
|
||||
|
||||
Blank()
|
||||
}
|
||||
.width('100%')
|
||||
.height(48)
|
||||
.alignItems(VerticalAlign.Center)
|
||||
}
|
||||
|
||||
@Builder
|
||||
buildExplainSheetContent() {
|
||||
Column() {
|
||||
Stack({ alignContent: Alignment.End }) {
|
||||
Text(this.cardConfig?.explain_title ||
|
||||
this.cardConfig?.card_title.value ||
|
||||
$r('app.string.ai_pick_title'))
|
||||
.fontSize(18)
|
||||
.fontWeight(500)
|
||||
.textAlign(TextAlign.Center)
|
||||
.width('100%')
|
||||
|
||||
Image($r('app.media.icon_close_24'))
|
||||
.width(24)
|
||||
.height(24)
|
||||
.fillColor($r('app.color.elements_icon_primary_02'))
|
||||
.onClick(() => {
|
||||
this.showExplainSheet = false;
|
||||
})
|
||||
}
|
||||
.height(64)
|
||||
.width('100%')
|
||||
|
||||
Scroll() {
|
||||
Text((this.cardConfig?.explain_message ?? '')
|
||||
.replace(new RegExp('\\\\n', 'g'), '\n'))
|
||||
.width('100%')
|
||||
.fontSize(14)
|
||||
.lineHeight(22)
|
||||
.fontColor($r('app.color.elements_text_primary_02'))
|
||||
}
|
||||
.width('100%')
|
||||
.scrollBar(BarState.Off)
|
||||
|
||||
Button($r('app.string.card_explain_confirm'))
|
||||
.type(ButtonType.Normal)
|
||||
.backgroundColor($r('app.color.elements_button_bg_primary'))
|
||||
.width('100%')
|
||||
.height(44)
|
||||
.borderRadius(4)
|
||||
.margin({ top: 16 })
|
||||
.onClick(() => {
|
||||
this.showExplainSheet = false;
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.backgroundColor($r('app.color.surface_layer3_background'))
|
||||
.padding({
|
||||
bottom: px2vp(GlobalContext.navigationBarHeight),
|
||||
left: 16,
|
||||
right: 16,
|
||||
})
|
||||
}
|
||||
|
||||
@Builder
|
||||
buildMainContent() {
|
||||
Column() {
|
||||
this.buildTabBar()
|
||||
if (this.cardData.tabs[this.tabIdx].items.length > 0) {
|
||||
this.buildStrategyDesc({ tabIdx: this.tabIdx })
|
||||
this.buildTable()
|
||||
} else {
|
||||
this.buildNoContractState()
|
||||
}
|
||||
this.buildCustomStrategy()
|
||||
}
|
||||
.width('100%')
|
||||
.height(MAIN_CONTENT_HEIGHT)
|
||||
}
|
||||
|
||||
@Builder
|
||||
buildTabBar() {
|
||||
Stack({ alignContent: Alignment.End }) {
|
||||
Scroll() {
|
||||
Row({ space: 8 }) {
|
||||
ForEach(this.cardData.tabs, (tab: PickTabData, index: number) => {
|
||||
Text(`${tab.strategy.name}(${tab.strategy.count})`)
|
||||
.fontSize(14)
|
||||
.fontWeight(this.tabIdx === index
|
||||
? FontWeight.Medium
|
||||
: FontWeight.Normal)
|
||||
.fontColor(this.tabIdx === index
|
||||
? $r('app.color.elements_text_primary_01')
|
||||
: $r('app.color.elements_text_secondary'))
|
||||
.constraintSize({ minWidth: 66 })
|
||||
.maxLines(1)
|
||||
.textAlign(TextAlign.Center)
|
||||
.height(TAB_BAR_HEIGHT)
|
||||
.padding({ left: 8, right: 8 })
|
||||
.borderRadius(4)
|
||||
.backgroundColor(this.tabIdx === index
|
||||
? $r('app.color.elements_others_bg_primary')
|
||||
: $r('app.color.elements_button_bg_tertiary'))
|
||||
.onClick(() => {
|
||||
this.tabIdx = index;
|
||||
})
|
||||
}, (tab: PickTabData): string =>
|
||||
`${tab.strategy.periodType}_${tab.strategy.id}`)
|
||||
}
|
||||
.onAreaChange((_oldValue: Area, newValue: Area) => {
|
||||
this.tabContentWidth = Number(newValue.width);
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.height(TAB_BAR_HEIGHT)
|
||||
.padding({ right: 10 })
|
||||
.scrollable(ScrollDirection.Horizontal)
|
||||
.scrollBar(BarState.Off)
|
||||
.align(Alignment.Start)
|
||||
.onScroll((xOffset: number, _yOffset: number) => {
|
||||
this.tabScrollOffset = xOffset;
|
||||
})
|
||||
|
||||
if (this.showTabGradient()) {
|
||||
Row()
|
||||
.width(24)
|
||||
.height(TAB_BAR_HEIGHT)
|
||||
.linearGradient({
|
||||
angle: 90,
|
||||
colors: [
|
||||
[$r('app.color.transparent_white'), 0],
|
||||
[$r('app.color.surface_layer1_foreground'), 1],
|
||||
],
|
||||
})
|
||||
.hitTestBehavior(HitTestMode.None)
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height(TAB_BAR_HEIGHT)
|
||||
.onAreaChange((_oldValue: Area, newValue: Area) => {
|
||||
this.tabViewportWidth = Number(newValue.width);
|
||||
})
|
||||
}
|
||||
|
||||
@Builder
|
||||
buildStrategyDesc($$: StrategyDescParams) {
|
||||
Row() {
|
||||
Column({ space: 4 }) {
|
||||
if (this.cardData.tabs[$$.tabIdx].strategy.detail !== '') {
|
||||
Text(this.cardData.tabs[$$.tabIdx].strategy.detail)
|
||||
.fontSize(14)
|
||||
.lineHeight(21)
|
||||
.fontColor($r('app.color.elements_text_primary_02'))
|
||||
.maxLines(2)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
.onClick(() => {
|
||||
this.jumpToStrategyDetail(
|
||||
this.cardData.tabs[$$.tabIdx].strategy,
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
if (this.cardData.tabs[$$.tabIdx].strategy.tagList.length > 0) {
|
||||
Row({ space: 4 }) {
|
||||
ForEach(
|
||||
this.cardData.tabs[$$.tabIdx].strategy.tagList,
|
||||
(tag: string) => {
|
||||
Text(tag)
|
||||
.fontSize(11)
|
||||
.lineHeight(18)
|
||||
.fontColor($r('app.color.elements_text_primary_01'))
|
||||
.maxLines(1)
|
||||
.height(18)
|
||||
.padding({ left: 3, right: 3 })
|
||||
.borderRadius(2)
|
||||
.border({
|
||||
width: 0.5,
|
||||
color: $r('app.color.elements_text_primary_01'),
|
||||
})
|
||||
.onClick(() => {
|
||||
this.jumpToLabel(
|
||||
this.cardData.tabs[$$.tabIdx].strategy,
|
||||
tag,
|
||||
);
|
||||
})
|
||||
},
|
||||
(tag: string): string => tag,
|
||||
)
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
}
|
||||
.layoutWeight(1)
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
|
||||
if ((this.cardData.tabs[$$.tabIdx]
|
||||
.strategy.imgs[this.isDarkMode ? 1 : 0] ?? '') !== '') {
|
||||
Image(this.cardData.tabs[$$.tabIdx]
|
||||
.strategy.imgs[this.isDarkMode ? 1 : 0] ?? '')
|
||||
.width(104)
|
||||
.height(66)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ left: 10 })
|
||||
.onClick(() => {
|
||||
this.jumpToStrategyDetail(
|
||||
this.cardData.tabs[$$.tabIdx].strategy,
|
||||
);
|
||||
})
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height(STRATEGY_DESC_HEIGHT)
|
||||
.padding({ top: 10, bottom: 10 })
|
||||
.alignItems(VerticalAlign.Top)
|
||||
}
|
||||
|
||||
@Builder
|
||||
buildTable() {
|
||||
Column() {
|
||||
Row({ space: 8 }) {
|
||||
Text(formatColName(this.cardData.tabs[this.tabIdx].keysList[0]))
|
||||
.fontSize(14)
|
||||
.fontColor($r('app.color.elements_text_tertiary'))
|
||||
.width('35%')
|
||||
Text(formatColName(this.cardData.tabs[this.tabIdx].keysList[1]))
|
||||
.fontSize(14)
|
||||
.fontColor($r('app.color.elements_text_tertiary'))
|
||||
.layoutWeight(1)
|
||||
.textAlign(TextAlign.End)
|
||||
Text(formatColName(this.cardData.tabs[this.tabIdx].keysList[2]))
|
||||
.fontSize(14)
|
||||
.fontColor($r('app.color.elements_text_tertiary'))
|
||||
.layoutWeight(1)
|
||||
.textAlign(TextAlign.End)
|
||||
}
|
||||
.width('100%')
|
||||
.height(TABLE_HEADER_HEIGHT)
|
||||
|
||||
ForEach(
|
||||
this.cardData.tabs[this.tabIdx].items,
|
||||
(item: PickContractItem) => {
|
||||
this.buildContractRow(item)
|
||||
},
|
||||
(item: PickContractItem): string =>
|
||||
`${item.contract}_${item.market}_${item.price ?? ''}_${item.priceChg ?? ''}`,
|
||||
)
|
||||
}
|
||||
.width('100%')
|
||||
.height(TABLE_HEIGHT)
|
||||
}
|
||||
|
||||
@Builder
|
||||
buildContractRow(item: PickContractItem) {
|
||||
Row({ space: 8 }) {
|
||||
Row({ space: 5 }) {
|
||||
Text(item.name)
|
||||
.fontSize(16)
|
||||
.maxFontSize(16)
|
||||
.minFontSize(9)
|
||||
.fontColor($r('app.color.elements_text_primary_02'))
|
||||
.layoutWeight(1)
|
||||
.maxLines(1)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
if (item.isMain) {
|
||||
Text($r('app.string.ai_pick_main_contract'))
|
||||
.fontSize(11)
|
||||
.fontColor($r('app.color.hotlist_orange'))
|
||||
.width(16)
|
||||
.height(16)
|
||||
.textAlign(TextAlign.Center)
|
||||
.borderRadius(2)
|
||||
.backgroundColor($r('app.color.elements_button_bg_tertiary'))
|
||||
}
|
||||
}
|
||||
.width('35%')
|
||||
.alignItems(VerticalAlign.Center)
|
||||
|
||||
Text(cellValue(
|
||||
this.cardData.tabs[this.tabIdx].keysList[1],
|
||||
item,
|
||||
this.cardData.tabs[this.tabIdx].fieldList,
|
||||
))
|
||||
.fontSize(16)
|
||||
.maxFontSize(16)
|
||||
.minFontSize(9)
|
||||
.fontWeight(500)
|
||||
.fontColor(cellColor(
|
||||
this.cardData.tabs[this.tabIdx].keysList[1],
|
||||
item,
|
||||
))
|
||||
.layoutWeight(1)
|
||||
.textAlign(TextAlign.End)
|
||||
.maxLines(1)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
|
||||
Text(cellValue(
|
||||
this.cardData.tabs[this.tabIdx].keysList[2],
|
||||
item,
|
||||
this.cardData.tabs[this.tabIdx].fieldList,
|
||||
))
|
||||
.fontSize(16)
|
||||
.maxFontSize(16)
|
||||
.minFontSize(9)
|
||||
.fontWeight(500)
|
||||
.fontColor(cellColor(
|
||||
this.cardData.tabs[this.tabIdx].keysList[2],
|
||||
item,
|
||||
))
|
||||
.layoutWeight(1)
|
||||
.textAlign(TextAlign.End)
|
||||
.maxLines(1)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
}
|
||||
.width('100%')
|
||||
.height(TABLE_ROW_HEIGHT)
|
||||
.alignItems(VerticalAlign.Center)
|
||||
.border({
|
||||
width: { top: 1 },
|
||||
color: $r('app.color.elements_others_divider_primary'),
|
||||
})
|
||||
.onClick(() => {
|
||||
this.jumpToDetail(item);
|
||||
})
|
||||
}
|
||||
|
||||
@Builder
|
||||
buildCustomStrategy() {
|
||||
Row({ space: 2 }) {
|
||||
Text($r('app.string.ai_pick_custom_strategy'))
|
||||
.fontSize(14)
|
||||
.lineHeight(20)
|
||||
.fontColor($r('app.color.elements_text_tertiary'))
|
||||
Image($r('app.media.icon_arrow_forward_20'))
|
||||
.width(14)
|
||||
.height(14)
|
||||
.fillColor($r('app.color.elements_icon_tertiary'))
|
||||
}
|
||||
.width('100%')
|
||||
.height(CUSTOM_STRATEGY_HEIGHT)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.alignItems(VerticalAlign.Center)
|
||||
.onClick(() => {
|
||||
this.jumpToNewHome();
|
||||
})
|
||||
}
|
||||
|
||||
@Builder
|
||||
buildEmptyState() {
|
||||
Column() {
|
||||
if (this.dataReady) {
|
||||
Image(this.isDarkMode ? EMPTY_IMAGE_DARK : EMPTY_IMAGE_LIGHT)
|
||||
.width(120)
|
||||
.height(120)
|
||||
.margin({ bottom: 8 })
|
||||
Text($r('app.string.ai_pick_no_contract'))
|
||||
.fontSize(14)
|
||||
.fontColor($r('app.color.elements_text_tertiary'))
|
||||
} else {
|
||||
Text($r('app.string.ai_pick_loading'))
|
||||
.fontSize(14)
|
||||
.fontColor($r('app.color.elements_text_tertiary'))
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height(MAIN_CONTENT_HEIGHT)
|
||||
.alignItems(HorizontalAlign.Center)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
}
|
||||
|
||||
@Builder
|
||||
buildNoContractState() {
|
||||
Column() {
|
||||
Image(this.isDarkMode ? EMPTY_IMAGE_DARK : EMPTY_IMAGE_LIGHT)
|
||||
.width(100)
|
||||
.height(100)
|
||||
Text($r('app.string.ai_pick_no_contract'))
|
||||
.fontSize(14)
|
||||
.fontColor($r('app.color.elements_text_tertiary'))
|
||||
}
|
||||
.width('100%')
|
||||
.height(NO_CONTRACT_HEIGHT)
|
||||
.alignItems(HorizontalAlign.Center)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
}
|
||||
|
||||
private jumpToDetail(item: PickContractItem): void {
|
||||
const contracts: PickContractItem[] = getUniqueContracts(this.cardData);
|
||||
const codeList: string =
|
||||
contracts.map((contract: PickContractItem): string => contract.contract).join(',');
|
||||
const marketIdList: string =
|
||||
contracts.map((contract: PickContractItem): string => contract.market).join(',');
|
||||
const nameList: string =
|
||||
contracts.map((contract: PickContractItem): string => contract.name).join(',');
|
||||
jumpToQuote(item.contract, item.market, codeList, marketIdList, nameList);
|
||||
}
|
||||
|
||||
private jumpToCardTitle(): void {
|
||||
const jumpUrl: string =
|
||||
this.cardConfig?.card_url.android || this.cardConfig?.card_url.ios || '';
|
||||
RouterUtil.jumpPage(jumpUrl, true);
|
||||
}
|
||||
|
||||
private jumpToNewHome(): void {
|
||||
const pageUrl: string =
|
||||
'https://fupage.10jqka.com.cn/ai-web/ai-diagnosis-home.html?sync=1';
|
||||
RouterUtil.jumpPage(this.buildClientUrl(pageUrl), true);
|
||||
}
|
||||
|
||||
private jumpToStrategyDetail(strategy: PickStrategy): void {
|
||||
const pageUrl: string =
|
||||
'https://fupage.10jqka.com.cn/ai-web/ai-diagnosis-detail.html' +
|
||||
`?id=${strategy.id}&type=${strategy.periodType}` +
|
||||
`&name=${encodeURIComponent(strategy.name)}`;
|
||||
RouterUtil.jumpPage(this.buildClientUrl(pageUrl), true);
|
||||
}
|
||||
|
||||
private jumpToLabel(strategy: PickStrategy, label: string): void {
|
||||
const pageUrl: string =
|
||||
'https://fupage.10jqka.com.cn/ai-web/ai-diagnosis-label.html' +
|
||||
`?id=${strategy.id}&type=${strategy.periodType}` +
|
||||
`&label=${encodeURIComponent(label)}`;
|
||||
RouterUtil.jumpPage(this.buildClientUrl(pageUrl), true);
|
||||
}
|
||||
|
||||
private buildClientUrl(pageUrl: string): string {
|
||||
const title: string =
|
||||
this.cardConfig?.card_title.value ||
|
||||
getResourceString(getContext(this), $r('app.string.ai_pick_title'));
|
||||
return 'client.html?action=ymtz^ishiddenbar=1^mode=new^webid=2804^' +
|
||||
`url=${pageUrl}^title=${title}`;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user