feat: 强制安装APK(推送+pm install 绕过厂商弹窗)+ 定位设备(亮屏+大字定位页,结束定位关闭浏览器含后台)+ 一键亮屏/息屏(并发全部设备)
This commit is contained in:
+42
-3
@@ -1,6 +1,7 @@
|
||||
// 监控页:设备状态表(排序/多选/截图/异常汇总/任务运行概况)
|
||||
// ================== 设备列表排序与多选 ==================
|
||||
let _selectedSerials=new Set(); // 已勾选的 serial 集合
|
||||
let _locatingSerials=new Set(); // 定位中的设备(按钮显示"结束定位")
|
||||
|
||||
// 排序比较:从设备对象取排序值(统一排序用,见 setListPager/sortValue)
|
||||
function _sortValue(dev,key){
|
||||
@@ -71,6 +72,38 @@ async function stopSelectedDevices(){
|
||||
setTimeout(loadMonitor,500);
|
||||
}
|
||||
|
||||
// 定位设备:点亮屏幕 + 打开大字定位页(显示设备 IP),便于在机架上找到目标
|
||||
// 注意:打开定位页会切换设备前台,任务运行中慎用
|
||||
async function locateDevice(serial){
|
||||
if(!confirm('点亮 '+serial+' 屏幕并打开大字定位页?\n\n(会切换设备前台显示,任务运行中慎用)'))return;
|
||||
const r=await apiPost('/api/device/locate',{serial:serial,show:true});
|
||||
if(!r)return;
|
||||
if(r.ok){
|
||||
_locatingSerials.add(serial);
|
||||
showToast(r.msg||'已定位','success');
|
||||
renderDevices();
|
||||
}else showToast(r.error||'定位失败','error');
|
||||
}
|
||||
|
||||
// 结束定位:关闭设备上的定位页(浏览器),按钮恢复为"定位"
|
||||
async function stopLocate(serial){
|
||||
const r=await apiPost('/api/device/locate/stop',{serial:serial});
|
||||
if(!r)return;
|
||||
_locatingSerials.delete(serial);
|
||||
renderDevices();
|
||||
if(r.ok)showToast(r.msg||'已结束定位','success');
|
||||
else showToast(r.error||'结束定位失败','error');
|
||||
}
|
||||
|
||||
// 批量亮屏/息屏所有在线设备(息屏会中断运行中任务,前端已确认)
|
||||
async function screenAllDevices(mode){
|
||||
if(mode==='off'&&!confirm('确定让所有在线设备息屏?\n\n运行中的任务会因屏幕熄灭而中断,请谨慎操作。'))return;
|
||||
const r=await apiPost('/api/device/screen_all',{mode:mode});
|
||||
if(!r)return;
|
||||
if(r.ok)showToast((mode==='off'?'已息屏':'已亮屏')+' '+r.success+'/'+r.total+' 台设备','success');
|
||||
else showToast(r.error||'操作失败','error');
|
||||
}
|
||||
|
||||
// 清除单台设备的异常状态(error/failed → 未启动)
|
||||
async function clearDeviceError(serial){
|
||||
if(!confirm('确认清除设备 '+serial+' 的异常状态?'))return;
|
||||
@@ -266,9 +299,10 @@ async function loadSummary(){
|
||||
let _devicesSig='';
|
||||
function renderDevices(){
|
||||
if(!_statusData||!_statusData.devices){return;}
|
||||
// 5秒自动刷新时若设备数据/分页/搜索/排序都没变化,跳过整表重渲染(避免DOM抖动)
|
||||
// 5秒自动刷新时若设备数据/分页/搜索/排序/定位状态都没变化,跳过整表重渲染(避免DOM抖动)
|
||||
const _st=_lp('devices');
|
||||
const _sig=JSON.stringify({d:_statusData.devices,p:_st.page,k:_st.kw,s:_st.sort});
|
||||
const _sig=JSON.stringify({d:_statusData.devices,p:_st.page,k:_st.kw,s:_st.sort,
|
||||
l:[..._locatingSerials].sort().join(',')});
|
||||
if(_sig===_devicesSig)return;
|
||||
_devicesSig=_sig;
|
||||
// 排序由 applyListPager 统一处理(sortValue + _lpSort)
|
||||
@@ -306,10 +340,15 @@ function renderDeviceRow(dev){
|
||||
const stopBtn=canDev&&(dev.worker_status==='running'||dev.worker_status==='connecting')?'<button class="btn btn-danger btn-xs" onclick="apiAction(\'/api/stop_device\',{serial:\''+esc(dev.serial)+'\'})">停止</button>':'';
|
||||
// 截图按钮(任何状态都可看,离线时会报错)
|
||||
const shotBtn='<button class="btn btn-xs" onclick="openScreenshot(\''+esc(dev.serial)+'\')" title="查看设备画面(不影响任务)">截图</button>';
|
||||
// 定位按钮:定位中显示"结束定位"(关闭定位页),否则显示"定位"(点亮+大字页)
|
||||
const locating=_locatingSerials.has(dev.serial);
|
||||
const locateBtn=canDev?(locating
|
||||
?'<button class="btn btn-xs btn-danger" onclick="stopLocate(\''+esc(dev.serial)+'\')" title="关闭定位页(退出浏览器)">结束定位</button>'
|
||||
:'<button class="btn btn-xs" onclick="locateDevice(\''+esc(dev.serial)+'\')" title="点亮屏幕并显示设备IP大字页(会切换前台,任务运行中慎用)">定位</button>'):'';
|
||||
// 异常/失败设备提供"清除异常"(把状态恢复为未启动)
|
||||
const clearBtn=canDev&&(dev.worker_status==='error'||dev.worker_status==='failed')
|
||||
?'<button class="btn btn-xs" onclick="clearDeviceError(\''+esc(dev.serial)+'\')" title="清除该设备的异常状态,恢复为未启动">清除异常</button>':'';
|
||||
const btns='<div style="display:flex;gap:4px;flex-wrap:wrap">'+shotBtn+clearBtn+stopBtn+'</div>';
|
||||
const btns='<div style="display:flex;gap:4px;flex-wrap:wrap">'+shotBtn+locateBtn+clearBtn+stopBtn+'</div>';
|
||||
const devName=dev.device_name||dev.model||'';
|
||||
const devLabel=devName?'<strong>'+esc(dev.serial)+'</strong><br><span style="font-size:11px;color:#94a3b8">'+esc(devName)+'</span>':'<strong>'+esc(dev.serial)+'</strong>';
|
||||
// 复选框列
|
||||
|
||||
Reference in New Issue
Block a user