This commit is contained in:
parent
9c7b1f7903
commit
6e48ac3f7a
|
|
@ -506,6 +506,46 @@ export default function HistoryPage() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Detect report language based on trader's final decision keywords
|
||||||
|
// This ensures PDF language matches the report content, not UI language
|
||||||
|
const detectReportLanguage = (reports: any): 'zh-TW' | 'en' => {
|
||||||
|
const traderPlan = reports?.trader_investment_plan;
|
||||||
|
if (!traderPlan || typeof traderPlan !== 'string') {
|
||||||
|
return 'zh-TW'; // Default to Chinese
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chinese decision keywords: 買入, 賣出, 持有
|
||||||
|
const chineseKeywords = ['買入', '賣出', '持有'];
|
||||||
|
// English decision keywords: buy, sell, hold (case insensitive)
|
||||||
|
const englishKeywords = ['buy', 'sell', 'hold'];
|
||||||
|
|
||||||
|
const lowerPlan = traderPlan.toLowerCase();
|
||||||
|
|
||||||
|
// Check for Chinese keywords first
|
||||||
|
for (const keyword of chineseKeywords) {
|
||||||
|
if (traderPlan.includes(keyword)) {
|
||||||
|
return 'zh-TW';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for English keywords
|
||||||
|
for (const keyword of englishKeywords) {
|
||||||
|
if (lowerPlan.includes(keyword)) {
|
||||||
|
return 'en';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: check for any Chinese characters
|
||||||
|
const chineseRegex = /[\u4e00-\u9fa5]/;
|
||||||
|
if (chineseRegex.test(traderPlan)) {
|
||||||
|
return 'zh-TW';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'en';
|
||||||
|
};
|
||||||
|
|
||||||
|
const reportLanguage = detectReportLanguage(report.result.reports);
|
||||||
|
|
||||||
// Build request body
|
// Build request body
|
||||||
const requestBody = {
|
const requestBody = {
|
||||||
ticker: report.ticker,
|
ticker: report.ticker,
|
||||||
|
|
@ -514,7 +554,7 @@ export default function HistoryPage() {
|
||||||
reports: report.result.reports,
|
reports: report.result.reports,
|
||||||
price_data: report.result.price_data,
|
price_data: report.result.price_data,
|
||||||
price_stats: report.result.price_stats,
|
price_stats: report.result.price_stats,
|
||||||
language: locale, // Pass current language for PDF generation
|
language: reportLanguage, // Use detected language based on trader decision
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await fetch('/api/download/reports', {
|
const response = await fetch('/api/download/reports', {
|
||||||
|
|
|
||||||
|
|
@ -49,15 +49,43 @@ export function DownloadReports({
|
||||||
return path.split('.').reduce((current, key) => current?.[key], obj);
|
return path.split('.').reduce((current, key) => current?.[key], obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper to detect if content contains Chinese characters
|
// Helper to detect report language based on trader's final decision keywords
|
||||||
const detectContentLanguage = (data: any): 'zh-TW' | 'en' | null => {
|
// This ensures PDF language matches the report content language, not UI language
|
||||||
|
const detectReportLanguage = (data: any): 'zh-TW' | 'en' | null => {
|
||||||
try {
|
try {
|
||||||
const contentStr = JSON.stringify(data);
|
// Get trader's investment plan (final decision)
|
||||||
// Check for Chinese characters (Unicode range \u4e00-\u9fa5)
|
const traderPlan = data?.trader_investment_plan;
|
||||||
|
if (!traderPlan || typeof traderPlan !== 'string') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chinese decision keywords: 買入, 賣出, 持有
|
||||||
|
const chineseKeywords = ['買入', '賣出', '持有'];
|
||||||
|
// English decision keywords: buy, sell, hold (case insensitive)
|
||||||
|
const englishKeywords = ['buy', 'sell', 'hold'];
|
||||||
|
|
||||||
|
const lowerPlan = traderPlan.toLowerCase();
|
||||||
|
|
||||||
|
// Check for Chinese keywords first
|
||||||
|
for (const keyword of chineseKeywords) {
|
||||||
|
if (traderPlan.includes(keyword)) {
|
||||||
|
return 'zh-TW';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for English keywords
|
||||||
|
for (const keyword of englishKeywords) {
|
||||||
|
if (lowerPlan.includes(keyword)) {
|
||||||
|
return 'en';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: check for any Chinese characters as secondary detection
|
||||||
const chineseRegex = /[\u4e00-\u9fa5]/;
|
const chineseRegex = /[\u4e00-\u9fa5]/;
|
||||||
if (chineseRegex.test(contentStr)) {
|
if (chineseRegex.test(traderPlan)) {
|
||||||
return 'zh-TW';
|
return 'zh-TW';
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'en';
|
return 'en';
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -80,8 +108,8 @@ export function DownloadReports({
|
||||||
try {
|
try {
|
||||||
// Build request body with all available analysts
|
// Build request body with all available analysts
|
||||||
// Always use direct mode when reports data is available (task may be cleaned up from Redis)
|
// Always use direct mode when reports data is available (task may be cleaned up from Redis)
|
||||||
// Detect content language
|
// Detect report language based on trader's final decision keywords
|
||||||
const contentLang = detectContentLanguage(reports);
|
const contentLang = detectReportLanguage(reports);
|
||||||
// Use detected language if available, otherwise fallback to prop or current locale
|
// Use detected language if available, otherwise fallback to prop or current locale
|
||||||
// This ensures that if reports are in Chinese, the PDF headers will also be in Chinese
|
// This ensures that if reports are in Chinese, the PDF headers will also be in Chinese
|
||||||
// even if the UI is in English
|
// even if the UI is in English
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue