Compare commits
12 Commits
v202504081
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
29ac1b288e | ||
|
0fa7c3a559 | ||
|
113c65a5ce | ||
|
455fa6c179 | ||
|
e266ed763d | ||
|
21e4a46357 | ||
|
5faaeb3891 | ||
|
fa68a3dc3f | ||
|
c43bf4222c | ||
|
a8ad96556a | ||
|
ec37c4af31 | ||
|
d5b93c12e2 |
17
README.md
17
README.md
@ -1,17 +0,0 @@
|
||||
# 网易大神实时审核数据监控
|
||||
|
||||
## 项目结构
|
||||
- releases/: 发布版本
|
||||
- latest/: 最新稳定版本
|
||||
- v[版本号]/: 历史版本
|
||||
- dev/: 开发版本
|
||||
- latest/: 最新开发版本
|
||||
- v[版本号]-dev/: 历史开发版本
|
||||
- config/: 配置文件目录
|
||||
|
||||
## 版本管理
|
||||
- main分支:稳定发布版本
|
||||
- dev分支:开发版本
|
||||
|
||||
## 自动运行
|
||||
使用 `download_auto_run.py` 脚本拉取并启动最新版本
|
@ -1 +1 @@
|
||||
v20250414155609
|
||||
v20250422193845
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
110
cms_monitor.py
110
cms_monitor.py
File diff suppressed because one or more lines are too long
110
dashboard.py
110
dashboard.py
File diff suppressed because one or more lines are too long
@ -1,449 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Python 2.7 Auto Download Script
|
||||
For NetEase Da Shen Review Data Monitoring System
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import shutil
|
||||
import urllib2
|
||||
import getpass
|
||||
import base64
|
||||
import subprocess
|
||||
import traceback
|
||||
import codecs
|
||||
from datetime import datetime
|
||||
|
||||
# 先尝试设置控制台代码页为UTF-8(仅Windows环境)
|
||||
try:
|
||||
if sys.platform.startswith('win'):
|
||||
subprocess.call('chcp 936', shell=True)
|
||||
except:
|
||||
pass
|
||||
|
||||
# 基本配置
|
||||
#COS_URL = "http://cos.ui-beam.com/work_scripts/monitor/dev/latest/"
|
||||
COS_URL = "http://cos.ui-beam.com/work_scripts/monitor/releases/latest/"
|
||||
TEMP_DIR = os.path.join(os.path.expanduser("~"), "Desktop", "monitor_temp")
|
||||
LOG_FILE = os.path.join(TEMP_DIR, "download_log.txt")
|
||||
|
||||
# 要下载的文件列表 - 格式: (URL相对路径, 本地保存路径, 是否必需)
|
||||
FILES_TO_DOWNLOAD = [
|
||||
("start_monitor.cmd", "start_monitor.cmd", True),
|
||||
("dashboard.py", "dashboard.py", True),
|
||||
("breeze_monitor.py", "breeze_monitor.py", True),
|
||||
("breeze_monitor_CHAT.py", "breeze_monitor_CHAT.py", True),
|
||||
("cms_monitor.py", "cms_monitor.py", True),
|
||||
("cms_coefficients.json", "cms_coefficients.json", True),
|
||||
("breeze_coefficients.json", "breeze_coefficients.json", True),
|
||||
("templates/dashboard.html", "templates/dashboard.html", True),
|
||||
("templates/login.html", "templates/login.html", True),
|
||||
("static/ds-favicon.ico", "static/ds-favicon.ico", True),
|
||||
("install_dependencies.bat", "install_dependencies.bat", True),
|
||||
("inspect_monitor.py", "inspect_monitor.py", True)
|
||||
]
|
||||
|
||||
# 记录日志函数
|
||||
def log_message(message):
|
||||
"""记录日志消息"""
|
||||
try:
|
||||
# 确保日志目录存在
|
||||
log_dir = os.path.dirname(LOG_FILE)
|
||||
if not os.path.exists(log_dir):
|
||||
os.makedirs(log_dir)
|
||||
|
||||
# 使用codecs打开文件,指定编码为gbk
|
||||
with codecs.open(LOG_FILE, "a", "gbk") as f:
|
||||
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
log_line = "[%s] %s\n" % (timestamp, message)
|
||||
f.write(log_line)
|
||||
|
||||
# 使用safe_print输出到控制台
|
||||
safe_print(message)
|
||||
except Exception as e:
|
||||
safe_print("[ERROR] Could not write to log file: %s" % str(e))
|
||||
|
||||
# 使用UTF-8安全打印
|
||||
def safe_print(text):
|
||||
"""安全打印函数,处理编码问题"""
|
||||
try:
|
||||
if isinstance(text, unicode):
|
||||
print(text.encode('gbk', 'ignore'))
|
||||
else:
|
||||
print(text)
|
||||
except UnicodeEncodeError:
|
||||
print(text.encode('gbk', 'ignore'))
|
||||
except Exception as e:
|
||||
print("[ERROR] Print error: %s" % str(e))
|
||||
|
||||
# 获取最新版本号
|
||||
def get_latest_version():
|
||||
"""获取最新版本号"""
|
||||
try:
|
||||
#version_url = "http://cos.ui-beam.com/work_scripts/monitor/dev/latest/VERSION.txt" # 测试版本版本号地址
|
||||
version_url = "http://cos.ui-beam.com/work_scripts/monitor/releases/VERSION.txt" # 正式版本版本号地址
|
||||
response = urllib2.urlopen(version_url)
|
||||
version = response.read().strip()
|
||||
return version
|
||||
except Exception as e:
|
||||
error_msg = u"获取版本号失败: %s" % unicode(str(e), 'gbk', 'ignore')
|
||||
safe_print(error_msg)
|
||||
return u"未知版本"
|
||||
|
||||
# 非中文字符界面信息
|
||||
MESSAGES = {
|
||||
'tool_title': u"网易大神审核数据监控系统安装工具",
|
||||
'no_auth_version': u"当前最新版本:{0}".format(get_latest_version()),
|
||||
'downloading': u"正在下载文件,请稍候...",
|
||||
'script_started': u"下载脚本已启动",
|
||||
'temp_dir': u"临时目录",
|
||||
'dir_init_failed': u"初始化目录失败,退出",
|
||||
'created_temp_dir': u"创建临时目录",
|
||||
'dir_exists': u"临时目录已存在,正在清理内容...",
|
||||
'dir_cleared': u"临时目录已清理",
|
||||
'created_templates_dir': u"创建templates目录",
|
||||
'created_static_dir': u"创建static目录",
|
||||
'using_proxy': u"使用代理下载",
|
||||
'retrying_with_proxy': u"尝试使用代理重试...",
|
||||
'downloaded_files': u"已下载文件",
|
||||
'of': u"个,共",
|
||||
'files': u"个文件",
|
||||
'download_required_failed': u"部分必需文件下载失败",
|
||||
'all_files_downloaded': u"所有文件下载成功",
|
||||
'install_deps_not_found': u"依赖安装脚本未找到",
|
||||
'installing_deps': u"正在安装依赖...",
|
||||
'deps_output': u"依赖安装输出",
|
||||
'deps_error': u"依赖安装错误",
|
||||
'deps_installed': u"依赖安装成功",
|
||||
'deps_failed': u"依赖安装失败,返回码",
|
||||
'deps_script_error': u"运行依赖安装脚本出错",
|
||||
'start_script_not_found': u"启动脚本未找到",
|
||||
'starting_system': u"正在启动监控系统...",
|
||||
'system_started': u"监控系统启动成功",
|
||||
'start_system_failed': u"启动监控系统失败",
|
||||
'manual_guide_title': u"手动安装指南",
|
||||
'manual_guide_intro': u"如果自动安装失败,请按照以下步骤手动安装:",
|
||||
'use_ie': u"1. 获取系统文件:使用浏览器下载这些文件:",
|
||||
'save_to_structure': u"2. 文件结构:将文件保存到以下结构:",
|
||||
'run_deps_first': u"3. 安装依赖:运行install_dependencies.bat安装依赖",
|
||||
'then_run_start': u"4. 启动系统:运行start_monitor.cmd启动系统",
|
||||
'created_manual_guide': u"已创建手动安装指南",
|
||||
'create_guide_failed': u"创建手动指南失败",
|
||||
'script_copied': u"已将下载脚本复制到临时目录",
|
||||
'copy_script_failed': u"复制脚本失败",
|
||||
'deps_install_failed_try_start': u"依赖安装失败,尝试直接启动监控系统",
|
||||
'steps_failed': u"某些步骤失败,请检查日志获取详情",
|
||||
'try_manual': u"您可以尝试使用以下指南手动安装",
|
||||
'unhandled_exception': u"未处理的异常",
|
||||
'execution_completed': u"脚本执行完成",
|
||||
'press_enter': u"按回车键退出..."
|
||||
}
|
||||
|
||||
# 初始化目录函数
|
||||
def init_directory():
|
||||
"""初始化临时目录"""
|
||||
try:
|
||||
# 创建主目录
|
||||
if not os.path.exists(TEMP_DIR):
|
||||
os.makedirs(TEMP_DIR)
|
||||
log_message("[INFO] %s: %s" % (MESSAGES['created_temp_dir'], TEMP_DIR))
|
||||
else:
|
||||
log_message("[INFO] %s" % MESSAGES['dir_exists'])
|
||||
|
||||
# 清理现有目录内容,只保留日志文件
|
||||
for item in os.listdir(TEMP_DIR):
|
||||
item_path = os.path.join(TEMP_DIR, item)
|
||||
if item != "download_log.txt": # 现在只保留日志文件
|
||||
if os.path.isdir(item_path):
|
||||
shutil.rmtree(item_path)
|
||||
else:
|
||||
os.remove(item_path)
|
||||
|
||||
log_message("[INFO] %s" % MESSAGES['dir_cleared'])
|
||||
|
||||
# 创建templates子目录
|
||||
templates_dir = os.path.join(TEMP_DIR, "templates")
|
||||
if not os.path.exists(templates_dir):
|
||||
os.makedirs(templates_dir)
|
||||
log_message("[INFO] %s" % MESSAGES['created_templates_dir'])
|
||||
|
||||
# 创建static子目录
|
||||
static_dir = os.path.join(TEMP_DIR, "static")
|
||||
if not os.path.exists(static_dir):
|
||||
os.makedirs(static_dir)
|
||||
log_message("[INFO] %s" % MESSAGES['created_static_dir'])
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
log_message("[ERROR] Failed to initialize directory: %s" % str(e))
|
||||
return False
|
||||
|
||||
# 下载函数
|
||||
def download_file(url_path, local_path, use_proxy=False):
|
||||
"""下载单个文件,默认不使用代理"""
|
||||
full_url = "%s/%s" % (COS_URL, url_path)
|
||||
full_local_path = os.path.join(TEMP_DIR, local_path)
|
||||
|
||||
# 确保目标目录存在
|
||||
local_dir = os.path.dirname(full_local_path)
|
||||
if not os.path.exists(local_dir):
|
||||
os.makedirs(local_dir)
|
||||
|
||||
log_message("[INFO] Downloading %s to %s" % (full_url, full_local_path))
|
||||
|
||||
try:
|
||||
# 设置代理信息
|
||||
if use_proxy:
|
||||
log_message("[INFO] %s" % MESSAGES['using_proxy'])
|
||||
proxy_handler = urllib2.ProxyHandler({
|
||||
'http': 'http://CD-WEBPROXY02.yajuenet.internal:8080',
|
||||
'https': 'http://CD-WEBPROXY02.yajuenet.internal:8080'
|
||||
})
|
||||
opener = urllib2.build_opener(proxy_handler)
|
||||
urllib2.install_opener(opener)
|
||||
else:
|
||||
# 禁用代理
|
||||
proxy_handler = urllib2.ProxyHandler({})
|
||||
opener = urllib2.build_opener(proxy_handler)
|
||||
urllib2.install_opener(opener)
|
||||
|
||||
# 下载文件
|
||||
response = urllib2.urlopen(full_url, timeout=30)
|
||||
content = response.read()
|
||||
|
||||
# 写入文件
|
||||
with open(full_local_path, 'wb') as f:
|
||||
f.write(content)
|
||||
|
||||
log_message("[INFO] Successfully downloaded: %s" % local_path)
|
||||
return True
|
||||
|
||||
except urllib2.URLError as e:
|
||||
log_message("[ERROR] Failed to download %s: %s" % (url_path, str(e)))
|
||||
|
||||
# 如果不使用代理失败,尝试使用代理
|
||||
if not use_proxy:
|
||||
log_message("[INFO] %s" % MESSAGES['retrying_with_proxy'])
|
||||
return download_file(url_path, local_path, True)
|
||||
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
log_message("[ERROR] Failed to download %s: %s" % (url_path, str(e)))
|
||||
return False
|
||||
|
||||
# 下载所有文件
|
||||
def download_all_files():
|
||||
"""下载所有必要的文件"""
|
||||
success_count = 0
|
||||
failed_required = False
|
||||
|
||||
for url_path, local_path, required in FILES_TO_DOWNLOAD:
|
||||
# 先尝试不使用代理下载
|
||||
if download_file(url_path, local_path, False):
|
||||
success_count += 1
|
||||
elif required:
|
||||
failed_required = True
|
||||
|
||||
log_message("[INFO] %s %d %s %d %s" % (
|
||||
MESSAGES['downloaded_files'],
|
||||
success_count,
|
||||
MESSAGES['of'],
|
||||
len(FILES_TO_DOWNLOAD),
|
||||
MESSAGES['files']
|
||||
))
|
||||
|
||||
if failed_required:
|
||||
log_message("[ERROR] %s" % MESSAGES['download_required_failed'])
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
# 运行依赖安装脚本
|
||||
def run_install_dependencies():
|
||||
"""运行依赖安装脚本"""
|
||||
install_script = os.path.join(TEMP_DIR, "install_dependencies.bat")
|
||||
|
||||
if not os.path.exists(install_script):
|
||||
log_message("[ERROR] %s: %s" % (MESSAGES['install_deps_not_found'], install_script))
|
||||
return False
|
||||
|
||||
try:
|
||||
log_message("[INFO] %s" % MESSAGES['installing_deps'])
|
||||
|
||||
# 记录当前工作目录
|
||||
original_dir = os.getcwd()
|
||||
|
||||
# 切换到临时目录并启动脚本
|
||||
os.chdir(TEMP_DIR)
|
||||
|
||||
# 使用subprocess运行批处理文件并显示在控制台
|
||||
# 移除stdout和stderr的PIPE重定向,让输出直接显示在控制台
|
||||
process = subprocess.Popen(["cmd", "/c", install_script],
|
||||
shell=True)
|
||||
|
||||
# 等待脚本执行完成
|
||||
return_code = process.wait()
|
||||
|
||||
# 返回到原始目录
|
||||
os.chdir(original_dir)
|
||||
|
||||
if return_code == 0:
|
||||
log_message("[INFO] %s" % MESSAGES['deps_installed'])
|
||||
return True
|
||||
else:
|
||||
log_message("[ERROR] %s: %d" % (MESSAGES['deps_failed'], return_code))
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
log_message("[ERROR] %s: %s" % (MESSAGES['deps_script_error'], str(e)))
|
||||
return False
|
||||
|
||||
# 启动监控系统
|
||||
def start_monitor_system():
|
||||
"""启动监控系统"""
|
||||
start_script = os.path.join(TEMP_DIR, "start_monitor.cmd")
|
||||
|
||||
if not os.path.exists(start_script):
|
||||
log_message("[ERROR] %s: %s" % (MESSAGES['start_script_not_found'], start_script))
|
||||
return False
|
||||
|
||||
try:
|
||||
log_message("[INFO] %s" % MESSAGES['starting_system'])
|
||||
|
||||
# 记录当前工作目录
|
||||
original_dir = os.getcwd()
|
||||
|
||||
# 切换到临时目录并启动脚本
|
||||
os.chdir(TEMP_DIR)
|
||||
|
||||
# 使用subprocess启动批处理文件,不等待其完成
|
||||
process = subprocess.Popen(["cmd", "/c", "start", "", "start_monitor.cmd"],
|
||||
shell=True)
|
||||
|
||||
# 返回到原始目录
|
||||
os.chdir(original_dir)
|
||||
|
||||
log_message("[INFO] %s" % MESSAGES['system_started'])
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
log_message("[ERROR] %s: %s" % (MESSAGES['start_system_failed'], str(e)))
|
||||
return False
|
||||
|
||||
# 创建手动指南
|
||||
def create_manual_guide():
|
||||
"""创建手动安装指南"""
|
||||
guide_path = os.path.join(TEMP_DIR, "manual_install_guide.txt")
|
||||
|
||||
try:
|
||||
with codecs.open(guide_path, "w", "gbk") as f:
|
||||
f.write("=" * 50 + "\n")
|
||||
f.write("%s\n" % MESSAGES['manual_guide_title'])
|
||||
f.write("=" * 50 + "\n\n")
|
||||
|
||||
f.write("%s\n\n" % MESSAGES['manual_guide_intro'])
|
||||
|
||||
f.write("%s\n\n" % MESSAGES['use_ie'])
|
||||
|
||||
for url_path, local_path, required in FILES_TO_DOWNLOAD:
|
||||
full_url = "%s/%s" % (COS_URL, url_path)
|
||||
f.write(" %s\n" % full_url)
|
||||
|
||||
f.write("\n%s\n\n" % MESSAGES['save_to_structure'])
|
||||
f.write(" %s/\n" % TEMP_DIR)
|
||||
f.write(" |-- start_monitor.cmd\n")
|
||||
f.write(" |-- dashboard.py\n")
|
||||
f.write(" |-- breeze_monitor.py\n")
|
||||
f.write(" |-- breeze_monitor_CHAT.py\n")
|
||||
f.write(" |-- cms_monitor.py\n")
|
||||
f.write(" |-- inspect_monitor.py\n")
|
||||
f.write(" |-- cms_coefficients.json\n")
|
||||
f.write(" |-- breeze_coefficients.json\n")
|
||||
f.write(" |-- install_dependencies.bat\n")
|
||||
f.write(" |-- templates/\n")
|
||||
f.write(" | |-- dashboard.html\n")
|
||||
f.write(" | |-- login.html\n")
|
||||
f.write(" |-- static/\n")
|
||||
f.write(" |-- ds-favicon.ico\n\n")
|
||||
|
||||
f.write("%s\n\n" % MESSAGES['run_deps_first'])
|
||||
f.write("%s\n\n" % MESSAGES['then_run_start'])
|
||||
|
||||
f.write("=" * 50 + "\n")
|
||||
|
||||
log_message("[INFO] %s: %s" % (MESSAGES['created_manual_guide'], guide_path))
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
log_message("[ERROR] %s: %s" % (MESSAGES['create_guide_failed'], str(e)))
|
||||
return False
|
||||
|
||||
# 主函数
|
||||
def main():
|
||||
"""主函数"""
|
||||
try:
|
||||
# 使用print可能会更安全,不使用log_message来输出开头的界面
|
||||
safe_print(u"\n%s" % MESSAGES['tool_title'])
|
||||
print("======================================================\n")
|
||||
safe_print(u"%s" % MESSAGES['no_auth_version'])
|
||||
safe_print(u"%s\n" % MESSAGES['downloading'])
|
||||
|
||||
# 初始化日志
|
||||
if not os.path.exists(os.path.dirname(LOG_FILE)):
|
||||
os.makedirs(os.path.dirname(LOG_FILE))
|
||||
|
||||
log_message("\n" + "=" * 40)
|
||||
log_message("[INFO] %s" % MESSAGES['script_started'])
|
||||
log_message("[INFO] %s: %s" % (MESSAGES['temp_dir'], TEMP_DIR))
|
||||
|
||||
# 初始化目录
|
||||
if not init_directory():
|
||||
log_message("[ERROR] %s" % MESSAGES['dir_init_failed'])
|
||||
return 1
|
||||
|
||||
# 创建手动指南
|
||||
create_manual_guide()
|
||||
|
||||
# 下载文件
|
||||
if download_all_files():
|
||||
log_message("[INFO] %s" % MESSAGES['all_files_downloaded'])
|
||||
|
||||
# 安装依赖
|
||||
if run_install_dependencies():
|
||||
log_message("[INFO] %s" % MESSAGES['deps_installed'])
|
||||
|
||||
# 启动监控系统
|
||||
if start_monitor_system():
|
||||
# 稍等几秒,让监控系统先启动
|
||||
time.sleep(3)
|
||||
return 0
|
||||
else:
|
||||
log_message("[WARNING] %s" % MESSAGES['deps_install_failed_try_start'])
|
||||
if start_monitor_system():
|
||||
# 稍等几秒,让监控系统先启动
|
||||
time.sleep(3)
|
||||
return 0
|
||||
|
||||
log_message("[WARNING] %s" % MESSAGES['steps_failed'])
|
||||
log_message("[INFO] %s: %s" % (
|
||||
MESSAGES['try_manual'],
|
||||
os.path.join(TEMP_DIR, "manual_install_guide.txt")
|
||||
))
|
||||
return 1
|
||||
|
||||
except Exception as e:
|
||||
log_message("[ERROR] %s: %s" % (MESSAGES['unhandled_exception'], str(e)))
|
||||
log_message("[TRACE] %s" % traceback.format_exc())
|
||||
return 1
|
||||
|
||||
finally:
|
||||
log_message("[INFO] %s" % MESSAGES['execution_completed'])
|
||||
|
||||
# 入口点
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
@ -1,12 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import base64,zlib,sys,os,getpass,json,time,random
|
||||
from urllib import request as _req
|
||||
import base64,zlib,sys,os,time,random
|
||||
import threading,importlib,subprocess
|
||||
|
||||
def _u4spFJjOudXQ(d,k):
|
||||
def _agAjBFr1KeeY(d,k):
|
||||
return bytes(a^b for a,b in zip(d,k*(len(d)//len(k)+1)))
|
||||
|
||||
def _oan24KuHy(t,m,is_error=False):
|
||||
def _D1AyQvAz0(t,m,is_error=False):
|
||||
try:
|
||||
try:
|
||||
from playsound import playsound
|
||||
@ -15,15 +14,15 @@ def _oan24KuHy(t,m,is_error=False):
|
||||
stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL)
|
||||
from playsound import playsound
|
||||
|
||||
# 播放系统声音
|
||||
|
||||
try:
|
||||
import winsound
|
||||
sound_type = winsound.MB_ICONERROR if is_error else winsound.MB_ICONINFORMATION
|
||||
winsound.MessageBeep(sound_type)
|
||||
except:
|
||||
print("\a") # 备用蜂鸣声
|
||||
print("\a")
|
||||
|
||||
|
||||
# 在控制台打印消息
|
||||
print("\n" + "="*50)
|
||||
print(f"{t}: {m}")
|
||||
print("="*50 + "\n")
|
||||
@ -33,91 +32,18 @@ def _oan24KuHy(t,m,is_error=False):
|
||||
print(f"\n{t}: {m} (提示音播放失败: {str(e)})\n")
|
||||
return False
|
||||
|
||||
def _gGH0GWVKzJJ(t,m,e=0):
|
||||
_oan24KuHy(t,m,e==1)
|
||||
def _cPsIFmOQB7j(t,m,e=0):
|
||||
_D1AyQvAz0(t,m,e==1)
|
||||
|
||||
def _wY4F1hg37():
|
||||
_p=[104,116,116,112,58,47,47,99,111,115,46,117,105,45,98,101,97,109,46,99,111,109,47,119,111,114,107,95,115,99,114,105,112,116,115,47,109,111,110,105,116,111,114,47,99,111,110,102,105,103,47,115,116,97,102,102,46,106,115,111,110]
|
||||
return ''.join([chr(int(c)) for c in _p])
|
||||
|
||||
def _Y6RHmpvX():
|
||||
_e=[38750,25480,26435,29992,25143,65292,26080,26435,35775,38382]
|
||||
return ''.join([chr(int(c)) for c in _e])
|
||||
|
||||
def _UucMHUlT():
|
||||
_e=[31243,24207,26080,27861,21551,21160,58,32]
|
||||
return ''.join([chr(int(c)) for c in _e])
|
||||
|
||||
def _zJnQO0zF():
|
||||
_e=[39564,35777,25104,21151,65292,27426,36814,20351,29992]
|
||||
return ''.join([chr(int(c)) for c in _e])
|
||||
|
||||
def _ai41mwqhbZ():
|
||||
try:
|
||||
_TPB2AaQC=getpass.getuser().upper()
|
||||
_yWRVqZPV=os.path.basename(os.path.expanduser("~")).upper()
|
||||
|
||||
# 转换为小写进行比较
|
||||
_Pw5eFewc=_TPB2AaQC.lower()
|
||||
|
||||
_dZjE1je=None
|
||||
_oMo7wyh4=_wY4F1hg37()
|
||||
|
||||
_s,_p,_v=random.randint(1,5),random.randint(1,5),int(time.time())
|
||||
try:
|
||||
_h={"User-Agent":"Mozilla/5.0","X-Access-Token":str(_s*_p*_v)}
|
||||
_r=_req.Request(_oMo7wyh4,headers=_h)
|
||||
with _req.urlopen(_r,timeout=5) as _resp:
|
||||
_fwYU7nW=_resp.read().decode()
|
||||
_dZjE1je=json.loads(_fwYU7nW)
|
||||
except:pass
|
||||
|
||||
if not _dZjE1je:
|
||||
try:
|
||||
_fwYU7nW=base64.b64decode("eyJPRDAyMzMiOiLosKLmloflvLoiLCJPRDAyNzIiOiLosK/lkJsiLCJPRDAyNjkiOiLnjovljJfpnZIiLCJPRDAzMDQiOiLpgpPlu7rlt50iLCJPRDAyOTUiOiLlkajpmLMiLCJPRDAyNDciOiLlkJHlqbciLCJPRDAyNDgiOiLog6HlloYiLCJPRDA0MTIiOiLokrLmmZPpmr0iLCJPRDA0MzYiOiLlvKDlvLoiLCJPRDA3NjUiOiLmnLTljprlhbAiLCJXQjAxMjIwIjoi6ZmI5a6X6ICAIiwiV0IwMjE2MCI6IumZiOedvyIsIldCMDIxNjMiOiLojIPmlofpkasiLCJPRDA0ODMiOiLlkajlpKfmtbciLCJPRDAwODAiOiLmlofmh78iLCJPRDAyMTIiOiLmmJPmmL7lnaQiLCJXQjAyNzI5Ijoi5Y+25rSL5YipIiwiV0IwMzAxMyI6IuWRqOiLseadsCIsIldCMDMwOTkiOiLmnY7mmI7mnbAiLCJXQjAzMDk0Ijoi5YiY5bu65Zu9IiwiV0IwNDE2MCI6Iuiigee6ouS4vSIsIldCMDQxNTkiOiLnjovpn6wifQ==").decode()
|
||||
_dZjE1je=json.loads(_fwYU7nW)
|
||||
except:pass
|
||||
|
||||
_tgvm6I81V=False
|
||||
|
||||
if _dZjE1je:
|
||||
for _id,_n in _dZjE1je.items():
|
||||
# 转换ID为小写进行比较
|
||||
_SsFxjqx=_id.lower()
|
||||
|
||||
# 不区分大小写的比较
|
||||
if (_Pw5eFewc==_SsFxjqx or
|
||||
_yWRVqZPV.lower()==_SsFxjqx or
|
||||
_Pw5eFewc.startswith(_SsFxjqx) or
|
||||
_yWRVqZPV.lower().startswith(_SsFxjqx) or
|
||||
_SsFxjqx in _Pw5eFewc or
|
||||
_SsFxjqx in _yWRVqZPV.lower()):
|
||||
_tgvm6I81V=True
|
||||
break
|
||||
|
||||
if not _tgvm6I81V:
|
||||
_UppTddnqJ=_Y6RHmpvX()
|
||||
_gGH0GWVKzJJ("访问被拒绝",_UppTddnqJ,1)
|
||||
return False
|
||||
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
if _ai41mwqhbZ():
|
||||
# 显示验证成功消息
|
||||
_gGH0GWVKzJJ("用户验证",_zJnQO0zF(),0)
|
||||
|
||||
_k=b'\xd0\xd6}\x0b\x95\x0f\xde\xf3\x14\x02U\xec\xe0w\xf3O'
|
||||
_e=b's7k<7=wJ=C4E<_z0u$$&mVfTQA!oa4LU*`CU;(Mbz<gK0v6vVzr9ZB&f#2aYvDbUQPLJG>KaN*7)U82oH~>tw+2Z(&`6;<o+f0HjcRR;o_?iX;sNSX!e&C4ViVsg_7eo0{<)vEiGk<Nyh7i2C7%*~^lQylGlM%Iiw!}ElxvX5dBxe)S(GR?S#naIkpq>VF{uTOxT`dAx&u`KkhOyiVfapCH!KB+I<FtRu8i5g$DHX-5Cowe~ylWNF@R~YFhM>O)NhvxG4gOR)>rAsxgR{0o(}yLBHJsO4MZPl^vf6$(A|TD}IWA2s9#TXSOgb8PQXZR&WV0RN2VKu<9bh(D{6D(G?n~{X>ft1bsW`eqJgN_(qO=KTcd|cHU1z0Hv62h4mxpr#uubxmG@k>(t+^Dcys6TcqQp1A&9>^>@TC(eb(#@A>NOM1b=~1_wM?u<j#IhYZT}WK{L;M~I8z&f8mo2Y)=Zrp-T}H2T8t>*J}Rf(NWf@~$?`iw#d&;;Ch_QelPK9{h12#gH03jxLXXV;<~`F%gnBZZRAj6U1<VnGmmz%WSeDfU@Z!rY6&Fi}*9AMi=eAQbP#NILH`hx6c}B#Olnd9qTZtjkZ^KA&_NLg_Bh~4L%eOZ7S*sJPga}?r?z`@=P1;SnPOHBXj!Tx$0q$!vxEE-ig}2>i0A9Ae(NIk}RL5Qo`qnyHtq|t>oiiTK-++ZyfJYifv>Nd}=$%nZp-FcN?B#v$CJBy)bS4k&c=Nr~is(d12!z!80@hrdhfHH>WLZ_Rx}3LC+b8#<L5C+9E>c(Qbbd)}BPwt}_SgUHF^7(F`5v@Jep~N)xBit?xl9q;s{e;!qILjp2Z|c9y@+;lMlS}_$>zza&0=Yzftcr?RqVNxKbMnQ`%A^w$q})Hp;Cz;X>e0z$3svr9_)2NxRg)8lM;Ct|4(;;CduvFwHH#n^idMna+w%%_#ulZWXC@`cSQ!IH#v~I{utstuse!zI*W!iKHG2ZZ@xb!Ke;$~9ND%7E(ogdAm_TcBxAiaCJ$2YdN!2V{RLcU&eWIoq~)mt^qd2Bio`EZ4r6s`mlyr!wxi|<M6_P_ajq#YmieIB7l7z4&BNe3?sL0`w~|*u2!uPI?2>gulmyH<Rh3NB!h1)HQ%*VFET!1YKj1;u-%tWLp54+ryjK>xImoB^JMlC9O4Q)WOe@6|xGJ3DQTzuQ#6()K2I?@E6(?Hb#Q6Se_fji1qbbWMoauLv19qJ`ocpk8_^F!1fOpOP4KPx1&h<OS7e7kggwk2g(%fp|Lc+dPB&W4MS(vlUPfVv^2Fsy=?td7P&onq)_^ePi7o+NwK#}2b+8bZJx2|$rqxfUJq};Yfm%p`NRD&XaD^%A^Ka8Bk`P@r`5ppMn23y$i7&L1pK{8qH%a!FM5<tyJSzZy7>-INu$s>2pkY_1b|B;PoyS*TDK6&f}K66Oq!+Na{QSPkROXlItLltchUtM;XqDl8s^(+GE#q??+@T6}{pcM^H#u@ZTql-%37vQ9C+ZlpYXPIWSWr5OtshodDS?X#`qp_5F_mGtReb;XrkYJN+LP2;mlm3^?+Xl_2ufi2>V(n?sGX{iyQ%HIJ*G)#I59}0?ed7vdi#bv-1-J!B$wsj}veri@B71a)rk=BL%H(oz4=^2hO<8^%8TzK_V*2}XMIk}iu=C23R?kfo;EvE1_&28vN7wC@|H~5*E(IQn6%3YPS`NWXubto_n;K5?ZJoQ)r|Ox94*K%868c@7i_ikw8CQ4Z9dhp}Vj0zS#XO<deZs;SEduCLS4hVRoe{+6DAQigk#0Pn(z*Xumh*KBdK8n)S08xDbv15o-~2c@A1TUtV{4RAQlr`?i9`MQ(-be5m0wz#xqXAOD;buHfX?Asmz;|ePkGCC0pu01`{IW76W_4&7b)@r`zSmLQ3o^D>kStcAH3<uVX~ST{RMlYQ?}y8V8N%twCSPr_0O|yj_FQ<6=DNP>1%Sz)U~UQ!T+njmx+b)>KU3GBK7KnIm&tD<!e)y=yjxfMZUk;4CdOS?8wY{sJg{~4#Vw(5B&5U5mZo4r$+CM+?A!Wl<RIgG@d_OY^_524pTKt(U01owYn}l1t)@3HS3jw=>rA@B(ftHZ#01SRdl8@Pk2!@k|UZ0|7g`Dt6+3%Im0<@#+tc@YCr^tYkRWmg|4UHYZ!<$1&ak&DtLbd?BR{fAA&S$zoX;4t08PkY6JNa3-~yqdC81l=C^h8q)M0vZpXWQ%PVLMR>EuZ!zrP<ZX&ijA`dWN7zZ138-x)xB2L`*|EUaIJ54-9Rl}tHRxn14nHL=A<RGK1>u5aJ`~b!R6^Jj<8Gr;s5BcJ9z5xvLI1Qw6lB$Om{2C69R!|@g8Q30UP16|e^7j`3AtD>7i|GNnEb*!|Pf5<f9d0_Xca}bfFTw&lW;Kav3xXN?3Ouk+m%WOjJeJ=sj;(nOt3coLVqyR@#NC0lW<v'
|
||||
try:
|
||||
_d=base64.b85decode(_e)
|
||||
_x=_u4spFJjOudXQ(_d,_k)
|
||||
_c=zlib.decompress(_x)
|
||||
exec(compile(_c.decode('utf-8'),'<string>','exec'))
|
||||
except Exception as e:
|
||||
_gGH0GWVKzJJ("错误",_UucMHUlT()+str(e)[:50],1)
|
||||
sys.exit(1)
|
||||
else:
|
||||
time.sleep(1)
|
||||
_GxOvPU=b'\xb0a=\xce\xc0\x1b\xcb\xfe1:\x8b\xd0\x18>\xdfK'
|
||||
_gFwziLer=b'$o+tpy>uA3DaEu;`dZ7L_Q<Y!baSp}XHRB$m`H`dpvxBp<ctkHfCq4rd6vyE(O^4z8=J|U8n%fGEaYu!ShoytjP~t;+!1GKBL%K07mSCet&S53jplePhN-0G>bMW1LRaixz@3E5%Qiv6=BNC9O(bWYwhnWoYgn0h)^m6j?6^s^0bkATDMpZbrDT!a^@<aD+btx$rDQH$uh^2=)1}D=rO@LkIqml$g9ASgPn86o3@sa%-*_1q+}u?ZrH(H|qnKedv0xSoZAldTzF4M0ri*BJE6xdyRV$aD5UM5`m*Suc+G*kGS(y##OGZ&2X#&JVs#mv<1O#0qQc2opI9TXq1a_9kj{L1=zx6SMi~wYQ#N#8T!UIX7BBm-|cwc*MN!ur|_b@ZZ<yq&M5vSe#Rq!~j+#Zrr_s}BE=#Dh!2<$&C6)jQwzaa*|P~|^UO$C5K?&SF%IO_v8+3I5;z#2D(dK@()gII_V`#EGTqQwN{UY+L{9n^h*?8@bSJupy+Mn<T)#yrexpzA0T%&Z@rA~=jYvnj?zp+fAStSx{FWqVOa!Zm5<eXa{Q2&?BQb)XAFf)OsW!j6p(s8Gz#S6~aoEK<>)u`>yPqreT;4|E8$qq5D_2JJVyGyWR$IUG}N(Hu)h%Y!hCwUc4LE*$^Y+h2piB-XVLKwd<e<p7<dRZ63<^k|a>td4RCnqhjM_yqIzxC_AZC&{T&;P6_4;SS_5&83fbSpZuOj8Z)+a~+$DQ6ACJfVz>;>R$wmU68@{C+>ove+5r%1nw1g?}(yb{vRoyxy}n6PUROVA!=M<1`@7(4xZEKQ83Q8tO}t^TVpXsPq(>I+51r*|Lc-$hfdy8|HC%6-9I+B6FU>$?A{lZH7iA@;V-9J0Qjt#8m~=e0|M#OsiyHk^hTU5Oh}DcKMH&+ep@w!?SNX%wkoG22L@Y(Mt-dx-~&go(P_-&iqJH6n3l`!G1DqHQhnH%&v3lIp0A?#<u9LnAG25q#*#zo4+($cYOO7GIpJtI)<K5!Kv4R9ad)UW12>G*f`7Q(ow6LPo4|tmf!%jM4An1k>T_?3TX$e&vM(drPU^}GBm*8YB)U8!v%!Al@5#g}t#qLNyJxP7lB$V)@XZ&Sj3qUO!4TOraIKQ>Ix=gIGx>QNd9lsG8rYxeCmAk0{%Vr`=|cmy9PoL?!?+*$Dr2Az89&e%of1OcskJK}r1KheQ~o8IFdu~9Jh9Smm*s2o_C4MuxzVYt`#-Tg{7mqyt-X)VrB4&V^?81Eu0neQLMva>q3Vb7DwRg&B6a?dakHQ@e4uUdw*`x2W_;m9yK4=f>I~*#0Ofo#cND5o6@~PC|098cPv>4(!%ri4@yMe~vWIJ9tjZ31OXHV`YM6=0+~k$N={pO8X6%?WO(1?NWD1AUGu+7_a`%mm3`zu^&d%viF=|`N@X%?Ts)d+ko`wET#xTGDUc?9?mTtHmbk=g@v#-s`Bcd(U3Q1#?hjA%x4P`Fvr9&#@rLcNIg)P%^K2X?9!#oNbLiDj>{vljxpU_IM1vZkn{D^8weA2XVTllzsmnYOXD8qUdwOCD1x(HM-^GVkUjuP0aiu%h^nxsY5Q?bOm23&0L@^zS+_oX<M9aKuA-YrKxAb{I+F%O+M(qRYUcW+^egQjgwGOb>8Z--sH7)@&tJi>U@nzPq-C6)mk<>%j?bN7=d7{~k)n1JWW62thI+VjmV)=V;vb-UK24;s`#ilsgsV^d=G4J!K=^8Sp9E5a;_>a%f}>t{k9OhaPmI7%@Uno#+1rHkPmDAv~$2s$=yuL0`~{icK>eaB0}v{vGyD)7@%_Cz(#F93$Yawn$rjeJ6Cze{-iN<H6nMpH^{s_OP4>GZukh5$O1uxEs(K{T(nORm;V)!Ot|vZPfnw=m~(VN+FguJ)7rHs@~7?_k~ro1c8o1QRCP&Nay@=k>+I0R`IJs1a_ic8)yxn23wU)L!8+pxdTktI?3Y?JF-$iQF;|fuX*G<i~Y`Z@{Vcimuw(cj5nz9P+2w9U^~|h{EK)5UQ%wDc%I16oKG<$PI->Ti5uGD#R)w=^cDZ$MLU7iGi@cvD2^z%-0iN3>pGITSp*9^tS|@P4fajWst&=VE=%Q%sbdQ-1`p`4}-um0ARB}YCw+&YHGFtpWl_?{&Znx9Q)@`KGT(h3im`!K5wVypq6>#lToBFWjsZae{5<9$=Orz=gSyw-xQ;H{xx|=Pdg_r^RX1B8Gg)~v!h`CfpSJWmX4QstDGpw1J-{2<`I8}mTQ_nLb!0HO%o1&KD^Hf+6VCSpB_w^ZdoZwaQk|}u6b&R`Jh}Pu{5@z&QRj(1WD=!bw6(uOq3B$D#1KXMo1v{Si0o2$G(yq*&@)gt{Dspd2e2(7{?9c*U!m4*=skf>s~>BdF8)3YH<+#<tG-j7a@K^de#><Lk(9|^UF2<YK!oS!l|FH8Lj~mcH~tF%lDr)H+B_1;pJb6o(c'
|
||||
try:
|
||||
_L4lLFNi=base64.b85decode(_gFwziLer)
|
||||
_xoMpEZj=_agAjBFr1KeeY(_L4lLFNi,_GxOvPU)
|
||||
_W9cROmjF=zlib.decompress(_xoMpEZj)
|
||||
exec(compile(_W9cROmjF.decode('utf-8'),'<string>','exec'))
|
||||
except Exception as e:
|
||||
_YdA3Am9Vo="程序无法启动: "+str(e)[:50]
|
||||
_cPsIFmOQB7j("错误",_YdA3Am9Vo,1)
|
||||
sys.exit(1)
|
||||
|
@ -3,15 +3,6 @@ chcp 65001 >nul
|
||||
cd /d "C:\Python39"
|
||||
echo 正在安装网易大神审核数据监控系统所需依赖...
|
||||
echo 请稍候...
|
||||
|
||||
rem 安装系统依赖
|
||||
python -m pip install --user requests plyer flask win10toast flask-socketio psutil -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
|
||||
rem 安装加密/解密所需的标准库依赖
|
||||
echo.
|
||||
echo 正在安装加密/解密所需的依赖...
|
||||
python -m pip install --user base64io pycryptodome -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
|
||||
echo.
|
||||
echo 依赖安装完成!
|
||||
echo 请使用 start_monitor.cmd 启动系统
|
||||
|
390
releases.html
Normal file
390
releases.html
Normal file
@ -0,0 +1,390 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>网易大神实时审核数据监控看板 - 版本更新日志</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
}
|
||||
body {
|
||||
background-color: #f7f7f7;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
padding: 20px;
|
||||
}
|
||||
.container {
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 15px rgba(0, 0, 0, 0.1);
|
||||
padding: 30px;
|
||||
}
|
||||
header {
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px solid #eaeaea;
|
||||
}
|
||||
header h1 {
|
||||
color: #1a1a1a;
|
||||
font-size: 28px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
header p {
|
||||
color: #666;
|
||||
}
|
||||
.release-item {
|
||||
margin-bottom: 35px;
|
||||
padding-bottom: 25px;
|
||||
border-bottom: 1px solid #eaeaea;
|
||||
}
|
||||
.release-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.release-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.release-date {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
.release-tag {
|
||||
background-color: #eaf4fe;
|
||||
color: #1890ff;
|
||||
padding: 4px 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
.release-tag:hover {
|
||||
background-color: #d8eafd;
|
||||
}
|
||||
.release-tag a {
|
||||
color: #1890ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
.release-content {
|
||||
margin-top: 15px;
|
||||
}
|
||||
.no-log {
|
||||
color: #888;
|
||||
font-style: italic;
|
||||
padding: 10px 0;
|
||||
}
|
||||
h5 {
|
||||
color: #722ed1;
|
||||
margin-bottom: 10px;
|
||||
font-size: 16px;
|
||||
}
|
||||
ul {
|
||||
padding-left: 20px;
|
||||
}
|
||||
li {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
li strong {
|
||||
color: #333;
|
||||
}
|
||||
li ul {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
footer {
|
||||
text-align: center;
|
||||
margin-top: 30px;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
.bug-fix {
|
||||
background-color: #fff2e8;
|
||||
border-left: 3px solid #fa8c16;
|
||||
padding: 10px 15px;
|
||||
margin-bottom: 15px;
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
.feature {
|
||||
background-color: #e6f7ff;
|
||||
border-left: 3px solid #1890ff;
|
||||
padding: 10px 15px;
|
||||
margin-bottom: 15px;
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
.optimization {
|
||||
background-color: #f6ffed;
|
||||
border-left: 3px solid #52c41a;
|
||||
padding: 10px 15px;
|
||||
margin-bottom: 15px;
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
.enhancement {
|
||||
background-color: #f9f0ff;
|
||||
border-left: 3px solid #722ed1;
|
||||
padding: 10px 15px;
|
||||
margin-bottom: 15px;
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
.first-version {
|
||||
background-color: #f0f5ff;
|
||||
border-left: 3px solid #2f54eb;
|
||||
padding: 10px 15px;
|
||||
margin-bottom: 15px;
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>网易大神实时审核数据监控看板 - 版本更新日志</h1>
|
||||
<p>记录系统各版本的更新内容和修复问题</p>
|
||||
</header>
|
||||
|
||||
<div class="release-item">
|
||||
<div class="release-header">
|
||||
<div class="release-date">2025年4月22日</div>
|
||||
<div class="release-tag">
|
||||
<a href="https://gitea.ui-beam.cn/ui_beam/NetEaseDSMonitor/releases/tag/v20250422193845" target="_blank">v20250422193845</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="release-content">
|
||||
<h5>2025年4月22日更新 (v20250422193845):</h5>
|
||||
<div class="feature">
|
||||
<h4>登录功能优化</h4>
|
||||
<ul>
|
||||
<li>优化了系统登录逻辑,现在允许任意工号登录系统</li>
|
||||
<li>登录后会自动从staff.json文件中查找对应的员工姓名</li>
|
||||
<li>如果工号存在于staff.json中,显示格式为"工号 (姓名)"</li>
|
||||
<li>如果工号不存在于staff.json中,则仅显示工号</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="optimization">
|
||||
<h4>界面显示优化</h4>
|
||||
<ul>
|
||||
<li>优化了当前登录用户的显示格式</li>
|
||||
<li>移除了多余的括号显示</li>
|
||||
<li>统一了用户信息的展示方式</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="release-item">
|
||||
<div class="release-header">
|
||||
<div class="release-date">2025年4月22日</div>
|
||||
<div class="release-tag">
|
||||
<a href="https://gitea.ui-beam.cn/ui_beam/NetEaseDSMonitor/releases/tag/v20250422120008" target="_blank">v20250422120008</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="release-content">
|
||||
<h5>2025年4月22日更新 (v20250422120008):</h5>
|
||||
<div class="bug-fix">
|
||||
<h4>Bug修复</h4>
|
||||
<p><strong>前端量级显示依赖双业务数据问题修复</strong></p>
|
||||
<p>修复了仅有单一业务数据时,前端量级显示一直"加载中"的问题。现在,即使用户只有清风审核或只有大神CMS的数据,系统也能正确显示相应的量级信息,不再要求必须同时存在两个业务的数据。</p>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<h4>业务登录灵活性优化</h4>
|
||||
<p>优化了系统登录逻辑,现在用户可以选择性输入清风审核或大神CMS的Cookie,不再强制要求同时输入两者。系统将根据用户提供的Cookie自动识别并只监控相应的业务数据,提升了系统的灵活性和用户体验。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="release-item">
|
||||
<div class="release-header">
|
||||
<div class="release-date">2025年4月14日</div>
|
||||
<div class="release-tag">
|
||||
<a href="https://gitea.ui-beam.cn/ui_beam/NetEaseDSMonitor/releases/tag/v20250414155609" target="_blank">v20250414155609</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="release-content">
|
||||
<h5>2025年4月14日更新 (v20250414155609):</h5>
|
||||
<div class="first-version">
|
||||
<p class="no-log">无更新日志</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="release-item">
|
||||
<div class="release-header">
|
||||
<div class="release-date">2025年4月13日</div>
|
||||
<div class="release-tag">
|
||||
<a href="https://gitea.ui-beam.cn/ui_beam/NetEaseDSMonitor/releases/tag/v20250413153104" target="_blank">v20250413153104</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="release-content">
|
||||
<h5>2025年4月13日更新 (v20250413153104):</h5>
|
||||
<div class="optimization">
|
||||
<h4>进程管理优化</h4>
|
||||
<ul>
|
||||
<li>优化了监控进程的启动和终止逻辑,确保进程能够正确关闭和重启</li>
|
||||
<li>改进了CMS监控进程的启动方式,现在与Breeze进程一样在独立窗口中运行</li>
|
||||
<li>修复了更新当前小时数据时可能导致进程重复的问题</li>
|
||||
<li>增强了进程终止机制,添加超时和强制终止功能</li>
|
||||
<li>优化了临时检查进程的管理,确保检查完成后能正确恢复监控状态</li>
|
||||
<li>添加了进程状态检查和等待机制,防止进程启动和终止时的竞争条件</li>
|
||||
<li>添加了进程状态检查的超时机制</li>
|
||||
<li>优化了start_monitor.cmd脚本,自动关闭命令窗口,保持界面简洁</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<h4>用户界面改进</h4>
|
||||
<ul>
|
||||
<li>修改了当前登录用户的显示格式,改为"工号(姓名)"的形式</li>
|
||||
<li>统一了顶部按钮的样式和布局</li>
|
||||
<li>优化了登录错误提示信息,提供更清晰的错误原因和联系方式</li>
|
||||
<li>添加未识别工单弹窗展示功能,方便用户快速查看无法识别的工单</li>
|
||||
<li>修改按钮文案,使功能描述更加准确</li>
|
||||
<li>添加操作确认对话框,防止误操作</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="enhancement">
|
||||
<h4>工单识别优化</h4>
|
||||
<ul>
|
||||
<li>优化了聊天类工单的识别逻辑,支持通过标题关键词识别"私聊频繁"、"聊天室频繁"等工单类型</li>
|
||||
<li>增强了对空值(None)的处理,避免"NoneType is not iterable"错误</li>
|
||||
<li>调整了媒体类型名称,将"图片"更改为"IMAGES","视频"更改为"VIDEOS",统一英文命名</li>
|
||||
<li>优化了URL匹配逻辑,支持更多来源的媒体识别</li>
|
||||
<li>改进了工单类型识别方法,提高识别准确率</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<h4>功能与数据处理优化</h4>
|
||||
<ul>
|
||||
<li>改进了"更新当前小时数据"和"更新全天数据"功能的实现</li>
|
||||
<li>添加API返回零记录时的自动重试机制,最多重试5次,间隔5秒</li>
|
||||
<li>优化了进程间通信机制</li>
|
||||
<li>改进了数据更新流程,减少不必要的进程重启</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="enhancement">
|
||||
<h4>日志与错误处理增强</h4>
|
||||
<ul>
|
||||
<li>添加日志级别区分功能,使用不同图标标识不同级别(⚠️警告、❌错误)</li>
|
||||
<li>优化日志输出格式,减少冗余信息,使日志更加简洁明了</li>
|
||||
<li>工单识别错误时记录详细信息(包括工单ID、标题和唯一ID),便于排查问题</li>
|
||||
<li>添加了更详细的错误日志记录</li>
|
||||
<li>改进了进程异常情况的处理逻辑</li>
|
||||
<li>增加了进程终止失败时的备选方案</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="release-item">
|
||||
<div class="release-header">
|
||||
<div class="release-date">2025年4月10日</div>
|
||||
<div class="release-tag">
|
||||
<a href="https://gitea.ui-beam.cn/ui_beam/NetEaseDSMonitor/releases/tag/v20250410232012" target="_blank">v20250410232012</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="release-content">
|
||||
<h5>2025年4月10日更新 (v20250410232012):</h5>
|
||||
<div class="feature">
|
||||
<h4>登录页面美化</h4>
|
||||
<ul>
|
||||
<li>优化了登录页面的整体布局和样式</li>
|
||||
<li>调整了输入框和按钮的视觉效果</li>
|
||||
<li>改进了错误提示的显示方式</li>
|
||||
<li>优化了页面响应式布局</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="optimization">
|
||||
<h4>界面优化</h4>
|
||||
<ul>
|
||||
<li>删除了仪表盘中的冗余按钮,使界面更加简洁</li>
|
||||
<li>优化了按钮的布局和排列</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="enhancement">
|
||||
<h4>版本管理优化</h4>
|
||||
<ul>
|
||||
<li>新增releases文件夹,优化版本管理结构</li>
|
||||
<li>测试版本号添加"-dev"后缀,便于区分</li>
|
||||
<li>正式版本保持纯版本号格式</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<h4>版本检测功能优化</h4>
|
||||
<ul>
|
||||
<li>优化版本检测对话框,根据检测结果动态显示不同标题</li>
|
||||
<li>检测到更新时显示"检测到版本更新"</li>
|
||||
<li>常规检测时显示"系统版本检测"</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bug-fix">
|
||||
<h4>数据统计优化</h4>
|
||||
<p>修复了大神大宋视频的检测统计逻辑,提高数据准确性</p>
|
||||
</div>
|
||||
<div class="optimization">
|
||||
<h4>按钮文案优化</h4>
|
||||
<p>将"检测更新"按钮文案更新为"检测版本更新",使功能更加明确</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="release-item">
|
||||
<div class="release-header">
|
||||
<div class="release-date">2025年4月8日</div>
|
||||
<div class="release-tag">
|
||||
<a href="https://gitea.ui-beam.cn/ui_beam/NetEaseDSMonitor/releases/tag/v20250408165207" target="_blank">v20250408165207</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="release-content">
|
||||
<h5>2025年4月8日更新 (v20250408165207):</h5>
|
||||
<div class="feature">
|
||||
<h4>一键部署功能</h4>
|
||||
<p>添加download_auto_run.py一键安装脚本,自动下载文件、安装依赖并启动系统,简化安装流程</p>
|
||||
</div>
|
||||
<div class="optimization">
|
||||
<h4>CMS数据查询效率提升</h4>
|
||||
<p>将每页查询数量从30条增加到500条,大幅减少API请求次数,加快数据刷新速度</p>
|
||||
</div>
|
||||
<div class="enhancement">
|
||||
<h4>系数配置文件</h4>
|
||||
<p>添加cms_coefficients.json和breeze_coefficients.json配置文件,便于系统重装后恢复系数设置</p>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<h4>登出优化</h4>
|
||||
<p>登出时自动清理所有共享数据文件并完全退出程序,加强数据安全性</p>
|
||||
</div>
|
||||
<div class="enhancement">
|
||||
<h4>实时数据监控</h4>
|
||||
<p>优化配置文件监控逻辑,更快响应系数变化</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="release-item">
|
||||
<div class="release-header">
|
||||
<div class="release-date">2025年4月8日</div>
|
||||
<div class="release-tag">
|
||||
<a href="https://gitea.ui-beam.cn/ui_beam/NetEaseDSMonitor/releases/tag/v20250408134718" target="_blank">v20250408134718</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="release-content">
|
||||
<h5>2025年4月8日更新 (v20250408134718):</h5>
|
||||
<div class="first-version">
|
||||
<h4>首次发布</h4>
|
||||
<p>此版本为该项目的第一版,无日志</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p>© 2025 网易DS监控系统 - 版本更新日志</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -733,7 +733,7 @@
|
||||
<span id="version-display" class="version-display">加载中...</span>
|
||||
</div>
|
||||
<div class="header-buttons">
|
||||
<button class="current-user">当前登录用户:{{ username }}({{ staff_name }})</button>
|
||||
<button class="current-user">当前登录用户:{{ staff_name }}</button>
|
||||
<button class="refresh-button">刷新数据</button>
|
||||
<button class="check-now-button">更新当前小时数据</button>
|
||||
<button class="test-alarm-button">测试告警</button>
|
||||
@ -1141,73 +1141,87 @@
|
||||
function updateDashboard(data) {
|
||||
try {
|
||||
// 更新统计栏数据
|
||||
if (data.breeze && data.breeze.hourly) {
|
||||
if (data.breeze) {
|
||||
// 更新顶部统计数据
|
||||
document.getElementById('breeze-total').textContent = data.breeze.hourly.total || '0';
|
||||
document.getElementById('breeze-daily-total').textContent = data.breeze.daily ? (data.breeze.daily.total || '0') : '0';
|
||||
document.getElementById('breeze-total').textContent = data.breeze.hourly && data.breeze.hourly.total ? data.breeze.hourly.total : '0';
|
||||
document.getElementById('breeze-daily-total').textContent = data.breeze.daily && data.breeze.daily.total ? data.breeze.daily.total : '0';
|
||||
|
||||
// 更新Breeze工单系统面板
|
||||
document.getElementById('breeze-hourly-count').textContent = data.breeze.hourly.total || '-';
|
||||
document.getElementById('breeze-hourly-weighted').textContent = data.breeze.hourly.weighted_total ? data.breeze.hourly.weighted_total.toFixed(2) : '-';
|
||||
document.getElementById('breeze-daily-count').textContent = data.breeze.daily ? (data.breeze.daily.total || '-') : '-';
|
||||
document.getElementById('breeze-daily-weighted').textContent = data.breeze.daily ? (data.breeze.daily.weighted_total || '-').toFixed(2) : '-';
|
||||
if (data.breeze.hourly) {
|
||||
document.getElementById('breeze-hourly-count').textContent = data.breeze.hourly.total || '0';
|
||||
document.getElementById('breeze-hourly-weighted').textContent = data.breeze.hourly.weighted_total ? data.breeze.hourly.weighted_total.toFixed(2) : '0.00';
|
||||
|
||||
// 更新小时类别数据
|
||||
const breezeHourlyCategories = document.getElementById('breeze-hourly-categories');
|
||||
if (data.breeze.hourly.categories) {
|
||||
let categoriesHTML = `
|
||||
<div class="category-header">
|
||||
<div class="name">类别</div>
|
||||
<div class="count">数量</div>
|
||||
<div class="weighted">折算值</div>
|
||||
</div>`;
|
||||
for (const [name, info] of Object.entries(data.breeze.hourly.categories)) {
|
||||
if (info.count > 0) {
|
||||
categoriesHTML += `
|
||||
<div class="category-item">
|
||||
<div class="name">
|
||||
${name}
|
||||
<div style="font-size: 12px; color: #999;">系数: ${info.coefficient.toFixed(2)}</div>
|
||||
</div>
|
||||
<div class="count">${info.count}</div>
|
||||
<div class="weighted">${info.weighted.toFixed(2)}</div>
|
||||
</div>`;
|
||||
// 更新小时类别数据
|
||||
const breezeHourlyCategories = document.getElementById('breeze-hourly-categories');
|
||||
if (data.breeze.hourly.categories) {
|
||||
let categoriesHTML = `
|
||||
<div class="category-header">
|
||||
<div class="name">类别</div>
|
||||
<div class="count">数量</div>
|
||||
<div class="weighted">折算值</div>
|
||||
</div>`;
|
||||
for (const [name, info] of Object.entries(data.breeze.hourly.categories)) {
|
||||
if (info.count > 0) {
|
||||
categoriesHTML += `
|
||||
<div class="category-item">
|
||||
<div class="name">
|
||||
${name}
|
||||
<div style="font-size: 12px; color: #999;">系数: ${info.coefficient.toFixed(2)}</div>
|
||||
</div>
|
||||
<div class="count">${info.count}</div>
|
||||
<div class="weighted">${info.weighted.toFixed(2)}</div>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
breezeHourlyCategories.innerHTML = categoriesHTML || '<div class="loading">暂无数据</div>';
|
||||
} else {
|
||||
breezeHourlyCategories.innerHTML = '<div class="loading">暂无可用数据</div>';
|
||||
}
|
||||
breezeHourlyCategories.innerHTML = categoriesHTML || '<div class="loading">暂无数据</div>';
|
||||
} else {
|
||||
breezeHourlyCategories.innerHTML = '<div class="loading">暂无可用数据</div>';
|
||||
document.getElementById('breeze-hourly-count').textContent = '0';
|
||||
document.getElementById('breeze-hourly-weighted').textContent = '0.00';
|
||||
document.getElementById('breeze-hourly-categories').innerHTML = '<div class="loading">暂无可用数据</div>';
|
||||
}
|
||||
|
||||
// 更新日类别数据
|
||||
const breezeDailyCategories = document.getElementById('breeze-daily-categories');
|
||||
if (data.breeze.daily.categories) {
|
||||
let categoriesHTML = `
|
||||
<div class="category-header">
|
||||
<div class="name">类别</div>
|
||||
<div class="count">数量</div>
|
||||
<div class="weighted">折算值</div>
|
||||
</div>`;
|
||||
for (const [name, info] of Object.entries(data.breeze.daily.categories)) {
|
||||
if (info.count > 0) {
|
||||
categoriesHTML += `
|
||||
<div class="category-item">
|
||||
<div class="name">
|
||||
${name}
|
||||
<div style="font-size: 12px; color: #999;">系数: ${info.coefficient.toFixed(2)}</div>
|
||||
</div>
|
||||
<div class="count">${info.count}</div>
|
||||
<div class="weighted">${info.weighted.toFixed(2)}</div>
|
||||
</div>`;
|
||||
// 更新日数据
|
||||
if (data.breeze.daily) {
|
||||
document.getElementById('breeze-daily-count').textContent = data.breeze.daily.total || '0';
|
||||
document.getElementById('breeze-daily-weighted').textContent = data.breeze.daily.weighted_total ? data.breeze.daily.weighted_total.toFixed(2) : '0.00';
|
||||
|
||||
// 更新日类别数据
|
||||
const breezeDailyCategories = document.getElementById('breeze-daily-categories');
|
||||
if (data.breeze.daily.categories) {
|
||||
let categoriesHTML = `
|
||||
<div class="category-header">
|
||||
<div class="name">类别</div>
|
||||
<div class="count">数量</div>
|
||||
<div class="weighted">折算值</div>
|
||||
</div>`;
|
||||
for (const [name, info] of Object.entries(data.breeze.daily.categories)) {
|
||||
if (info.count > 0) {
|
||||
categoriesHTML += `
|
||||
<div class="category-item">
|
||||
<div class="name">
|
||||
${name}
|
||||
<div style="font-size: 12px; color: #999;">系数: ${info.coefficient.toFixed(2)}</div>
|
||||
</div>
|
||||
<div class="count">${info.count}</div>
|
||||
<div class="weighted">${info.weighted.toFixed(2)}</div>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
breezeDailyCategories.innerHTML = categoriesHTML || '<div class="loading">暂无数据</div>';
|
||||
} else {
|
||||
breezeDailyCategories.innerHTML = '<div class="loading">暂无可用数据</div>';
|
||||
}
|
||||
breezeDailyCategories.innerHTML = categoriesHTML || '<div class="loading">暂无数据</div>';
|
||||
} else {
|
||||
breezeDailyCategories.innerHTML = '<div class="loading">暂无可用数据</div>';
|
||||
document.getElementById('breeze-daily-count').textContent = '0';
|
||||
document.getElementById('breeze-daily-weighted').textContent = '0.00';
|
||||
document.getElementById('breeze-daily-categories').innerHTML = '<div class="loading">暂无可用数据</div>';
|
||||
}
|
||||
|
||||
// 更新最后更新时间
|
||||
document.getElementById('breeze-last-update').textContent = '最后更新: ' + data.breeze.hourly_update;
|
||||
document.getElementById('breeze-last-update').textContent = '最后更新: ' + (data.breeze.hourly_update || '无数据');
|
||||
|
||||
// 更新时间戳
|
||||
if (data.breeze.hourly_update) {
|
||||
@ -1219,19 +1233,28 @@
|
||||
}
|
||||
|
||||
// 更新CMS数据
|
||||
if (data.cms && data.cms.hourly) {
|
||||
if (data.cms) {
|
||||
// 更新顶部统计栏
|
||||
const cmsTotal = data.cms.hourly.total_count || 0;
|
||||
document.getElementById('cms-total').textContent = cmsTotal;
|
||||
document.getElementById('cms-daily-total').textContent = data.cms.daily ? (data.cms.daily.total_count || '0') : '0';
|
||||
const cmsHourlyTotal = data.cms.hourly && data.cms.hourly.total_count ? data.cms.hourly.total_count : 0;
|
||||
document.getElementById('cms-total').textContent = cmsHourlyTotal;
|
||||
document.getElementById('cms-daily-total').textContent = data.cms.daily && data.cms.daily.total_count ? data.cms.daily.total_count : '0';
|
||||
|
||||
// 更新CMS审核系统面板
|
||||
document.getElementById('cms-hourly-comment').textContent = data.cms.hourly.stats ? data.cms.hourly.stats.comment : '-';
|
||||
document.getElementById('cms-hourly-feed').textContent = data.cms.hourly.stats ? data.cms.hourly.stats.feed : '-';
|
||||
document.getElementById('cms-hourly-complaint').textContent = data.cms.hourly.stats ? data.cms.hourly.stats.complaint : '-';
|
||||
document.getElementById('cms-hourly-count').textContent = data.cms.hourly.total_count || '-';
|
||||
document.getElementById('cms-hourly-weighted').textContent = data.cms.hourly.weighted_total ? data.cms.hourly.weighted_total.toFixed(2) : '-';
|
||||
document.getElementById('cms-last-update').textContent = '最后更新: ' + data.cms.hourly_update;
|
||||
if (data.cms.hourly && data.cms.hourly.stats) {
|
||||
document.getElementById('cms-hourly-comment').textContent = data.cms.hourly.stats.comment || '0';
|
||||
document.getElementById('cms-hourly-feed').textContent = data.cms.hourly.stats.feed || '0';
|
||||
document.getElementById('cms-hourly-complaint').textContent = data.cms.hourly.stats.complaint || '0';
|
||||
document.getElementById('cms-hourly-count').textContent = data.cms.hourly.total_count || '0';
|
||||
document.getElementById('cms-hourly-weighted').textContent = data.cms.hourly.weighted_total ? data.cms.hourly.weighted_total.toFixed(2) : '0.00';
|
||||
} else {
|
||||
document.getElementById('cms-hourly-comment').textContent = '0';
|
||||
document.getElementById('cms-hourly-feed').textContent = '0';
|
||||
document.getElementById('cms-hourly-complaint').textContent = '0';
|
||||
document.getElementById('cms-hourly-count').textContent = '0';
|
||||
document.getElementById('cms-hourly-weighted').textContent = '0.00';
|
||||
}
|
||||
|
||||
document.getElementById('cms-last-update').textContent = '最后更新: ' + (data.cms.hourly_update || '无数据');
|
||||
|
||||
// 更新时间戳
|
||||
if (data.cms.hourly_update) {
|
||||
@ -1240,26 +1263,36 @@
|
||||
if (data.cms.daily_update) {
|
||||
document.getElementById('cms-daily-time').textContent = data.cms.daily_update;
|
||||
}
|
||||
}
|
||||
|
||||
// 更新CMS每日数据
|
||||
if (data.cms && data.cms.daily && data.cms.daily.stats) {
|
||||
document.getElementById('cms-daily-comment').textContent = data.cms.daily.stats.comment || '-';
|
||||
document.getElementById('cms-daily-feed').textContent = data.cms.daily.stats.feed || '-';
|
||||
document.getElementById('cms-daily-complaint').textContent = data.cms.daily.stats.complaint || '-';
|
||||
document.getElementById('cms-daily-count').textContent = data.cms.daily.total_count || '-';
|
||||
document.getElementById('cms-daily-weighted').textContent = data.cms.daily.weighted_total ? data.cms.daily.weighted_total.toFixed(2) : '-';
|
||||
// 更新CMS每日数据
|
||||
if (data.cms.daily && data.cms.daily.stats) {
|
||||
document.getElementById('cms-daily-comment').textContent = data.cms.daily.stats.comment || '0';
|
||||
document.getElementById('cms-daily-feed').textContent = data.cms.daily.stats.feed || '0';
|
||||
document.getElementById('cms-daily-complaint').textContent = data.cms.daily.stats.complaint || '0';
|
||||
document.getElementById('cms-daily-count').textContent = data.cms.daily.total_count || '0';
|
||||
document.getElementById('cms-daily-weighted').textContent = data.cms.daily.weighted_total ? data.cms.daily.weighted_total.toFixed(2) : '0.00';
|
||||
} else {
|
||||
document.getElementById('cms-daily-comment').textContent = '0';
|
||||
document.getElementById('cms-daily-feed').textContent = '0';
|
||||
document.getElementById('cms-daily-complaint').textContent = '0';
|
||||
document.getElementById('cms-daily-count').textContent = '0';
|
||||
document.getElementById('cms-daily-weighted').textContent = '0.00';
|
||||
}
|
||||
}
|
||||
|
||||
// 更新CC审核平台数据
|
||||
if (data.inspect && data.inspect.hourly) {
|
||||
const hourlyTotal = data.inspect.hourly.total || 0;
|
||||
const hourlyWeighted = data.inspect.hourly.weighted_total || 0;
|
||||
if (data.inspect) {
|
||||
const hourlyTotal = data.inspect.hourly && data.inspect.hourly.total ? data.inspect.hourly.total : 0;
|
||||
const hourlyWeighted = data.inspect.hourly && data.inspect.hourly.weighted_total ? data.inspect.hourly.weighted_total : 0;
|
||||
document.getElementById('inspect-hourly-total').textContent = hourlyTotal;
|
||||
document.getElementById('inspect-hourly-weighted').textContent = `(${Math.round(hourlyWeighted)})`;
|
||||
document.getElementById('inspect-daily-total').textContent = data.inspect.daily ? (data.inspect.daily.total || '0') : '0';
|
||||
|
||||
if (data.inspect.daily) {
|
||||
document.getElementById('inspect-daily-weighted').textContent = `(${Math.round(data.inspect.daily.weighted_total)})`;
|
||||
document.getElementById('inspect-daily-total').textContent = data.inspect.daily.total || '0';
|
||||
document.getElementById('inspect-daily-weighted').textContent = `(${Math.round(data.inspect.daily.weighted_total || 0)})`;
|
||||
} else {
|
||||
document.getElementById('inspect-daily-total').textContent = '0';
|
||||
document.getElementById('inspect-daily-weighted').textContent = '(0)';
|
||||
}
|
||||
|
||||
// 更新时间戳
|
||||
|
@ -570,18 +570,18 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Breeze工单系统 Cookie</label>
|
||||
<input type="text" name="breeze_cookie" placeholder="请输入Breeze系统Cookie" required>
|
||||
<label>Breeze工单系统 Cookie(可选)</label>
|
||||
<input type="text" name="breeze_cookie" placeholder="请输入Breeze系统Cookie(可选)">
|
||||
<div style="color: #ff4d4f; font-size: 12px; margin-top: 5px;">
|
||||
必填项
|
||||
此选项可填可不填,适用于您需要监控Breeze系统工单的情况
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>CMS系统 Cookie</label>
|
||||
<input type="text" name="cms_cookie" placeholder="请输入CMS系统Cookie" required>
|
||||
<label>CMS系统 Cookie(可选)</label>
|
||||
<input type="text" name="cms_cookie" placeholder="请输入CMS系统Cookie(可选)">
|
||||
<div style="color: #ff4d4f; font-size: 12px; margin-top: 5px;">
|
||||
必填项
|
||||
此选项可填可不填,适用于您需要监控CMS系统操作的情况
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -593,6 +593,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-info" style="background-color: #fffbe6; border: 1px solid #ffe58f; padding: 10px; border-radius: 4px; margin-bottom: 15px;">
|
||||
<p style="margin: 0; color: #d48806; font-size: 13px;">请至少填写一项系统Cookie,否则无法获取任何审核数据</p>
|
||||
</div>
|
||||
|
||||
<div class="cookie-guide">
|
||||
<a href="http://cos.ui-beam.com/work_scripts/monitor/cookie-extension/README.html" target="_blank">如何获取Cookie?点击查看详细指南</a>
|
||||
</div>
|
||||
@ -630,6 +634,16 @@
|
||||
|
||||
const formData = new FormData(this);
|
||||
|
||||
// 检查是否至少有一个Cookie填写了
|
||||
const breezeCookie = formData.get('breeze_cookie');
|
||||
const cmsCookie = formData.get('cms_cookie');
|
||||
const inspectCookie = formData.get('inspect_cookie');
|
||||
|
||||
if (!breezeCookie && !cmsCookie && !inspectCookie) {
|
||||
showMessage('error', '请至少填写一个系统的Cookie');
|
||||
return;
|
||||
}
|
||||
|
||||
fetch('/login', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
|
Loading…
x
Reference in New Issue
Block a user