Skip to content

Commit 424e596

Browse files
committed
feat: 优化多语言
1 parent c09faf5 commit 424e596

4 files changed

Lines changed: 278 additions & 122 deletions

File tree

iframe/footprint.html

Lines changed: 101 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<script src="/iframe/assets/jszip.min.js"></script>
77
<script src="/iframe/assets/pdf.min.js"></script>
8-
<title id="pageTitle"></title>
8+
<title id="pageTitle" data-i18n="footprint_generator"></title>
99
<style>
1010
body {
1111
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
@@ -893,19 +893,19 @@
893893
<div id="settings-modal" class="settings-modal">
894894
<div class="settings-content" style="width: 500px">
895895
<div class="settings-header">
896-
<h3 class="settings-title" id="settingsTitle"></h3>
896+
<h3 class="settings-title" id="settingsTitle" data-i18n="settings"></h3>
897897
<button class="close-btn" id="close-settings">×</button>
898898
</div>
899899
<div class="form-group">
900-
<label for="provider-select" id="labelProvider"></label>
900+
<label for="provider-select" id="labelProvider" data-i18n="model_provider"></label>
901901
<select id="provider-select">
902-
<option value="qwen" id="optQwen"></option>
903-
<option value="zhipu" id="optZhipu"></option>
904-
<option value="custom" id="optCustom"></option>
902+
<option value="qwen" id="optQwen" data-i18n="tongyi_qianwen"></option>
903+
<option value="zhipu" id="optZhipu" data-i18n="zhipu_ai"></option>
904+
<option value="custom" id="optCustom" data-i18n="custom"></option>
905905
</select>
906906
</div>
907907
<div class="form-group" id="model-group">
908-
<label for="model-select" id="labelModel"></label>
908+
<label for="model-select" id="labelModel" data-i18n="select_model"></label>
909909
<select id="model-select">
910910
<option value="qwen3-vl-plus" selected>qwen3-vl-plus</option>
911911
<option value="qwen-vl-max-latest">qwen-vl-max-latest</option>
@@ -915,20 +915,20 @@ <h3 class="settings-title" id="settingsTitle"></h3>
915915
</select>
916916
</div>
917917
<div class="form-group" id="api-key-group">
918-
<label for="api-key" id="labelApiKey"></label>
919-
<input type="text" id="api-key" />
918+
<label for="api-key" id="labelApiKey" data-i18n="api_key"></label>
919+
<input type="text" id="api-key" data-i18n-placeholder="enter_api_key" />
920920
</div>
921921
<div class="form-group" id="api-url-group" style="display: none">
922-
<label for="api-url" id="labelApiUrl"></label>
923-
<input type="text" id="api-url" />
922+
<label for="api-url" id="labelApiUrl" data-i18n="api_url"></label>
923+
<input type="text" id="api-url" data-i18n-placeholder="enter_api_url" />
924924
</div>
925925
<div class="form-group" id="custom-model-group" style="display: none">
926-
<label for="custom-model" id="labelCustomModel"></label>
927-
<input type="text" id="custom-model" />
926+
<label for="custom-model" id="labelCustomModel" data-i18n="model_name"></label>
927+
<input type="text" id="custom-model" data-i18n-placeholder="enter_model_name" />
928928
</div>
929929
<div style="display: flex; justify-content: flex-end; gap: 12px; margin-top: 24px">
930-
<button type="button" id="cancel-settings" style="background: #e9ecef; color: #495057"></button>
931-
<button type="button" id="save-settings" class="btn-primary"></button>
930+
<button type="button" id="cancel-settings" style="background: #e9ecef; color: #495057" data-i18n="cancel"></button>
931+
<button type="button" id="save-settings" class="btn-primary" data-i18n="save"></button>
932932
</div>
933933
</div>
934934
</div>
@@ -937,14 +937,14 @@ <h3 class="settings-title" id="settingsTitle"></h3>
937937
<!-- 左侧面板 -->
938938
<div class="left-panel">
939939
<div class="header">
940-
<h1 id="headerTitle"></h1>
941-
<button class="settings-btn" id="open-settings"></button>
940+
<h1 id="headerTitle" data-i18n="footprint_generator"></h1>
941+
<button class="settings-btn" id="open-settings" data-i18n="settings"></button>
942942
</div>
943943

944944
<!-- 上传区域 -->
945945
<div class="upload-section">
946946
<div id="drop-area" class="upload-area">
947-
<p id="uploadText"></p>
947+
<p id="uploadText" data-i18n="drag_upload"></p>
948948
<input type="file" id="file-input" multiple accept=".pdf,image/*" style="display: none" />
949949
</div>
950950
</div>
@@ -953,17 +953,17 @@ <h1 id="headerTitle"></h1>
953953
<div class="controls-section">
954954
<div class="control-row single-row">
955955
<div class="control-buttons">
956-
<button id="search-position" class="btn-primary" disabled></button>
957-
<button id="extract-params" class="btn-success" disabled></button>
958-
<button id="clear-selection"></button>
959-
<button id="manual-select"></button>
960-
<button class="btn-secondary" id="hideButton"></button>
961-
<button class="settings-btn" id="open-settings-control"></button>
956+
<button id="search-position" class="btn-primary" disabled data-i18n="search_footprint_position"></button>
957+
<button id="extract-params" class="btn-success" disabled data-i18n="extract_parameters"></button>
958+
<button id="clear-selection" data-i18n="clear_selection"></button>
959+
<button id="manual-select" data-i18n="manual_select"></button>
960+
<button class="btn-secondary" id="hideButton" data-i18n="hide_window"></button>
961+
<button class="settings-btn" id="open-settings-control" data-i18n="settings"></button>
962962
</div>
963-
<div class="timing-display" id="timing-display"></div>
963+
<div class="timing-display" id="timing-display" data-i18n="elapsed_dash"></div>
964964
</div>
965965
<div class="progress-container">
966-
<div class="coordinate-display" id="coordinate-display"></div>
966+
<div class="coordinate-display" id="coordinate-display" data-i18n="coordinates_no_selection"></div>
967967
<div class="progress-bar" id="progress-bar">
968968
<div class="progress-fill" id="progress-fill"></div>
969969
</div>
@@ -974,21 +974,23 @@ <h1 id="headerTitle"></h1>
974974
<!-- 图片显示区域 -->
975975
<div class="image-display" id="image-display">
976976
<div class="selection-overlay" id="selection-overlay"></div>
977-
<div class="empty-state" id="emptyState"></div>
977+
<div class="empty-state" id="emptyState" data-i18n="upload_prompt"></div>
978978
<input type="file" id="file-input" multiple accept=".pdf,image/*" style="display: none" />
979979
</div>
980980

981981
<!-- 图片导航区域 -->
982982
<div class="image-navigation" id="image-navigation" style="display: none">
983983
<div class="nav-controls">
984-
<button id="prev-image" class="nav-btn"></button>
984+
<button id="prev-image" class="nav-btn" data-i18n="previous_image"></button>
985985
<input
986986
type="number"
987987
id="page-input"
988988
min="1"
989989
value="1"
990990
placeholder=""
991991
title=""
992+
data-i18n-placeholder="page"
993+
data-i18n-title="page_jump_hint"
992994
style="
993995
width: 40px;
994996
text-align: center;
@@ -1002,7 +1004,7 @@ <h1 id="headerTitle"></h1>
10021004
"
10031005
/>
10041006
/ <span id="total-pages">1</span>
1005-
<button id="next-image" class="nav-btn"></button>
1007+
<button id="next-image" class="nav-btn" data-i18n="next_image"></button>
10061008
</div>
10071009
<div class="image-info" id="image-info"></div>
10081010
</div>
@@ -1012,9 +1014,9 @@ <h1 id="headerTitle"></h1>
10121014
<div class="right-panel">
10131015
<div class="pin-table-section">
10141016
<div class="table-controls">
1015-
<button id="add-param"></button>
1016-
<button id="clear-table"></button>
1017-
<button id="create-footprint" class="btn-success"></button>
1017+
<button id="add-param" data-i18n="add_parameter"></button>
1018+
<button id="clear-table" data-i18n="clear_table"></button>
1019+
<button id="create-footprint" class="btn-success" data-i18n="create_footprint"></button>
10181020
<select
10191021
id="package-type-select"
10201022
style="
@@ -1027,7 +1029,7 @@ <h1 id="headerTitle"></h1>
10271029
margin-left: 8px;
10281030
"
10291031
>
1030-
<option value="" id="optPackageType"></option>
1032+
<option value="" id="optPackageType" data-i18n="package_type"></option>
10311033
<option value="BGA">BGA</option>
10321034
<option value="DIP">DIP</option>
10331035
<option value="QFN">QFN</option>
@@ -1040,7 +1042,7 @@ <h1 id="headerTitle"></h1>
10401042
</div>
10411043
<div class="pin-table-content">
10421044
<div id="pin-table-container">
1043-
<div class="empty-state" id="emptyPinState"></div>
1045+
<div class="empty-state" id="emptyPinState" data-i18n="no_footprint_params"></div>
10441046
</div>
10451047
</div>
10461048
</div>
@@ -1054,6 +1056,18 @@ <h1 id="headerTitle"></h1>
10541056
if (edaObj && edaObj.sys_I18n) return edaObj.sys_I18n.text(tag, undefined, undefined, ...args);
10551057
return tag;
10561058
}
1059+
function applyI18n() {
1060+
document.querySelectorAll('[data-i18n]').forEach(function(el) {
1061+
el.textContent = t(el.getAttribute('data-i18n'));
1062+
});
1063+
document.querySelectorAll('[data-i18n-title]').forEach(function(el) {
1064+
el.setAttribute('title', t(el.getAttribute('data-i18n-title')));
1065+
});
1066+
document.querySelectorAll('[data-i18n-placeholder]').forEach(function(el) {
1067+
el.setAttribute('placeholder', t(el.getAttribute('data-i18n-placeholder')));
1068+
});
1069+
}
1070+
applyI18n();
10571071

10581072
// 设置PDF.js的worker路径
10591073
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';
@@ -1125,67 +1139,67 @@ <h1 id="headerTitle"></h1>
11251139
// 封装类型参数配置
11261140
const packageParams = {
11271141
'BGA': [
1128-
{ name: '引脚行数', key: 'pin_rows', unit: '' },
1129-
{ name: '引脚列数', key: 'pin_cols', unit: '' },
1130-
{ name: '本体长度(BL)', key: 'body_length', unit: 'mm' },
1131-
{ name: '本体宽度(BW)', key: 'body_width', unit: 'mm' },
1132-
{ name: '引脚直径(PD)', key: 'pin_diameter', unit: 'mm' },
1133-
{ name: '引脚间距(PS)', key: 'pin_spacing', unit: 'mm' },
1134-
{ name: '引脚纵向间距(PP)', key: 'pin_pitch', unit: 'mm' },
1142+
{ name: t('Pin Rows'), key: 'pin_rows', unit: '' },
1143+
{ name: t('Pin Columns'), key: 'pin_cols', unit: '' },
1144+
{ name: t('Body Length (BL)'), key: 'body_length', unit: 'mm' },
1145+
{ name: t('Body Width (BW)'), key: 'body_width', unit: 'mm' },
1146+
{ name: t('Pin Diameter (PD)'), key: 'pin_diameter', unit: 'mm' },
1147+
{ name: t('Pin Spacing (PS)'), key: 'pin_spacing', unit: 'mm' },
1148+
{ name: t('Pin Pitch Vertical (PP)'), key: 'pin_pitch', unit: 'mm' },
11351149
],
11361150
'DIP': [
1137-
{ name: '引脚数量', key: 'pin_count', unit: '' },
1138-
{ name: '引脚跨距', key: 'LS', unit: 'mm' },
1139-
{ name: '本体长度', key: 'BL', unit: 'mm' },
1140-
{ name: '本体宽度', key: 'BW', unit: 'mm' },
1141-
{ name: '引脚直径', key: 'PD', unit: 'mm' },
1142-
{ name: '引脚间距', key: 'PS', unit: 'mm' },
1151+
{ name: t('Pin Count'), key: 'pin_count', unit: '' },
1152+
{ name: t('Lead Span'), key: 'LS', unit: 'mm' },
1153+
{ name: t('Body Length'), key: 'BL', unit: 'mm' },
1154+
{ name: t('Body Width'), key: 'BW', unit: 'mm' },
1155+
{ name: t('Pin Diameter'), key: 'PD', unit: 'mm' },
1156+
{ name: t('Pin Spacing'), key: 'PS', unit: 'mm' },
11431157
],
11441158
'QFN': [
1145-
{ name: '引脚数(左右)', key: 'pin_count_lr', unit: '' },
1146-
{ name: '引脚数(上下)', key: 'pin_count_tb', unit: '' },
1147-
{ name: '本体长度(BL)', key: 'body_length', unit: 'mm' },
1148-
{ name: '本体宽度(BW)', key: 'body_width', unit: 'mm' },
1149-
{ name: '引脚长度(PL)', key: 'pin_length', unit: 'mm' },
1150-
{ name: '引脚宽度(PW)', key: 'pin_width', unit: 'mm' },
1151-
{ name: '引脚间距(PP)', key: 'pin_pitch', unit: 'mm' },
1159+
{ name: t('Pin Count (Left/Right)'), key: 'pin_count_lr', unit: '' },
1160+
{ name: t('Pin Count (Top/Bottom)'), key: 'pin_count_tb', unit: '' },
1161+
{ name: t('Body Length (BL)'), key: 'body_length', unit: 'mm' },
1162+
{ name: t('Body Width (BW)'), key: 'body_width', unit: 'mm' },
1163+
{ name: t('Pin Length (PL)'), key: 'pin_length', unit: 'mm' },
1164+
{ name: t('Pin Width (PW)'), key: 'pin_width', unit: 'mm' },
1165+
{ name: t('Pin Pitch (PP)'), key: 'pin_pitch', unit: 'mm' },
11521166
],
11531167
'QFP': [
1154-
{ name: '引脚数(左右)', key: 'pin_count_lr', unit: '' },
1155-
{ name: '引脚数(上下)', key: 'pin_count_tb', unit: '' },
1156-
{ name: '引脚跨距(LS1)', key: 'lead_span1', unit: 'mm' },
1157-
{ name: '引脚纵向跨距(LS2)', key: 'lead_span2', unit: 'mm' },
1158-
{ name: '本体长度(BL)', key: 'body_length', unit: 'mm' },
1159-
{ name: '本体宽度(BW)', key: 'body_width', unit: 'mm' },
1160-
{ name: '引脚长度(PL)', key: 'pin_length', unit: 'mm' },
1161-
{ name: '引脚宽度(PW)', key: 'pin_width', unit: 'mm' },
1162-
{ name: '引脚间距(PP)', key: 'pin_pitch', unit: 'mm' },
1168+
{ name: t('Pin Count (Left/Right)'), key: 'pin_count_lr', unit: '' },
1169+
{ name: t('Pin Count (Top/Bottom)'), key: 'pin_count_tb', unit: '' },
1170+
{ name: t('Lead Span (LS1)'), key: 'lead_span1', unit: 'mm' },
1171+
{ name: t('Lead Span Vertical (LS2)'), key: 'lead_span2', unit: 'mm' },
1172+
{ name: t('Body Length (BL)'), key: 'body_length', unit: 'mm' },
1173+
{ name: t('Body Width (BW)'), key: 'body_width', unit: 'mm' },
1174+
{ name: t('Pin Length (PL)'), key: 'pin_length', unit: 'mm' },
1175+
{ name: t('Pin Width (PW)'), key: 'pin_width', unit: 'mm' },
1176+
{ name: t('Pin Pitch (PP)'), key: 'pin_pitch', unit: 'mm' },
11631177
],
11641178
'SOD': [
1165-
{ name: '引脚跨距(LS)', key: 'lead_span', unit: 'mm' },
1166-
{ name: '本体长度(BL)', key: 'body_length', unit: 'mm' },
1167-
{ name: '本体宽度(BW)', key: 'body_width', unit: 'mm' },
1168-
{ name: '引脚长度(PL)', key: 'pin_length', unit: 'mm' },
1169-
{ name: '引脚宽度(PW)', key: 'pin_width', unit: 'mm' },
1179+
{ name: t('Lead Span (LS)'), key: 'lead_span', unit: 'mm' },
1180+
{ name: t('Body Length (BL)'), key: 'body_length', unit: 'mm' },
1181+
{ name: t('Body Width (BW)'), key: 'body_width', unit: 'mm' },
1182+
{ name: t('Pin Length (PL)'), key: 'pin_length', unit: 'mm' },
1183+
{ name: t('Pin Width (PW)'), key: 'pin_width', unit: 'mm' },
11701184
],
11711185
'SOT23': [
1172-
{ name: '引脚数量', key: 'pin_count', unit: '' },
1173-
{ name: '引脚跨距(LS)', key: 'lead_span', unit: 'mm' },
1174-
{ name: '本体长度(BL)', key: 'body_length', unit: 'mm' },
1175-
{ name: '本体宽度(BW)', key: 'body_width', unit: 'mm' },
1176-
{ name: '引脚长度(PL)', key: 'pin_length', unit: 'mm' },
1177-
{ name: '引脚宽度(PW)', key: 'pin_width', unit: 'mm' },
1178-
{ name: '引脚间距(PP)', key: 'pin_pitch', unit: 'mm' },
1186+
{ name: t('Pin Count'), key: 'pin_count', unit: '' },
1187+
{ name: t('Lead Span (LS)'), key: 'lead_span', unit: 'mm' },
1188+
{ name: t('Body Length (BL)'), key: 'body_length', unit: 'mm' },
1189+
{ name: t('Body Width (BW)'), key: 'body_width', unit: 'mm' },
1190+
{ name: t('Pin Length (PL)'), key: 'pin_length', unit: 'mm' },
1191+
{ name: t('Pin Width (PW)'), key: 'pin_width', unit: 'mm' },
1192+
{ name: t('Pin Pitch (PP)'), key: 'pin_pitch', unit: 'mm' },
11791193
],
11801194
'SOT223': [
1181-
{ name: '引脚数量', key: 'pin_count', unit: '' },
1182-
{ name: '引脚跨距(LS)', key: 'lead_span', unit: 'mm' },
1183-
{ name: '本体长度(BL)', key: 'body_length', unit: 'mm' },
1184-
{ name: '本体宽度(BW)', key: 'body_width', unit: 'mm' },
1185-
{ name: '引脚长度(PL)', key: 'pin_length', unit: 'mm' },
1186-
{ name: '引脚宽度(PW)', key: 'pin_width', unit: 'mm' },
1187-
{ name: '引脚间距(PS)', key: 'pin_spacing', unit: 'mm' },
1188-
{ name: '引脚宽度(PW1)', key: 'pin_width1', unit: 'mm' },
1195+
{ name: t('Pin Count'), key: 'pin_count', unit: '' },
1196+
{ name: t('Lead Span (LS)'), key: 'lead_span', unit: 'mm' },
1197+
{ name: t('Body Length (BL)'), key: 'body_length', unit: 'mm' },
1198+
{ name: t('Body Width (BW)'), key: 'body_width', unit: 'mm' },
1199+
{ name: t('Pin Length (PL)'), key: 'pin_length', unit: 'mm' },
1200+
{ name: t('Pin Width (PW)'), key: 'pin_width', unit: 'mm' },
1201+
{ name: t('Pin Spacing (PS)'), key: 'pin_spacing', unit: 'mm' },
1202+
{ name: t('Pin Width (PW1)'), key: 'pin_width1', unit: 'mm' },
11891203
],
11901204
};
11911205

@@ -2869,7 +2883,7 @@ <h1 id="headerTitle"></h1>
28692883
// 验证content是否有效
28702884
if (!content || typeof content !== 'string') {
28712885
console.error('content为空或不是字符串:', content);
2872-
throw new Error('API返回的内容为空或格式错误');
2886+
throw new Error(t('Empty response returned'));
28732887
}
28742888

28752889
console.log(`第 ${attempt} 次提取结果:`, content);
@@ -2916,8 +2930,8 @@ <h1 id="headerTitle"></h1>
29162930
// 根据提取次数显示不同的成功消息
29172931
const successMessage =
29182932
extractionCount === 1
2919-
? `成功提取 ${imagesWithSelections.length} 张图片的封装参数(已选择封装类型)`
2920-
: `成功提取 ${imagesWithSelections.length} 张图片的封装参数(智能选择最佳结果)`;
2933+
? t('Successfully extracted package parameters from ${1} images (package type selected)', imagesWithSelections.length)
2934+
: t('Successfully extracted package parameters from ${1} images (intelligent best result)', imagesWithSelections.length);
29212935
eda.sys_ToastMessage.showMessage(successMessage, 1);
29222936
} catch (error) {
29232937
console.error('提取参数失败:', error);
@@ -4286,7 +4300,7 @@ <h1 id="headerTitle"></h1>
42864300

42874301
// 检查JSON数据是否包含必要的字段
42884302
if (!data || typeof data !== 'object' || !data.type || !Array.isArray(data.pins)) {
4289-
throw new Error('JSON数据格式不正确,缺少type或pins字段');
4303+
throw new Error(t('Invalid JSON data format, missing type or pins field'));
42904304
}
42914305

42924306
const type = data.type;

0 commit comments

Comments
 (0)