pPowerManger 燃料电池页操控表单防误操作改造:滑块改为步进数字输入,提交前弹窗确认并高亮危险指令(停机/紧急停机/关机等)
build-test-deploy / ci (push) Successful in 30m21s
build-test-deploy / ci (push) Successful in 30m21s
This commit is contained in:
@@ -278,34 +278,192 @@ body {
|
|||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.slider-container {
|
/* 数值步进控件(替代滑块,防误拖) */
|
||||||
|
.stepper-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-btn {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border: 1px solid #d1d5db;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #f9fafb;
|
||||||
|
color: #1a1a1a;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.15s;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-btn:hover {
|
||||||
|
background-color: #e5e7eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-btn:active {
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
border-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-input {
|
||||||
|
width: 90px;
|
||||||
|
height: 40px;
|
||||||
|
padding: 0 8px;
|
||||||
|
border: 1px solid #d1d5db;
|
||||||
|
border-radius: 4px;
|
||||||
|
text-align: center;
|
||||||
|
font-family: 'SF Mono', 'Consolas', monospace;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--primary-color);
|
||||||
|
box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-unit {
|
||||||
|
min-width: 84px;
|
||||||
|
color: #4b5563;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-family: 'SF Mono', 'Consolas', monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 下拉框危险选项标记 */
|
||||||
|
.select-control option.danger {
|
||||||
|
color: #dc2626;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 指令确认弹窗 */
|
||||||
|
.modal-overlay {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
background: rgba(17, 24, 39, 0.55);
|
||||||
|
z-index: 100;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-overlay.visible {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 560px;
|
||||||
|
max-height: 85vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-title {
|
||||||
|
padding: 16px 20px;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
border-bottom: 1px solid #e5e7eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
padding: 16px 20px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-hint {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #6b7280;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-summary {
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
border-radius: 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border-bottom: 1px solid #f3f4f6;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-row:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-label {
|
||||||
|
color: #4b5563;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-value {
|
||||||
|
font-weight: 600;
|
||||||
|
font-family: 'SF Mono', 'Consolas', monospace;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-row.danger {
|
||||||
|
background-color: #fef2f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-row.danger .summary-label,
|
||||||
|
.summary-row.danger .summary-value {
|
||||||
|
color: #b91c1c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-danger-mark {
|
||||||
|
margin-right: 6px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-note {
|
||||||
|
margin-top: 12px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #fef2f2;
|
||||||
|
color: #b91c1c;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 600;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-note.visible {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-actions {
|
||||||
|
padding: 16px 20px;
|
||||||
|
border-top: 1px solid #e5e7eb;
|
||||||
|
display: flex;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.slider {
|
.modal-actions .button {
|
||||||
flex-grow: 1;
|
flex: 1;
|
||||||
height: 6px;
|
padding: 12px;
|
||||||
-webkit-appearance: none;
|
font-size: 1rem;
|
||||||
background: #d1d5db;
|
|
||||||
border-radius: 3px;
|
|
||||||
outline: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.slider::-webkit-slider-thumb {
|
.button-confirm {
|
||||||
-webkit-appearance: none;
|
background-color: var(--primary-color);
|
||||||
width: 18px;
|
color: white;
|
||||||
height: 18px;
|
|
||||||
background: var(--primary-color);
|
|
||||||
border-radius: 50%;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.slider-value {
|
.button-confirm:hover {
|
||||||
min-width: 60px;
|
background-color: var(--primary-hover);
|
||||||
text-align: right;
|
|
||||||
font-family: 'SF Mono', 'Consolas', monospace;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-submit {
|
.form-submit {
|
||||||
@@ -521,22 +679,24 @@ body {
|
|||||||
<option value="00H">无效</option>
|
<option value="00H">无效</option>
|
||||||
<option value="01H">自检</option>
|
<option value="01H">自检</option>
|
||||||
<option value="02H">启动</option>
|
<option value="02H">启动</option>
|
||||||
<option value="03H">停机</option>
|
|
||||||
<option value="04H">复位</option>
|
<option value="04H">复位</option>
|
||||||
<option value="05H">紧急停机</option>
|
|
||||||
<option value="06H">补给</option>
|
<option value="06H">补给</option>
|
||||||
<option value="07H">制氢预热</option>
|
<option value="07H">制氢预热</option>
|
||||||
<option value="08H">停机维护</option>
|
|
||||||
<option value="0AH">开机</option>
|
<option value="0AH">开机</option>
|
||||||
<option value="0BH">关机</option>
|
<option value="03H" class="danger">⚠ 停机(危险)</option>
|
||||||
|
<option value="05H" class="danger">⚠ 紧急停机(危险)</option>
|
||||||
|
<option value="08H" class="danger">⚠ 停机维护(危险)</option>
|
||||||
|
<option value="0BH" class="danger">⚠ 关机(危险)</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label">输出功率指令 (0~250,分辨率0.1kW)</label>
|
<label class="control-label">输出功率指令 (0~250,分辨率0.1kW)</label>
|
||||||
<div class="slider-container">
|
<div class="stepper-container">
|
||||||
<input type="range" class="slider" name="fcPower" min="0" max="250" value="0" step="1">
|
<button type="button" class="stepper-btn" data-target="fcPower" data-step="-1">−</button>
|
||||||
<span class="slider-value">0 (0.0 kW)</span>
|
<input type="number" class="stepper-input" id="fcPower" name="fcPower" min="0" max="250" step="1" value="0">
|
||||||
|
<button type="button" class="stepper-btn" data-target="fcPower" data-step="1">+</button>
|
||||||
|
<span class="stepper-unit" id="fcPowerUnit">0 (0.0 kW)</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -567,9 +727,11 @@ body {
|
|||||||
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label">潜深深度 (m)</label>
|
<label class="control-label">潜深深度 (m)</label>
|
||||||
<div class="slider-container">
|
<div class="stepper-container">
|
||||||
<input type="range" class="slider" name="depth" min="0" max="1000" value="0" step="1">
|
<button type="button" class="stepper-btn" data-target="depth" data-step="-1">−</button>
|
||||||
<span class="slider-value">0 m</span>
|
<input type="number" class="stepper-input" id="depth" name="depth" min="0" max="1000" step="1" value="0">
|
||||||
|
<button type="button" class="stepper-btn" data-target="depth" data-step="1">+</button>
|
||||||
|
<span class="stepper-unit" id="depthUnit">0 m</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -612,9 +774,11 @@ body {
|
|||||||
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label">动力锂电池功率配置值 (0~400 kW)</label>
|
<label class="control-label">动力锂电池功率配置值 (0~400 kW)</label>
|
||||||
<div class="slider-container">
|
<div class="stepper-container">
|
||||||
<input type="range" class="slider" name="powerBatPower" min="0" max="400" value="0" step="10">
|
<button type="button" class="stepper-btn" data-target="powerBatPower" data-step="-10">−</button>
|
||||||
<span class="slider-value">0 kW</span>
|
<input type="number" class="stepper-input" id="powerBatPower" name="powerBatPower" min="0" max="400" step="10" value="0">
|
||||||
|
<button type="button" class="stepper-btn" data-target="powerBatPower" data-step="10">+</button>
|
||||||
|
<span class="stepper-unit" id="powerBatPowerUnit">0 kW</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -622,18 +786,34 @@ body {
|
|||||||
<label class="control-label">主机状态</label>
|
<label class="control-label">主机状态</label>
|
||||||
<div class="radio-group">
|
<div class="radio-group">
|
||||||
<label class="radio-option"><input type="radio" name="hostStatus" value="AAH" checked><span>运行</span></label>
|
<label class="radio-option"><input type="radio" name="hostStatus" value="AAH" checked><span>运行</span></label>
|
||||||
<label class="radio-option"><input type="radio" name="hostStatus" value="FFH"><span>关机</span></label>
|
<label class="radio-option"><input type="radio" name="hostStatus" value="FFH"><span>⚠ 关机(危险)</span></label>
|
||||||
<label class="radio-option"><input type="radio" name="hostStatus" value="55H"><span>故障</span></label>
|
<label class="radio-option"><input type="radio" name="hostStatus" value="55H"><span>⚠ 故障(危险)</span></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="button form-submit">提交操控指令</button>
|
<button type="submit" class="button form-submit">预览并提交操控指令</button>
|
||||||
<div id="statusMessage" class="status-message"></div>
|
<div id="statusMessage" class="status-message"></div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 指令确认弹窗(防误操作,提交前拦截) -->
|
||||||
|
<div class="modal-overlay" id="confirmOverlay">
|
||||||
|
<div class="modal">
|
||||||
|
<div class="modal-title">⚠ 指令确认</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="modal-hint">请逐项核对下方指令摘要,红色条目为高风险指令。点击“确认执行”后指令将立即下发。</div>
|
||||||
|
<div class="modal-summary" id="modalSummary"></div>
|
||||||
|
<div class="modal-note" id="modalDangerNote">本次包含高风险指令(停机/紧急停机/停机维护/关机等),请再次确认!</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-actions">
|
||||||
|
<button type="button" class="button button-secondary" id="modalCancelBtn">取消</button>
|
||||||
|
<button type="button" class="button button-confirm" id="modalConfirmBtn">确认执行</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
let ws = null;
|
let ws = null;
|
||||||
|
|
||||||
@@ -793,32 +973,42 @@ function initWebSocket() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新滑块值显示
|
// 数值步进控件(替代滑块,防误拖)
|
||||||
document.querySelectorAll('.slider').forEach(slider => {
|
const stepperUnitText = {
|
||||||
const valueDisplay = slider.nextElementSibling;
|
fcPower: v => v + ' (' + (v * 0.1).toFixed(1) + ' kW)',
|
||||||
if (slider.name === 'fcPower') {
|
depth: v => v + ' m',
|
||||||
valueDisplay.textContent = slider.value + ' (0.0 kW)';
|
powerBatPower: v => v + ' kW'
|
||||||
} else if (slider.name === 'depth') {
|
};
|
||||||
valueDisplay.textContent = slider.value + ' m';
|
|
||||||
} else if (slider.name === 'powerBatPower') {
|
|
||||||
valueDisplay.textContent = slider.value + ' kW';
|
|
||||||
} else {
|
|
||||||
valueDisplay.textContent = slider.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
slider.addEventListener('input', () => {
|
function clampStepper(input) {
|
||||||
if (slider.name === 'fcPower') {
|
const min = parseInt(input.min, 10);
|
||||||
valueDisplay.textContent = slider.value + ' (' + (slider.value * 0.1).toFixed(1) + ' kW)';
|
const max = parseInt(input.max, 10);
|
||||||
} else if (slider.name === 'depth') {
|
let v = parseInt(input.value, 10);
|
||||||
valueDisplay.textContent = slider.value + ' m';
|
if (isNaN(v)) v = isNaN(min) ? 0 : min;
|
||||||
} else if (slider.name === 'powerBatPower') {
|
if (!isNaN(min)) v = Math.max(v, min);
|
||||||
valueDisplay.textContent = slider.value + ' kW';
|
if (!isNaN(max)) v = Math.min(v, max);
|
||||||
} else {
|
input.value = v;
|
||||||
valueDisplay.textContent = slider.value;
|
const unitFn = stepperUnitText[input.id];
|
||||||
}
|
if (unitFn) {
|
||||||
|
const unitEl = document.getElementById(input.id + 'Unit');
|
||||||
|
if (unitEl) unitEl.textContent = unitFn(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('.stepper-btn').forEach(btn => {
|
||||||
|
btn.addEventListener('click', () => {
|
||||||
|
const input = document.getElementById(btn.dataset.target);
|
||||||
|
if (!input) return;
|
||||||
|
input.value = (parseInt(input.value, 10) || 0) + parseInt(btn.dataset.step, 10);
|
||||||
|
clampStepper(input);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll('.stepper-input').forEach(input => {
|
||||||
|
input.addEventListener('input', () => clampStepper(input));
|
||||||
|
input.addEventListener('blur', () => clampStepper(input));
|
||||||
|
});
|
||||||
|
|
||||||
// 处理按钮组选择
|
// 处理按钮组选择
|
||||||
document.querySelectorAll('.button-group button').forEach(button => {
|
document.querySelectorAll('.button-group button').forEach(button => {
|
||||||
button.addEventListener('click', () => {
|
button.addEventListener('click', () => {
|
||||||
@@ -838,16 +1028,71 @@ document.querySelectorAll('.button-group button').forEach(button => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 处理表单提交
|
// 指令文本映射(用于确认弹窗摘要)
|
||||||
document.getElementById('fcsForm').addEventListener('submit', async (e) => {
|
const FC_MODE_TEXT = { '00H': '无效', '01H': '调试', '02H': '自动', '03H': '补给/排放' };
|
||||||
|
const FC_CMD_TEXT = { '00H': '无效', '01H': '自检', '02H': '启动', '03H': '停机', '04H': '复位', '05H': '紧急停机', '06H': '补给', '07H': '制氢预热', '08H': '停机维护', '0AH': '开机', '0BH': '关机' };
|
||||||
|
const EMERGENCY_TEXT = { '00H': '无', '01H': '允许降载', '02H': '允许排气', '03H': '降载+排气' };
|
||||||
|
const SUPPLY_TEXT = { '00H': '无效', '01H': '液氧加注', '02H': '甲醇加注', '03H': '液氧排空', '04H': '甲醇排空', '05H': 'CO2排空', '07H': '合金加注', '08H': '氮气加注', '09H': '纯水加注', '0AH': '备用', '0BH': '备用' };
|
||||||
|
const BAT_CMD_TEXT = { '00H': '无效', '10H': '启动', '20H': '关闭' };
|
||||||
|
const HOST_STATUS_TEXT = { 'AAH': '运行', 'FFH': '关机', '55H': '故障' };
|
||||||
|
const DANGER_FC_CMDS = ['03H', '05H', '08H', '0BH'];
|
||||||
|
const DANGER_HOST_STATUS = ['FFH', '55H'];
|
||||||
|
|
||||||
|
// 生成指令摘要并打开确认弹窗(提交前拦截,防误操作)
|
||||||
|
function openConfirmModal() {
|
||||||
|
const form = document.getElementById('fcsForm');
|
||||||
|
const fv = name => form.elements[name].value;
|
||||||
|
|
||||||
|
const rows = [
|
||||||
|
{ label: '模式设定', value: FC_MODE_TEXT[fv('fcMode')] || fv('fcMode') },
|
||||||
|
{ label: '操控指令', value: FC_CMD_TEXT[fv('fcCommand')] || fv('fcCommand'), danger: DANGER_FC_CMDS.includes(fv('fcCommand')) },
|
||||||
|
{ label: '输出功率指令', value: fv('fcPower') + ' (' + (fv('fcPower') * 0.1).toFixed(1) + ' kW)' },
|
||||||
|
{ label: '纵倾姿态数据1', value: fv('pitch') },
|
||||||
|
{ label: '横倾姿态数据1', value: fv('roll') },
|
||||||
|
{ label: '应急允许', value: EMERGENCY_TEXT[fv('emergencyAllow')] || fv('emergencyAllow') },
|
||||||
|
{ label: '潜深深度', value: fv('depth') + ' m' },
|
||||||
|
{ label: '补给/排放指令', value: SUPPLY_TEXT[fv('supplyExhaustCmd')] || fv('supplyExhaustCmd') },
|
||||||
|
{ label: '仪表锂电池启停指令', value: BAT_CMD_TEXT[fv('insBatCmd')] || fv('insBatCmd') },
|
||||||
|
{ label: '动力锂电池启停指令', value: BAT_CMD_TEXT[fv('powerBatCmd')] || fv('powerBatCmd') },
|
||||||
|
{ label: '动力锂电池功率配置值', value: fv('powerBatPower') + ' kW' },
|
||||||
|
{ label: '主机状态', value: HOST_STATUS_TEXT[fv('hostStatus')] || fv('hostStatus'), danger: DANGER_HOST_STATUS.includes(fv('hostStatus')) }
|
||||||
|
];
|
||||||
|
|
||||||
|
document.getElementById('modalSummary').innerHTML = rows.map(r =>
|
||||||
|
'<div class="summary-row' + (r.danger ? ' danger' : '') + '">' +
|
||||||
|
'<span class="summary-label">' + (r.danger ? '<span class="summary-danger-mark">⚠</span>' : '') + r.label + '</span>' +
|
||||||
|
'<span class="summary-value">' + r.value + '</span>' +
|
||||||
|
'</div>'
|
||||||
|
).join('');
|
||||||
|
|
||||||
|
const hasDanger = rows.some(r => r.danger);
|
||||||
|
document.getElementById('modalDangerNote').className = 'modal-note' + (hasDanger ? ' visible' : '');
|
||||||
|
|
||||||
|
document.getElementById('confirmOverlay').classList.add('visible');
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeConfirmModal() {
|
||||||
|
document.getElementById('confirmOverlay').classList.remove('visible');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交按钮:先弹出确认框,不直接发送
|
||||||
|
document.getElementById('fcsForm').addEventListener('submit', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const form = e.target;
|
openConfirmModal();
|
||||||
const formData = new FormData(form);
|
});
|
||||||
|
|
||||||
|
// 取消:关闭弹窗,不做任何提交
|
||||||
|
document.getElementById('modalCancelBtn').addEventListener('click', closeConfirmModal);
|
||||||
|
|
||||||
|
// 确认执行:真正下发指令
|
||||||
|
document.getElementById('modalConfirmBtn').addEventListener('click', async () => {
|
||||||
|
const form = document.getElementById('fcsForm');
|
||||||
const statusMessage = document.getElementById('statusMessage');
|
const statusMessage = document.getElementById('statusMessage');
|
||||||
|
closeConfirmModal();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
for (const [key, value] of formData.entries()) {
|
for (const [key, value] of new FormData(form).entries()) {
|
||||||
params.append(key, value);
|
params.append(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -864,18 +1109,16 @@ document.getElementById('fcsForm').addEventListener('submit', async (e) => {
|
|||||||
if (result.success) {
|
if (result.success) {
|
||||||
statusMessage.textContent = '操控指令提交成功';
|
statusMessage.textContent = '操控指令提交成功';
|
||||||
statusMessage.className = 'status-message';
|
statusMessage.className = 'status-message';
|
||||||
statusMessage.style.display = 'block';
|
|
||||||
} else {
|
} else {
|
||||||
statusMessage.textContent = result.message || '操控指令提交失败';
|
statusMessage.textContent = result.message || '操控指令提交失败';
|
||||||
statusMessage.className = 'status-message error';
|
statusMessage.className = 'status-message error';
|
||||||
statusMessage.style.display = 'block';
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
statusMessage.textContent = '网络错误: ' + error.message;
|
statusMessage.textContent = '网络错误: ' + error.message;
|
||||||
statusMessage.className = 'status-message error';
|
statusMessage.className = 'status-message error';
|
||||||
statusMessage.style.display = 'block';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
statusMessage.style.display = 'block';
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
statusMessage.style.display = 'none';
|
statusMessage.style.display = 'none';
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|||||||
Reference in New Issue
Block a user