652 lines
34 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>定位管理</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="../lib/layui-v2.6.3/css/layui.css" media="all">
<link rel="stylesheet" href="../css/public.css" media="all">
<style>
.layui-tab-content{padding: 1.2em;}
.transfer-wrap{display:flex;justify-content:center;align-items:flex-start;padding:1em 0}
.transfer-inner{min-width:720px}
#rtk-transfer .layui-transfer{display:flex;justify-content:center}
#rtk-transfer .layui-transfer .layui-transfer-box{width:50% !important;height:360px !important}
/* RTK panel ~80vh */
#rtk-panel{height:80vh;}
#rtk-info{max-height:calc(80vh - 120px);} /* leave room for header/badges */
#table-ntrip + .layui-table-view{ width:100% !important; }
#table-device + .layui-table-view{ width:100% !important; }
#table-group + .layui-table-view{ width:100% !important; }
</style>
</head>
<body>
<div class="layuimini-container">
<div class="layuimini-main">
<div class="layui-tab layui-tab-card" lay-filter="rtk-tab">
<ul class="layui-tab-title">
<li class="layui-this">Ntrip 推送管理</li>
<li>分组管理</li>
<li>设备管理</li>
<li>单设备定位</li>
<li style="display:none;">组设备定位</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<div class="layui-row" style="margin:10px 0;">
<div class="layui-col-md12">
<div class="layui-form layui-form-pane">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">设备号</label>
<div class="layui-input-inline">
<input type="text" id="ntrip-deviceid" placeholder="设备号" autocomplete="off" class="layui-input" />
</div>
</div>
<div class="layui-inline">
<button class="layui-btn" id="btn-ntrip-search">搜索</button>
</div>
</div>
</div>
</div>
</div>
<div style="margin-top:10px;">
<table class="layui-hide" id="table-ntrip" lay-filter="table-ntrip-filter"></table>
</div>
</div>
<div class="layui-tab-item">
<div class="layui-row">
<div class="layui-col-md12">
<div class="btn-bar">
<button class="layui-btn" id="btn-group-add">新增分组</button>
<button class="layui-btn layui-btn-normal" id="btn-group-edit">编辑分组</button>
<button class="layui-btn layui-btn-danger" id="btn-group-del">删除分组</button>
<button class="layui-btn layui-btn-warm" id="btn-transfer-save">保存设备分配</button>
</div>
</div>
</div>
<div style="margin-top:10px;">
<table class="layui-hide" id="table-group" lay-filter="table-group-filter"></table>
</div>
<div class="transfer-wrap">
<div class="transfer-inner">
<div id="rtk-transfer"></div>
</div>
</div>
</div>
<div class="layui-tab-item">
<div class="layui-row" style="margin:10px 0;">
<div class="layui-col-md12">
<div class="layui-form layui-form-pane">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">分组</label>
<div class="layui-input-inline">
<select id="sel-group" lay-search=""><option value="">全部</option></select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">设备号</label>
<div class="layui-input-inline">
<input type="text" id="q-deviceid" placeholder="设备号" autocomplete="off" class="layui-input" />
</div>
</div>
<div class="layui-inline">
<button class="layui-btn" id="btn-device-search">搜索</button>
</div>
</div>
</div>
</div>
</div>
<div style="margin-top:10px;">
<table class="layui-hide" id="table-device" lay-filter="table-device-filter"></table>
</div>
</div>
<div class="layui-tab-item">
<div class="layui-row">
<div class="layui-col-md12">
<form class="layui-form layui-form-pane" action="" id="rtk-form">
<div class="layui-form-item">
<label class="layui-form-label">分组</label>
<div class="layui-input-block">
<select id="rtk-group" lay-search="" lay-filter="rtk-group"></select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">设备</label>
<div class="layui-input-block">
<select id="rtk-device" lay-search="" lay-filter="rtk-device"></select>
</div>
</div>
<div class="layui-form-item">
<button class="layui-btn" id="btn-rtk-start" type="button">开始定位</button>
<button class="layui-btn layui-btn-warm" id="btn-connect-cmd" type="button">连接设备通讯通道</button>
</div>
<div class="layui-form-item">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-primary" type="button" id="btn-cmd-open-rtcm">博通开所有RTCM</button>
<button class="layui-btn layui-btn-primary" type="button" id="btn-cmd-close-4065">博通关4065</button>
<button class="layui-btn layui-btn-primary" type="button" id="btn-cmd-msm4">RTCM MSM4</button>
<button class="layui-btn layui-btn-primary" type="button" id="btn-cmd-save">博通save</button>
<button class="layui-btn layui-btn-normal" type="button" id="btn-cmd-0102">0102</button>
<button class="layui-btn layui-btn-normal" type="button" id="btn-cmd-0100">0100</button>
</div>
</div>
</form>
</div>
</div>
<div class="layui-row" style="margin-top: 1em;">
<div class="layui-col-md12">
<div id="rtk-panel" style="border: 1px solid #e6e6e6;border-radius: 2px;padding: 1em;">
<div style="display:flex;align-items:center;justify-content:space-between;gap:12px;">
<div class="layui-text">RTK定位信息</div>
<div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;">
<span id="rtk-sol-badge" class="layui-badge layui-bg-gray">--</span>
<span id="rtk-sat-badge" class="layui-badge layui-bg-gray">--</span>
<span id="rtk-llh" class="layui-badge-rim">LLH: --</span>
<span id="rtk-gngga" class="layui-badge-rim">GNGGA: --</span>
</div>
</div>
<hr>
<pre id="rtk-info" style="white-space: pre-wrap;word-break: break-all;overflow-y:auto;"></pre>
</div>
</div>
</div>
<div class="layui-row" style="margin-top: 1em;">
<div class="layui-col-md12">
<div id="cmd-panel" style="border: 1px solid #e6e6e6;border-radius: 2px;padding: 1em;">
<div class="layui-text">命令行消息</div>
<hr>
<pre id="cmd-info" style="white-space: pre-wrap;word-break: break-all;max-height:30vh;overflow-y:auto;"></pre>
</div>
</div>
</div>
</div>
<div class="layui-tab-item" style="display:none;">
<div class="layui-row">
<div class="layui-col-md12">
<form class="layui-form layui-form-pane" action="" id="rtk-group-form">
<div class="layui-form-item">
<label class="layui-form-label">分组</label>
<div class="layui-input-block">
<select id="gr-group" lay-search="" lay-filter="gr-group"></select>
</div>
</div>
<div class="layui-form-item">
<button class="layui-btn" id="btn-gr-start" type="button">开始组定位</button>
</div>
</form>
</div>
</div>
<div class="layui-row" style="margin-top: 1em;">
<div class="layui-col-md12">
<table class="layui-hide" id="group-table" lay-filter="group-table-filter"></table>
</div>
</div>
<div class="layui-row" style="margin-top: 1em;">
<div class="layui-col-md12">
<div id="group-panel" style="border:1px solid #e6e6e6;border-radius:2px;padding:1em;height:60vh;">
<div class="layui-text">组定位消息</div>
<hr>
<pre id="group-info" style="white-space: pre-wrap;word-break: break-all;overflow-y:auto;height:calc(60vh - 80px);"></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="../lib/layui-v2.6.3/layui.js" charset="utf-8"></script>
<script>
layui.use(['form','table','element','layer','transfer'], function(){
var $ = layui.$,
form = layui.form,
table = layui.table,
element = layui.element,
layer = layui.layer,
transfer = layui.transfer;
form.render();
// Ntrip 推送管理
var ntripTableIns = table.render({
elem: '#table-ntrip',
url: '/gnss/ntrip/list',
id: 'ntrip-table-id',
cols: [ [
{field:'deviceid', title:'设备号', sort:true},
{field:'tenantname', title:'所属组织', sort:true},
{field:'devicetype', title:'设备类型', templet: '#ntripDevTypeTrans'},
{field:'model', title:'型号', templet: '#ntripModelTrans'},
{field:'project_id', title:'项目号'},
{field:'updatetime', title:'更新时间', templet: "<div>{{layui.util.toDateString(d.updatetime, 'yyyy-MM-dd HH:mm:ss')}}</div>"},
{field:'forward_to_ntrip', title:'推送Ntrip', width:120, fixed:'right', align:'center', templet: function(d){
var checked = d.forward_to_ntrip? 'checked' : '';
return '<input type="checkbox" lay-filter="ntrip-fwd-switch" data-device="'+ (d.deviceid||'') +'" '+checked+' lay-skin="switch" lay-text="开|关">';
}}
] ],
limits:[10,20,50,100],
limit:10,
page:true,
skin:'line'
});
$('#btn-ntrip-search').on('click', function(){
var did = $('#ntrip-deviceid').val();
ntripTableIns.reload({ where:{ device_id: did }, page:{ curr:1 } });
});
form.on('switch(ntrip-fwd-switch)', function(obj){
var el = $(obj.elem);
var device = el.attr('data-device');
var val = obj.elem.checked;
$.post('/gnss/ntrip/update_forward', { device_id: device, forward: val }, function(res){
if(res === 'ok' || (res && res.code === 0)){
layer.msg('已更新');
} else {
layer.alert((res && res.msg) || '更新失败');
obj.elem.checked = !val; form.render('checkbox');
}
}).fail(function(){
layer.alert('请求失败');
obj.elem.checked = !val; form.render('checkbox');
});
});
var selectedGroup = null;
var transferIns = null;
var groupTableIns = table.render({
elem: '#table-group',
url: '/rtk/group/list',
cols: [ [
{type:'radio', width:50},
{field:'id', title:'ID', width:90},
{field:'name', title:'分组名称', width:180},
{field:'inpstr2_path', title:'inpstr2-path'},
{field:'inpstr3_path', title:'inpstr3-path'}
] ],
limits: [10,20,50,100],
limit: 10,
page: true,
skin: 'line'
});
table.on('radio(table-group-filter)', function(obj){
selectedGroup = obj.data;
loadTransfer();
});
$('#btn-group-add').on('click', function(){
var index = layer.open({
title: '新增分组',
type: 2,
shade: 0.2,
maxmin:true,
shadeClose: true,
area: ['600px', '420px'],
content: '../page/table/rtk_group_edit'
});
});
$('#btn-group-edit').on('click', function(){
if(!selectedGroup){ layer.msg('请先选择一行'); return; }
var index = layer.open({
title: '编辑分组',
type: 2,
shade: 0.2,
maxmin:true,
shadeClose: true,
area: ['600px', '420px'],
content: '../page/table/rtk_group_edit',
success: function(layero, idx){
var iframeWin = window[layero.find('iframe')[0]['name']];
if(iframeWin && iframeWin.setParams){
iframeWin.setParams(selectedGroup);
}
}
});
});
$('#btn-group-del').on('click', function(){
if(!selectedGroup){ layer.msg('请先选择一行'); return; }
layer.confirm('确认删除该分组?', function(i){
$.post('/rtk/group/delete', {del_id: selectedGroup.id}, function(res){
if(res === 'ok' || res.code === 0){
onRtkGroupUpdated();
layer.close(i);
} else {
layer.alert(res.msg || '删除失败');
}
}).fail(function(){ layer.alert('请求失败'); });
});
});
window.onRtkGroupUpdated = function(){
selectedGroup = null;
groupTableIns.reload({page:{curr:1}});
}
function loadTransfer(){
if(!selectedGroup) return;
$.get('/rtk/transfer/options', {group_id: selectedGroup.id}, function(res){
if(res.code !== 0){ layer.alert(res.msg || '加载失败'); return; }
var opt = res.data;
if(transferIns){ $("#rtk-transfer").html(''); }
transferIns = transfer.render({
elem: '#rtk-transfer',
title: ['待加入设备','组内设备'],
data: opt.data,
value: opt.value,
id: 'rtk-transfer-id',
showSearch: true,
parseData: function(item){ return {value: item.value, title: item.title}; }
});
// 覆盖渲染后的内联尺寸
var boxes = $('#rtk-transfer .layui-transfer .layui-transfer-box');
if(boxes && boxes.length){ boxes.css({width:'50%', height:'360px'}); }
}).fail(function(){ layer.alert('请求失败'); });
}
$('#btn-transfer-save').on('click', function(){
if(!selectedGroup){ layer.msg('请先选择分组'); return; }
var vals = transfer.getData('rtk-transfer-id').map(function(it){ return it.value; });
$.ajax({
type: 'POST',
url: '/rtk/profile/save_group_devices',
contentType: 'application/json;charset=UTF-8',
data: JSON.stringify({group_id: selectedGroup.id, device_ids: vals}),
success: function(result){
if(result.code === 0){ layer.msg('已保存'); }
else { layer.alert(result.msg || '保存失败'); }
},
error: function(){ layer.alert('请求失败'); }
});
});
function loadGroupSelect(){
$.get('/rtk/group/list', {page:1, limit:1000}, function(res){
if(res.code===0){
var sel = $('#sel-group');
sel.empty(); sel.append('<option value="">全部</option>');
res.data.forEach(function(g){ sel.append('<option value="'+g.id+'">'+g.name+'</option>'); });
form.render('select');
var gr = $('#gr-group');
gr.empty(); gr.append('<option value="">请选择</option>');
res.data.forEach(function(g){ gr.append('<option value="'+g.id+'">'+g.name+'</option>'); });
form.render('select');
}
});
}
loadGroupSelect();
var deviceTableIns = table.render({
elem: '#table-device',
url: '/rtk/profile/list',
id: 'rtk-profile-table',
cols: [ [
{type:'numbers', title:'序号', width:70},
{field:'id', title:'ID', width:80},
{field:'device_id', title:'设备号', width:140},
{field:'rtkgroup_id', title:'分组ID', width:100},
{field:'pos1_posmode', title:'pos1-posmode', width:130},
{field:'inpstr1_type', title:'inpstr1-type', width:120},
{field:'inpstr1_path', title:'inpstr1-path'},
{field:'outstr2_path', title:'outstr2-path'},
{field:'out_height', title:'out-height', width:120},
{title: '操作', toolbar: '#rtkProfileBar', fixed: 'right', width: 100}
] ],
limits: [10,20,50,100],
limit: 10,
page: true,
skin: 'line'
});
$('#btn-device-search').on('click', function(){
var gid = $('#sel-group').val();
var did = $('#q-deviceid').val();
deviceTableIns.reload({where:{group_id: gid, device_id: did}, page:{curr:1}});
});
table.on('tool(table-device-filter)', function(obj){
var data = obj.data;
if(obj.event === 'edit'){
var index = layer.open({
title: '编辑设备配置',
type: 2,
shade: 0.2,
maxmin:true,
shadeClose: true,
area: ['700px', '520px'],
content: '../page/table/rtk_profile_edit',
success: function(layero){
var iframeWin = window[layero.find('iframe')[0]['name']];
if(iframeWin && iframeWin.setParams){ iframeWin.setParams(data); }
}
});
}
});
// toolbar template for device table
var rtkWs = null;
var rtkSelectedDevice = '';
var rtkRunning = false;
var rtkGnggaTimer = null;
var cmdWs = null;
var cmdConnected = false;
function connectRtkWs(){
if(rtkWs && rtkWs.readyState === WebSocket.OPEN) return;
var curPath = window.document.location.href;
var pathName = window.document.location.pathname;
var pos = curPath.indexOf(pathName);
var basePath = curPath.substring(0, pos);
var wsUrl = (basePath+"/websocket/rtkrcv").replace("http","ws");
rtkWs = new WebSocket(wsUrl);
rtkWs.onopen = function(){ };
rtkWs.onerror = function(){ layer.msg('RTK WebSocket 连接失败'); };
rtkWs.onclose = function(){ };
rtkWs.onmessage = function (event) {
var msg = event.data || '';
var info = $('#rtk-info');
try {
var obj = JSON.parse(msg);
if(obj && obj.type==='rtk'){
if(rtkSelectedDevice && obj.deviceId !== rtkSelectedDevice) return;
var sol = (obj.q===1)?'固定解':((obj.q===2)?'浮点解':'--');
var solCls = (obj.q===1)?'layui-bg-green':((obj.q===2)?'layui-bg-orange':'layui-bg-gray');
$('#rtk-sol-badge').attr('class','layui-badge ' + solCls).text(sol);
var ns = (obj.ns!=null? obj.ns : '--');
$('#rtk-sat-badge').attr('class','layui-badge layui-bg-blue').text('卫星数: '+ns);
var llh = (obj.lat && obj.lon && obj.h!=null)? (obj.lat.toFixed(9)+' '+obj.lon.toFixed(9)+' '+obj.h) : '--';
$('#rtk-llh').text('LLH: ' + llh);
info.text(info.text() + (obj.raw || msg) + "\n");
} else if(obj && obj.type==='rtk_gngga'){
if(rtkSelectedDevice && obj.deviceId !== rtkSelectedDevice) return;
var gtxt = 'lat='+ (obj.lat!=null?obj.lat:0) + ', lon='+(obj.lon!=null?obj.lon:0)+', alt='+(obj.alt!=null?obj.alt:0)+', geo='+(obj.geo!=null?obj.geo:0);
$('#rtk-gngga').text('GNGGA: ' + gtxt);
} else if(obj && obj.type==='rtk_ctrl'){
if(obj.action==='auto_stop' && (!rtkSelectedDevice || obj.deviceId === rtkSelectedDevice)){
rtkRunning = false; updateToggleBtn();
layer.msg('已自动停止: 连续固定解达阈值');
}
if(groupSelectedId){
if(obj.deviceId){ groupStatus[obj.deviceId]='DONE'; renderGroupTable(); }
}
} else if(obj && obj.type==='rtk_group'){
if(groupSelectedId && obj.groupId==groupSelectedId){
groupStatus[obj.deviceId]=obj.status; renderGroupTable();
}
} else {
info.text(info.text() + msg + "\n");
}
} catch(e){
var parts = msg.trim().split(/\s+/);
var ok = parts.length >= 3 && parts[0] === 'RTK';
if(ok){
var did = parts[1];
if(rtkSelectedDevice && did !== rtkSelectedDevice) return;
}
info.text(info.text() + msg + "\n");
}
var el = document.getElementById('rtk-info');
el.scrollTop = el.scrollHeight;
if(groupSelectedId){
try{ var o=JSON.parse(msg); if(o && o.type==='rtk' && groupDevices.has(o.deviceId)){ appendGroupLog(o.raw || msg); } }catch(ex){ var pp=msg.trim().split(/\s+/); if(pp[0]==='RTK' && groupDevices.has(pp[1])) appendGroupLog(msg); }
}
};
}
function closeRtkWs(){ if(rtkWs){ try{ rtkWs.close(); }catch(e){} rtkWs=null; } }
function updateCmdBtn(){ var b=$('#btn-connect-cmd'); if(cmdConnected){ b.text('关闭设备通讯通道'); b.addClass('layui-btn-danger'); } else { b.text('连接设备通讯通道'); b.removeClass('layui-btn-danger'); } }
function connectCmdWs(){ if(cmdWs && cmdWs.readyState===WebSocket.OPEN) return; var cur=window.location.href; var pn=window.location.pathname; var pos=cur.indexOf(pn); var base=cur.substring(0,pos); var url=(base+"/websocket/cmdline").replace("http","ws"); cmdWs=new WebSocket(url); cmdWs.onopen=function(){ cmdConnected=true; updateCmdBtn(); }; cmdWs.onmessage=function(e){ var msg=e.data||''; var did=$('#rtk-device').val(); var parts=msg.trim().split(/\s+/); if(parts[0]==='RX' && parts.length>3){ if(did && parts[3]!==did) return; } var ci=$('#cmd-info'); ci.text(ci.text()+msg+'\n'); var el=document.getElementById('cmd-info'); el.scrollTop=el.scrollHeight; }; cmdWs.onclose=function(){ cmdConnected=false; updateCmdBtn(); }; cmdWs.onerror=function(){ layer.msg('通讯通道连接失败'); } }
function closeCmdWs(){ if(cmdWs){ try{ cmdWs.close(); }catch(e){} cmdWs=null; } }
function startGnggaTimer(){ if(rtkGnggaTimer) clearInterval(rtkGnggaTimer); rtkGnggaTimer = setInterval(function(){ if(!rtkSelectedDevice) return; $.get('/rtk/gngga',{device_id: rtkSelectedDevice}, function(res){ if(res){ var gtxt = 'lat='+(res.lat!=null?res.lat:0)+', lon='+(res.lon!=null?res.lon:0)+', alt='+(res.alt!=null?res.alt:0)+', geo='+(res.geo!=null?res.geo:0); $('#rtk-gngga').text('GNGGA: '+gtxt); } }); }, 5000); }
function stopGnggaTimer(){ if(rtkGnggaTimer){ clearInterval(rtkGnggaTimer); rtkGnggaTimer=null; } }
function loadRtkGroups(){
$.get('/rtk/group/list', {page:1,limit:1000}, function(res){
if(res.code===0){
var sel = $('#rtk-group'); sel.empty();
sel.append('<option value="">请选择</option>');
(res.data||[]).forEach(function(g){ sel.append('<option value="'+g.id+'">'+g.name+'</option>'); });
form.render('select');
}
});
}
function loadRtkDevices(gid){
var devSel = $('#rtk-device'); devSel.empty();
devSel.append('<option value="">请选择</option>');
if(!gid){ form.render('select'); return; }
$.get('/rtk/profile/list', {page:1,limit:1000, group_id: gid}, function(res){
if(res.code===0){
(res.data||[]).forEach(function(p){ devSel.append('<option value="'+p.device_id+'">'+p.device_id+'</option>'); });
form.render('select');
}
});
}
loadRtkGroups();
form.on('select(rtk-group)', function(data){
loadRtkDevices(data.value);
});
form.on('select(rtk-device)', function(data){ rtkSelectedDevice = data.value; });
function updateToggleBtn(){
var btn = $('#btn-rtk-start');
if(rtkRunning){
btn.text('停止定位');
btn.addClass('layui-btn-danger');
} else {
btn.text('开始定位');
btn.removeClass('layui-btn-danger');
}
}
updateToggleBtn();
$('#btn-rtk-start').on('click', function(){
rtkSelectedDevice = $('#rtk-device').val();
if(!rtkSelectedDevice){ layer.msg('请选择设备'); return; }
if(!rtkRunning){
$.get('/rtk/log_exists', {device_id: rtkSelectedDevice}, function(exists){
function doStart(clear){
$.post('/rtk/start', {device_id: rtkSelectedDevice, clear_log: clear}, function(res){
if(res && res.code === 0){
if(res.data === 'ok' || res.data === 'all_zero'){
connectRtkWs(); startGnggaTimer(); rtkRunning = true; updateToggleBtn();
if(res.data === 'all_zero'){ layer.msg('GNGGA全零使用默认配置启动'); }
} else {
layer.msg(res.data||'已处理');
}
} else { layer.alert((res&&res.msg)||'启动失败'); }
}).fail(function(){ layer.alert('启动请求失败'); });
}
if(exists){
layer.confirm('检测到已有日志,是否清空后再开始?', {btn:['清空','追加','取消']}, function(idx){
layer.close(idx); doStart(true);
}, function(idx){
layer.close(idx); doStart(false);
});
} else {
doStart(false);
}
}).fail(function(){ layer.alert('检查日志失败'); });
} else {
$.post('/rtk/stop', {device_id: rtkSelectedDevice}, function(){
rtkRunning = false; updateToggleBtn();
closeRtkWs(); stopGnggaTimer();
});
}
});
$('#btn-connect-cmd').on('click', function(){ if(!cmdConnected){ connectCmdWs(); layer.msg('已连接设备通讯通道'); } else { closeCmdWs(); layer.msg('已关闭设备通讯通道'); } });
function sendHexCmd(hex){ var dev=$('#rtk-device').val(); if(!dev){ layer.msg('请选择设备'); return; } $.ajax({ type:'POST', url:'/gnss/config_cmd', data:{ tx_win: hex, device_id: dev, cmd_type: 0, send_channel: 0 }, success:function(res){ if(res && res.code===0){ var ci=$('#cmd-info'); ci.text(ci.text()+(res.data||'')+'\n'); var el=document.getElementById('cmd-info'); el.scrollTop=el.scrollHeight; } else { layer.alert((res&&res.msg)||'发送失败'); } }, error:function(){ layer.alert('请求失败'); } }); }
function sendDebugCmd(content){ var dev=$('#rtk-device').val(); if(!dev){ layer.msg('请选择设备'); return; } $.ajax({ type:'POST', url:'/gnss/config_cmd', data:{ tx_win: content, device_id: dev, cmd_type: 3, send_channel: 0 }, success:function(res){ if(res && res.code===0){ var ci=$('#cmd-info'); ci.text(ci.text()+(res.data||'')+'\n'); var el=document.getElementById('cmd-info'); el.scrollTop=el.scrollHeight; } else { layer.alert((res&&res.msg)||'发送失败'); } }, error:function(){ layer.alert('请求失败'); } }); }
$('#btn-cmd-open-rtcm').on('click', function(){ sendHexCmd('42 4b 51 45 26 02 00 0c 55 00 23 71 00 00 00 31 00 00 00 ff'); });
$('#btn-cmd-close-4065').on('click', function(){ sendHexCmd('42 4b e4 6b 26 02 00 0c 55 55 00 01 00 00 00 31 00 00 00 01'); });
$('#btn-cmd-msm4').on('click', function(){ sendHexCmd('42 4b 46 8e 26 02 00 0c 55 55 00 01 00 00 00 10 00 00 00 01'); });
$('#btn-cmd-save').on('click', function(){ sendHexCmd('42 4b cc 17 26 04 00 00'); });
$('#btn-cmd-0102').on('click', function(){ sendDebugCmd('0102'); });
$('#btn-cmd-0100').on('click', function(){ sendDebugCmd('0100'); });
var grRunning = false; function updateGrBtn(){ var b=$('#btn-gr-start'); if(grRunning){b.text('停止组定位').addClass('layui-btn-danger');} else {b.text('开始组定位').removeClass('layui-btn-danger');} }
updateGrBtn();
var groupSelectedId = null; var groupDevices = new Set(); var groupStatus = {};
form.on('select(gr-group)', function(data){ groupSelectedId = data.value; reloadGroupStatus(); loadGroupDevices(); });
function loadGroupDevices(){ groupDevices.clear(); if(!groupSelectedId)return; $.get('/rtk/profile/list',{page:1,limit:1000, group_id: groupSelectedId}, function(res){ if(res.code===0){ (res.data||[]).forEach(function(p){ groupDevices.add(p.device_id);}); renderGroupTable(); } }); }
function renderGroupTable(){
table.render({
elem: '#group-table',
data: Array.from(groupDevices).map(function(d){ return {device_id:d, status: (groupStatus[d]||'--')}; }),
cols: [ [
{field:'device_id', title:'设备号'},
{field:'status', title:'状态', templet: function(d){
var s=d.status;
var m={'RUNNING':'layui-bg-green','QUEUED':'','DONE':'layui-bg-blue','FAILED':'layui-bg-red'};
var cls=m[s]||'';
return '<span class="layui-badge '+cls+'">'+(s||'--')+'</span>';
}}
] ],
page: true,
limit: 10,
limits: [10,20,50,100]
});
}
function reloadGroupStatus(){ if(!groupSelectedId) return; $.get('/rtk/group/status',{group_id: groupSelectedId}, function(res){ if(res.code===0){ (res.data||[]).forEach(function(r){ groupStatus[r.device_id]=r.status; }); renderGroupTable(); } }); }
$('#btn-gr-start').on('click', function(){ if(!groupSelectedId){ layer.msg('请选择分组'); return; } if(!grRunning){ layer.confirm('是否清空日志后开始?',{btn:['清空','追加','取消']}, function(idx){ layer.close(idx); $.post('/rtk/group/start',{group_id: groupSelectedId, clear_log:true}, function(){ grRunning=true; updateGrBtn(); connectRtkWs(); }); }, function(idx){ layer.close(idx); $.post('/rtk/group/start',{group_id: groupSelectedId, clear_log:false}, function(){ grRunning=true; updateGrBtn(); connectRtkWs(); }); }); } else { $.post('/rtk/group/stop',{group_id: groupSelectedId}, function(){ grRunning=false; updateGrBtn(); }); } });
function appendGroupLog(msg){ var gi=$('#group-info'); gi.text(gi.text()+msg+'\n'); var el=document.getElementById('group-info'); el.scrollTop=el.scrollHeight; }
});
</script>
<script type="text/html" id="rtkProfileBar">
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit">编辑</a>
</script>
<script type="text/html" id="ntripDevTypeTrans">
{{# if(d.devicetype == 1){ }}
<span>基准站</span>
{{# } else { }}
<span>监测站</span>
{{# } }}
</script>
<script type="text/html" id="ntripModelTrans">
{{# if(d.model == 1){ }}
<span>G510</span>
{{# } else { }}
<span>G505</span>
{{# } }}
</script>
</body>
</html>