| 1 | // ==================== 国际化配置 ==================== |
| 2 | const translations = { |
| 3 | 'zh': { |
| 4 | brand_title: '文多多 AiPPT', |
| 5 | page1_title: '🤖 AI智能生成PPT演示文稿', |
| 6 | page1_steps: '生成大纲 ---> 挑选模板 ---> 实时生成PPT', |
| 7 | subject_label: '主题:', |
| 8 | subject_placeholder: '请输入PPT主题', |
| 9 | generate_outline_btn: '生成大纲', |
| 10 | next_to_template_btn: '下一步:选择模板', |
| 11 | select_template_title: '---- 选择模板 ----', |
| 12 | next_to_generate_btn: '下一步:生成PPT', |
| 13 | templates_loading: '模板加载中...', |
| 14 | generating_msg: '正在生成中,请稍后...', |
| 15 | generating_progress: '正在生成中,进度', |
| 16 | insert_element_title: '-- 插入元素 --', |
| 17 | insert_title1: '插入大标题', |
| 18 | insert_title2: '插入副标题', |
| 19 | insert_content: '插入正文文本', |
| 20 | insert_image: '插入图片', |
| 21 | insert_geometry: '插入随机形状', |
| 22 | insert_table: '插入表格', |
| 23 | insert_bar_chart: '插入柱状图', |
| 24 | insert_pie_chart: '插入饼图', |
| 25 | insert_doughnut_chart: '插入环形图', |
| 26 | insert_line_chart: '插入折线图', |
| 27 | download_options_title: '-- 下载选项 --', |
| 28 | download_no_animation: '不添加动画', |
| 29 | download_with_animation: '智能添加动画', |
| 30 | download_pptx_btn: '渲染pptx并下载', |
| 31 | rendering: '正在渲染中...', |
| 32 | load_more_templates: '换一批', |
| 33 | alert_empty_subject: '请输入主题', |
| 34 | alert_subject_too_short: '主题太短', |
| 35 | alert_subject_too_long: '主题太长,不能超过30字', |
| 36 | alert_outline_error: '生成大纲异常:', |
| 37 | alert_ppt_error: '生成PPT异常:', |
| 38 | alert_download_error: '下载失败:', |
| 39 | seconds: '秒', |
| 40 | // ppt2json.html 页面翻译 |
| 41 | ppt2json_title: 'ppt2json', |
| 42 | refresh_json: '刷新', |
| 43 | refresh_json_title: '刷新JSON数据', |
| 44 | download_json: '下载json文件', |
| 45 | download_json_title: '下载json数据', |
| 46 | render_download_pptx: '渲染pptx并下载', |
| 47 | render_download_pptx_title: '渲染pptx并下载', |
| 48 | edit_mode_label: '编辑模式:', |
| 49 | parsing_msg: '解析中,请稍后...', |
| 50 | please_select_file: '请选择文件', |
| 51 | file_too_large: '文件不能超过50M', |
| 52 | read_error: '读取错误: ', |
| 53 | rendering_pptx: '正在渲染中...', |
| 54 | http_status: 'http status: ', |
| 55 | // 示例数据翻译 |
| 56 | table_cell: '第{row}行{col}列', |
| 57 | chart_title: '图表标题', |
| 58 | chart_sales: '销售额', |
| 59 | chart_q1: '第一季度', |
| 60 | chart_q2: '第二季度', |
| 61 | chart_q3: '第三季度', |
| 62 | chart_q4: '第四季度', |
| 63 | chart_series: '系列 {n}', |
| 64 | chart_category: '类别 {n}' |
| 65 | }, |
| 66 | 'en': { |
| 67 | brand_title: 'Docmee AI PPT', |
| 68 | page1_title: '🤖 AI-Powered PPT Generation', |
| 69 | page1_steps: 'Generate Outline ---> Choose Template ---> Generate PPT', |
| 70 | subject_label: 'Topic:', |
| 71 | subject_placeholder: 'Enter PPT topic', |
| 72 | generate_outline_btn: 'Generate Outline', |
| 73 | next_to_template_btn: 'Next: Choose Template', |
| 74 | select_template_title: '---- Select Template ----', |
| 75 | next_to_generate_btn: 'Next: Generate PPT', |
| 76 | templates_loading: 'Loading templates...', |
| 77 | generating_msg: 'Generating, please wait...', |
| 78 | generating_progress: 'Generating, progress', |
| 79 | insert_element_title: '-- Insert Element --', |
| 80 | insert_title1: 'Insert Main Title', |
| 81 | insert_title2: 'Insert Subtitle', |
| 82 | insert_content: 'Insert Text Content', |
| 83 | insert_image: 'Insert Image', |
| 84 | insert_geometry: 'Insert Random Shape', |
| 85 | insert_table: 'Insert Table', |
| 86 | insert_bar_chart: 'Insert Bar Chart', |
| 87 | insert_pie_chart: 'Insert Pie Chart', |
| 88 | insert_doughnut_chart: 'Insert Doughnut Chart', |
| 89 | insert_line_chart: 'Insert Line Chart', |
| 90 | download_options_title: '-- Download Options --', |
| 91 | download_no_animation: 'No Animation', |
| 92 | download_with_animation: 'Smart Animation', |
| 93 | download_pptx_btn: 'Render & Download PPTX', |
| 94 | rendering: 'Rendering...', |
| 95 | load_more_templates: 'Load More', |
| 96 | alert_empty_subject: 'Please enter a topic', |
| 97 | alert_subject_too_short: 'Topic is too short', |
| 98 | alert_subject_too_long: 'Topic is too long, max 30 characters', |
| 99 | alert_outline_error: 'Outline generation error: ', |
| 100 | alert_ppt_error: 'PPT generation error: ', |
| 101 | alert_download_error: 'Download failed: ', |
| 102 | seconds: 's', |
| 103 | // ppt2json.html page translations |
| 104 | ppt2json_title: 'ppt2json', |
| 105 | refresh_json: 'Refresh', |
| 106 | refresh_json_title: 'Refresh JSON data', |
| 107 | download_json: 'Download JSON', |
| 108 | download_json_title: 'Download JSON data', |
| 109 | render_download_pptx: 'Render & Download PPTX', |
| 110 | render_download_pptx_title: 'Render and download PPTX', |
| 111 | edit_mode_label: 'Edit Mode:', |
| 112 | parsing_msg: 'Parsing, please wait...', |
| 113 | please_select_file: 'Please select a file', |
| 114 | file_too_large: 'File size cannot exceed 50MB', |
| 115 | read_error: 'Read error: ', |
| 116 | rendering_pptx: 'Rendering...', |
| 117 | http_status: 'HTTP status: ', |
| 118 | // Sample data translations |
| 119 | table_cell: 'Row {row} Col {col}', |
| 120 | chart_title: 'Chart Title', |
| 121 | chart_sales: 'Sales', |
| 122 | chart_q1: 'Q1', |
| 123 | chart_q2: 'Q2', |
| 124 | chart_q3: 'Q3', |
| 125 | chart_q4: 'Q4', |
| 126 | chart_series: 'Series {n}', |
| 127 | chart_category: 'Category {n}' |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | // 当前语言 |
| 132 | let currentLanguage = detectLanguage() |
| 133 | |
| 134 | /** |
| 135 | * 检测浏览器语言 |
| 136 | */ |
| 137 | function detectLanguage() { |
| 138 | const savedLang = localStorage.getItem('ppt_language') |
| 139 | if (savedLang && (savedLang === 'zh' || savedLang === 'en')) { |
| 140 | return savedLang |
| 141 | } |
| 142 | const browserLang = navigator.language || navigator.userLanguage |
| 143 | return browserLang.toLowerCase().startsWith('zh') ? 'zh' : 'en' |
| 144 | } |
| 145 | |
| 146 | /** |
| 147 | * 切换语言 |
| 148 | */ |
| 149 | function toggleLanguage() { |
| 150 | currentLanguage = currentLanguage === 'zh' ? 'en' : 'zh' |
| 151 | localStorage.setItem('ppt_language', currentLanguage) |
| 152 | applyLanguage() |
| 153 | } |
| 154 | |
| 155 | /** |
| 156 | * 获取当前语言 |
| 157 | */ |
| 158 | function getCurrentLanguage() { |
| 159 | return currentLanguage |
| 160 | } |
| 161 | |
| 162 | /** |
| 163 | * 设置语言 |
| 164 | */ |
| 165 | function setLanguage(lang) { |
| 166 | if (lang === 'zh' || lang === 'en') { |
| 167 | currentLanguage = lang |
| 168 | localStorage.setItem('ppt_language', currentLanguage) |
| 169 | applyLanguage() |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | /** |
| 174 | * 翻译文本 |
| 175 | */ |
| 176 | function t(key) { |
| 177 | return translations[currentLanguage][key] || translations['zh'][key] || key |
| 178 | } |
| 179 | |
| 180 | /** |
| 181 | * 应用语言到页面 |
| 182 | */ |
| 183 | function applyLanguage() { |
| 184 | document.documentElement.lang = currentLanguage |
| 185 | |
| 186 | // 更新语言切换按钮 |
| 187 | const langText = document.getElementById('lang-text') |
| 188 | if (langText) { |
| 189 | langText.textContent = currentLanguage === 'zh' ? 'EN' : '中文' |
| 190 | } |
| 191 | |
| 192 | // 更新所有带 data-i18n 属性的元素 |
| 193 | document.querySelectorAll('[data-i18n]').forEach(element => { |
| 194 | const key = element.getAttribute('data-i18n') |
| 195 | if (element.tagName === 'INPUT') { |
| 196 | element.placeholder = t(key) |
| 197 | } else if (element.tagName === 'OPTION') { |
| 198 | element.textContent = t(key) |
| 199 | } else { |
| 200 | element.innerHTML = t(key) |
| 201 | } |
| 202 | }) |
| 203 | |
| 204 | // 更新带 data-i18n-placeholder 的元素 |
| 205 | document.querySelectorAll('[data-i18n-placeholder]').forEach(element => { |
| 206 | const key = element.getAttribute('data-i18n-placeholder') |
| 207 | element.placeholder = t(key) |
| 208 | }) |
| 209 | |
| 210 | // 更新带 data-i18n-title 的元素 |
| 211 | document.querySelectorAll('[data-i18n-title]').forEach(element => { |
| 212 | const key = element.getAttribute('data-i18n-title') |
| 213 | element.title = t(key) |
| 214 | }) |
| 215 | } |
| 216 | |
| 217 |