From f8757a757eb9f7173117efbc913595761ce62332 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 20 Apr 2026 09:12:15 +0800 Subject: [PATCH] i18n(feeder): replace all English UI text with Chinese Co-Authored-By: Claude Opus 4.6 --- web/core/html/modals.html | 2 +- web/feeder/html/modals.html | 2 +- web/feeder/js/app.js | 4 ++-- web/feeder/js/chart.js | 12 +++++------ web/feeder/js/equipment.js | 12 +++++------ web/feeder/js/ops.js | 8 +++---- web/feeder/js/points.js | 42 ++++++++++++++++++------------------- web/feeder/js/roles.js | 20 +++++++++--------- web/feeder/js/sources.js | 14 ++++++------- web/feeder/js/units.js | 10 ++++----- 10 files changed, 63 insertions(+), 63 deletions(-) diff --git a/web/core/html/modals.html b/web/core/html/modals.html index 79245f9..71c52c9 100644 --- a/web/core/html/modals.html +++ b/web/core/html/modals.html @@ -38,7 +38,7 @@
-
Nodes: 0
+
节点: 0
diff --git a/web/feeder/html/modals.html b/web/feeder/html/modals.html index ee282ba..3f058c4 100644 --- a/web/feeder/html/modals.html +++ b/web/feeder/html/modals.html @@ -42,7 +42,7 @@
-
Nodes: 0
+
节点: 0
diff --git a/web/feeder/js/app.js b/web/feeder/js/app.js index 55f4208..fb6d762 100644 --- a/web/feeder/js/app.js +++ b/web/feeder/js/app.js @@ -105,8 +105,8 @@ function bindEvents() { dom.closeEquipmentModalBtn.addEventListener("click", closeEquipmentModal); dom.openPointModalBtn.addEventListener("click", openPointCreateModal); dom.pointSourceSelect.addEventListener("change", () => { - dom.nodeTree.innerHTML = '
Click "Load Nodes" to fetch node tree
'; - dom.pointSourceNodeCount.textContent = "Nodes: 0"; + dom.nodeTree.innerHTML = '
点击"加载节点"获取节点树
'; + dom.pointSourceNodeCount.textContent = "节点: 0"; }); dom.browseNodesBtn.addEventListener("click", () => withStatus(browseAndLoadTree())); dom.refreshTreeBtn.addEventListener("click", () => withStatus(loadTree())); diff --git a/web/feeder/js/chart.js b/web/feeder/js/chart.js index 111d631..c19f8fe 100644 --- a/web/feeder/js/chart.js +++ b/web/feeder/js/chart.js @@ -52,8 +52,8 @@ function formatTimeLabel(timestamp) { export async function openChart(pointId, pointName) { state.chartPointId = pointId; - state.chartPointName = pointName || "Point"; - dom.chartTitle.textContent = `${state.chartPointName} Chart`; + state.chartPointName = pointName || "点位"; + dom.chartTitle.textContent = `${state.chartPointName} 趋势图`; const items = await apiFetch(`/api/point/${pointId}/history?limit=120`); state.chartData = (items || []) @@ -99,8 +99,8 @@ export function renderChart() { if (!state.chartData.length) { ctx.fillStyle = "#94a3b8"; ctx.font = "14px Segoe UI"; - ctx.fillText("Click a point row to view its chart", 24, 40); - dom.chartSummary.textContent = "Click a point row to view its chart"; + ctx.fillText("点击点位行查看图表", 24, 40); + dom.chartSummary.textContent = "点击点位行查看图表"; return; } @@ -158,9 +158,9 @@ export function renderChart() { ctx.translate(16, padding.top + plotHeight / 2); ctx.rotate(-Math.PI / 2); ctx.fillStyle = "#64748b"; - ctx.fillText("Value", 0, 0); + ctx.fillText("数值", 0, 0); ctx.restore(); - ctx.fillText("Time", width / 2 - 12, height - 28); + ctx.fillText("时间", width / 2 - 12, height - 28); ctx.strokeStyle = "#2563eb"; ctx.lineWidth = 2; diff --git a/web/feeder/js/equipment.js b/web/feeder/js/equipment.js index 7f1bfaa..4464868 100644 --- a/web/feeder/js/equipment.js +++ b/web/feeder/js/equipment.js @@ -41,7 +41,7 @@ function renderEquipmentUnitOptions(selected = "", target = dom.equipmentUnitId) } export function renderBindingEquipmentOptions(selected = "", target = dom.bindingEquipmentId) { - const options = ['']; + const options = ['']; filteredEquipments().forEach((item) => { const equipment = equipmentOf(item); const isSelected = equipment.id === selected ? "selected" : ""; @@ -112,7 +112,7 @@ export function renderEquipments() { const items = filteredEquipments(); if (!items.length) { - dom.equipmentList.innerHTML = '
No equipment
'; + dom.equipmentList.innerHTML = '
暂无设备
'; return; } @@ -126,7 +126,7 @@ export function renderEquipments() { ${item.point_count ?? 0} pts
${equipment.name}
-
${equipment.kind || "No type"}
+
${equipment.kind || "未分类"}
单元: ${currentUnitLabel(equipment.unit_id)}
`; @@ -141,7 +141,7 @@ export function renderEquipments() { const editBtn = document.createElement("button"); editBtn.className = "secondary"; - editBtn.textContent = "Edit"; + editBtn.textContent = "编辑"; editBtn.addEventListener("click", (event) => { event.stopPropagation(); openEditEquipmentModal(equipment); @@ -149,7 +149,7 @@ export function renderEquipments() { const deleteBtn = document.createElement("button"); deleteBtn.className = "danger"; - deleteBtn.textContent = "Delete"; + deleteBtn.textContent = "删除"; deleteBtn.addEventListener("click", (event) => { event.stopPropagation(); deleteEquipment(equipment.id).catch((error) => { @@ -218,7 +218,7 @@ export async function saveEquipment(event) { } export async function deleteEquipment(equipmentId) { - if (!window.confirm("Delete this equipment?")) { + if (!window.confirm("确认删除该设备?")) { return; } diff --git a/web/feeder/js/ops.js b/web/feeder/js/ops.js index 83fe9b4..ec468d2 100644 --- a/web/feeder/js/ops.js +++ b/web/feeder/js/ops.js @@ -58,7 +58,7 @@ export function renderOpsUnits() { const startBlocked = !isAutoOn && (runtime?.fault_locked || runtime?.manual_ack_required || runtime?.rem_local); const autoBtn = document.createElement("button"); autoBtn.className = isAutoOn ? "danger" : "secondary"; - autoBtn.textContent = isAutoOn ? "Stop Auto" : "Start Auto"; + autoBtn.textContent = isAutoOn ? "停止自动" : "启动自动"; autoBtn.disabled = startBlocked; autoBtn.title = startBlocked ? (runtime?.fault_locked ? "设备故障中,无法启动自动控制" @@ -75,7 +75,7 @@ export function renderOpsUnits() { if (runtime?.manual_ack_required) { const ackBtn = document.createElement("button"); ackBtn.className = "danger"; - ackBtn.textContent = "Ack Fault"; + ackBtn.textContent = "故障确认"; ackBtn.title = "人工确认解除故障锁定"; ackBtn.addEventListener("click", (e) => { e.stopPropagation(); @@ -153,13 +153,13 @@ function renderOpsEquipments(equipments) { const startBtn = document.createElement("button"); startBtn.className = "secondary"; - startBtn.textContent = "Start"; + startBtn.textContent = "启动"; startBtn.addEventListener("click", () => apiFetch(`/api/control/equipment/${eq.id}/start`, { method: "POST" }).catch(() => {}) ); const stopBtn = document.createElement("button"); stopBtn.className = "danger"; - stopBtn.textContent = "Stop"; + stopBtn.textContent = "停止"; stopBtn.addEventListener("click", () => apiFetch(`/api/control/equipment/${eq.id}/stop`, { method: "POST" }).catch(() => {}) ); diff --git a/web/feeder/js/points.js b/web/feeder/js/points.js index 621c191..e09a9ac 100644 --- a/web/feeder/js/points.js +++ b/web/feeder/js/points.js @@ -11,7 +11,7 @@ import { state } from "./state.js"; function updatePointSourceNodeCount() { const count = dom.nodeTree.querySelectorAll("details").length; - dom.pointSourceNodeCount.textContent = `Nodes: ${count}`; + dom.pointSourceNodeCount.textContent = `节点: ${count}`; } export function formatValue(monitor) { @@ -28,13 +28,13 @@ export function formatValue(monitor) { } export function renderSelectedNodes() { - dom.selectedCount.textContent = `Selected ${state.selectedNodeIds.size} nodes`; + dom.selectedCount.textContent = `已选中 ${state.selectedNodeIds.size} 个节点`; } export function updateSelectedPointSummary() { const count = state.selectedPointIds.size; - dom.selectedPointCount.textContent = `Selected ${count} points`; - dom.batchBindingSummary.textContent = `Selected ${count} points`; + dom.selectedPointCount.textContent = `已选中 ${count} 个点位`; + dom.batchBindingSummary.textContent = `已选中 ${count} 个点位`; dom.openBatchBindingBtn.disabled = count === 0; } @@ -42,16 +42,16 @@ export function updatePointFilterSummary() { const filters = []; if (state.selectedEquipmentId) { const equipment = state.equipmentMap.get(state.selectedEquipmentId); - filters.push(`Equipment:${equipment?.name || equipment?.code || "Unknown"}`); + filters.push(`设备:${equipment?.name || equipment?.code || "未知"}`); } if (state.selectedSourceId) { const source = state.sources.find((item) => item.id === state.selectedSourceId); - filters.push(`Source:${source?.name || "Unknown"}`); + filters.push(`数据源:${source?.name || "未知"}`); } dom.pointFilterSummary.textContent = filters.length - ? `Current filter: ${filters.join(" / ")}` - : "Current filter: All points"; + ? `当前筛选: ${filters.join(" / ")}` + : "当前筛选: 全部点位"; } export function clearSelectedPoints() { @@ -102,8 +102,8 @@ export function openPointCreateModal() { if (dom.pointSourceSelect) { dom.pointSourceSelect.value = state.selectedSourceId || ""; } - dom.nodeTree.innerHTML = '
Select a source and load nodes
'; - dom.pointSourceNodeCount.textContent = "Nodes: 0"; + dom.nodeTree.innerHTML = '
选择数据源并加载节点
'; + dom.pointSourceNodeCount.textContent = "节点: 0"; state.selectedNodeIds.clear(); renderSelectedNodes(); } @@ -111,8 +111,8 @@ export function openPointCreateModal() { export async function loadTree() { const sourceId = dom.pointSourceSelect.value || state.selectedSourceId; if (!sourceId) { - dom.nodeTree.innerHTML = '
Select a source
'; - dom.pointSourceNodeCount.textContent = "Nodes: 0"; + dom.nodeTree.innerHTML = '
请选择数据源
'; + dom.pointSourceNodeCount.textContent = "节点: 0"; return; } @@ -126,7 +126,7 @@ export async function loadTree() { export async function browseAndLoadTree() { const sourceId = dom.pointSourceSelect.value || state.selectedSourceId; if (!sourceId) { - throw new Error("Select a source first"); + throw new Error("请先选择数据源"); } state.selectedSourceId = sourceId; @@ -178,7 +178,7 @@ export async function loadPoints() { dom.pointList.innerHTML = ""; if (!items.length) { - dom.pointList.innerHTML = 'No points'; + dom.pointList.innerHTML = '暂无点位'; dom.pointsPageInfo.textContent = `${state.pointsPage} / 1`; clearSelectedPoints(); updatePointFilterSummary(); @@ -207,7 +207,7 @@ export async function loadPoints() { ${(monitor?.quality || "unknown").toUpperCase()}
-
${equipment ? equipment.name : 'Unbound'}
+
${equipment ? equipment.name : '未绑定'}
${point.signal_role || "--"}
@@ -228,7 +228,7 @@ export async function loadPoints() { actionCell.className = "point-actions"; const editBtn = document.createElement("button"); editBtn.className = "secondary"; - editBtn.textContent = "Edit"; + editBtn.textContent = "编辑"; editBtn.addEventListener("click", (event) => { event.stopPropagation(); openPointBinding(point); @@ -236,7 +236,7 @@ export async function loadPoints() { const deleteBtn = document.createElement("button"); deleteBtn.className = "danger"; - deleteBtn.textContent = "Delete"; + deleteBtn.textContent = "删除"; deleteBtn.addEventListener("click", (event) => { event.stopPropagation(); deletePoint(point.id).catch((error) => { @@ -270,14 +270,14 @@ export function openPointBinding(point) { dom.bindingPointName.disabled = false; const modalTitle = dom.pointBindingModal.querySelector("h3"); if (modalTitle) { - modalTitle.textContent = "Edit Point"; + modalTitle.textContent = "编辑点位"; } if (dom.clearPointBindingBtn) { - dom.clearPointBindingBtn.textContent = "Clear Equipment"; + dom.clearPointBindingBtn.textContent = "清除设备"; } const saveButton = dom.pointBindingForm?.querySelector('button[type="submit"]'); if (saveButton) { - saveButton.textContent = "Save"; + saveButton.textContent = "保存"; } renderBindingEquipmentOptions(point.equipment_id || ""); dom.bindingSignalRole.innerHTML = renderRoleOptions(point.signal_role || ""); @@ -353,7 +353,7 @@ export async function clearBatchBinding() { } export async function deletePoint(pointId) { - if (!window.confirm("Delete this point?")) { + if (!window.confirm("确认删除该点位?")) { return; } diff --git a/web/feeder/js/roles.js b/web/feeder/js/roles.js index 83103ac..e2425c5 100644 --- a/web/feeder/js/roles.js +++ b/web/feeder/js/roles.js @@ -1,17 +1,17 @@ export const SIGNAL_ROLE_OPTIONS = [ - { value: "", label: "Unset" }, - { value: "rem", label: "REM Remote Enable" }, - { value: "run", label: "RUN Running" }, - { value: "flt", label: "FLT Fault" }, - { value: "ii", label: "II Current" }, - { value: "start_cmd", label: "Start Command" }, - { value: "stop_cmd", label: "Stop Command" }, + { value: "", label: "未设置" }, + { value: "rem", label: "REM 远程使能" }, + { value: "run", label: "RUN 运行" }, + { value: "flt", label: "FLT 故障" }, + { value: "ii", label: "II 电流" }, + { value: "start_cmd", label: "启动命令" }, + { value: "stop_cmd", label: "停止命令" }, ]; export const EQUIPMENT_KIND_OPTIONS = [ - { value: "", label: "Unset" }, - { value: "coal_feeder", label: "Coal Feeder" }, - { value: "distributor", label: "Distributor" }, + { value: "", label: "未设置" }, + { value: "coal_feeder", label: "投煤器" }, + { value: "distributor", label: "布料机" }, ]; export function renderRoleOptions(selected = "") { diff --git a/web/feeder/js/sources.js b/web/feeder/js/sources.js index 2450b84..15bd75d 100644 --- a/web/feeder/js/sources.js +++ b/web/feeder/js/sources.js @@ -8,7 +8,7 @@ function renderPointSourceOptions() { return; } - const options = ['']; + const options = ['']; state.sources.forEach((source) => { const selected = source.id === state.selectedSourceId ? "selected" : ""; options.push(``); @@ -41,7 +41,7 @@ export function renderSources() { const editBtn = document.createElement("button"); editBtn.className = "secondary"; - editBtn.textContent = "Edit"; + editBtn.textContent = "编辑"; editBtn.addEventListener("click", (event) => { event.stopPropagation(); dom.sourceId.value = source.id; @@ -53,7 +53,7 @@ export function renderSources() { const reconnectBtn = document.createElement("button"); reconnectBtn.className = "secondary"; - reconnectBtn.textContent = "Reconnect"; + reconnectBtn.textContent = "重连"; reconnectBtn.addEventListener("click", (event) => { event.stopPropagation(); reconnectSource(source.id, source.name).catch((error) => { @@ -63,7 +63,7 @@ export function renderSources() { const deleteBtn = document.createElement("button"); deleteBtn.className = "danger"; - deleteBtn.textContent = "Delete"; + deleteBtn.textContent = "删除"; deleteBtn.addEventListener("click", (event) => { event.stopPropagation(); deleteSource(source.id).catch((error) => { @@ -118,14 +118,14 @@ export async function saveSource(event) { } export async function reconnectSource(sourceId, name) { - dom.statusText.textContent = `Reconnecting ${name || "Source"}...`; + dom.statusText.textContent = `正在重连 ${name || "数据源"}...`; await apiFetch(`/api/source/${sourceId}/reconnect`, { method: "POST" }); await loadSources(); - dom.statusText.textContent = "Ready"; + dom.statusText.textContent = "就绪"; } export async function deleteSource(sourceId) { - if (!window.confirm("Delete this source?")) { + if (!window.confirm("确认删除该数据源?")) { return; } diff --git a/web/feeder/js/units.js b/web/feeder/js/units.js index 0ffb5dd..dcd8708 100644 --- a/web/feeder/js/units.js +++ b/web/feeder/js/units.js @@ -125,8 +125,8 @@ function buildUnitCard(unit, mode) { ${unit.enabled ? "EN" : "DIS"}
${unit.name}
-
设备 ${bound.length} 台 | Acc ${runtime ? Math.floor(runtime.display_acc_sec / 1000) : 0}s
-
Run ${unit.run_time_sec}s / Stop ${unit.stop_time_sec}s / Acc ${unit.acc_time_sec}s / BL ${unit.bl_time_sec}s
+
设备 ${bound.length} 台 | 累计 ${runtime ? Math.floor(runtime.display_acc_sec / 1000) : 0}s
+
运行 ${unit.run_time_sec}s / 停止 ${unit.stop_time_sec}s / 累计 ${unit.acc_time_sec}s / 间隔 ${unit.bl_time_sec}s
${mode === "config" ? `
${equipTags}
` : ""}
`; @@ -143,7 +143,7 @@ function buildUnitCard(unit, mode) { const editBtn = document.createElement("button"); editBtn.className = "secondary"; - editBtn.textContent = "Edit"; + editBtn.textContent = "编辑"; editBtn.addEventListener("click", (event) => { event.stopPropagation(); openEditUnitModal(unit); @@ -151,7 +151,7 @@ function buildUnitCard(unit, mode) { const deleteBtn = document.createElement("button"); deleteBtn.className = "danger"; - deleteBtn.textContent = "Delete"; + deleteBtn.textContent = "删除"; deleteBtn.addEventListener("click", (event) => { event.stopPropagation(); deleteUnit(unit.id).catch((error) => { @@ -240,7 +240,7 @@ export async function saveUnit(event) { } export async function deleteUnit(unitId) { - if (!window.confirm("Delete this unit?")) { + if (!window.confirm("确认删除该单元?")) { return; }