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 @@
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 @@
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 = '';
+ 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()} |
|
@@ -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;
}