update pay ui

This commit is contained in:
2025-12-10 13:23:49 +08:00
parent 1adbeda168
commit d6d4bb8a12
3 changed files with 213 additions and 25 deletions

View File

@@ -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,

View File

@@ -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: [] };
};
/**