feat: 优化卡片内容显示

This commit is contained in:
Cassianvale
2025-03-06 14:46:59 +08:00
parent 4393bf68cd
commit 8781eebdfa
5 changed files with 939 additions and 53 deletions

View File

@@ -227,22 +227,37 @@ function handleStreamInit(data: StreamInitMessage) {
// 处理流式更新消息
function handleStreamUpdate(data: StreamAnalysisUpdate) {
const stockIndex = analyzedStocks.value.findIndex(s => s.code === data.stock_code);
const stockIndex = analyzedStocks.value.findIndex((s: StockInfo) => s.code === data.stock_code);
if (stockIndex >= 0) {
const stock = { ...analyzedStocks.value[stockIndex] };
// 更新分析状态
stock.analysisStatus = data.status;
if (data.status) {
stock.analysisStatus = data.status;
}
// 如果有分析结果,则更新
if (data.analysis !== undefined) {
stock.analysis = data.analysis;
}
// 处理AI分析片段
if (data.ai_analysis_chunk !== undefined) {
// 如果之前没有分析内容,则初始化
if (!stock.analysis) {
stock.analysis = '';
}
// 追加新的分析片段
stock.analysis += data.ai_analysis_chunk;
// 确保分析状态为正在分析
stock.analysisStatus = 'analyzing';
}
// 如果有错误,则更新
if (data.error !== undefined) {
stock.error = data.error;
stock.analysisStatus = 'error';
}
// 更新股票名称、价格等信息
@@ -262,6 +277,41 @@ function handleStreamUpdate(data: StreamAnalysisUpdate) {
stock.marketValue = data.market_value;
}
// 添加新字段的处理
if (data.score !== undefined) {
stock.score = data.score;
}
if (data.recommendation !== undefined) {
stock.recommendation = data.recommendation;
}
if (data.price_change !== undefined) {
stock.price_change = data.price_change;
}
if (data.rsi !== undefined) {
stock.rsi = data.rsi;
}
// 添加技术指标字段的处理
if (data.ma_trend !== undefined) {
stock.ma_trend = data.ma_trend;
}
if (data.macd_signal !== undefined) {
stock.macd_signal = data.macd_signal;
}
if (data.volume_status !== undefined) {
stock.volume_status = data.volume_status;
}
// 添加分析日期字段的处理
if (data.analysis_date !== undefined) {
stock.analysis_date = data.analysis_date;
}
// 更新数组中的股票信息
analyzedStocks.value[stockIndex] = stock;
}
@@ -280,8 +330,8 @@ async function analyzeStocks() {
// 解析股票代码
const codes = stockCodes.value
.split(/[,\s\n]+/)
.map(code => code.trim())
.filter(code => code);
.map((code: string) => code.trim())
.filter((code: string) => code);
if (codes.length === 0) {
message.warning('未找到有效的股票代码');
@@ -362,6 +412,14 @@ async function analyzeStocks() {
processStreamData(buffer);
}
// 将所有分析中的股票状态更新为已完成
analyzedStocks.value.forEach((stock, index) => {
if (stock.analysisStatus === 'analyzing') {
const updatedStock = { ...stock, analysisStatus: 'completed' };
analyzedStocks.value[index] = updatedStock;
}
});
message.success('分析完成');
} catch (error: any) {
message.error(`分析出错: ${error.message || '未知错误'}`);
@@ -381,9 +439,78 @@ async function copyAnalysisResults() {
try {
// 格式化分析结果
const formattedResults = analyzedStocks.value
.filter(stock => stock.analysisStatus === 'completed')
.map(stock => {
return `${stock.code} ${stock.name || ''}\n${stock.analysis || '无分析结果'}\n`;
.filter((stock: StockInfo) => stock.analysisStatus === 'completed')
.map((stock: StockInfo) => {
let result = `${stock.code} ${stock.name || ''}\n`;
// 添加分析日期
if (stock.analysis_date) {
try {
const date = new Date(stock.analysis_date);
if (!isNaN(date.getTime())) {
result += `分析日期: ${date.toISOString().split('T')[0]}\n`;
} else {
result += `分析日期: ${stock.analysis_date}\n`;
}
} catch (e) {
result += `分析日期: ${stock.analysis_date}\n`;
}
}
// 添加评分和推荐信息
if (stock.score !== undefined) {
result += `评分: ${stock.score}\n`;
}
if (stock.recommendation) {
result += `推荐: ${stock.recommendation}\n`;
}
// 添加技术指标信息
if (stock.rsi !== undefined) {
result += `RSI: ${stock.rsi.toFixed(2)}\n`;
}
if (stock.price_change !== undefined) {
const sign = stock.price_change > 0 ? '+' : '';
result += `价格变动: ${sign}${stock.price_change.toFixed(2)}\n`;
}
if (stock.ma_trend) {
const trendMap: Record<string, string> = {
'UP': '上升',
'DOWN': '下降',
'NEUTRAL': '平稳'
};
const trend = trendMap[stock.ma_trend] || stock.ma_trend;
result += `均线趋势: ${trend}\n`;
}
if (stock.macd_signal) {
const signalMap: Record<string, string> = {
'BUY': '买入',
'SELL': '卖出',
'HOLD': '持有',
'NEUTRAL': '中性'
};
const signal = signalMap[stock.macd_signal] || stock.macd_signal;
result += `MACD信号: ${signal}\n`;
}
if (stock.volume_status) {
const statusMap: Record<string, string> = {
'HIGH': '放量',
'LOW': '缩量',
'NORMAL': '正常'
};
const status = statusMap[stock.volume_status] || stock.volume_status;
result += `成交量: ${status}\n`;
}
// 添加分析结果
result += `\n${stock.analysis || '无分析结果'}\n`;
return result;
})
.join('\n');

View File

@@ -3,15 +3,74 @@
<div class="card-header">
<div class="stock-info">
<div class="stock-code">{{ stock.code }}</div>
<div class="stock-name">{{ stock.name || '加载中...' }}</div>
</div>
<div class="stock-price-info" v-if="stock.price !== undefined">
<div class="stock-price">{{ stock.price.toFixed(2) }}</div>
<div class="stock-price">当前价格: {{ stock.price.toFixed(2) }}</div>
<div class="stock-change" :class="{
'up': stock.changePercent && stock.changePercent > 0,
'down': stock.changePercent && stock.changePercent < 0
'up': calculatedChangePercent && calculatedChangePercent > 0,
'down': calculatedChangePercent && calculatedChangePercent < 0
}">
{{ formatChangePercent(stock.changePercent) }}
涨跌幅: {{ formatChangePercent(calculatedChangePercent) }}
</div>
</div>
</div>
<div class="stock-summary" v-if="stock.score !== undefined || stock.recommendation">
<div class="summary-item score-item" v-if="stock.score !== undefined">
<div class="summary-value" :class="getScoreClass(stock.score)">{{ stock.score }}</div>
<div class="summary-label">评分</div>
</div>
<div class="summary-item recommendation-item" v-if="stock.recommendation">
<div class="summary-value recommendation">{{ stock.recommendation }}</div>
<div class="summary-label">推荐</div>
</div>
</div>
<div class="analysis-date" v-if="stock.analysis_date">
<n-tag type="info" size="small">
<template #icon>
<n-icon><CalendarOutline /></n-icon>
</template>
分析日期: {{ formatDate(stock.analysis_date) }}
</n-tag>
</div>
<div class="technical-indicators" v-if="hasAnyTechnicalIndicator">
<n-divider dashed style="margin: 12px 0 8px 0">技术指标</n-divider>
<div class="indicators-grid">
<div class="indicator-item" v-if="stock.rsi !== undefined">
<div class="indicator-value" :class="getRsiClass(stock.rsi)">{{ stock.rsi.toFixed(2) }}</div>
<div class="indicator-label">RSI</div>
</div>
<div class="indicator-item" v-if="stock.price_change !== undefined">
<div class="indicator-value" :class="{
'up': stock.price_change > 0,
'down': stock.price_change < 0
}">{{ formatPriceChange(stock.price_change) }}</div>
<div class="indicator-label">价格变动</div>
</div>
<div class="indicator-item" v-if="stock.ma_trend">
<div class="indicator-value" :class="getTrendClass(stock.ma_trend)">
{{ getChineseTrend(stock.ma_trend) }}
</div>
<div class="indicator-label">均线趋势</div>
</div>
<div class="indicator-item" v-if="stock.macd_signal">
<div class="indicator-value" :class="getSignalClass(stock.macd_signal)">
{{ getChineseSignal(stock.macd_signal) }}
</div>
<div class="indicator-label">MACD信号</div>
</div>
<div class="indicator-item" v-if="stock.volume_status">
<div class="indicator-value" :class="getVolumeStatusClass(stock.volume_status)">
{{ getChineseVolumeStatus(stock.volume_status) }}
</div>
<div class="indicator-label">成交量</div>
</div>
</div>
</div>
@@ -31,6 +90,7 @@
<n-spin size="small" />
<span>正在分析...</span>
</div>
<div class="analysis-result analysis-streaming" v-if="parsedAnalysis" v-html="parsedAnalysis" :key="analysisContentKey"></div>
</template>
<template v-else-if="stock.analysisStatus === 'error'">
@@ -41,27 +101,20 @@
</template>
<template v-else-if="stock.analysisStatus === 'completed'">
<div class="analysis-result" v-html="parsedAnalysis"></div>
<div class="analysis-result analysis-completed" v-html="parsedAnalysis"></div>
</template>
</div>
<template #footer>
<div class="card-footer">
<div class="market-value" v-if="stock.marketValue">
市值: {{ formatMarketValue(stock.marketValue) }}
</div>
<div class="market-type">
{{ getMarketName(stock.marketType) }}
</div>
</div>
</template>
</n-card>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import { NCard, NDivider, NSpin, NIcon } from 'naive-ui';
import { AlertCircleOutline as AlertCircleIcon } from '@vicons/ionicons5';
import { computed, watch, ref } from 'vue';
import { NCard, NDivider, NSpin, NIcon, NTag } from 'naive-ui';
import {
AlertCircleOutline as AlertCircleIcon,
CalendarOutline
} from '@vicons/ionicons5';
import { parseMarkdown, formatMarketValue as formatMarketValueFn } from '@/utils';
import type { StockInfo } from '@/types';
@@ -73,13 +126,87 @@ const isAnalyzing = computed(() => {
return props.stock.analysisStatus === 'analyzing';
});
const lastAnalysisLength = ref(0);
// 监听分析内容变化
watch(() => props.stock.analysis, (newVal) => {
if (newVal && props.stock.analysisStatus === 'analyzing') {
lastAnalysisLength.value = newVal.length;
}
}, { immediate: true });
// 添加一个计算属性,用于监控分析内容是否更新
const analysisContentKey = ref(0);
watch(() => props.stock.analysis, (newVal, oldVal) => {
if (newVal && oldVal && newVal.length > oldVal.length && props.stock.analysisStatus === 'analyzing') {
analysisContentKey.value++;
}
}, { immediate: false });
const parsedAnalysis = computed(() => {
if (props.stock.analysis) {
return parseMarkdown(props.stock.analysis);
let result = parseMarkdown(props.stock.analysis);
// 为关键词添加样式类
result = highlightKeywords(result);
return result;
}
return '';
});
// 关键词高亮处理函数
function highlightKeywords(html: string): string {
// 买入/卖出/持有信号
html = html.replace(/(<strong>)(买入|卖出|持有)(<\/strong>)/g, '$1<span class="buy">$2</span>$3');
// 上涨/增长相关词
html = html.replace(/(<strong>)(上涨|看涨|增长|增加|上升)(<\/strong>)/g, '$1<span class="up">$2</span>$3');
// 下跌/减少相关词
html = html.replace(/(<strong>)(下跌|看跌|减少|降低|下降)(<\/strong>)/g, '$1<span class="down">$2</span>$3');
// 技术指标相关词
html = html.replace(/(<strong>)(RSI|MACD|MA|KDJ|均线|成交量|布林带|Bollinger|移动平均|相对强弱|背离)(<\/strong>)/g,
'$1<span class="indicator">$2</span>$3');
// 高亮重要的百分比数字 (如 +12.34%, -12.34%)
html = html.replace(/([+-]?\d+\.?\d*\s*%)/g, '<span class="number">$1</span>');
// 高亮重要的数值 (如带小数位的数字)
html = html.replace(/(\s|>)(\d+\.\d+)(\s|<)/g, '$1<span class="number">$2</span>$3');
return html;
}
// 计算涨跌幅
const calculatedChangePercent = computed(() => {
// 如果已有changePercent则直接使用
if (props.stock.changePercent !== undefined) {
return props.stock.changePercent;
}
// 如果有price_change和price则计算涨跌幅
if (props.stock.price_change !== undefined && props.stock.price !== undefined) {
// 计算涨跌幅百分比 = (价格变动 / (当前价格 - 价格变动)) * 100
const basePrice = props.stock.price - props.stock.price_change;
if (basePrice !== 0) {
return (props.stock.price_change / basePrice) * 100;
}
}
// 无法计算则返回undefined
return undefined;
});
const hasAnyTechnicalIndicator = computed(() => {
return props.stock.rsi !== undefined ||
props.stock.price_change !== undefined ||
props.stock.ma_trend !== undefined ||
props.stock.macd_signal !== undefined ||
props.stock.volume_status !== undefined;
});
function formatChangePercent(percent: number | undefined): string {
if (percent === undefined) return '--';
@@ -87,10 +214,28 @@ function formatChangePercent(percent: number | undefined): string {
return `${sign}${percent.toFixed(2)}%`;
}
function formatPriceChange(change: number): string {
const sign = change > 0 ? '+' : '';
return `${sign}${change.toFixed(2)}`;
}
function formatMarketValue(value: number): string {
return formatMarketValueFn(value);
}
function formatDate(dateStr: string): string {
try {
const date = new Date(dateStr);
if (isNaN(date.getTime())) {
return dateStr;
}
return date.toISOString().split('T')[0];
} catch (e) {
return dateStr;
}
}
function getMarketName(marketType: string): string {
const marketMap: Record<string, string> = {
'A': 'A股',
@@ -100,6 +245,69 @@ function getMarketName(marketType: string): string {
return marketMap[marketType] || marketType;
}
function getScoreClass(score: number): string {
if (score >= 80) return 'score-high';
if (score >= 70) return 'score-medium-high';
if (score >= 60) return 'score-medium';
if (score >= 40) return 'score-medium-low';
return 'score-low';
}
function getRsiClass(rsi: number): string {
if (rsi >= 70) return 'rsi-overbought';
if (rsi <= 30) return 'rsi-oversold';
return '';
}
function getTrendClass(trend: string): string {
if (trend === 'UP') return 'trend-up';
if (trend === 'DOWN') return 'trend-down';
return 'trend-neutral';
}
function getSignalClass(signal: string): string {
if (signal === 'BUY') return 'signal-buy';
if (signal === 'SELL') return 'signal-sell';
return 'signal-neutral';
}
function getVolumeStatusClass(status: string): string {
if (status === 'HIGH') return 'volume-high';
if (status === 'LOW') return 'volume-low';
return 'volume-normal';
}
function getChineseTrend(trend: string): string {
const trendMap: Record<string, string> = {
'UP': '上升',
'DOWN': '下降',
'NEUTRAL': '平稳'
};
return trendMap[trend] || trend;
}
function getChineseSignal(signal: string): string {
const signalMap: Record<string, string> = {
'BUY': '买入',
'SELL': '卖出',
'HOLD': '持有',
'NEUTRAL': '中性'
};
return signalMap[signal] || signal;
}
function getChineseVolumeStatus(status: string): string {
const statusMap: Record<string, string> = {
'HIGH': '放量',
'LOW': '缩量',
'NORMAL': '正常'
};
return statusMap[status] || status;
}
</script>
<style scoped>
@@ -131,12 +339,10 @@ function getMarketName(marketType: string): string {
font-size: 1.125rem;
font-weight: bold;
color: var(--n-text-color);
}
.stock-name {
font-size: 0.875rem;
color: var(--n-text-color-3);
margin-top: 0.25rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
.stock-price-info {
@@ -156,6 +362,136 @@ function getMarketName(marketType: string): string {
margin-top: 0.25rem;
}
.stock-summary {
display: flex;
justify-content: space-around;
margin: 0.75rem 0;
padding: 0.5rem;
background-color: rgba(0, 0, 0, 0.02);
border-radius: 4px;
}
.summary-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 0 0.5rem;
}
.summary-value {
font-size: 1.25rem;
font-weight: 700;
}
.summary-label {
font-size: 0.75rem;
color: var(--n-text-color-3);
margin-top: 0.25rem;
}
.analysis-date {
margin: 0.5rem 0;
display: flex;
justify-content: flex-end;
}
.technical-indicators {
margin-top: 0.5rem;
}
.indicators-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0.75rem;
margin-top: 0.5rem;
}
.indicator-item {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.indicator-value {
font-size: 0.875rem;
font-weight: 600;
}
.indicator-label {
font-size: 0.75rem;
color: var(--n-text-color-3);
margin-top: 0.25rem;
}
.score-high {
color: #18a058;
}
.score-medium-high {
color: #63e2b7;
}
.score-medium {
color: #f0a020;
}
.score-medium-low {
color: #f5a623;
}
.score-low {
color: #d03050;
}
.rsi-overbought {
color: #d03050;
}
.rsi-oversold {
color: #18a058;
}
.trend-up {
color: #d03050;
}
.trend-down {
color: #18a058;
}
.trend-neutral {
color: #f0a020;
}
.signal-buy {
color: #d03050;
}
.signal-sell {
color: #18a058;
}
.signal-neutral {
color: #f0a020;
}
.volume-high {
color: #d03050;
}
.volume-low {
color: #18a058;
}
.volume-normal {
color: #f0a020;
}
.recommendation {
color: #2080f0;
}
.up {
color: var(--n-error-color);
}
@@ -168,6 +504,9 @@ function getMarketName(marketType: string): string {
flex: 1;
min-height: 100px;
margin-bottom: 0.5rem;
text-align: left;
display: flex;
flex-direction: column;
}
.waiting-status,
@@ -178,6 +517,7 @@ function getMarketName(marketType: string): string {
gap: 0.5rem;
color: var(--n-text-color-3);
font-size: 0.875rem;
margin-bottom: 0.75rem;
}
.error-icon {
@@ -186,22 +526,208 @@ function getMarketName(marketType: string): string {
.analysis-result {
font-size: 0.875rem;
line-height: 1.5;
line-height: 1.6;
text-align: left;
padding: 0.75rem 1rem;
border-radius: 4px;
background-color: rgba(0, 0, 0, 0.01);
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.05);
max-height: 400px;
overflow-y: auto;
word-break: break-word;
hyphens: auto;
}
.analysis-streaming {
position: relative;
border-left: 2px solid var(--n-info-color);
animation: fadePulse 2s infinite;
}
/* 改进流式输出的动画效果,消除闪烁 */
.analysis-streaming > :deep(*) {
animation: none;
}
/* 添加打字机光标效果 */
.analysis-streaming::after {
content: '|';
display: inline-block;
color: var(--n-info-color);
animation: blink 1s step-end infinite;
margin-left: 2px;
font-weight: bold;
vertical-align: middle;
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
.analysis-completed {
border-left: 2px solid var(--n-success-color);
}
@keyframes fadePulse {
0% { border-left-color: var(--n-info-color); }
50% { border-left-color: rgba(31, 126, 212, 0.4); }
100% { border-left-color: var(--n-info-color); }
}
/* 优化标题样式,增加颜色显示 */
.analysis-result :deep(h1), .analysis-result :deep(h2), .analysis-result :deep(h3) {
margin: 1.25rem 0 0.75rem 0;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
padding-bottom: 0.4rem;
font-weight: 600;
}
.analysis-result :deep(h1) {
font-size: 1.4rem;
color: #2080f0;
}
.analysis-result :deep(h2) {
font-size: 1.2rem;
color: #2080f0;
}
.analysis-result :deep(h3) {
font-size: 1.1rem;
color: #2080f0;
}
/* 优化列表样式 */
.analysis-result :deep(ul), .analysis-result :deep(ol) {
margin: 0.75rem 0;
padding-left: 1.5rem;
}
.analysis-result :deep(ul) li, .analysis-result :deep(ol) li {
margin-bottom: 0.3rem;
}
/* 优化段落样式 */
.analysis-result :deep(p) {
margin: 0.5rem 0;
margin: 0.75rem 0;
text-align: left;
}
.analysis-result :deep(ul) {
margin: 0.5rem 0;
padding-left: 1.25rem;
/* 优化代码样式 */
.analysis-result :deep(code) {
background: rgba(0, 0, 0, 0.05);
padding: 0.1rem 0.3rem;
border-radius: 3px;
font-family: monospace;
font-size: 0.85em;
}
.card-footer {
display: flex;
justify-content: space-between;
font-size: 0.75rem;
color: var(--n-text-color-3);
.analysis-result :deep(pre) {
background: rgba(0, 0, 0, 0.05);
padding: 0.75rem;
border-radius: 4px;
overflow-x: auto;
margin: 0.75rem 0;
border-left: 3px solid #2080f0;
}
.analysis-result :deep(pre code) {
background: transparent;
padding: 0;
}
/* 优化引用样式 */
.analysis-result :deep(blockquote) {
margin: 0.75rem 0;
padding: 0.5rem 1rem;
border-left: 3px solid #f0a020;
background-color: rgba(240, 160, 32, 0.05);
color: var(--n-text-color-2);
}
/* 优化表格样式 */
.analysis-result :deep(table) {
border-collapse: collapse;
width: 100%;
margin: 0.75rem 0;
border-radius: 4px;
overflow: hidden;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.analysis-result :deep(th) {
background-color: rgba(32, 128, 240, 0.1);
color: #2080f0;
font-weight: 600;
padding: 0.6rem;
text-align: left;
border: 1px solid rgba(0, 0, 0, 0.1);
}
.analysis-result :deep(td) {
padding: 0.6rem;
border: 1px solid rgba(0, 0, 0, 0.1);
}
.analysis-result :deep(tr:nth-child(even)) {
background-color: rgba(0, 0, 0, 0.02);
}
/* 优化文本强调和术语显示 */
.analysis-result :deep(strong) {
font-weight: 600;
color: #2080f0;
}
/* 特定指标和信号的样式 */
.analysis-result :deep(.buy),
.analysis-result :deep(.sell),
.analysis-result :deep(.hold) {
color: #d03050;
background-color: rgba(208, 48, 80, 0.1);
padding: 0 0.3rem;
border-radius: 2px;
font-weight: 600;
}
.analysis-result :deep(.up),
.analysis-result :deep(.increase) {
color: #d03050;
font-weight: 600;
}
.analysis-result :deep(.down),
.analysis-result :deep(.decrease) {
color: #18a058;
font-weight: 600;
}
.analysis-result :deep(.indicator) {
color: #2080f0;
background-color: rgba(32, 128, 240, 0.1);
padding: 0 0.3rem;
border-radius: 2px;
font-weight: 600;
}
.analysis-result :deep(.number) {
font-family: 'Consolas', monospace;
font-weight: 600;
color: #f0a020;
}
/* 优化链接样式 */
.analysis-result :deep(a) {
color: #2080f0;
text-decoration: none;
border-bottom: 1px dotted #2080f0;
transition: all 0.2s ease;
font-weight: 500;
}
.analysis-result :deep(a:hover) {
color: #36ad6a;
border-bottom: 1px solid #36ad6a;
}
</style>

View File

@@ -17,6 +17,14 @@ export interface StockInfo {
analysis?: string;
analysisStatus: 'waiting' | 'analyzing' | 'completed' | 'error';
error?: string;
score?: number;
recommendation?: string;
price_change?: number;
rsi?: number;
ma_trend?: string;
macd_signal?: string;
volume_status?: string;
analysis_date?: string;
}
export interface SearchResult {
@@ -77,4 +85,13 @@ export interface StreamAnalysisUpdate {
price?: number;
change_percent?: number;
market_value?: number;
score?: number;
recommendation?: string;
price_change?: number;
rsi?: number;
ma_trend?: string;
macd_signal?: string;
volume_status?: string;
analysis_date?: string;
ai_analysis_chunk?: string;
}

View File

@@ -42,6 +42,126 @@
resolved "https://registry.npmmirror.com/@emotion/hash/-/hash-0.8.0.tgz"
integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==
"@esbuild/aix-ppc64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz#499600c5e1757a524990d5d92601f0ac3ce87f64"
integrity sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==
"@esbuild/android-arm64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz#b9b8231561a1dfb94eb31f4ee056b92a985c324f"
integrity sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==
"@esbuild/android-arm@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.25.0.tgz#ca6e7888942505f13e88ac9f5f7d2a72f9facd2b"
integrity sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==
"@esbuild/android-x64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.25.0.tgz#e765ea753bac442dfc9cb53652ce8bd39d33e163"
integrity sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==
"@esbuild/darwin-arm64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz#fa394164b0d89d4fdc3a8a21989af70ef579fa2c"
integrity sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==
"@esbuild/darwin-x64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz#91979d98d30ba6e7d69b22c617cc82bdad60e47a"
integrity sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==
"@esbuild/freebsd-arm64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz#b97e97073310736b430a07b099d837084b85e9ce"
integrity sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==
"@esbuild/freebsd-x64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz#f3b694d0da61d9910ec7deff794d444cfbf3b6e7"
integrity sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==
"@esbuild/linux-arm64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz#f921f699f162f332036d5657cad9036f7a993f73"
integrity sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==
"@esbuild/linux-arm@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz#cc49305b3c6da317c900688995a4050e6cc91ca3"
integrity sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==
"@esbuild/linux-ia32@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz#3e0736fcfab16cff042dec806247e2c76e109e19"
integrity sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==
"@esbuild/linux-loong64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz#ea2bf730883cddb9dfb85124232b5a875b8020c7"
integrity sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==
"@esbuild/linux-mips64el@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz#4cababb14eede09248980a2d2d8b966464294ff1"
integrity sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==
"@esbuild/linux-ppc64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz#8860a4609914c065373a77242e985179658e1951"
integrity sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==
"@esbuild/linux-riscv64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz#baf26e20bb2d38cfb86ee282dff840c04f4ed987"
integrity sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==
"@esbuild/linux-s390x@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz#8323afc0d6cb1b6dc6e9fd21efd9e1542c3640a4"
integrity sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==
"@esbuild/linux-x64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz#08fcf60cb400ed2382e9f8e0f5590bac8810469a"
integrity sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==
"@esbuild/netbsd-arm64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz#935c6c74e20f7224918fbe2e6c6fe865b6c6ea5b"
integrity sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==
"@esbuild/netbsd-x64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz#414677cef66d16c5a4d210751eb2881bb9c1b62b"
integrity sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==
"@esbuild/openbsd-arm64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz#8fd55a4d08d25cdc572844f13c88d678c84d13f7"
integrity sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==
"@esbuild/openbsd-x64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz#0c48ddb1494bbc2d6bcbaa1429a7f465fa1dedde"
integrity sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==
"@esbuild/sunos-x64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz#86ff9075d77962b60dd26203d7352f92684c8c92"
integrity sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==
"@esbuild/win32-arm64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz#849c62327c3229467f5b5cd681bf50588442e96c"
integrity sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==
"@esbuild/win32-ia32@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz#f62eb480cd7cca088cb65bb46a6db25b725dc079"
integrity sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==
"@esbuild/win32-x64@0.25.0":
version "0.25.0"
resolved "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz"
@@ -57,6 +177,96 @@
resolved "https://registry.npmmirror.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz"
integrity sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==
"@rollup/rollup-android-arm-eabi@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.9.tgz#661a45a4709c70e59e596ec78daa9cb8b8d27604"
integrity sha512-qZdlImWXur0CFakn2BJ2znJOdqYZKiedEPEVNTBrpfPjc/YuTGcaYZcdmNFTkUj3DU0ZM/AElcM8Ybww3xVLzA==
"@rollup/rollup-android-arm64@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.9.tgz#128fe8dd510d880cf98b4cb6c7add326815a0c4b"
integrity sha512-4KW7P53h6HtJf5Y608T1ISKvNIYLWRKMvfnG0c44M6In4DQVU58HZFEVhWINDZKp7FZps98G3gxwC1sb0wXUUg==
"@rollup/rollup-darwin-arm64@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.9.tgz#363467bc49fd0b1e17075798ac8e9ad1e1e29535"
integrity sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ==
"@rollup/rollup-darwin-x64@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.9.tgz#c2fe3d85fffe47f0ed0f076b3563ada22c8af19c"
integrity sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q==
"@rollup/rollup-freebsd-arm64@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.9.tgz#d95bd8f6eaaf829781144fc8bd2d5d71d9f6a9f5"
integrity sha512-2lzjQPJbN5UnHm7bHIUKFMulGTQwdvOkouJDpPysJS+QFBGDJqcfh+CxxtG23Ik/9tEvnebQiylYoazFMAgrYw==
"@rollup/rollup-freebsd-x64@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.9.tgz#c3576c6011656e4966ded29f051edec636b44564"
integrity sha512-SLl0hi2Ah2H7xQYd6Qaiu01kFPzQ+hqvdYSoOtHYg/zCIFs6t8sV95kaoqjzjFwuYQLtOI0RZre/Ke0nPaQV+g==
"@rollup/rollup-linux-arm-gnueabihf@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.9.tgz#48c87d0dee4f8dc9591a416717f91b4a89d77e3d"
integrity sha512-88I+D3TeKItrw+Y/2ud4Tw0+3CxQ2kLgu3QvrogZ0OfkmX/DEppehus7L3TS2Q4lpB+hYyxhkQiYPJ6Mf5/dPg==
"@rollup/rollup-linux-arm-musleabihf@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.9.tgz#f4c4e7c03a7767f2e5aa9d0c5cfbf5c0f59f2d41"
integrity sha512-3qyfWljSFHi9zH0KgtEPG4cBXHDFhwD8kwg6xLfHQ0IWuH9crp005GfoUUh/6w9/FWGBwEHg3lxK1iHRN1MFlA==
"@rollup/rollup-linux-arm64-gnu@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.9.tgz#1015c9d07a99005025d13b8622b7600029d0b52f"
integrity sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw==
"@rollup/rollup-linux-arm64-musl@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.9.tgz#8f895eb5577748fc75af21beae32439626e0a14c"
integrity sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A==
"@rollup/rollup-linux-loongarch64-gnu@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.9.tgz#c9cd5dbbdc6b3ca4dbeeb0337498cf31949004a0"
integrity sha512-dRAgTfDsn0TE0HI6cmo13hemKpVHOEyeciGtvlBTkpx/F65kTvShtY/EVyZEIfxFkV5JJTuQ9tP5HGBS0hfxIg==
"@rollup/rollup-linux-powerpc64le-gnu@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.9.tgz#7ebb5b4441faa17843a210f7d0583a20c93b40e4"
integrity sha512-PHcNOAEhkoMSQtMf+rJofwisZqaU8iQ8EaSps58f5HYll9EAY5BSErCZ8qBDMVbq88h4UxaNPlbrKqfWP8RfJA==
"@rollup/rollup-linux-riscv64-gnu@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.9.tgz#10f5d7349fbd2fe78f9e36ecc90aab3154435c8d"
integrity sha512-Z2i0Uy5G96KBYKjeQFKbbsB54xFOL5/y1P5wNBsbXB8yE+At3oh0DVMjQVzCJRJSfReiB2tX8T6HUFZ2k8iaKg==
"@rollup/rollup-linux-s390x-gnu@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.9.tgz#196347d2fa20593ab09d0b7e2589fb69bdf742c6"
integrity sha512-U+5SwTMoeYXoDzJX5dhDTxRltSrIax8KWwfaaYcynuJw8mT33W7oOgz0a+AaXtGuvhzTr2tVKh5UO8GVANTxyQ==
"@rollup/rollup-linux-x64-gnu@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.9.tgz#7193cbd8d128212b8acda37e01b39d9e96259ef8"
integrity sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A==
"@rollup/rollup-linux-x64-musl@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.9.tgz#29a6867278ca0420b891574cfab98ecad70c59d1"
integrity sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA==
"@rollup/rollup-win32-arm64-msvc@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.9.tgz#89427dcac0c8e3a6d32b13a03a296a275d0de9a9"
integrity sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q==
"@rollup/rollup-win32-ia32-msvc@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.9.tgz#ecb9711ba2b6d2bf6ee51265abe057ab90913deb"
integrity sha512-KB48mPtaoHy1AwDNkAJfHXvHp24H0ryZog28spEs0V48l3H1fr4i37tiyHsgKZJnCmvxsbATdZGBpbmxTE3a9w==
"@rollup/rollup-win32-x64-msvc@4.34.9":
version "4.34.9"
resolved "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.9.tgz"
@@ -89,7 +299,7 @@
resolved "https://registry.npmmirror.com/@types/marked/-/marked-5.0.2.tgz"
integrity sha512-OucS4KMHhFzhz27KxmWg7J+kIYqyqoW5kdIEI319hqARQQUTqhao3M/F+uFnDXD0Rg72iDDZxZNxq5gvctmLlg==
"@types/node@^18.0.0 || ^20.0.0 || >=22.0.0", "@types/node@^22.13.9":
"@types/node@^22.13.9":
version "22.13.9"
resolved "https://registry.npmmirror.com/@types/node/-/node-22.13.9.tgz"
integrity sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw==
@@ -111,7 +321,7 @@
resolved "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.1.tgz"
integrity sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==
"@volar/language-core@~2.4.11", "@volar/language-core@2.4.11":
"@volar/language-core@2.4.11", "@volar/language-core@~2.4.11":
version "2.4.11"
resolved "https://registry.npmmirror.com/@volar/language-core/-/language-core-2.4.11.tgz"
integrity sha512-lN2C1+ByfW9/JRPpqScuZt/4OrUUse57GLI6TbLgTIqBVemdl1wNcZ1qYGEo2+Gw8coYLgCy7SuKqn6IrQcQgg==
@@ -143,7 +353,7 @@
estree-walker "^2.0.2"
source-map-js "^1.2.0"
"@vue/compiler-dom@^3.5.0", "@vue/compiler-dom@3.5.13":
"@vue/compiler-dom@3.5.13", "@vue/compiler-dom@^3.5.0":
version "3.5.13"
resolved "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz"
integrity sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==
@@ -229,7 +439,7 @@
"@vue/compiler-ssr" "3.5.13"
"@vue/shared" "3.5.13"
"@vue/shared@^3.5.0", "@vue/shared@3.5.13":
"@vue/shared@3.5.13", "@vue/shared@^3.5.0":
version "3.5.13"
resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.13.tgz"
integrity sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==
@@ -312,7 +522,7 @@ combined-stream@^1.0.8:
dependencies:
delayed-stream "~1.0.0"
css-render@^0.15.10, css-render@^0.15.14, css-render@~0.15.14:
css-render@^0.15.10, css-render@^0.15.14:
version "0.15.14"
resolved "https://registry.npmmirror.com/css-render/-/css-render-0.15.14.tgz"
integrity sha512-9nF4PdUle+5ta4W5SyZdLCCmFd37uVimSjg1evcTqKJCyvCEEj12WKzOSBNak6r4im4J4iYXKH1OWpUV5LBYFg==
@@ -335,7 +545,7 @@ date-fns-tz@^3.1.3:
resolved "https://registry.npmmirror.com/date-fns-tz/-/date-fns-tz-3.2.0.tgz"
integrity sha512-sg8HqoTEulcbbbVXeg84u5UnlsQa8GS5QXMqjjYIhS4abEVVKIUwe0/l/UhrZdKaL/W5eWZNlbTeEIiOXTcsBQ==
"date-fns@^3.0.0 || ^4.0.0", date-fns@^3.6.0:
date-fns@^3.6.0:
version "3.6.0"
resolved "https://registry.npmmirror.com/date-fns/-/date-fns-3.6.0.tgz"
integrity sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==
@@ -447,6 +657,11 @@ form-data@^4.0.0:
es-set-tostringtag "^2.1.0"
mime-types "^2.1.12"
fsevents@~2.3.2, fsevents@~2.3.3:
version "2.3.3"
resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
function-bind@^1.1.2:
version "1.1.2"
resolved "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz"
@@ -658,7 +873,7 @@ treemate@^0.3.11:
resolved "https://registry.npmmirror.com/treemate/-/treemate-0.3.11.tgz"
integrity sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==
typescript@*, typescript@>=5.0.0, typescript@~5.7.2, typescript@5.x:
typescript@~5.7.2:
version "5.7.3"
resolved "https://registry.npmmirror.com/typescript/-/typescript-5.7.3.tgz"
integrity sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==
@@ -675,7 +890,7 @@ vdirs@^0.1.4, vdirs@^0.1.8:
dependencies:
evtd "^0.2.2"
"vite@^5.0.0 || ^6.0.0", vite@^6.2.0:
vite@^6.2.0:
version "6.2.0"
resolved "https://registry.npmmirror.com/vite/-/vite-6.2.0.tgz"
integrity sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==
@@ -706,7 +921,7 @@ vue-tsc@^2.2.4:
"@volar/typescript" "~2.4.11"
"@vue/language-core" "2.2.8"
vue@^3.0.0, vue@^3.0.11, vue@^3.2.25, vue@^3.4.0, vue@^3.5.13, vue@3.5.13:
vue@^3.5.13:
version "3.5.13"
resolved "https://registry.npmmirror.com/vue/-/vue-3.5.13.tgz"
integrity sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==

View File

@@ -502,7 +502,8 @@ class StockAnalyzer:
try:
json_data = json.loads(data_content)
if 'choices' in json_data:
# 检查 choices 列表是否为空
if 'choices' in json_data and json_data['choices']:
delta = json_data['choices'][0].get('delta', {})
content = delta.get('content', '')