fix(i18n): cost-predict.ts hash key 清理 + 硬编码中文清零 + 错误 key 引用修复

- 23 个 predictutilsts.s* hash-style 键重命名为 costPredict.* 语义化键
- 7 处 buildCostInsightPrompt 硬编码中文模板字面量→i18n.t() 插值调用
- 修复 costRecommendation 函数引用错误 key (predictMemLeak→costPredict.rec*)
- 修复 dimension 字段引用 predictDiskFull→costPredict.allProviders
- 修复 providerLabel 引用 predictIn24h→costPredict.allProviders
- 新增 34 个语义化翻译键 (aiops.costPredict.*), zh/en 8102→8113 对齐
- tsc -b=0, npm build✓ (19.29s), ESLint=0/43/any=0, go build=0
- 17/17 集成测试通过
This commit is contained in:
attacker committed 2026-07-17 04:05:32 +08:00
1 parent d6ed1978ef
commit 083f4477db
3 files changed
+117 -83

No files matched your search

+47 -35
View File
@@ -83,20 +83,20 @@ function costTrendFromSlope(slope: number): 'up' | 'down' | 'stable' {
/** 成本优化建议 */ /** 成本优化建议 */
export function costRecommendation(trend: 'up' | 'down' | 'stable', ratio: number): string { export function costRecommendation(trend: 'up' | 'down' | 'stable', ratio: number): string {
if (trend === 'up' && ratio >= 0.85) { if (trend === 'up' && ratio >= 0.85) {
return i18n.t('aiops.predictMemLeak'); return i18n.t('aiops.costPredict.recHighSpend');
} }
if (trend === 'up') { if (trend === 'up') {
return i18n.t('aiops.predictMemLeak'); return i18n.t('aiops.costPredict.recRising');
} }
if (trend === 'down') { if (trend === 'down') {
return i18n.t('aiops.predictMemLeak'); return i18n.t('aiops.costPredict.recDeclining');
} }
return i18n.t('aiops.predictutilsts.sa3b5c7d9'); return i18n.t('aiops.costPredict.recStable');
} }
/** 预算风险建议 */ /** 预算风险建议 */
function budgetRiskAction(metric: 'daily' | 'monthly', provider: string): string { function budgetRiskAction(metric: 'daily' | 'monthly', provider: string): string {
const scope = provider && provider !== i18n.t('aiops.predictutilsts.sg5a3d8e1') ? `${provider} ` : ''; const scope = provider && provider !== i18n.t('aiops.costPredict.allProviders') ? `${provider} ` : '';
if (metric === 'daily') { if (metric === 'daily') {
return i18n.t('aiops.predictUtils.dailyCostHint', { scope }); return i18n.t('aiops.predictUtils.dailyCostHint', { scope });
} }
@@ -139,7 +139,7 @@ function topServicesByCost(records: JsonData[], limit = 5): { service: string; c
records.forEach((r) => { records.forEach((r) => {
const date = String(r.billing_date || ''); const date = String(r.billing_date || '');
if (date < start) return; if (date < start) return;
const svc = String(r.service || i18n.t('aiops.predictutilsts.sh7c2b9d6')); const svc = String(r.service || i18n.t('aiops.costPredict.unknownService'));
map.set(svc, (map.get(svc) || 0) + (Number(r.cost) || 0)); map.set(svc, (map.get(svc) || 0) + (Number(r.cost) || 0));
}); });
return [...map.entries()] return [...map.entries()]
@@ -256,7 +256,7 @@ export function computeCostPredictions(input: ComputeCostPredictionsInput): Comp
const allRatio = const allRatio =
summary.predictedMonthEnd > 0 ? summary.monthCost / summary.predictedMonthEnd : 0; summary.predictedMonthEnd > 0 ? summary.monthCost / summary.predictedMonthEnd : 0;
dimensionForecasts.push({ dimensionForecasts.push({
dimension: i18n.t('aiops.predictDiskFull'), dimension: i18n.t('aiops.costPredict.allProviders'),
currentMonth: summary.monthCost, currentMonth: summary.monthCost,
predictedMonthEnd: summary.predictedMonthEnd, predictedMonthEnd: summary.predictedMonthEnd,
dailyAvg: summary.dailyAvg, dailyAvg: summary.dailyAvg,
@@ -302,7 +302,7 @@ export function computeCostPredictions(input: ComputeCostPredictionsInput): Comp
const metric = (rule.metric === 'daily' ? 'daily' : 'monthly') as 'daily' | 'monthly'; const metric = (rule.metric === 'daily' ? 'daily' : 'monthly') as 'daily' | 'monthly';
const ruleProvider = String(rule.provider || ''); const ruleProvider = String(rule.provider || '');
const providerLabel = ruleProvider ? PROVIDER_LABELS[ruleProvider] || ruleProvider : i18n.t('aiops.predictIn24h'); const providerLabel = ruleProvider ? PROVIDER_LABELS[ruleProvider] || ruleProvider : i18n.t('aiops.costPredict.allProviders');
let current = 0; let current = 0;
let predicted = 0; let predicted = 0;
@@ -339,17 +339,17 @@ export function computeCostPredictions(input: ComputeCostPredictionsInput): Comp
if (current >= threshold) probability += 25; if (current >= threshold) probability += 25;
probability = Math.max(5, Math.min(92, probability)); probability = Math.max(5, Math.min(92, probability));
let timeframe = metric === 'daily' ? i18n.t('aiops.predictNext24h') : i18n.t('aiops.predictutilsts.sd4e5f6g7'); let timeframe = metric === 'daily' ? i18n.t('aiops.predictNext24h') : i18n.t('aiops.costPredict.monthEnd');
if (slope > 0.01 && threshold > current) { if (slope > 0.01 && threshold > current) {
const days = (threshold - current) / slope; const days = (threshold - current) / slope;
if (days < 1) timeframe = metric === 'daily' ? i18n.t('aiops.predictutilsts.se5f6g7h8') : i18n.t('aiops.predictutilsts.sf6g7h8i9'); if (days < 1) timeframe = metric === 'daily' ? i18n.t('aiops.costPredict.withinToday') : i18n.t('aiops.costPredict.withinOneDay');
else if (days <= 7) timeframe = i18n.t('aiops.predictutilsts.sg7h8i9j0', { days: Math.ceil(days) }); else if (days <= 7) timeframe = i18n.t('aiops.costPredict.withinDays', { days: Math.ceil(days) });
else timeframe = i18n.t('aiops.predictutilsts.sh8i9j0k1', { days: Math.ceil(days) }); else timeframe = i18n.t('aiops.costPredict.approxAfterDays', { days: Math.ceil(days) });
} }
if (probability >= 30 || current >= threshold * 0.7) { if (probability >= 30 || current >= threshold * 0.7) {
budgetRisks.push({ budgetRisks.push({
ruleName: String(rule.name || i18n.t('aiops.predictutilsts.si9j0k1l2')), ruleName: String(rule.name || i18n.t('aiops.costPredict.budgetRule')),
provider: providerLabel, provider: providerLabel,
metric, metric,
threshold, threshold,
@@ -386,49 +386,61 @@ export function buildCostInsightPrompt(data: ComputedCostPredictions): string {
const patternHint = const patternHint =
billingPattern === 'front_loaded' billingPattern === 'front_loaded'
? i18n.t('aiops.predictutilsts.sj0k1l2m3') ? i18n.t('aiops.costPredict.frontLoadedHint')
: billingPattern === 'sparse' : billingPattern === 'sparse'
? i18n.t('aiops.predictutilsts.sk1l2m3n4') ? i18n.t('aiops.costPredict.sparseHint')
: i18n.t('aiops.predictutilsts.sl2m3n4o5'); : i18n.t('aiops.costPredict.steadyHint');
const dimLines = dimensionForecasts.slice(0, 6).map( const dimLines = dimensionForecasts.slice(0, 6).map(
(d) => (d) =>
`- ${d.dimension}:本月 ${d.currentMonth.toFixed(2)} 元 → 预测月末 ${d.predictedMonthEnd.toFixed(2)} 元(趋势 ${d.trend})`, i18n.t('aiops.costPredict.dimLine', {
dim: d.dimension,
current: d.currentMonth.toFixed(2),
predicted: d.predictedMonthEnd.toFixed(2),
trend: d.trend,
}),
); );
const riskLines = const riskLines =
budgetRisks.length > 0 budgetRisks.length > 0
? budgetRisks.slice(0, 5).map( ? budgetRisks.slice(0, 5).map(
(r) => (r) =>
`- ${r.ruleName}(${r.provider}):当前 ${r.current} / 阈值 ${r.threshold},预测 ${r.predicted},触线概率 ${r.probability}%`, i18n.t('aiops.costPredict.riskLine', {
rule: r.ruleName,
provider: r.provider,
current: r.current,
threshold: r.threshold,
predicted: r.predicted,
probability: r.probability,
}),
) )
: [`- ${i18n.t('aiops.predictutilsts.sm3n4o5p6')}`]; : [`- ${i18n.t('aiops.costPredict.noBudgetRisk')}`];
const serviceLines = const serviceLines =
topServices.length > 0 topServices.length > 0
? topServices.map((s) => `- ${s.service}:${s.cost.toFixed(2)} 元`) ? topServices.map((s) => i18n.t('aiops.costPredict.serviceLine', { service: s.service, cost: s.cost.toFixed(2) }))
: [`- ${i18n.t('aiops.predictutilsts.sn4o5p6q7')}`]; : [`- ${i18n.t('aiops.costPredict.noServiceDetail')}`];
return [ return [
i18n.t('aiops.predictutilsts.so5p6q7r8'), i18n.t('aiops.costPredict.promptIntro'),
'', '',
i18n.t('aiops.predictutilsts.sp6q7r8s9'), i18n.t('aiops.costPredict.sectionOverview'),
`- 本月已花:${summary.monthCost.toFixed(2)} 元`, i18n.t('aiops.costPredict.monthSpent', { amount: summary.monthCost.toFixed(2) }),
`- 预测月末:${summary.predictedMonthEnd.toFixed(2)} 元(置信 ${summary.confidence}%)`, i18n.t('aiops.costPredict.predictedEnd', { amount: summary.predictedMonthEnd.toFixed(2), confidence: summary.confidence }),
`- 全月日均:${summary.dailyAvg.toFixed(2)} 元;近7日日均:${recentDailyAvg.toFixed(2)} 元;剩余 ${summary.daysRemaining} 天`, i18n.t('aiops.costPredict.dailySummary', { dailyAvg: summary.dailyAvg.toFixed(2), recentAvg: recentDailyAvg.toFixed(2), daysRemaining: summary.daysRemaining }),
`- 账单形态:${patternHint}`, i18n.t('aiops.costPredict.billingPatternLabel', { hint: patternHint }),
'', '',
i18n.t('aiops.predictutilsts.sq7r8s9t0'), i18n.t('aiops.costPredict.sectionTopServices'),
...serviceLines, ...serviceLines,
'', '',
i18n.t('aiops.predictutilsts.sr8s9t0u1'), i18n.t('aiops.costPredict.sectionDimensionForecast'),
...dimLines, ...dimLines,
'', '',
i18n.t('aiops.predictutilsts.ss9t0u1v2'), i18n.t('aiops.costPredict.sectionBudgetRisk'),
...riskLines, ...riskLines,
'', '',
i18n.t('aiops.predictutilsts.st0u1v2w3'), i18n.t('aiops.costPredict.promptRequirements'),
i18n.t('aiops.predictutilsts.su1v2w3x4'), i18n.t('aiops.costPredict.promptReq1'),
i18n.t('aiops.predictutilsts.sv2w3x4y5'), i18n.t('aiops.costPredict.promptReq2'),
i18n.t('aiops.predictutilsts.sw3x4y5z6'), i18n.t('aiops.costPredict.promptReq3'),
i18n.t('aiops.predictutilsts.sx4y5z6a7'), i18n.t('aiops.costPredict.promptReq4'),
].join('\n'); ].join('\n');
} }
+35 -24
View File
@@ -8602,29 +8602,6 @@
"predictutilsts.providerAliyun": "Alibaba Cloud", "predictutilsts.providerAliyun": "Alibaba Cloud",
"predictutilsts.providerHuawei": "Huawei Cloud", "predictutilsts.providerHuawei": "Huawei Cloud",
"predictutilsts.providerTencent": "Tencent Cloud", "predictutilsts.providerTencent": "Tencent Cloud",
"predictutilsts.sd4e5f6g7": "End of month",
"predictutilsts.se5f6g7h8": "Within today",
"predictutilsts.sf6g7h8i9": "Within 1 day",
"predictutilsts.sg5a3d8e1": "All",
"predictutilsts.sg7h8i9j0": "Within {{days}} days",
"predictutilsts.sh7c2b9d6": "Other",
"predictutilsts.sh8i9j0k1": "In about {{days}} days",
"predictutilsts.si9j0k1l2": "Budget Rule",
"predictutilsts.sj0k1l2m3": "Bills front-loaded at month start, may contain pre-paid or retired resources; prediction uses recent 7-day run rate",
"predictutilsts.sk1l2m3n4": "Insufficient daily bill samples, lower prediction confidence",
"predictutilsts.sl2m3n4o5": "Daily bills are relatively stable, extrapolated by trend",
"predictutilsts.sm3n4o5p6": "No budget threshold risk",
"predictutilsts.sn4o5p6q7": "No service-level detail",
"predictutilsts.so5p6q7r8": "You are a FinOps cloud cost optimization expert. Based on the following cloud billing prediction data, provide comprehensive cost risk assessment and actionable cost-reduction recommendations:",
"predictutilsts.sp6q7r8s9": "[Overview]",
"predictutilsts.sq7r8s9t0": "[Top Service Costs]",
"predictutilsts.sr8s9t0u1": "[Dimension Forecasts]",
"predictutilsts.ss9t0u1v2": "[Budget Risks]",
"predictutilsts.st0u1v2w3": "Output requirements (Markdown, Chinese):",
"predictutilsts.su1v2w3x4": "1. Use **bold subtitles** for sections with 1 key point each, e.g.: **Data Anomalies**, **Idle Resource Cleanup**, **Billing Mode Optimization**, **Storage Lifecycle**",
"predictutilsts.sv2w3x4y5": "2. If monthly avg and recent 7-day avg clearly contradict predicted month-end, explain in 'Data Anomalies' (pre-paid/shutdown etc.)",
"predictutilsts.sw3x4y5z6": "3. Give actionable recommendations per top service (EIP/disk/ECS spec/OSS lifecycle/reserved instances etc.)",
"predictutilsts.sx4y5z6a7": "4. Pick 3-5 most relevant recommendations, under 350 words, no generic platitudes",
"probabilityColon": "Probability: ", "probabilityColon": "Probability: ",
"processing": "Processing...", "processing": "Processing...",
"providerAndCredential": "Model & Credential", "providerAndCredential": "Model & Credential",
@@ -8775,7 +8752,41 @@
"recentReleases": "Recent releases:", "recentReleases": "Recent releases:",
"overviewFallback": "Servers:{{servers}}(running {{running}}) | K8s clusters:{{clusters}} Nodes:{{nodes}} Pods:{{pods}} | Alerts:{{alerts}}(firing {{firing}}) | Pipelines:{{pipelines}}(success {{rate}}%) | Monthly cost:¥{{cost}}", "overviewFallback": "Servers:{{servers}}(running {{running}}) | K8s clusters:{{clusters}} Nodes:{{nodes}} Pods:{{pods}} | Alerts:{{alerts}}(firing {{firing}}) | Pipelines:{{pipelines}}(success {{rate}}%) | Monthly cost:¥{{cost}}",
"noAgentData": "(No Agent data currently, monitoring Agent may not be deployed)" "noAgentData": "(No Agent data currently, monitoring Agent may not be deployed)"
} },
"costPredict.allProviders": "All",
"costPredict.unknownService": "Other",
"costPredict.monthEnd": "End of month",
"costPredict.withinToday": "Within today",
"costPredict.withinOneDay": "Within 1 day",
"costPredict.withinDays": "Within {{days}} days",
"costPredict.approxAfterDays": "In about {{days}} days",
"costPredict.budgetRule": "Budget Rule",
"costPredict.frontLoadedHint": "Bills front-loaded at month start, may contain pre-paid or retired resources; prediction uses recent 7-day run rate",
"costPredict.sparseHint": "Insufficient daily bill samples, lower prediction confidence",
"costPredict.steadyHint": "Daily bills are relatively stable, extrapolated by trend",
"costPredict.noBudgetRisk": "No budget threshold risk",
"costPredict.noServiceDetail": "No service-level detail",
"costPredict.promptIntro": "You are a FinOps cloud cost optimization expert. Based on the following cloud billing prediction data, provide comprehensive cost risk assessment and actionable cost-reduction recommendations:",
"costPredict.sectionOverview": "[Overview]",
"costPredict.sectionTopServices": "[Top Service Costs]",
"costPredict.sectionDimensionForecast": "[Dimension Forecasts]",
"costPredict.sectionBudgetRisk": "[Budget Risks]",
"costPredict.promptRequirements": "Output requirements (Markdown, Chinese):",
"costPredict.promptReq1": "1. Use **bold subtitles** for sections with 1 key point each, e.g.: **Data Anomalies**, **Idle Resource Cleanup**, **Billing Mode Optimization**, **Storage Lifecycle**",
"costPredict.promptReq2": "2. If monthly avg and recent 7-day avg clearly contradict predicted month-end, explain in 'Data Anomalies' (pre-paid/shutdown etc.)",
"costPredict.promptReq3": "3. Give actionable recommendations per top service (EIP/disk/ECS spec/OSS lifecycle/reserved instances etc.)",
"costPredict.promptReq4": "4. Pick 3-5 most relevant recommendations, under 350 words, no generic platitudes",
"costPredict.dimLine": "- {{dim}}: This month {{current}} CNY → Predicted month-end {{predicted}} CNY (trend {{trend}})",
"costPredict.riskLine": "- {{rule}} ({{provider}}): Current {{current}} / Threshold {{threshold}}, Predicted {{predicted}}, Probability {{probability}}%",
"costPredict.serviceLine": "- {{service}}: {{cost}} CNY",
"costPredict.monthSpent": "- Spent this month: {{amount}} CNY",
"costPredict.predictedEnd": "- Predicted month-end: {{amount}} CNY (confidence {{confidence}}%)",
"costPredict.dailySummary": "- Monthly avg: {{dailyAvg}} CNY; Recent 7-day avg: {{recentAvg}} CNY; {{daysRemaining}} days remaining",
"costPredict.billingPatternLabel": "- Billing pattern: {{hint}}",
"costPredict.recHighSpend": "Cost rising rapidly, investigate high-spend resources and optimize specs",
"costPredict.recRising": "Cost trending up, monitor new service spending",
"costPredict.recDeclining": "Cost declining, optimization is effective",
"costPredict.recStable": "Cost stable, maintain current strategy"
}, },
"breadcrumb": { "breadcrumb": {
"aiAlertAnalyzer": "Alert Analysis", "aiAlertAnalyzer": "Alert Analysis",
+35 -24
View File
@@ -8602,29 +8602,6 @@
"predictutilsts.providerAliyun": "阿里云", "predictutilsts.providerAliyun": "阿里云",
"predictutilsts.providerHuawei": "华为云", "predictutilsts.providerHuawei": "华为云",
"predictutilsts.providerTencent": "腾讯云", "predictutilsts.providerTencent": "腾讯云",
"predictutilsts.sd4e5f6g7": "本月末",
"predictutilsts.se5f6g7h8": "今日内",
"predictutilsts.sf6g7h8i9": "1 天内",
"predictutilsts.sg5a3d8e1": "全部",
"predictutilsts.sg7h8i9j0": "{{days}} 天内",
"predictutilsts.sh7c2b9d6": "其他",
"predictutilsts.sh8i9j0k1": "约 {{days}} 天后",
"predictutilsts.si9j0k1l2": "预算规则",
"predictutilsts.sj0k1l2m3": "账单呈月初集中、近期趋零,可能含包年包月预付费或资源已停用,预测已按近7日运行费率外推",
"predictutilsts.sk1l2m3n4": "日账单样本不足,预测置信度较低",
"predictutilsts.sl2m3n4o5": "日账单相对平稳,按趋势外推",
"predictutilsts.sm3n4o5p6": "暂无预算触线风险",
"predictutilsts.sn4o5p6q7": "暂无服务维度明细",
"predictutilsts.so5p6q7r8": "你是 FinOps 云成本优化专家。基于以下云账单预测数据,给出综合成本风险评估与可执行的降本建议:",
"predictutilsts.sp6q7r8s9": "【总览】",
"predictutilsts.sq7r8s9t0": "【Top 服务消费】",
"predictutilsts.sr8s9t0u1": "【分维度预测】",
"predictutilsts.ss9t0u1v2": "【预算风险】",
"predictutilsts.st0u1v2w3": "输出要求(Markdown,中文):",
"predictutilsts.su1v2w3x4": "1. 用 **加粗小标题** 分段,每段下 1 条要点,例如:**数据疑点**、**闲置资源清理**、**计费模式优化**、**存储生命周期**",
"predictutilsts.sv2w3x4y5": "2. 若全月日均与近7日日均、预测月末存在明显矛盾,必须在「数据疑点」中说明原因(预付费/资源停机等)",
"predictutilsts.sw3x4y5z6": "3. 结合 Top 服务给出可落地建议(EIP/云盘/ECS规格/OSS生命周期/预留实例等)",
"predictutilsts.sx4y5z6a7": "4. 选 3~5 条最相关建议,总字数 350 字以内,不要空泛套话",
"probabilityColon": "概率:", "probabilityColon": "概率:",
"processing": "处理中...", "processing": "处理中...",
"providerAndCredential": "模型与凭证", "providerAndCredential": "模型与凭证",
@@ -8775,7 +8752,41 @@
"recentReleases": "最近发布:", "recentReleases": "最近发布:",
"overviewFallback": "服务器:{{servers}}(运行{{running}}) | Kubernetes集群:{{clusters}} 节点:{{nodes}} Pod:{{pods}} | 告警:{{alerts}}(firing {{firing}}) | 流水线:{{pipelines}}(成功率{{rate}}%) | 本月成本:¥{{cost}}", "overviewFallback": "服务器:{{servers}}(运行{{running}}) | Kubernetes集群:{{clusters}} 节点:{{nodes}} Pod:{{pods}} | 告警:{{alerts}}(firing {{firing}}) | 流水线:{{pipelines}}(成功率{{rate}}%) | 本月成本:¥{{cost}}",
"noAgentData": "(当前无 Agent 上报数据,可能未部署监控 Agent)" "noAgentData": "(当前无 Agent 上报数据,可能未部署监控 Agent)"
} },
"costPredict.allProviders": "全部",
"costPredict.unknownService": "其他",
"costPredict.monthEnd": "本月末",
"costPredict.withinToday": "今日内",
"costPredict.withinOneDay": "1 天内",
"costPredict.withinDays": "{{days}} 天内",
"costPredict.approxAfterDays": "约 {{days}} 天后",
"costPredict.budgetRule": "预算规则",
"costPredict.frontLoadedHint": "账单呈月初集中、近期趋零,可能含包年包月预付费或资源已停用,预测已按近7日运行费率外推",
"costPredict.sparseHint": "日账单样本不足,预测置信度较低",
"costPredict.steadyHint": "日账单相对平稳,按趋势外推",
"costPredict.noBudgetRisk": "暂无预算触线风险",
"costPredict.noServiceDetail": "暂无服务维度明细",
"costPredict.promptIntro": "你是 FinOps 云成本优化专家。基于以下云账单预测数据,给出综合成本风险评估与可执行的降本建议:",
"costPredict.sectionOverview": "【总览】",
"costPredict.sectionTopServices": "【Top 服务消费】",
"costPredict.sectionDimensionForecast": "【分维度预测】",
"costPredict.sectionBudgetRisk": "【预算风险】",
"costPredict.promptRequirements": "输出要求(Markdown,中文):",
"costPredict.promptReq1": "1. 用 **加粗小标题** 分段,每段下 1 条要点,例如:**数据疑点**、**闲置资源清理**、**计费模式优化**、**存储生命周期**",
"costPredict.promptReq2": "2. 若全月日均与近7日日均、预测月末存在明显矛盾,必须在「数据疑点」中说明原因(预付费/资源停机等)",
"costPredict.promptReq3": "3. 结合 Top 服务给出可落地建议(EIP/云盘/ECS规格/OSS生命周期/预留实例等)",
"costPredict.promptReq4": "4. 选 3~5 条最相关建议,总字数 350 字以内,不要空泛套话",
"costPredict.dimLine": "- {{dim}}:本月 {{current}} 元 → 预测月末 {{predicted}} 元(趋势 {{trend}})",
"costPredict.riskLine": "- {{rule}}({{provider}}):当前 {{current}} / 阈值 {{threshold}},预测 {{predicted}},触线概率 {{probability}}%",
"costPredict.serviceLine": "- {{service}}:{{cost}} 元",
"costPredict.monthSpent": "- 本月已花:{{amount}} 元",
"costPredict.predictedEnd": "- 预测月末:{{amount}} 元(置信 {{confidence}}%)",
"costPredict.dailySummary": "- 全月日均:{{dailyAvg}} 元;近7日日均:{{recentAvg}} 元;剩余 {{daysRemaining}} 天",
"costPredict.billingPatternLabel": "- 账单形态:{{hint}}",
"costPredict.recHighSpend": "费用增长迅猛,建议排查高消费资源并优化规格",
"costPredict.recRising": "费用呈上升趋势,建议关注新增服务消费",
"costPredict.recDeclining": "费用持续下降,成本优化有效",
"costPredict.recStable": "费用平稳,保持当前成本策略"
}, },
"breadcrumb": { "breadcrumb": {
"aiAlertAnalyzer": "告警分析", "aiAlertAnalyzer": "告警分析",