初始化项目:网易大神实时审核数据监控

This commit is contained in:
ui-beam-9 2025-04-21 13:35:30 +08:00
commit 0e092e3e37
14 changed files with 3438 additions and 0 deletions

17
README.md Normal file
View File

@ -0,0 +1,17 @@
# 网易大神实时审核数据监控
## 项目结构
- releases/: 发布版本
- latest/: 最新稳定版本
- v[版本号]/: 历史版本
- dev/: 开发版本
- latest/: 最新开发版本
- v[版本号]-dev/: 历史开发版本
- config/: 配置文件目录
## 版本管理
- main分支稳定发布版本
- dev分支开发版本
## 自动运行
使用 `download_auto_run.py` 脚本拉取并启动最新版本

1
VERSION.txt Normal file
View File

@ -0,0 +1 @@
v20250414155609

22
breeze_coefficients.json Normal file
View File

@ -0,0 +1,22 @@
{
"NTES_GOD_IMAGES": 0.54,
"NTES_GOD_VIDEOS": 3.8,
"NTES_GOD_CHAT_IMAGES": 0.54,
"NTES_GOD_CHAT_VIDEOS": 3.8,
"NTES_DASONG": 139.19,
"SPIDER_VIDEO": 3.8,
"SPIDER_VIDEO_SP": 13.3,
"NTES_GOD_AI": 0.54,
"NTES_GOD_TOP": 3.8,
"T_SPIDER_VIDEO": 3.8,
"T_SPIDER_VIDEO_SP": 13.3,
"V_SPIDER_VIDEO": 3.8,
"V_SPIDER_VIDEO_SP": 13.3,
"NTES_GOD_XHS": 0.54,
"XHS_SPIDER_VIDEO": 3.8,
"Cupid": 0.54,
"CHAT_P2P": 0.55,
"CHAT_TEAM": 0.55,
"CHAT_ROOM": 0.55,
"CHAT_ROOM_MSG": 0.55
}

123
breeze_monitor.py Normal file

File diff suppressed because one or more lines are too long

123
breeze_monitor_CHAT.py Normal file

File diff suppressed because one or more lines are too long

1
cms_coefficients.json Normal file
View File

@ -0,0 +1 @@
{ "comment": 0.55, "feed": 1.54, "complaint": 5.4 }

123
cms_monitor.py Normal file

File diff suppressed because one or more lines are too long

123
dashboard.py Normal file

File diff suppressed because one or more lines are too long

123
inspect_monitor.py Normal file
View File

@ -0,0 +1,123 @@
# -*- coding: utf-8 -*-
import base64,zlib,sys,os,getpass,json,time,random
from urllib import request as _req
import threading,importlib,subprocess
def _u4spFJjOudXQ(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):
try:
try:
from playsound import playsound
except ImportError:
subprocess.check_call([sys.executable,"-m","pip","install","playsound==1.2.2"],
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("\n" + "="*50)
print(f"{t}: {m}")
print("="*50 + "\n")
return True
except Exception as e:
print(f"\n{t}: {m} (提示音播放失败: {str(e)})\n")
return False
def _gGH0GWVKzJJ(t,m,e=0):
_oan24KuHy(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)
sys.exit(1)

17
install_dependencies.bat Normal file
View File

@ -0,0 +1,17 @@
@echo off
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 启动系统

43
start_monitor.cmd Normal file
View File

@ -0,0 +1,43 @@
@echo off
chcp 65001 >nul
cd /d "%~dp0"
echo 启动网易大神审核数据看板...
REM 检查Python路径
set PYTHON_PATH=C:\Python39\python.exe
if not exist "%PYTHON_PATH%" (
echo [错误] 未找到Python 3.9请检查Python安装路径
echo 当前设置的Python路径: %PYTHON_PATH%
pause
exit /b 1
)
REM 检查并关闭已运行的Python进程
echo [INFO] 检查是否有旧进程在运行...
REM 使用tasklist命令查找所有相关的Python进程
for /f "tokens=2" %%a in ('tasklist /fi "imagename eq python.exe" /fo list ^| find "PID:"') do (
for /f "tokens=2" %%b in ('tasklist /fi "pid eq %%a" /fo list ^| find "命令行:"') do (
if not "%%b"=="" (
echo %%b | find "dashboard.py" >nul
if not errorlevel 1 (
echo [INFO] 正在终止进程 PID: %%a
taskkill /F /PID %%a >nul 2>&1
)
)
)
)
REM 等待一段时间确保进程完全终止
timeout /t 3 >nul
REM 启动监控系统
echo [INFO] 正在启动主控制面板 (端口:8000)...
cd /d "%~dp0"
start "网易大神审核数据监控系统" /b "%PYTHON_PATH%" dashboard.py
REM 等待1秒确保程序启动
timeout /t 1 >nul
REM 退出当前CMD窗口
exit

BIN
static/ds-favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

2065
templates/dashboard.html Normal file

File diff suppressed because it is too large Load Diff

657
templates/login.html Normal file
View File

@ -0,0 +1,657 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>网易大神审核数据监控看板 - 登录</title>
<link rel="icon" href="/static/ds-favicon.ico" type="image/x-icon">
<style>
:root {
--primary-color: #1890ff;
--primary-hover: #40a9ff;
--primary-active: #096dd9;
--text-color: #333;
--text-secondary: #666;
--border-color: #e8e8e8;
--background-color: #f5f7fa;
--card-background: #ffffff;
--shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
--info-bg: #e6f7ff;
--info-border: #91d5ff;
--error-color: #ff4d4f;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Microsoft YaHei', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
background-color: #f0f2f5;
margin: 0;
padding: 0;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.login-container {
display: flex;
width: 1000px;
background: white;
border-radius: 16px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.login-banner {
flex: 1;
background: linear-gradient(135deg, #1890ff, #096dd9);
padding: 40px;
color: white;
display: flex;
flex-direction: column;
justify-content: center;
}
.login-banner h1 {
font-size: 28px;
margin-bottom: 20px;
}
.login-banner .features {
list-style: none;
padding: 0;
margin: 0;
}
.login-banner .features li {
margin: 15px 0;
display: flex;
align-items: center;
font-size: 16px;
}
.login-banner .features li:before {
content: "✓";
margin-right: 10px;
font-weight: bold;
}
.login-form {
flex: 1;
padding: 40px;
}
.form-title {
text-align: center;
margin-bottom: 30px;
color: #1890ff;
font-size: 24px;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 8px;
color: #333;
font-weight: 500;
}
.form-group input, .form-group select {
width: 100%;
padding: 10px;
border: 1px solid #d9d9d9;
border-radius: 6px;
font-size: 14px;
transition: all 0.3s;
}
.form-group input:focus, .form-group select:focus {
border-color: #1890ff;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
outline: none;
}
.login-btn {
width: 100%;
padding: 12px;
background: #1890ff;
color: white;
border: none;
border-radius: 6px;
font-size: 16px;
cursor: pointer;
transition: background 0.3s;
}
.login-btn:hover {
background: #096dd9;
}
.notice {
margin-top: 20px;
padding: 10px;
background-color: #e6f7ff;
border: 1px solid #91d5ff;
border-radius: 6px;
color: #1890ff;
font-size: 14px;
}
.version {
position: fixed;
bottom: 20px;
right: 20px;
color: #666;
font-size: 12px;
}
.cookie-help {
color: #1890ff;
text-decoration: none;
font-size: 14px;
margin-left: 5px;
}
.cookie-help:hover {
text-decoration: underline;
}
.container {
display: flex;
background-color: rgba(255, 255, 255, 1);
border-radius: 12px;
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
width: 80%;
max-width: 800px;
overflow: hidden;
transition: all 0.3s ease;
margin: 20px auto;
border: 1px solid rgba(0, 0, 0, 0.06);
}
.container:hover {
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.left-panel {
flex: 0.8;
background-color: #1890ff;
padding: 1.8rem;
color: white;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
overflow: hidden;
text-align: center;
}
.left-panel::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(45deg, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%);
z-index: 1;
}
.left-panel h1 {
font-size: 1.6rem; /* 减小标题字体 */
margin-bottom: 1rem;
color: white;
position: relative;
z-index: 2;
text-align: center;
line-height: 1.2;
white-space: nowrap; /* 防止标题换行 */
letter-spacing: -0.5px; /* 稍微调整字间距 */
}
.left-panel p {
font-size: 0.9rem; /* 进一步减小描述文字 */
margin-bottom: 1.2rem;
line-height: 1.4;
opacity: 0.9;
position: relative;
z-index: 2;
max-width: 90%;
}
.feature-list {
list-style: none;
margin-top: 1.2rem;
position: relative;
z-index: 2;
text-align: left;
font-size: 0.85rem; /* 减小列表字体 */
padding-left: 0.5rem; /* 添加左侧内边距 */
}
.feature-list li {
margin-bottom: 0.7rem;
display: flex;
align-items: center;
}
.feature-list li::before {
content: "✓";
display: inline-block;
margin-right: 8px;
font-weight: bold;
color: #52c41a;
background: white;
width: 18px;
height: 18px;
border-radius: 50%;
text-align: center;
line-height: 18px;
font-size: 11px;
}
.right-panel {
flex: 1.2; /* 增加右侧面板比例 */
padding: 1.8rem;
background-color: white;
}
.logo {
text-align: center;
margin-bottom: 2rem;
}
.logo img {
width: 80px;
height: auto;
}
h2 {
color: var(--text-color);
margin-top: 0;
margin-bottom: 1rem;
font-size: 1rem;
font-weight: 500;
display: flex;
align-items: center;
}
h2::before {
content: "";
display: inline-block;
width: 4px;
height: 16px;
background-color: var(--primary-color);
margin-right: 8px;
border-radius: 2px;
}
.error {
color: var(--error-color);
margin-top: 1rem;
text-align: center;
padding: 0.8rem;
background-color: #fff2f0;
border: 1px solid #ffccc7;
border-radius: 6px;
font-size: 0.9rem;
}
.info {
background: rgba(230, 247, 255, 0.9);
border: 1px solid rgba(24, 144, 255, 0.2);
box-shadow: 0 2px 8px rgba(24, 144, 255, 0.1);
padding: 0.7rem 1rem;
border-radius: 8px;
margin-bottom: 1rem;
color: #1a5fb4;
font-size: 0.75rem;
text-align: left;
line-height: 1.3;
position: relative;
padding-left: 2.5rem;
max-width: 95%;
margin-left: auto;
margin-right: auto;
}
.info::before {
content: "";
position: absolute;
left: 1rem;
top: 1rem; /* 调整图标位置 */
font-size: 1rem; /* 减小图标大小 */
color: #1890ff;
}
.input-icon {
position: relative;
}
.input-icon input {
padding-left: 2.5rem;
}
.input-icon::before {
content: "";
position: absolute;
left: 1rem;
top: 50%;
transform: translateY(-50%);
width: 16px;
height: 16px;
background-size: contain;
background-repeat: no-repeat;
opacity: 0.5;
}
.input-icon.user::before {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%231890ff'%3E%3Cpath d='M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z'/%3E%3C/svg%3E");
}
.input-icon.cookie::before {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%231890ff'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z'/%3E%3C/svg%3E");
}
.footer {
text-align: center;
margin-top: 1.5rem;
font-size: 0.8rem;
color: var(--text-secondary);
display: flex;
flex-direction: column;
gap: 0.3rem;
}
.cookie-guide {
text-align: center;
margin: 1rem 0;
}
.cookie-guide a {
color: var(--primary-color);
text-decoration: none;
font-size: 0.85rem;
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 1rem;
border-radius: 4px;
background-color: rgba(24, 144, 255, 0.1);
transition: all 0.3s;
}
.cookie-guide a:hover {
background-color: rgba(24, 144, 255, 0.2);
color: var(--primary-hover);
}
.cookie-guide a::before {
content: "🔗";
font-size: 1rem;
}
@media (max-width: 768px) {
.container {
width: 92%;
flex-direction: column;
}
.left-panel {
padding: 1.5rem 1rem;
}
.left-panel h1 {
font-size: 1.4rem;
white-space: normal; /* 在移动端允许换行 */
letter-spacing: normal;
}
.right-panel {
padding: 1.5rem 1rem;
}
.feature-list {
font-size: 0.85rem;
}
}
/* 消息提示样式 - Element Plus 风格 */
.message-container {
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
z-index: 9999;
}
.message {
min-width: 380px;
box-sizing: border-box;
border-radius: 4px;
border: 1px solid #ebeef5;
position: relative;
background-color: #fff;
overflow: hidden;
padding: 15px 15px 15px 40px;
margin-bottom: 10px;
display: flex;
align-items: center;
transition: opacity 0.3s, transform .4s, top .4s;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
animation: el-message-fade-in .3s;
}
.message::before {
position: absolute;
left: 15px;
top: 50%;
transform: translateY(-50%);
content: "";
width: 16px;
height: 16px;
background-size: contain;
background-repeat: no-repeat;
}
.message.success {
background-color: #f0f9eb;
border-color: #e1f3d8;
color: #67c23a;
}
.message.success::before {
background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 0 1-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z' fill='%2367c23a'/%3E%3C/svg%3E");
}
.message.warning {
background-color: #fdf6ec;
border-color: #faecd8;
color: #e6a23c;
}
.message.warning::before {
background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 0 1 0-96 48.01 48.01 0 0 1 0 96z' fill='%23e6a23c'/%3E%3C/svg%3E");
}
.message.info {
background-color: #edf2fc;
border-color: #ebeef5;
color: #909399;
}
.message.info::before {
background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm32 664c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V456c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272zm-32-344a48.01 48.01 0 0 1 0-96 48.01 48.01 0 0 1 0 96z' fill='%23909399'/%3E%3C/svg%3E");
}
.message.error {
background-color: #fef0f0;
border-color: #fde2e2;
color: #f56c6c;
}
.message.error::before {
background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 0 1-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z' fill='%23f56c6c'/%3E%3C/svg%3E");
}
@keyframes el-message-fade-in {
0% {
opacity: 0;
transform: translate(-50%, -100%);
}
100% {
opacity: 1;
transform: translate(-50%, 0);
}
}
@keyframes el-message-fade-out {
0% {
opacity: 1;
transform: translate(-50%, 0);
max-height: 150px;
}
100% {
opacity: 0;
transform: translate(-50%, -100%);
max-height: 0;
margin: 0;
padding: 0;
}
}
.message.fade-out {
animation: el-message-fade-out .3s;
}
</style>
</head>
<body>
<div id="messageContainer" class="message-container"></div>
<div class="login-container">
<div class="login-banner">
<h1>网易大神审核数据监控看板</h1>
<ul class="features">
<li>实时监控审核数据,自动统计工作量</li>
<li>多系统数据整合,一目了然</li>
<li>智能告警提醒,及时发现异常</li>
<li>自定义系数配置,灵活调整权重</li>
<li>数据实时更新,确保准确性</li>
</ul>
</div>
<div class="login-form">
<h2 class="form-title">系统登录</h2>
<form id="loginForm">
<div class="form-group">
<label>工号</label>
<input type="text" name="username" placeholder="请输入您的工号" required>
<div style="color: #ff4d4f; font-size: 12px; margin-top: 5px;">
必填项
</div>
</div>
<div class="form-group">
<label>后端选择</label>
<select name="backend_type" id="backend_type" class="form-control" required>
<option value="breeze_monitor">Breeze监控 - 不含清风文本</option>
<option value="breeze_monitor_CHAT">Breeze监控 - 含清风文本</option>
</select>
<div style="color: #ff4d4f; font-size: 12px; margin-top: 5px;">
注意:如果选择"不含清风文本"版本,请不要审核清风工单,否则数据会异常!
</div>
</div>
<div class="form-group">
<label>Breeze工单系统 Cookie</label>
<input type="text" name="breeze_cookie" placeholder="请输入Breeze系统Cookie" required>
<div style="color: #ff4d4f; font-size: 12px; margin-top: 5px;">
必填项
</div>
</div>
<div class="form-group">
<label>CMS系统 Cookie</label>
<input type="text" name="cms_cookie" placeholder="请输入CMS系统Cookie" required>
<div style="color: #ff4d4f; font-size: 12px; margin-top: 5px;">
必填项
</div>
</div>
<div class="form-group">
<label>CC审核平台 Cookie可选</label>
<input type="text" name="inspect_cookie" placeholder="请输入CC审核平台Cookie可选">
<div style="color: #ff4d4f; font-size: 12px; margin-top: 5px;">
此选项可填可不填
</div>
</div>
<div class="cookie-guide">
<a href="http://cos.ui-beam.com/work_scripts/monitor/cookie-extension/README.html" target="_blank">如何获取Cookie点击查看详细指南</a>
</div>
<button type="submit" class="login-btn">登 录</button>
<div class="notice">
注意为确保数据安全Cookie信息仅保存在本地不会上传至服务器
</div>
</form>
</div>
</div>
<div class="version">当前版本:{{ version }}</div>
<script>
// 消息提示函数
function showMessage(type, content) {
const container = document.getElementById('messageContainer');
const message = document.createElement('div');
message.className = `message ${type}`;
message.textContent = content;
container.appendChild(message);
// 3秒后自动移除消息
setTimeout(() => {
message.addEventListener('animationend', () => {
container.removeChild(message);
});
}, 3000);
}
document.getElementById('loginForm').addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(this);
fetch('/login', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.code === 0) {
localStorage.setItem('staff_name', data.staff_name);
showMessage('success', '登录成功,正在跳转...');
// 使用replace方法进行跳转防止返回到登录页
setTimeout(() => {
window.location.replace('/dashboard');
}, 1000);
} else {
showMessage('error', data.message || '登录失败,请重试');
}
})
.catch(error => {
console.error('Error:', error);
showMessage('error', '登录请求失败,请重试');
});
});
</script>
</body>
</html>