406 lines
28 KiB
HTML
406 lines
28 KiB
HTML
{% raw %}<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Cookie监控管理系统</title>
|
|
<link rel="stylesheet" href="/static/css/style.css">
|
|
<link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css">
|
|
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
|
|
<script src="https://unpkg.com/element-plus"></script>
|
|
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
|
|
</head>
|
|
<body>
|
|
<div id="app">
|
|
<div class="container">
|
|
<el-container>
|
|
<el-header>
|
|
<div class="header-left">
|
|
<h1>网站监控仪表板</h1>
|
|
<el-button v-if="activeTab === 'settings'" @click="activeTab = 'dashboard'" type="primary" plain>返回监控首页</el-button>
|
|
</div>
|
|
<div class="header-right">
|
|
<div v-if="activeTab === 'dashboard'" class="auto-refresh-indicator">
|
|
<el-icon class="rotating-icon"><Refresh /></el-icon>
|
|
<span class="refresh-text">{{ countdown }}秒后自动刷新</span>
|
|
</div>
|
|
<span class="header-stat" v-if="activeTab === 'dashboard'">网站总数:<b>{{ stats.totalWebsites }}</b></span>
|
|
<el-dropdown @command="handleDropdownCommand" v-if="!isAdmin">
|
|
<el-button link type="text" style="color: rgba(255,255,255,0.8); font-size: 18px">
|
|
<el-icon><arrow-down /></el-icon>
|
|
</el-button>
|
|
<template #dropdown>
|
|
<el-dropdown-menu>
|
|
<el-dropdown-item command="login"><el-icon><Lock /></el-icon> 登录后台</el-dropdown-item>
|
|
</el-dropdown-menu>
|
|
</template>
|
|
</el-dropdown>
|
|
<el-dropdown @command="handleAdminCommand" v-else>
|
|
<el-button type="success" plain>后台管理 <el-icon><arrow-down /></el-icon></el-button>
|
|
<template #dropdown>
|
|
<el-dropdown-menu>
|
|
<el-dropdown-item command="settings">系统设置</el-dropdown-item>
|
|
<el-dropdown-item command="dashboard">监控首页</el-dropdown-item>
|
|
<el-dropdown-item command="logout" divided>退出登录</el-dropdown-item>
|
|
</el-dropdown-menu>
|
|
</template>
|
|
</el-dropdown>
|
|
</div>
|
|
</el-header>
|
|
|
|
<el-main>
|
|
<!-- 监控仪表板 -->
|
|
<div v-if="activeTab === 'dashboard'">
|
|
|
|
<div v-for="user in dashboardData" :key="user.id" class="user-section">
|
|
<div class="user-header">
|
|
<h3>{{ user.name }}</h3>
|
|
<el-tag :type="user.websites.some(w => w.loginStatus === 'success') ? 'success' : user.websites.some(w => w.loginStatus === 'failed') ? 'danger' : 'info'">
|
|
{{ user.websites.filter(w => w.loginStatus === 'success').length }}/{{ user.websites.length }} 在线
|
|
</el-tag>
|
|
</div>
|
|
|
|
<el-table :data="user.websites" style="width: 100%; margin-bottom: 20px">
|
|
<el-table-column label="启用状态" width="90">
|
|
<template #default="scope">
|
|
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'" size="small">
|
|
{{ scope.row.status === 1 ? '启用' : '禁用' }}
|
|
</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="name" label="网站名称" width="150"></el-table-column>
|
|
<el-table-column prop="url" label="URL" width="250">
|
|
<template #default="scope">
|
|
<el-link :href="scope.row.url" target="_blank" type="primary">{{ scope.row.url }}</el-link>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="网络状态" width="100">
|
|
<template #default="scope">
|
|
<el-tag :type="scope.row.networkStatus === 'online' ? 'success' : scope.row.networkStatus === 'offline' ? 'danger' : 'info'">
|
|
{{ scope.row.networkStatus === 'online' ? '在线' : scope.row.networkStatus === 'offline' ? '离线' : '未知' }}
|
|
</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="登录状态" width="100">
|
|
<template #default="scope">
|
|
<el-tag :type="scope.row.loginStatus === 'success' ? 'success' : scope.row.loginStatus === 'failed' ? 'danger' : scope.row.loginStatus === 'checking' ? 'warning' : 'info'">
|
|
{{ scope.row.loginStatus === 'success' ? '已登录' : scope.row.loginStatus === 'failed' ? '未登录' : scope.row.loginStatus === 'checking' ? '检测中' : '未检测' }}
|
|
</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="lastCheckTime" label="最后检测" width="180"></el-table-column>
|
|
<el-table-column label="操作" width="200">
|
|
<template #default="scope">
|
|
<el-button size="small" type="primary" @click="checkLogin(scope.row)" :loading="scope.row.loginStatus === 'checking'" :disabled="scope.row.loginStatus === 'checking'">
|
|
{{ scope.row.loginStatus === 'checking' ? '检测中' : '检测登录' }}
|
|
</el-button>
|
|
<el-button size="small" type="success" @click="manageWebsite(scope.row)" v-if="scope.row.loginStatus === 'success'">管理</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</div>
|
|
|
|
<el-empty v-if="dashboardData.length === 0" description="暂无网站数据"></el-empty>
|
|
|
|
<div class="dashboard-footer">
|
|
<p>免责声明:本系统仅用于Cookie状态监控和自动化管理,不对任何网站数据承担责任。请确保您有权访问和管理相关网站账号。</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 网站管理 -->
|
|
<div v-if="activeTab === 'website_manage'">
|
|
<div class="website-manage-header">
|
|
<el-button @click="activeTab = 'dashboard'" type="info">返回监控首页</el-button>
|
|
<h2>网站管理 - {{ currentWebsite?.name }}</h2>
|
|
</div>
|
|
|
|
<el-tabs v-model="manageTab">
|
|
<el-tab-pane label="Cookie管理" name="cookies">
|
|
<el-button @click="showAddCookieDialog" type="primary" size="small">添加Cookie</el-button>
|
|
<el-button @click="loadWebsiteCookies" size="small">刷新</el-button>
|
|
<el-table :data="websiteCookies" style="width: 100%; margin-top: 10px">
|
|
<el-table-column prop="name" label="名称" width="200"></el-table-column>
|
|
<el-table-column prop="value" label="值" width="300">
|
|
<template #default="scope">
|
|
<span class="cookie-value">{{ maskCookieValue(scope.row.value) }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="domain" label="域名" width="150"></el-table-column>
|
|
<el-table-column label="操作" width="150">
|
|
<template #default="scope">
|
|
<el-button size="small" @click="editCookie(scope.row)">编辑</el-button>
|
|
<el-button size="small" type="danger" @click="deleteCookie(scope.row)">删除</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</el-tab-pane>
|
|
<el-tab-pane label="网站设置" name="settings">
|
|
<el-form :model="websiteForm" label-width="120px" style="max-width: 500px">
|
|
<el-form-item label="网站名称">
|
|
<el-input v-model="websiteForm.name"></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="URL">
|
|
<el-input v-model="websiteForm.url"></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="登录检测选择器">
|
|
<el-input v-model="websiteForm.login_check_selector"></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="登录成功文本">
|
|
<el-input v-model="websiteForm.success_text"></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="检测间隔(分钟)">
|
|
<el-input-number v-model="websiteForm.interval_minutes" :min="1" :max="1440"></el-input-number>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-button type="primary" @click="saveWebsiteSettings">保存设置</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
</el-tab-pane>
|
|
<el-tab-pane label="检测记录" name="history">
|
|
<el-button @click="loadWebsiteDetections" type="primary" size="small">刷新</el-button>
|
|
<el-table :data="websiteDetections" style="width: 100%; margin-top: 10px">
|
|
<el-table-column prop="status" label="状态" width="80">
|
|
<template #default="scope">
|
|
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
|
|
{{ scope.row.status === 1 ? '成功' : '失败' }}
|
|
</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="message" label="消息"></el-table-column>
|
|
<el-table-column prop="created_at" label="时间" width="180"></el-table-column>
|
|
</el-table>
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
</div>
|
|
|
|
<!-- 系统设置页面 -->
|
|
<div v-if="activeTab === 'settings'">
|
|
<h2>系统设置</h2>
|
|
<el-tabs v-model="settingsTab">
|
|
<el-tab-pane label="用户管理" name="users">
|
|
<el-button @click="showAddUserDialog" type="primary" size="small" style="margin-bottom: 10px">添加用户</el-button>
|
|
<el-table :data="users" style="width: 100%">
|
|
<el-table-column prop="id" label="ID" width="80"></el-table-column>
|
|
<el-table-column prop="name" label="用户名" width="150"></el-table-column>
|
|
<el-table-column prop="iyuu_token" label="爱语飞飞令牌" width="200"></el-table-column>
|
|
<el-table-column prop="max_fail_count" label="最大失败次数" width="120"></el-table-column>
|
|
<el-table-column prop="website_count" label="网站数量" width="100"></el-table-column>
|
|
<el-table-column label="操作">
|
|
<template #default="scope">
|
|
<el-button size="small" @click="editUser(scope.row)">编辑</el-button>
|
|
<el-button size="small" type="warning" @click="manageUserWebsites(scope.row)">管理网站</el-button>
|
|
<el-button size="small" type="danger" @click="deleteUser(scope.row)">删除</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</el-tab-pane>
|
|
|
|
<el-tab-pane label="网站管理" name="websites">
|
|
<div class="filter-form">
|
|
<el-select v-model="filterWebsiteUser" placeholder="选择用户" @change="loadWebsites">
|
|
<el-option label="全部用户" :value="null"></el-option>
|
|
<el-option v-for="user in users" :key="user.id" :label="user.name" :value="user.id"></el-option>
|
|
</el-select>
|
|
<el-button @click="showAddWebsiteDialog" type="primary" size="small" style="margin-left: 10px">添加网站</el-button>
|
|
</div>
|
|
<el-table :data="filteredWebsites" style="width: 100%">
|
|
<el-table-column prop="id" label="ID" width="80"></el-table-column>
|
|
<el-table-column prop="user_id" label="用户ID" width="100"></el-table-column>
|
|
<el-table-column prop="name" label="网站名称" width="150"></el-table-column>
|
|
<el-table-column prop="url" label="URL" width="250"></el-table-column>
|
|
<el-table-column prop="interval_minutes" label="间隔(分钟)" width="100"></el-table-column>
|
|
<el-table-column prop="status" label="状态" width="80">
|
|
<template #default="scope">
|
|
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
|
|
{{ scope.row.status === 1 ? '启用' : '禁用' }}
|
|
</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="操作">
|
|
<template #default="scope">
|
|
<el-button size="small" @click="editWebsite(scope.row)">编辑</el-button>
|
|
<el-button size="small" type="danger" @click="deleteWebsite(scope.row)">删除</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</el-tab-pane>
|
|
|
|
<el-tab-pane label="检测记录" name="detections">
|
|
<el-button @click="loadDetections" type="primary" size="small" style="margin-bottom: 10px">刷新</el-button>
|
|
<el-table :data="detections" style="width: 100%">
|
|
<el-table-column prop="id" label="ID" width="80"></el-table-column>
|
|
<el-table-column prop="website_id" label="网站ID" width="100"></el-table-column>
|
|
<el-table-column prop="status" label="状态" width="80">
|
|
<template #default="scope">
|
|
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
|
|
{{ scope.row.status === 1 ? '成功' : '失败' }}
|
|
</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="response_time" label="响应时间(ms)" width="120"></el-table-column>
|
|
<el-table-column prop="http_status" label="HTTP状态" width="100"></el-table-column>
|
|
<el-table-column prop="message" label="消息"></el-table-column>
|
|
<el-table-column prop="created_at" label="检测时间" width="180"></el-table-column>
|
|
</el-table>
|
|
</el-tab-pane>
|
|
|
|
<el-tab-pane label="通知记录" name="notifications">
|
|
<el-button @click="loadNotifications" type="primary" size="small" style="margin-bottom: 10px">刷新</el-button>
|
|
<el-table :data="notifications" style="width: 100%">
|
|
<el-table-column prop="id" label="ID" width="80"></el-table-column>
|
|
<el-table-column prop="user_id" label="用户ID" width="100"></el-table-column>
|
|
<el-table-column prop="website_id" label="网站ID" width="100"></el-table-column>
|
|
<el-table-column prop="title" label="标题" width="200"></el-table-column>
|
|
<el-table-column prop="status" label="状态" width="80">
|
|
<template #default="scope">
|
|
<el-tag :type="scope.row.status === 'sent' ? 'success' : scope.row.status === 'failed' ? 'danger' : 'warning'">
|
|
{{ scope.row.status === 'sent' ? '已发送' : scope.row.status === 'failed' ? '失败' : '待发送' }}
|
|
</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="send_time" label="发送时间" width="180"></el-table-column>
|
|
<el-table-column prop="created_at" label="创建时间" width="180"></el-table-column>
|
|
<el-table-column label="操作">
|
|
<template #default="scope">
|
|
<el-button size="small" @click="viewNotificationDetail(scope.row)">查看</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
</div>
|
|
|
|
<!-- 用户网站管理 -->
|
|
<div v-if="activeTab === 'user_websites'">
|
|
<div class="website-manage-header">
|
|
<el-button @click="activeTab = 'settings'; settingsTab = 'users'" type="info">返回设置</el-button>
|
|
<h2>网站管理 - {{ currentUser?.name }}</h2>
|
|
<el-button @click="showAddWebsiteDialogForUser" type="primary">添加网站</el-button>
|
|
</div>
|
|
|
|
<el-table :data="currentUserWebsites" style="width: 100%">
|
|
<el-table-column prop="id" label="ID" width="80"></el-table-column>
|
|
<el-table-column prop="name" label="网站名称" width="150"></el-table-column>
|
|
<el-table-column prop="url" label="URL" width="250"></el-table-column>
|
|
<el-table-column prop="interval_minutes" label="间隔(分钟)" width="100"></el-table-column>
|
|
<el-table-column prop="status" label="状态" width="80">
|
|
<template #default="scope">
|
|
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
|
|
{{ scope.row.status === 1 ? '启用' : '禁用' }}
|
|
</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="操作">
|
|
<template #default="scope">
|
|
<el-button size="small" @click="editWebsite(scope.row)">编辑</el-button>
|
|
<el-button size="small" type="danger" @click="deleteWebsite(scope.row)">删除</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</div>
|
|
</el-main>
|
|
</el-container>
|
|
</div>
|
|
|
|
<!-- 后台登录对话框 -->
|
|
<el-dialog v-model="adminLoginVisible" title="登录后台" width="400px">
|
|
<el-form :model="adminLoginForm" label-width="80px">
|
|
<el-form-item label="密码">
|
|
<el-input v-model="adminLoginForm.password" type="password" show-password @keyup.enter="adminLogin"></el-input>
|
|
</el-form-item>
|
|
</el-form>
|
|
<template #footer>
|
|
<el-button @click="adminLoginVisible = false">取消</el-button>
|
|
<el-button type="primary" @click="adminLogin">登录</el-button>
|
|
</template>
|
|
</el-dialog>
|
|
|
|
<!-- 用户对话框 -->
|
|
<el-dialog v-model="userDialogVisible" :title="userDialogTitle" width="600px">
|
|
<el-form :model="userForm" label-width="120px">
|
|
<el-form-item label="用户名">
|
|
<el-input v-model="userForm.name"></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="爱语飞飞令牌">
|
|
<el-input v-model="userForm.iyuu_token"></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="最大失败次数">
|
|
<el-input-number v-model="userForm.max_fail_count" :min="1" :max="10"></el-input-number>
|
|
</el-form-item>
|
|
<el-divider content-position="left">Cookie Cloud 设置</el-divider>
|
|
<el-form-item label="UUID">
|
|
<el-input v-model="userForm.cookie_cloud_uuid" placeholder="hu6n2vcUmzpu7mqUN2rVCg"></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="密码">
|
|
<el-input v-model="userForm.cookie_cloud_password" show-password></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="API地址">
|
|
<el-input v-model="userForm.cookie_cloud_api_url" placeholder="https://movie-pilot.org/cookiecloud"></el-input>
|
|
</el-form-item>
|
|
</el-form>
|
|
<template #footer>
|
|
<el-button @click="userDialogVisible = false">取消</el-button>
|
|
<el-button type="primary" @click="saveUser">保存</el-button>
|
|
</template>
|
|
</el-dialog>
|
|
|
|
<!-- 网站对话框 -->
|
|
<el-dialog v-model="websiteDialogVisible" :title="websiteDialogTitle">
|
|
<el-form :model="websiteFormDialog" label-width="120px">
|
|
<el-form-item label="所属用户">
|
|
<el-select v-model="websiteFormDialog.user_id" placeholder="选择用户">
|
|
<el-option v-for="user in users" :key="user.id" :label="user.name" :value="user.id"></el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="网站名称">
|
|
<el-input v-model="websiteFormDialog.name"></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="URL">
|
|
<el-input v-model="websiteFormDialog.url"></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="登录检测选择器">
|
|
<el-input v-model="websiteFormDialog.login_check_selector"></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="登录成功文本">
|
|
<el-input v-model="websiteFormDialog.success_text"></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="检测间隔(分钟)">
|
|
<el-input-number v-model="websiteFormDialog.interval_minutes" :min="1" :max="1440"></el-input-number>
|
|
</el-form-item>
|
|
<el-form-item label="状态">
|
|
<el-switch v-model="websiteFormDialog.status" :active-value="1" :inactive-value="0"></el-switch>
|
|
</el-form-item>
|
|
</el-form>
|
|
<template #footer>
|
|
<el-button @click="websiteDialogVisible = false">取消</el-button>
|
|
<el-button type="primary" @click="saveWebsite">保存</el-button>
|
|
</template>
|
|
</el-dialog>
|
|
|
|
<!-- Cookie对话框 -->
|
|
<el-dialog v-model="cookieDialogVisible" :title="cookieDialogTitle">
|
|
<el-form :model="cookieForm" label-width="100px">
|
|
<el-form-item label="名称">
|
|
<el-input v-model="cookieForm.name"></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="值">
|
|
<el-input v-model="cookieForm.value" type="textarea" :rows="3"></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="域名">
|
|
<el-input v-model="cookieForm.domain"></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="路径">
|
|
<el-input v-model="cookieForm.path"></el-input>
|
|
</el-form-item>
|
|
</el-form>
|
|
<template #footer>
|
|
<el-button @click="cookieDialogVisible = false">取消</el-button>
|
|
<el-button type="primary" @click="saveCookie">保存</el-button>
|
|
</template>
|
|
</el-dialog>
|
|
</div>
|
|
|
|
<script src="/static/js/app.js"></script>
|
|
</body>
|
|
</html>{% endraw %}
|