add AI pick card
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
import { AbsRowData, RowData, TableData } from '@b2b/hq_table';
|
||||
import { TableRequestClient } from '@b2c/lib_baseui';
|
||||
import { RequestHelper, StuffTableStruct } from '@kernel/lib_communication';
|
||||
import {
|
||||
CardData,
|
||||
PickContractItem,
|
||||
PickTabData,
|
||||
} from '../../ai-pick/AiPickModels';
|
||||
import { getUniqueContracts } from '../../ai-pick/AiPickUtils';
|
||||
import { TableConstants } from '../../market-ranking/TableConstants';
|
||||
|
||||
const FRAME_ID = 2201;
|
||||
const PAGE_ID = 4106;
|
||||
const FIELD_IDS: number[] = [
|
||||
TableConstants.DATA_ID_CODE_4,
|
||||
TableConstants.DATA_ID_PRICE,
|
||||
TableConstants.DATA_ID_MARKET,
|
||||
TableConstants.DATA_ID_ZF_YTD,
|
||||
];
|
||||
|
||||
interface AiPickQuote {
|
||||
price?: number;
|
||||
priceChg?: number;
|
||||
}
|
||||
|
||||
export type AiPickCardDataListener = (cardData: CardData) => void;
|
||||
|
||||
class AiPickTableRequestClient extends TableRequestClient {
|
||||
private requestParams: string;
|
||||
private sourceCardData: CardData;
|
||||
private listener: AiPickCardDataListener;
|
||||
|
||||
constructor(
|
||||
requestParams: string,
|
||||
sourceCardData: CardData,
|
||||
listener: AiPickCardDataListener,
|
||||
) {
|
||||
super(FRAME_ID, PAGE_ID, [], null, undefined);
|
||||
this.requestParams = requestParams;
|
||||
this.sourceCardData = sourceCardData;
|
||||
this.listener = listener;
|
||||
this.setSubscribeIds(FIELD_IDS);
|
||||
}
|
||||
|
||||
protected doRequest(): void {
|
||||
RequestHelper.getHqManager()
|
||||
.addRequestStructToBuff(this.frameId, this.pageId, this.getInstanceId(), this.requestParams);
|
||||
RequestHelper.build().base(this.frameId, this.pageId, this, this.requestParams).request();
|
||||
}
|
||||
|
||||
protected afterParserModel(tableData: TableData, _structData: StuffTableStruct): void {
|
||||
const quoteMap: Map<string, AiPickQuote> = this.toQuoteMap(tableData);
|
||||
const nextCardData: CardData = this.mergeQuoteData(quoteMap);
|
||||
this.sourceCardData = nextCardData;
|
||||
this.listener(nextCardData);
|
||||
}
|
||||
|
||||
private toQuoteMap(tableData: TableData): Map<string, AiPickQuote> {
|
||||
const quoteMap: Map<string, AiPickQuote> = new Map<string, AiPickQuote>();
|
||||
if (!tableData.tableRows) {
|
||||
return quoteMap;
|
||||
}
|
||||
tableData.tableRows.forEach((row: AbsRowData): void => {
|
||||
if (!(row instanceof RowData)) {
|
||||
return;
|
||||
}
|
||||
const codeValue = row.originalData.get(TableConstants.DATA_ID_CODE_4);
|
||||
const marketValue = row.originalData.get(TableConstants.DATA_ID_MARKET);
|
||||
if (codeValue === undefined || marketValue === undefined) {
|
||||
return;
|
||||
}
|
||||
const quote: AiPickQuote = {
|
||||
price: this.getNumber(row, TableConstants.DATA_ID_PRICE),
|
||||
priceChg: this.getNumber(row, TableConstants.DATA_ID_ZF_YTD),
|
||||
};
|
||||
quoteMap.set(`${codeValue}_${marketValue}`, quote);
|
||||
});
|
||||
return quoteMap;
|
||||
}
|
||||
|
||||
private mergeQuoteData(quoteMap: Map<string, AiPickQuote>): CardData {
|
||||
const tabs: PickTabData[] =
|
||||
this.sourceCardData.tabs.map((tab: PickTabData): PickTabData => {
|
||||
const items: PickContractItem[] =
|
||||
tab.items.map((item: PickContractItem): PickContractItem => {
|
||||
const quote: AiPickQuote | undefined =
|
||||
quoteMap.get(`${item.contract}_${item.market}`);
|
||||
const nextItem: PickContractItem = {
|
||||
contract: item.contract,
|
||||
market: item.market,
|
||||
name: item.name,
|
||||
price: quote?.price ?? item.price,
|
||||
priceChg: quote?.priceChg ?? item.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;
|
||||
});
|
||||
const nextCardData: CardData = { tabs: tabs };
|
||||
return nextCardData;
|
||||
}
|
||||
|
||||
private getNumber(row: RowData, fieldId: number): number | undefined {
|
||||
const value = row.originalData.get(fieldId);
|
||||
if (typeof value === 'number') {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === 'string' && value !== '' && value !== '--') {
|
||||
const result: number = parseFloat(value);
|
||||
return Number.isNaN(result) ? undefined : result;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export class AiPickHqRequestClient {
|
||||
private static readonly instance: AiPickHqRequestClient =
|
||||
new AiPickHqRequestClient();
|
||||
|
||||
private constructor() {
|
||||
}
|
||||
|
||||
static getInstance(): AiPickHqRequestClient {
|
||||
return AiPickHqRequestClient.instance;
|
||||
}
|
||||
|
||||
subscribeHq(cardData: CardData, listener: AiPickCardDataListener): () => void {
|
||||
const contracts: PickContractItem[] = getUniqueContracts(cardData);
|
||||
if (contracts.length === 0) {
|
||||
return (): void => {
|
||||
};
|
||||
}
|
||||
const requestParams: string = this.buildRequestParams(contracts);
|
||||
const requestClient: AiPickTableRequestClient =
|
||||
new AiPickTableRequestClient(requestParams, cardData, listener);
|
||||
requestClient.request(0, contracts.length);
|
||||
return (): void => {
|
||||
requestClient.release(true);
|
||||
};
|
||||
}
|
||||
|
||||
private buildRequestParams(contracts: PickContractItem[]): string {
|
||||
return `\r\nsortid=-1\r\n` +
|
||||
`sortorder=0\r\n` +
|
||||
`push=1\r\n` +
|
||||
`dataitem=${FIELD_IDS.map((fieldId: number): string => `${fieldId},`).join('')}\r\n` +
|
||||
`codelist=${this.formatCodeList(contracts)}\r\n` +
|
||||
`update=1\r\n` +
|
||||
`scenario=qht_qihuo_sort\r\n` +
|
||||
`precision=1\r\n` +
|
||||
`pushtime=2.5\r\n`;
|
||||
}
|
||||
|
||||
private formatCodeList(contracts: PickContractItem[]): string {
|
||||
const markets: string[] = [];
|
||||
const codeGroups: string[][] = [];
|
||||
contracts.forEach((contract: PickContractItem): void => {
|
||||
const marketIndex: number = markets.indexOf(contract.market);
|
||||
if (marketIndex >= 0) {
|
||||
codeGroups[marketIndex].push(contract.contract);
|
||||
} else {
|
||||
markets.push(contract.market);
|
||||
codeGroups.push([contract.contract]);
|
||||
}
|
||||
});
|
||||
return markets.map((market: string, index: number): string =>
|
||||
`${market}(${codeGroups[index].map((code: string): string => `${code},`).join('')});`
|
||||
).join('');
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,7 @@ export interface FirstPageCardsConfig {
|
||||
aiRiseFall: AllCardsCard
|
||||
commodityOptions: CommodityOptionsCardConfig
|
||||
marketRanking: AllCardsCard
|
||||
aiPick: AllCardsCard
|
||||
}
|
||||
|
||||
export class FirstPageCardsConfigLoader {
|
||||
|
||||
Reference in New Issue
Block a user