update pay ui
This commit is contained in:
@@ -106,8 +106,48 @@ const handleSZSERealtimeMessage = (
|
||||
switch (category) {
|
||||
case 'stock': {
|
||||
const stockData = data as SZSEStockData;
|
||||
const { prices: bidPrices, volumes: bidVolumes } = extractOrderBook(stockData.bids);
|
||||
const { prices: askPrices, volumes: askVolumes } = extractOrderBook(stockData.asks);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const rawData = data as any; // 用于检查替代字段名
|
||||
|
||||
// 调试日志:检查深交所返回的盘口原始数据(临时使用 warn 级别方便调试)
|
||||
if (!stockData.bids || stockData.bids.length === 0) {
|
||||
logger.warn('FlexScreen', `SZSE股票数据无盘口 ${fullCode}`, {
|
||||
hasBids: !!stockData.bids,
|
||||
hasAsks: !!stockData.asks,
|
||||
bidsLength: stockData.bids?.length || 0,
|
||||
asksLength: stockData.asks?.length || 0,
|
||||
// 检查替代字段名
|
||||
hasBidPrices: !!rawData.bid_prices,
|
||||
hasAskPrices: !!rawData.ask_prices,
|
||||
dataKeys: Object.keys(stockData), // 查看服务端实际返回了哪些字段
|
||||
});
|
||||
}
|
||||
|
||||
// 优先使用 bids/asks 对象数组格式,如果不存在则尝试 bid_prices/ask_prices 分离数组格式
|
||||
let bidPrices: number[] = [];
|
||||
let bidVolumes: number[] = [];
|
||||
let askPrices: number[] = [];
|
||||
let askVolumes: number[] = [];
|
||||
|
||||
if (stockData.bids && stockData.bids.length > 0) {
|
||||
const extracted = extractOrderBook(stockData.bids);
|
||||
bidPrices = extracted.prices;
|
||||
bidVolumes = extracted.volumes;
|
||||
} else if (rawData.bid_prices && Array.isArray(rawData.bid_prices)) {
|
||||
// 替代格式:bid_prices 和 bid_volumes 分离
|
||||
bidPrices = rawData.bid_prices;
|
||||
bidVolumes = rawData.bid_volumes || [];
|
||||
}
|
||||
|
||||
if (stockData.asks && stockData.asks.length > 0) {
|
||||
const extracted = extractOrderBook(stockData.asks);
|
||||
askPrices = extracted.prices;
|
||||
askVolumes = extracted.volumes;
|
||||
} else if (rawData.ask_prices && Array.isArray(rawData.ask_prices)) {
|
||||
// 替代格式:ask_prices 和 ask_volumes 分离
|
||||
askPrices = rawData.ask_prices;
|
||||
askVolumes = rawData.ask_volumes || [];
|
||||
}
|
||||
|
||||
updated[fullCode] = {
|
||||
code: fullCode,
|
||||
@@ -270,8 +310,43 @@ const handleSZSESnapshotMessage = (
|
||||
|
||||
if (subscribedCodes.has(rawCode) || subscribedCodes.has(fullCode)) {
|
||||
hasUpdate = true;
|
||||
const { prices: bidPrices, volumes: bidVolumes } = extractOrderBook(s.bids);
|
||||
const { prices: askPrices, volumes: askVolumes } = extractOrderBook(s.asks);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const rawData = s as any; // 用于检查替代字段名
|
||||
|
||||
// 调试日志:检查快照消息中的盘口数据(无盘口时警告)
|
||||
if (!s.bids || s.bids.length === 0) {
|
||||
logger.warn('FlexScreen', `SZSE快照股票数据无盘口 ${fullCode}`, {
|
||||
hasBids: !!s.bids,
|
||||
hasAsks: !!s.asks,
|
||||
hasBidPrices: !!rawData.bid_prices,
|
||||
hasAskPrices: !!rawData.ask_prices,
|
||||
dataKeys: Object.keys(s),
|
||||
});
|
||||
}
|
||||
|
||||
// 优先使用 bids/asks 对象数组格式,如果不存在则尝试 bid_prices/ask_prices 分离数组格式
|
||||
let bidPrices: number[] = [];
|
||||
let bidVolumes: number[] = [];
|
||||
let askPrices: number[] = [];
|
||||
let askVolumes: number[] = [];
|
||||
|
||||
if (s.bids && s.bids.length > 0) {
|
||||
const extracted = extractOrderBook(s.bids);
|
||||
bidPrices = extracted.prices;
|
||||
bidVolumes = extracted.volumes;
|
||||
} else if (rawData.bid_prices && Array.isArray(rawData.bid_prices)) {
|
||||
bidPrices = rawData.bid_prices;
|
||||
bidVolumes = rawData.bid_volumes || [];
|
||||
}
|
||||
|
||||
if (s.asks && s.asks.length > 0) {
|
||||
const extracted = extractOrderBook(s.asks);
|
||||
askPrices = extracted.prices;
|
||||
askVolumes = extracted.volumes;
|
||||
} else if (rawData.ask_prices && Array.isArray(rawData.ask_prices)) {
|
||||
askPrices = rawData.ask_prices;
|
||||
askVolumes = rawData.ask_volumes || [];
|
||||
}
|
||||
|
||||
updated[fullCode] = {
|
||||
code: fullCode,
|
||||
|
||||
@@ -75,20 +75,65 @@ export const normalizeCode = (code: string): string => {
|
||||
return code.split('.')[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* 盘口数据可能的格式(根据不同的 WebSocket 服务端实现)
|
||||
*/
|
||||
type OrderBookInput =
|
||||
| OrderBookLevel[] // 格式1: [{price, volume}, ...]
|
||||
| Array<[number, number]> // 格式2: [[price, volume], ...]
|
||||
| { prices: number[]; volumes: number[] } // 格式3: {prices: [...], volumes: [...]}
|
||||
| undefined;
|
||||
|
||||
/**
|
||||
* 从深交所 bids/asks 数组提取价格和量数组
|
||||
* @param orderBook - 盘口数组 [{price, volume}, ...]
|
||||
* 支持多种可能的数据格式
|
||||
* @param orderBook - 盘口数据,支持多种格式
|
||||
* @returns { prices, volumes }
|
||||
*/
|
||||
export const extractOrderBook = (
|
||||
orderBook: OrderBookLevel[] | undefined
|
||||
orderBook: OrderBookInput
|
||||
): { prices: number[]; volumes: number[] } => {
|
||||
if (!orderBook || !Array.isArray(orderBook)) {
|
||||
if (!orderBook) {
|
||||
return { prices: [], volumes: [] };
|
||||
}
|
||||
const prices = orderBook.map(item => item.price || 0);
|
||||
const volumes = orderBook.map(item => item.volume || 0);
|
||||
return { prices, volumes };
|
||||
|
||||
// 格式3: 已经是 {prices, volumes} 结构
|
||||
if (!Array.isArray(orderBook) && 'prices' in orderBook && 'volumes' in orderBook) {
|
||||
return {
|
||||
prices: orderBook.prices || [],
|
||||
volumes: orderBook.volumes || [],
|
||||
};
|
||||
}
|
||||
|
||||
// 必须是数组才能继续
|
||||
if (!Array.isArray(orderBook) || orderBook.length === 0) {
|
||||
return { prices: [], volumes: [] };
|
||||
}
|
||||
|
||||
const firstItem = orderBook[0];
|
||||
|
||||
// 格式2: [[price, volume], ...]
|
||||
if (Array.isArray(firstItem)) {
|
||||
const prices = orderBook.map((item: unknown) => {
|
||||
const arr = item as [number, number];
|
||||
return arr[0] || 0;
|
||||
});
|
||||
const volumes = orderBook.map((item: unknown) => {
|
||||
const arr = item as [number, number];
|
||||
return arr[1] || 0;
|
||||
});
|
||||
return { prices, volumes };
|
||||
}
|
||||
|
||||
// 格式1: [{price, volume}, ...] (标准格式)
|
||||
if (typeof firstItem === 'object' && firstItem !== null) {
|
||||
const typedBook = orderBook as OrderBookLevel[];
|
||||
const prices = typedBook.map(item => item.price || 0);
|
||||
const volumes = typedBook.map(item => item.volume || 0);
|
||||
return { prices, volumes };
|
||||
}
|
||||
|
||||
return { prices: [], volumes: [] };
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user