信息查看器

logview2信息查看器

Dieses Skript sollte nicht direkt installiert werden. Es handelt sich hier um eine Bibliothek für andere Skripte, welche über folgenden Befehl in den Metadaten eines Skriptes eingebunden wird // @require https://update.greasyfork.org/scripts/498149/1395619/%E4%BF%A1%E6%81%AF%E6%9F%A5%E7%9C%8B%E5%99%A8.js

  1. (function() {
  2. 'use strict';
  3.  
  4. // 日志类型定义
  5. const LOG_TYPES = ['info', 'warning', 'error'];
  6.  
  7. let logContainer; // 日志容器
  8.  
  9. // 全局记录各种类型日志数量
  10. window.logCounts = {
  11. info: 0,
  12. warning: 0,
  13. error: 0
  14. };
  15.  
  16. // 创建日志列表的容器
  17. logContainer = document.createElement('div');
  18. logContainer.style.position = 'fixed';
  19. logContainer.style.bottom = '20px'; // 距离底部 20px
  20. logContainer.style.right = '20px'; // 距离右侧 20px
  21. logContainer.style.zIndex = '9999';
  22. logContainer.style.padding = '10px';
  23. logContainer.style.backgroundColor = '#f0f0f0';
  24. logContainer.style.border = '1px solid #ccc';
  25. logContainer.style.width = '400px'; // 固定宽度
  26. logContainer.style.height = '300px'; // 固定高度
  27. logContainer.style.overflowY = 'auto'; // 垂直滚动条
  28. logContainer.style.overflowX = 'hidden'; // 隐藏水平滚动条
  29. logContainer.style.display = 'none'; // 初始不可见
  30. document.body.appendChild(logContainer);
  31.  
  32. // 创建导出按钮
  33. const exportButton = document.createElement('button');
  34. exportButton.textContent = '导出 Errors';
  35. exportButton.style.position = 'fixed';
  36. exportButton.style.bottom = '50px'; // 距离底部 50px
  37. exportButton.style.right = '30px'; // 距离右侧 30px
  38. exportButton.style.zIndex = '10000'; // 比日志容器高
  39. exportButton.style.display = 'none'; // 初始不显示
  40. exportButton.addEventListener('click', () => {
  41. // 收集所有错误信息
  42. const errorLogs = Array.from(logContainer.querySelectorAll('.error')).map(log => log.textContent);
  43. const errorLogsText = errorLogs.join('\n');
  44.  
  45. // 创建文本文件并下载
  46. const blob = new Blob([errorLogsText], { type: 'text/plain' });
  47. const url = URL.createObjectURL(blob);
  48.  
  49. // 创建下载链接
  50. const downloadLink = document.createElement('a');
  51. downloadLink.href = url;
  52. downloadLink.download = 'error_logs.txt';
  53. downloadLink.style.display = 'none';
  54. document.body.appendChild(downloadLink);
  55.  
  56. // 模拟点击下载链接
  57. downloadLink.click();
  58.  
  59. // 清理资源
  60. URL.revokeObjectURL(url);
  61. document.body.removeChild(downloadLink);
  62. });
  63. document.body.appendChild(exportButton);
  64.  
  65. // 创建隐藏按钮
  66. const hideButton = document.createElement('button');
  67. hideButton.textContent = 'Hide Logs';
  68. hideButton.style.position = 'fixed';
  69. hideButton.style.bottom = '20px'; // 距离底部 20px
  70. hideButton.style.right = '30px'; // 距离右侧 30px
  71. hideButton.style.zIndex = '10000'; // 比日志容器高
  72. hideButton.style.display = 'none'; // 初始不显示
  73. hideButton.addEventListener('click', () => {
  74. logContainer.style.display = 'none';
  75. hideButton.style.display = 'none';
  76. exportButton.style.display = 'none';
  77. });
  78. document.body.appendChild(hideButton);
  79.  
  80. // 创建显示方法
  81. window.showLogContainer = function() {
  82. logContainer.style.display = 'block';
  83. hideButton.style.display = 'block';
  84. exportButton.style.display = 'block';
  85. };
  86.  
  87. // 创建日志类型选择器
  88. const typeSelector = document.createElement('div');
  89. typeSelector.style.marginBottom = '10px';
  90. logContainer.appendChild(typeSelector);
  91.  
  92. // 创建日志条目列表
  93. const logList = document.createElement('ul');
  94. logList.style.listStyleType = 'none';
  95. logContainer.appendChild(logList);
  96.  
  97. // 函数:向日志列表中添加条目
  98. window.addToLog = function(message, type) {
  99. const logEntry = document.createElement('li');
  100. const options = { timeZone: 'Asia/Shanghai', hour12: false, hour: 'numeric', minute: 'numeric', second: 'numeric' };
  101. const currentTime = new Date().toLocaleTimeString('zh-CN', options); // 获取当前北京时间,中国格式,24小时制
  102. logEntry.textContent = `[${type.toUpperCase()}] ${currentTime} - ${message}`;
  103. logEntry.classList.add(type); // 添加类型类名
  104.  
  105. // 根据日志类型设置不同的颜色样式
  106. if (type === 'info') {
  107. logEntry.style.color = '#3498db';
  108. } else if (type === 'warning') {
  109. logEntry.style.color = '#f39c12';
  110. } else if (type === 'error') {
  111. logEntry.style.color = '#e74c3c';
  112. }
  113.  
  114. // 添加日志条目到日志列表的顶部
  115. logList.insertBefore(logEntry, logList.firstChild);
  116.  
  117. // 更新日志类型计数
  118. window.logCounts[type]++;
  119. updateTypeButtonsDisplay();
  120. };
  121.  
  122. // 函数:更新类型按钮显示的日志数量
  123. function updateTypeButtonsDisplay() {
  124. LOG_TYPES.forEach(type => {
  125. const button = getTypeButton(type);
  126. if (button) {
  127. const count = window.logCounts[type];
  128. button.textContent = `${type.charAt(0).toUpperCase()}${type.slice(1)} Logs (${count})`;
  129. }
  130. });
  131.  
  132. // 更新 "All Logs" 按钮的显示
  133. const allLogsButton = getTypeButton('all');
  134. if (allLogsButton) {
  135. const totalLogs = Object.values(window.logCounts).reduce((acc, curr) => acc + curr, 0);
  136. allLogsButton.textContent = `All Logs (${totalLogs})`;
  137. }
  138. }
  139.  
  140. // 函数:获取指定类型的按钮
  141. function getTypeButton(type) {
  142. return Array.from(typeSelector.children).find(btn => btn.textContent.toLowerCase().includes(type));
  143. }
  144.  
  145. // 函数:清空日志列表和计数
  146. window.clearLogs = function() {
  147. logList.innerHTML = '';
  148. window.logCounts.info = 0;
  149. window.logCounts.warning = 0;
  150. window.logCounts.error = 0;
  151.  
  152. updateTypeButtonsDisplay();
  153. };
  154.  
  155. // 函数:根据选择的日志类型过滤显示
  156. window.filterLogs = function(type) {
  157. const logEntries = logList.getElementsByTagName('li');
  158. for (let i = 0; i < logEntries.length; i++) {
  159. const logEntry = logEntries[i];
  160. if (type === 'all' || logEntry.classList.contains(type)) {
  161. logEntry.style.display = 'block';
  162. } else {
  163. logEntry.style.display = 'none';
  164. }
  165. }
  166. };
  167.  
  168. // 初始化:创建类型选择按钮
  169. const allLogsButton = document.createElement('button');
  170. allLogsButton.textContent = 'All Logs (0)';
  171. allLogsButton.addEventListener('click', () => window.filterLogs('all'));
  172. typeSelector.appendChild(allLogsButton);
  173.  
  174. LOG_TYPES.forEach(type => {
  175. const typeButton = document.createElement('button');
  176. typeButton.textContent = `${type.charAt(0).toUpperCase()}${type.slice(1)} Logs (0)`;
  177. typeButton.addEventListener('click', () => window.filterLogs(type));
  178. typeSelector.appendChild(typeButton);
  179. });
  180. })();