3695 lines
151 KiB
HTML
3695 lines
151 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Boss自动化助手 - 控制面板</title>
|
||
<style>
|
||
/* 基础样式 */
|
||
:root {
|
||
--primary-color: #1e40af;
|
||
--secondary-color: #3b82f6;
|
||
--success-color: #10b981;
|
||
--warning-color: #f59e0b;
|
||
--danger-color: #ef4444;
|
||
--info-color: #0ea5e9;
|
||
--bg-color: #f8fafc;
|
||
--card-bg: #ffffff;
|
||
--border-color: #e2e8f0;
|
||
--text-primary: #1e293b;
|
||
--text-secondary: #64748b;
|
||
--sidebar-width: 260px;
|
||
}
|
||
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
|
||
}
|
||
|
||
body {
|
||
background-color: var(--bg-color);
|
||
color: var(--text-primary);
|
||
line-height: 1.6;
|
||
overflow-x: hidden;
|
||
}
|
||
|
||
/* 布局 */
|
||
.app-container {
|
||
display: flex;
|
||
min-height: 100vh;
|
||
}
|
||
|
||
/* 侧边栏 */
|
||
.sidebar {
|
||
width: var(--sidebar-width);
|
||
background: linear-gradient(180deg, #1e293b, #0f172a);
|
||
color: white;
|
||
padding: 25px 0;
|
||
position: fixed;
|
||
height: 100vh;
|
||
overflow-y: auto;
|
||
box-shadow: 2px 0 15px rgba(0, 0, 0, 0.1);
|
||
z-index: 1000;
|
||
}
|
||
|
||
.logo {
|
||
text-align: center;
|
||
padding: 0 20px 25px;
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||
}
|
||
|
||
.logo h1 {
|
||
font-size: 22px;
|
||
font-weight: 700;
|
||
margin-bottom: 5px;
|
||
color: #60a5fa;
|
||
}
|
||
|
||
.logo span {
|
||
font-size: 12px;
|
||
opacity: 0.8;
|
||
}
|
||
|
||
.nav-menu {
|
||
margin-top: 25px;
|
||
}
|
||
|
||
.nav-item {
|
||
padding: 14px 25px;
|
||
display: flex;
|
||
align-items: center;
|
||
cursor: pointer;
|
||
transition: all 0.3s;
|
||
border-left: 3px solid transparent;
|
||
font-size: 15px;
|
||
}
|
||
|
||
.nav-item:hover {
|
||
background: rgba(255, 255, 255, 0.08);
|
||
}
|
||
|
||
.nav-item.active {
|
||
background: rgba(255, 255, 255, 0.12);
|
||
border-left-color: #60a5fa;
|
||
color: #60a5fa;
|
||
}
|
||
|
||
.nav-item i {
|
||
margin-right: 12px;
|
||
font-size: 16px;
|
||
width: 20px;
|
||
text-align: center;
|
||
}
|
||
|
||
.nav-badge {
|
||
margin-left: auto;
|
||
background: rgba(96, 165, 250, 0.2);
|
||
color: #60a5fa;
|
||
padding: 2px 8px;
|
||
border-radius: 10px;
|
||
font-size: 12px;
|
||
}
|
||
|
||
/* 主内容区 */
|
||
.main-content {
|
||
flex: 1;
|
||
margin-left: var(--sidebar-width);
|
||
padding: 25px;
|
||
min-height: 100vh;
|
||
background: var(--bg-color);
|
||
}
|
||
|
||
.header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 30px;
|
||
padding-bottom: 20px;
|
||
border-bottom: 1px solid var(--border-color);
|
||
}
|
||
|
||
.header h2 {
|
||
color: var(--primary-color);
|
||
font-size: 24px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.header-controls {
|
||
display: flex;
|
||
gap: 15px;
|
||
align-items: center;
|
||
}
|
||
|
||
/* 通用组件 */
|
||
.card {
|
||
background: var(--card-bg);
|
||
border-radius: 12px;
|
||
padding: 25px;
|
||
margin-bottom: 25px;
|
||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
|
||
border: 1px solid var(--border-color);
|
||
}
|
||
|
||
.card-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 25px;
|
||
}
|
||
|
||
.card-header h3 {
|
||
color: var(--primary-color);
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.btn {
|
||
padding: 10px 20px;
|
||
border: none;
|
||
border-radius: 8px;
|
||
font-weight: 600;
|
||
cursor: pointer;
|
||
transition: all 0.3s;
|
||
font-size: 14px;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.btn-primary {
|
||
background: linear-gradient(135deg, var(--primary-color), #1e3a8a);
|
||
color: white;
|
||
}
|
||
|
||
.btn-primary:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 5px 15px rgba(30, 64, 175, 0.3);
|
||
}
|
||
|
||
.btn-success {
|
||
background: linear-gradient(135deg, var(--success-color), #059669);
|
||
color: white;
|
||
}
|
||
|
||
.btn-danger {
|
||
background: linear-gradient(135deg, var(--danger-color), #dc2626);
|
||
color: white;
|
||
}
|
||
|
||
.btn-warning {
|
||
background: linear-gradient(135deg, var(--warning-color), #d97706);
|
||
color: white;
|
||
}
|
||
|
||
.btn-secondary {
|
||
background: var(--bg-color);
|
||
color: var(--text-primary);
|
||
border: 1px solid var(--border-color);
|
||
}
|
||
|
||
.btn-secondary:hover {
|
||
background: #e2e8f0;
|
||
}
|
||
|
||
.btn-sm {
|
||
padding: 6px 12px;
|
||
font-size: 12px;
|
||
}
|
||
|
||
/* 统计数据卡片 */
|
||
.stats-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||
gap: 20px;
|
||
margin-bottom: 30px;
|
||
}
|
||
|
||
.stat-card {
|
||
background: var(--card-bg);
|
||
padding: 20px;
|
||
border-radius: 12px;
|
||
border: 1px solid var(--border-color);
|
||
transition: transform 0.3s;
|
||
}
|
||
|
||
.stat-card:hover {
|
||
transform: translateY(-5px);
|
||
}
|
||
|
||
.stat-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.stat-icon {
|
||
width: 50px;
|
||
height: 50px;
|
||
border-radius: 10px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 24px;
|
||
color: white;
|
||
}
|
||
|
||
.icon-blue { background: linear-gradient(135deg, #3b82f6, #1d4ed8); }
|
||
.icon-green { background: linear-gradient(135deg, #10b981, #059669); }
|
||
.icon-orange { background: linear-gradient(135deg, #f59e0b, #d97706); }
|
||
.icon-purple { background: linear-gradient(135deg, #8b5cf6, #7c3aed); }
|
||
|
||
.stat-value {
|
||
font-size: 28px;
|
||
font-weight: 700;
|
||
color: var(--text-primary);
|
||
margin-bottom: 5px;
|
||
}
|
||
|
||
.stat-label {
|
||
color: var(--text-secondary);
|
||
font-size: 14px;
|
||
}
|
||
|
||
/* 账号控制区域 */
|
||
.account-control-area {
|
||
margin-top: 30px;
|
||
}
|
||
|
||
/* 账号表格布局(水平排列) */
|
||
.account-table-container {
|
||
overflow-x: auto;
|
||
margin-top: 20px;
|
||
}
|
||
|
||
.account-table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
min-width: 1000px;
|
||
}
|
||
|
||
.account-table th {
|
||
background: var(--bg-color);
|
||
padding: 15px;
|
||
text-align: left;
|
||
font-weight: 600;
|
||
color: var(--text-secondary);
|
||
border-bottom: 2px solid var(--border-color);
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.account-table td {
|
||
padding: 15px;
|
||
border-bottom: 1px solid var(--border-color);
|
||
}
|
||
|
||
.account-table tr:hover {
|
||
background: var(--bg-color);
|
||
}
|
||
|
||
.account-table tr.selected {
|
||
background: rgba(30, 64, 175, 0.05);
|
||
}
|
||
|
||
/* 表格中的复选框 */
|
||
.table-checkbox {
|
||
width: 20px;
|
||
height: 20px;
|
||
border: 2px solid var(--border-color);
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.table-checkbox.checked {
|
||
background: var(--primary-color);
|
||
border-color: var(--primary-color);
|
||
}
|
||
|
||
.table-checkbox.checked:after {
|
||
content: "✓";
|
||
color: white;
|
||
font-size: 14px;
|
||
}
|
||
|
||
/* 账号状态 */
|
||
.account-status {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.status-dot {
|
||
width: 10px;
|
||
height: 10px;
|
||
border-radius: 50%;
|
||
}
|
||
|
||
.status-online {
|
||
background-color: var(--success-color);
|
||
box-shadow: 0 0 10px var(--success-color);
|
||
}
|
||
|
||
.status-offline {
|
||
background-color: var(--danger-color);
|
||
}
|
||
|
||
.status-badge {
|
||
display: inline-block;
|
||
padding: 4px 12px;
|
||
border-radius: 20px;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
text-align: center;
|
||
}
|
||
|
||
.status-running { background: #d1fae5; color: #065f46; }
|
||
.status-paused { background: #fef3c7; color: #92400e; }
|
||
.status-stopped { background: #fee2e2; color: #991b1b; }
|
||
|
||
/* 进度条 */
|
||
.progress-bar {
|
||
height: 8px;
|
||
background: var(--border-color);
|
||
border-radius: 4px;
|
||
overflow: hidden;
|
||
margin-top: 5px;
|
||
}
|
||
|
||
.progress-fill {
|
||
height: 100%;
|
||
background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
|
||
border-radius: 4px;
|
||
}
|
||
|
||
/* 批量操作栏 */
|
||
.batch-controls {
|
||
background: var(--card-bg);
|
||
border-radius: 12px;
|
||
padding: 20px;
|
||
margin-top: 20px;
|
||
border: 1px solid var(--border-color);
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.batch-info {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 15px;
|
||
}
|
||
|
||
.batch-actions {
|
||
display: flex;
|
||
gap: 15px;
|
||
}
|
||
|
||
/* 运行日志 */
|
||
.running-logs {
|
||
margin-top: 30px;
|
||
}
|
||
|
||
.log-container {
|
||
background: #1e293b;
|
||
color: #e2e8f0;
|
||
padding: 20px;
|
||
border-radius: 8px;
|
||
font-family: 'Consolas', 'Monaco', monospace;
|
||
font-size: 13px;
|
||
max-height: 300px;
|
||
overflow-y: auto;
|
||
margin-top: 20px;
|
||
}
|
||
|
||
.log-entry {
|
||
padding: 5px 0;
|
||
border-bottom: 1px solid #334155;
|
||
}
|
||
|
||
.log-time {
|
||
color: #94a3b8;
|
||
margin-right: 15px;
|
||
}
|
||
|
||
.log-info { color: #60a5fa; }
|
||
.log-success { color: #34d399; }
|
||
.log-warning { color: #fbbf24; }
|
||
.log-error { color: #f87171; }
|
||
|
||
/* 页面切换 */
|
||
.page {
|
||
display: none;
|
||
}
|
||
|
||
.page.active {
|
||
display: block;
|
||
}
|
||
|
||
/* 表单样式 */
|
||
.form-group {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.form-label {
|
||
display: block;
|
||
margin-bottom: 8px;
|
||
font-weight: 600;
|
||
color: var(--text-primary);
|
||
}
|
||
|
||
.form-control {
|
||
width: 100%;
|
||
padding: 12px;
|
||
border: 1px solid var(--border-color);
|
||
border-radius: 8px;
|
||
font-size: 14px;
|
||
transition: border-color 0.3s;
|
||
}
|
||
|
||
.form-control:focus {
|
||
outline: none;
|
||
border-color: var(--primary-color);
|
||
}
|
||
|
||
.form-row {
|
||
display: flex;
|
||
gap: 20px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.form-col {
|
||
flex: 1;
|
||
}
|
||
|
||
.checkbox-group {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 15px;
|
||
margin-top: 10px;
|
||
}
|
||
|
||
.checkbox-label {
|
||
display: flex;
|
||
align-items: center;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.checkbox-label input {
|
||
margin-right: 8px;
|
||
}
|
||
|
||
/* 任务管理 */
|
||
.task-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
|
||
gap: 20px;
|
||
margin-top: 20px;
|
||
}
|
||
|
||
.task-card {
|
||
background: var(--card-bg);
|
||
border-radius: 12px;
|
||
padding: 20px;
|
||
border: 1px solid var(--border-color);
|
||
transition: all 0.3s;
|
||
}
|
||
|
||
.task-card:hover {
|
||
transform: translateY(-3px);
|
||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
.task-card-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 15px;
|
||
padding-bottom: 15px;
|
||
border-bottom: 1px solid var(--border-color);
|
||
}
|
||
|
||
.task-card-title {
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
color: var(--primary-color);
|
||
}
|
||
|
||
.task-card-status {
|
||
padding: 4px 10px;
|
||
border-radius: 20px;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.task-card-body {
|
||
color: var(--text-secondary);
|
||
font-size: 14px;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.task-card-footer {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-top: 15px;
|
||
}
|
||
|
||
.task-card-actions {
|
||
display: flex;
|
||
gap: 10px;
|
||
}
|
||
|
||
/* 数据表格 */
|
||
.data-table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
margin-top: 20px;
|
||
}
|
||
|
||
.data-table th {
|
||
background: var(--bg-color);
|
||
padding: 15px;
|
||
text-align: left;
|
||
font-weight: 600;
|
||
color: var(--text-secondary);
|
||
border-bottom: 2px solid var(--border-color);
|
||
}
|
||
|
||
.data-table td {
|
||
padding: 15px;
|
||
border-bottom: 1px solid var(--border-color);
|
||
}
|
||
|
||
.data-table tr:hover {
|
||
background: var(--bg-color);
|
||
}
|
||
|
||
/* 响应式 */
|
||
@media (max-width: 1200px) {
|
||
.sidebar {
|
||
width: 220px;
|
||
}
|
||
|
||
.main-content {
|
||
margin-left: 220px;
|
||
}
|
||
|
||
.form-row {
|
||
flex-direction: column;
|
||
}
|
||
|
||
.task-grid {
|
||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||
}
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.sidebar {
|
||
width: 70px;
|
||
padding: 20px 0;
|
||
}
|
||
|
||
.sidebar .logo h1,
|
||
.sidebar .logo span,
|
||
.sidebar .nav-item span:not(.nav-badge) {
|
||
display: none;
|
||
}
|
||
|
||
.sidebar .nav-item {
|
||
justify-content: center;
|
||
padding: 15px;
|
||
}
|
||
|
||
.sidebar .nav-item i {
|
||
margin-right: 0;
|
||
font-size: 18px;
|
||
}
|
||
|
||
.main-content {
|
||
margin-left: 70px;
|
||
padding: 15px;
|
||
}
|
||
|
||
.batch-controls {
|
||
flex-direction: column;
|
||
gap: 15px;
|
||
align-items: stretch;
|
||
}
|
||
|
||
.batch-actions {
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.task-grid {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
|
||
.data-table {
|
||
font-size: 14px;
|
||
}
|
||
|
||
.data-table th,
|
||
.data-table td {
|
||
padding: 10px;
|
||
}
|
||
}
|
||
|
||
/* 动画 */
|
||
@keyframes pulse {
|
||
0% { opacity: 1; }
|
||
50% { opacity: 0.5; }
|
||
100% { opacity: 1; }
|
||
}
|
||
|
||
.pulse {
|
||
animation: pulse 2s infinite;
|
||
}
|
||
|
||
/* 侧边栏状态 */
|
||
.sidebar-status {
|
||
padding: 20px;
|
||
margin-top: auto;
|
||
}
|
||
|
||
.system-status {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
/* 筛选条件标签 */
|
||
.filter-tags {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 10px;
|
||
margin-top: 20px;
|
||
}
|
||
|
||
.filter-tag {
|
||
background: var(--bg-color);
|
||
padding: 8px 15px;
|
||
border-radius: 20px;
|
||
font-size: 14px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.filter-tag i {
|
||
cursor: pointer;
|
||
color: var(--danger-color);
|
||
}
|
||
|
||
/* 话术卡片 */
|
||
.script-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||
gap: 20px;
|
||
margin-top: 20px;
|
||
}
|
||
|
||
.script-card {
|
||
background: var(--card-bg);
|
||
border-radius: 12px;
|
||
padding: 20px;
|
||
border: 1px solid var(--border-color);
|
||
}
|
||
|
||
.script-card-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 15px;
|
||
padding-bottom: 15px;
|
||
border-bottom: 1px solid var(--border-color);
|
||
}
|
||
|
||
.script-card-title {
|
||
font-weight: 600;
|
||
color: var(--primary-color);
|
||
}
|
||
|
||
.script-card-body {
|
||
color: var(--text-secondary);
|
||
line-height: 1.6;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
/* 图表容器 */
|
||
.chart-container {
|
||
height: 300px;
|
||
margin-top: 20px;
|
||
}
|
||
|
||
.chart-placeholder {
|
||
background: linear-gradient(135deg, #f8fafc, #e2e8f0);
|
||
border-radius: 8px;
|
||
height: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: var(--text-secondary);
|
||
font-size: 18px;
|
||
}
|
||
|
||
/* 设置项 */
|
||
.settings-group {
|
||
margin-bottom: 30px;
|
||
}
|
||
|
||
.settings-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 15px 0;
|
||
border-bottom: 1px solid var(--border-color);
|
||
}
|
||
|
||
.settings-label {
|
||
font-weight: 600;
|
||
color: var(--text-primary);
|
||
}
|
||
|
||
.settings-description {
|
||
color: var(--text-secondary);
|
||
font-size: 14px;
|
||
margin-top: 5px;
|
||
}
|
||
|
||
/* 开关按钮 */
|
||
.switch {
|
||
position: relative;
|
||
display: inline-block;
|
||
width: 50px;
|
||
height: 24px;
|
||
}
|
||
|
||
.switch input {
|
||
opacity: 0;
|
||
width: 0;
|
||
height: 0;
|
||
}
|
||
|
||
.slider {
|
||
position: absolute;
|
||
cursor: pointer;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background-color: #ccc;
|
||
transition: .4s;
|
||
border-radius: 34px;
|
||
}
|
||
|
||
.slider:before {
|
||
position: absolute;
|
||
content: "";
|
||
height: 16px;
|
||
width: 16px;
|
||
left: 4px;
|
||
bottom: 4px;
|
||
background-color: white;
|
||
transition: .4s;
|
||
border-radius: 50%;
|
||
}
|
||
|
||
input:checked + .slider {
|
||
background-color: var(--success-color);
|
||
}
|
||
|
||
input:checked + .slider:before {
|
||
transform: translateX(26px);
|
||
}
|
||
</style>
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||
</head>
|
||
<body>
|
||
<div class="app-container">
|
||
<!-- 侧边栏 -->
|
||
<div class="sidebar">
|
||
<div class="logo">
|
||
<h1>Boss助手</h1>
|
||
<span>专业自动化系统</span>
|
||
</div>
|
||
|
||
<div class="nav-menu">
|
||
<div class="nav-item active" data-page="dashboard">
|
||
<i class="fas fa-tachometer-alt"></i>
|
||
<span>控制面板</span>
|
||
</div>
|
||
<div class="nav-item" data-page="accounts">
|
||
<i class="fas fa-user-circle"></i>
|
||
<span>账号管理</span>
|
||
<span class="nav-badge" id="accountCount">5</span>
|
||
</div>
|
||
<div class="nav-item" data-page="filters">
|
||
<i class="fas fa-filter"></i>
|
||
<span>筛选设置</span>
|
||
</div>
|
||
<div class="nav-item" data-page="tasks">
|
||
<i class="fas fa-tasks"></i>
|
||
<span>任务管理</span>
|
||
<span class="nav-badge" id="taskCount">8</span>
|
||
</div>
|
||
<div class="nav-item" data-page="rechat">
|
||
<i class="fas fa-comments"></i>
|
||
<span>复聊管理</span>
|
||
</div>
|
||
<div class="nav-item" data-page="data">
|
||
<i class="fas fa-database"></i>
|
||
<span>数据管理</span>
|
||
</div>
|
||
<div class="nav-item" data-page="analytics">
|
||
<i class="fas fa-chart-bar"></i>
|
||
<span>统计分析</span>
|
||
</div>
|
||
<div class="nav-item" data-page="settings">
|
||
<i class="fas fa-cog"></i>
|
||
<span>系统设置</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sidebar-status">
|
||
<div class="system-status">
|
||
<div class="status-dot status-online pulse"></div>
|
||
<span>系统就绪</span>
|
||
</div>
|
||
<small style="opacity: 0.7; display: block;">v2.1.0</small>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 主内容区 -->
|
||
<div class="main-content" id="mainContent">
|
||
<!-- 控制面板页面 -->
|
||
<div class="page active" id="dashboard">
|
||
<div class="header">
|
||
<h2>控制面板</h2>
|
||
<div class="header-controls">
|
||
<div class="btn btn-secondary" id="refreshData">
|
||
<i class="fas fa-sync-alt"></i>
|
||
刷新数据
|
||
</div>
|
||
<div class="btn btn-primary" id="addAccountBtn">
|
||
<i class="fas fa-plus"></i>
|
||
添加账号
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 数据统计 -->
|
||
<div class="stats-grid">
|
||
<div class="stat-card">
|
||
<div class="stat-header">
|
||
<div>
|
||
<div class="stat-value" id="totalContacts">3,248</div>
|
||
<div class="stat-label">累计联系</div>
|
||
</div>
|
||
<div class="stat-icon icon-blue">
|
||
<i class="fas fa-handshake"></i>
|
||
</div>
|
||
</div>
|
||
<div style="font-size: 13px; color: var(--text-secondary);">
|
||
今日: <span id="todayContacts">142</span> 人
|
||
</div>
|
||
</div>
|
||
|
||
<div class="stat-card">
|
||
<div class="stat-header">
|
||
<div>
|
||
<div class="stat-value" id="totalReplies">487</div>
|
||
<div class="stat-label">收到回复</div>
|
||
</div>
|
||
<div class="stat-icon icon-green">
|
||
<i class="fas fa-comment-dots"></i>
|
||
</div>
|
||
</div>
|
||
<div style="font-size: 13px; color: var(--text-secondary);">
|
||
回复率: <span id="replyRate">15.0%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="stat-card">
|
||
<div class="stat-header">
|
||
<div>
|
||
<div class="stat-value" id="totalWechat">216</div>
|
||
<div class="stat-label">微信交换</div>
|
||
</div>
|
||
<div class="stat-icon icon-orange">
|
||
<i class="fas fa-weixin"></i>
|
||
</div>
|
||
</div>
|
||
<div style="font-size: 13px; color: var(--text-secondary);">
|
||
成功率: <span id="wechatRate">44.4%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="stat-card">
|
||
<div class="stat-header">
|
||
<div>
|
||
<div class="stat-value" id="totalCollections">89</div>
|
||
<div class="stat-label">收藏人数</div>
|
||
</div>
|
||
<div class="stat-icon icon-purple">
|
||
<i class="fas fa-star"></i>
|
||
</div>
|
||
</div>
|
||
<div style="font-size: 13px; color: var(--text-secondary);">
|
||
今日新增: <span id="todayCollections">12</span> 人
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 账号选择和控制 -->
|
||
<div class="account-control-area">
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>账号选择与运行控制</h3>
|
||
<div class="batch-info">
|
||
<span id="selectedCount">已选择 2 个账号</span>
|
||
<button class="btn btn-secondary" id="selectAll">
|
||
<i class="fas fa-check-square"></i>
|
||
全选
|
||
</button>
|
||
<button class="btn btn-secondary" id="clearSelection">
|
||
<i class="fas fa-times"></i>
|
||
清空选择
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 账号表格(水平排列) -->
|
||
<div class="account-table-container">
|
||
<table class="account-table" id="accountTable">
|
||
<thead>
|
||
<tr>
|
||
<th style="width: 50px;">
|
||
<div class="table-checkbox" id="selectAllCheckbox"></div>
|
||
</th>
|
||
<th>账号名称</th>
|
||
<th>Boss账号</th>
|
||
<th>线程数</th>
|
||
<th>今日联系</th>
|
||
<th>微信交换</th>
|
||
<th>状态</th>
|
||
<th>操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="accountTableBody">
|
||
<!-- 账号行会动态生成 -->
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- 批量操作栏 -->
|
||
<div class="batch-controls">
|
||
<div class="batch-info">
|
||
<span id="selectedAccountsInfo">已选择 2 个账号</span>
|
||
<span id="selectedStatusInfo">状态: 2运行中 0已暂停 0已停止</span>
|
||
</div>
|
||
<div class="batch-actions">
|
||
<button class="btn btn-success" id="startSelected">
|
||
<i class="fas fa-play"></i>
|
||
启动选中账号
|
||
</button>
|
||
<button class="btn btn-warning" id="pauseSelected">
|
||
<i class="fas fa-pause"></i>
|
||
暂停选中账号
|
||
</button>
|
||
<button class="btn btn-danger" id="stopSelected">
|
||
<i class="fas fa-stop"></i>
|
||
停止选中账号
|
||
</button>
|
||
<button class="btn btn-primary" id="startAllAccounts">
|
||
<i class="fas fa-rocket"></i>
|
||
启动全部账号
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 运行日志 -->
|
||
<div class="running-logs">
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>实时运行日志</h3>
|
||
<div>
|
||
<button class="btn btn-secondary" id="clearLogs">
|
||
<i class="fas fa-trash-alt"></i>
|
||
清空日志
|
||
</button>
|
||
<button class="btn btn-secondary" id="pauseLogs">
|
||
<i class="fas fa-pause"></i>
|
||
暂停更新
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="log-container" id="realtimeLogs">
|
||
<div class="log-entry">
|
||
<span class="log-time">14:25:32</span>
|
||
<span class="log-info">[INFO]</span>
|
||
系统初始化完成,准备开始运行
|
||
</div>
|
||
<div class="log-entry">
|
||
<span class="log-time">14:25:45</span>
|
||
<span class="log-success">[SUCCESS]</span>
|
||
成功启动3个自动化线程
|
||
</div>
|
||
<div class="log-entry">
|
||
<span class="log-time">14:26:10</span>
|
||
<span class="log-info">[INFO]</span>
|
||
开始执行筛选:年龄22-35,学历本科,3天内活跃
|
||
</div>
|
||
<div class="log-entry">
|
||
<span class="log-time">14:26:35</span>
|
||
<span class="log-success">[SUCCESS]</span>
|
||
账号"张三的账号"成功发送5条招呼
|
||
</div>
|
||
<div class="log-entry">
|
||
<span class="log-time">14:27:05</span>
|
||
<span class="log-info">[INFO]</span>
|
||
检测到2条新回复消息
|
||
</div>
|
||
<div class="log-entry">
|
||
<span class="log-time">14:27:30</span>
|
||
<span class="log-success">[SUCCESS]</span>
|
||
成功与候选人交换微信
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 快速操作 -->
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>快速操作</h3>
|
||
</div>
|
||
<div style="display: flex; gap: 15px; flex-wrap: wrap;">
|
||
<button class="btn btn-secondary" onclick="quickAction('export')">
|
||
<i class="fas fa-download"></i>
|
||
导出今日数据
|
||
</button>
|
||
<button class="btn btn-secondary" onclick="quickAction('pauseAll')">
|
||
<i class="fas fa-pause-circle"></i>
|
||
暂停所有任务
|
||
</button>
|
||
<button class="btn btn-secondary" onclick="quickAction('checkUpdate')">
|
||
<i class="fas fa-sync"></i>
|
||
检查更新
|
||
</button>
|
||
<button class="btn btn-secondary" onclick="quickAction('backup')">
|
||
<i class="fas fa-database"></i>
|
||
立即备份
|
||
</button>
|
||
<button class="btn btn-secondary" onclick="quickAction('report')">
|
||
<i class="fas fa-chart-pie"></i>
|
||
生成日报
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 账号管理页面 -->
|
||
<div class="page" id="accounts">
|
||
<div class="header">
|
||
<h2>账号管理</h2>
|
||
<div class="header-controls">
|
||
<button class="btn btn-primary" id="addNewAccount">
|
||
<i class="fas fa-plus"></i>
|
||
添加账号
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>账号列表</h3>
|
||
<div class="header-controls">
|
||
<button class="btn btn-secondary" id="exportAccounts">
|
||
<i class="fas fa-download"></i>
|
||
导出账号
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="account-table-container">
|
||
<table class="account-table">
|
||
<thead>
|
||
<tr>
|
||
<th>账号名称</th>
|
||
<th>Boss账号</th>
|
||
<th>密码</th>
|
||
<th>线程数</th>
|
||
<th>每日上限</th>
|
||
<th>状态</th>
|
||
<th>操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="accountsTableBody">
|
||
<!-- 账号行会动态生成 -->
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card" id="addAccountForm" style="display: none;">
|
||
<div class="card-header">
|
||
<h3>添加新账号</h3>
|
||
</div>
|
||
<div class="form-row">
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">账号名称</label>
|
||
<input type="text" class="form-control" id="accountName" placeholder="例如:张三的账号">
|
||
</div>
|
||
</div>
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">Boss账号</label>
|
||
<input type="text" class="form-control" id="bossAccount" placeholder="手机号码">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">密码</label>
|
||
<input type="password" class="form-control" id="accountPassword" placeholder="Boss账号密码">
|
||
</div>
|
||
</div>
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">确认密码</label>
|
||
<input type="password" class="form-control" id="confirmPassword" placeholder="再次输入密码">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">线程数</label>
|
||
<input type="number" class="form-control" id="threadCount" min="1" max="10" value="3">
|
||
</div>
|
||
</div>
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">每日联系上限</label>
|
||
<input type="number" class="form-control" id="dailyLimit" min="10" max="500" value="150">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">备注信息</label>
|
||
<textarea class="form-control" id="accountNotes" rows="3" placeholder="账号备注信息"></textarea>
|
||
</div>
|
||
|
||
<div style="display: flex; gap: 15px; justify-content: flex-end;">
|
||
<button class="btn btn-secondary" id="cancelAddAccount">
|
||
<i class="fas fa-times"></i>
|
||
取消
|
||
</button>
|
||
<button class="btn btn-primary" id="saveAccount">
|
||
<i class="fas fa-save"></i>
|
||
保存账号
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 筛选设置页面 -->
|
||
<div class="page" id="filters">
|
||
<div class="header">
|
||
<h2>筛选设置</h2>
|
||
<div class="header-controls">
|
||
<button class="btn btn-primary" id="saveFilters">
|
||
<i class="fas fa-save"></i>
|
||
保存设置
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>基础筛选条件</h3>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">年龄范围</label>
|
||
<div style="display: flex; align-items: center; gap: 10px;">
|
||
<input type="number" class="form-control" id="minAge" min="18" max="60" placeholder="最小" value="22">
|
||
<span>至</span>
|
||
<input type="number" class="form-control" id="maxAge" min="18" max="60" placeholder="最大" value="35">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">性别</label>
|
||
<div class="checkbox-group">
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="genderMale" checked> 男
|
||
</label>
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="genderFemale" checked> 女
|
||
</label>
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="genderOther"> 不限
|
||
</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">学历要求</label>
|
||
<select class="form-control" id="educationLevel">
|
||
<option value="不限">不限</option>
|
||
<option value="大专">大专</option>
|
||
<option value="本科" selected>本科</option>
|
||
<option value="硕士">硕士</option>
|
||
<option value="博士">博士</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">活跃度</label>
|
||
<select class="form-control" id="activityLevel">
|
||
<option value="不限">不限</option>
|
||
<option value="3天内活跃" selected>3天内活跃</option>
|
||
<option value="1周内活跃">1周内活跃</option>
|
||
<option value="2周内活跃">2周内活跃</option>
|
||
<option value="1月内活跃">1月内活跃</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">期望岗位</label>
|
||
<div class="checkbox-group">
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="positionJava" checked> Java开发
|
||
</label>
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="positionFrontend" checked> 前端开发
|
||
</label>
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="positionBackend"> 后端开发
|
||
</label>
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="positionTest"> 软件测试
|
||
</label>
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="positionProduct"> 产品经理
|
||
</label>
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="positionUI"> UI设计
|
||
</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>高级设置</h3>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">打招呼数量</label>
|
||
<div style="display: flex; align-items: center; gap: 10px;">
|
||
<input type="number" class="form-control" id="minMessages" min="1" max="50" placeholder="最少" value="5">
|
||
<span>至</span>
|
||
<input type="number" class="form-control" id="maxMessages" min="1" max="50" placeholder="最多" value="20">
|
||
<span>条/天</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">休息时间</label>
|
||
<div style="display: flex; align-items: center; gap: 10px;">
|
||
<input type="number" class="form-control" id="restMinutes" min="1" max="120" placeholder="分钟" value="30">
|
||
<span>分钟(每轮间隔)</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">收藏数量</label>
|
||
<div style="display: flex; align-items: center; gap: 10px;">
|
||
<input type="number" class="form-control" id="minCollections" min="0" max="100" placeholder="最少" value="10">
|
||
<span>至</span>
|
||
<input type="number" class="form-control" id="maxCollections" min="0" max="100" placeholder="最多" value="50">
|
||
<span>个/天</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">打招呼间隔</label>
|
||
<div style="display: flex; align-items: center; gap: 10px;">
|
||
<input type="number" class="form-control" id="messageInterval" min="5" max="300" placeholder="秒" value="30">
|
||
<span>秒/次</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">已保存的筛选条件</label>
|
||
<div class="filter-tags" id="filterTags">
|
||
<div class="filter-tag">
|
||
年龄22-35,本科,3天内活跃
|
||
<i class="fas fa-times" onclick="removeFilterTag(this)"></i>
|
||
</div>
|
||
<div class="filter-tag">
|
||
Java/前端开发,活跃用户
|
||
<i class="fas fa-times" onclick="removeFilterTag(this)"></i>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 任务管理页面 -->
|
||
<div class="page" id="tasks">
|
||
<div class="header">
|
||
<h2>任务管理</h2>
|
||
<div class="header-controls">
|
||
<button class="btn btn-primary" id="createNewTask">
|
||
<i class="fas fa-plus"></i>
|
||
创建任务
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>最近创建的任务</h3>
|
||
<div class="header-controls">
|
||
<select class="form-control" id="taskFilter" style="width: 200px;">
|
||
<option value="all">全部任务</option>
|
||
<option value="running">运行中</option>
|
||
<option value="paused">已暂停</option>
|
||
<option value="stopped">已停止</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="task-grid" id="taskGrid">
|
||
<!-- 任务卡片会动态生成 -->
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>运行任务选择</h3>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">选择要运行的任务体系</label>
|
||
<div id="taskSelectionArea">
|
||
<!-- 任务选择选项会动态生成 -->
|
||
</div>
|
||
</div>
|
||
|
||
<div style="display: flex; gap: 15px; margin-top: 20px;">
|
||
<button class="btn btn-success" id="runSelectedTasks">
|
||
<i class="fas fa-play"></i>
|
||
运行选中任务
|
||
</button>
|
||
<button class="btn btn-secondary" id="selectAllTasks">
|
||
<i class="fas fa-check-square"></i>
|
||
全选
|
||
</button>
|
||
<button class="btn btn-secondary" id="clearTaskSelection">
|
||
<i class="fas fa-times"></i>
|
||
清空选择
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card" id="taskForm" style="display: none;">
|
||
<div class="card-header">
|
||
<h3>创建新任务</h3>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">任务名称</label>
|
||
<input type="text" class="form-control" id="taskName" placeholder="例如:自动化打招呼任务">
|
||
</div>
|
||
</div>
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">任务类型</label>
|
||
<select class="form-control" id="taskType">
|
||
<option value="greeting">自动化打招呼</option>
|
||
<option value="rechat">复聊任务</option>
|
||
<option value="collection">收藏任务</option>
|
||
<option value="monitoring">监测消息</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">执行时间</label>
|
||
<input type="time" class="form-control" id="taskTime" value="09:00">
|
||
</div>
|
||
</div>
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">重复周期</label>
|
||
<select class="form-control" id="taskRepeat">
|
||
<option value="daily">每天</option>
|
||
<option value="weekdays">工作日</option>
|
||
<option value="weekly">每周</option>
|
||
<option value="monthly">每月</option>
|
||
<option value="once">仅一次</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">任务描述</label>
|
||
<textarea class="form-control" id="taskDescription" rows="3" placeholder="任务详细描述"></textarea>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">执行账号</label>
|
||
<div id="accountSelection" class="checkbox-group">
|
||
<!-- 账号选择会动态生成 -->
|
||
</div>
|
||
</div>
|
||
|
||
<div style="display: flex; gap: 15px; justify-content: flex-end;">
|
||
<button class="btn btn-secondary" id="cancelTask">
|
||
<i class="fas fa-times"></i>
|
||
取消
|
||
</button>
|
||
<button class="btn btn-primary" id="saveTask">
|
||
<i class="fas fa-save"></i>
|
||
创建任务
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 复聊管理页面 -->
|
||
<div class="page" id="rechat">
|
||
<div class="header">
|
||
<h2>复聊管理</h2>
|
||
<div class="header-controls">
|
||
<button class="btn btn-primary" id="addScript">
|
||
<i class="fas fa-plus"></i>
|
||
添加话术
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>复聊策略配置</h3>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">复聊触发条件</label>
|
||
<div class="checkbox-group">
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="triggerReply" checked> 对方回复消息
|
||
</label>
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="triggerNoReply" checked> 24小时未回复
|
||
</label>
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="triggerWechat"> 对方询问微信
|
||
</label>
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="triggerInterest"> 对方表示感兴趣
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">微信交换规则</label>
|
||
<div class="form-row">
|
||
<div class="form-col">
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="ruleImmediate" checked> 立即交换
|
||
</label>
|
||
</div>
|
||
<div class="form-col">
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="ruleDelay"> 延迟交换(沟通后)
|
||
</label>
|
||
</div>
|
||
<div class="form-col">
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="ruleVerify"> 需验证身份
|
||
</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>岗位对应话术</h3>
|
||
</div>
|
||
|
||
<div class="script-grid" id="scriptGrid">
|
||
<!-- 话术卡片会动态生成 -->
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card" id="scriptForm" style="display: none;">
|
||
<div class="card-header">
|
||
<h3>添加/编辑话术</h3>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">岗位类型</label>
|
||
<select class="form-control" id="scriptPosition">
|
||
<option value="Java开发">Java开发</option>
|
||
<option value="前端开发">前端开发</option>
|
||
<option value="后端开发">后端开发</option>
|
||
<option value="软件测试">软件测试</option>
|
||
<option value="产品经理">产品经理</option>
|
||
<option value="UI设计">UI设计</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">回复类型</label>
|
||
<select class="form-control" id="scriptType">
|
||
<option value="first">首次回复</option>
|
||
<option value="followup">跟进回复</option>
|
||
<option value="wechat">微信交换</option>
|
||
<option value="closing">结束语</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">回复内容</label>
|
||
<textarea class="form-control" id="scriptContent" rows="5" placeholder="请输入回复话术内容..."></textarea>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">关键词触发</label>
|
||
<input type="text" class="form-control" id="scriptKeywords" placeholder="用逗号分隔关键词,例如:薪资,经验,微信">
|
||
</div>
|
||
|
||
<div style="display: flex; gap: 15px; justify-content: flex-end;">
|
||
<button class="btn btn-secondary" id="cancelScript">
|
||
<i class="fas fa-times"></i>
|
||
取消
|
||
</button>
|
||
<button class="btn btn-primary" id="saveScript">
|
||
<i class="fas fa-save"></i>
|
||
保存话术
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 数据管理页面 -->
|
||
<div class="page" id="data">
|
||
<div class="header">
|
||
<h2>数据管理</h2>
|
||
<div class="header-controls">
|
||
<button class="btn btn-primary" id="exportData">
|
||
<i class="fas fa-download"></i>
|
||
导出数据
|
||
</button>
|
||
<button class="btn btn-secondary" id="refreshData">
|
||
<i class="fas fa-sync-alt"></i>
|
||
刷新数据
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>用户信息记录</h3>
|
||
<div class="header-controls">
|
||
<input type="text" class="form-control" id="dataSearch" placeholder="搜索用户..." style="width: 200px;">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="account-table-container">
|
||
<table class="data-table" id="dataTable">
|
||
<thead>
|
||
<tr>
|
||
<th>用户ID</th>
|
||
<th>姓名</th>
|
||
<th>岗位</th>
|
||
<th>联系方式</th>
|
||
<th>联系时间</th>
|
||
<th>回复状态</th>
|
||
<th>微信交换</th>
|
||
<th>操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="dataTableBody">
|
||
<!-- 数据行会动态生成 -->
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div style="display: flex; justify-content: space-between; align-items: center; margin-top: 20px;">
|
||
<div>
|
||
显示 <span id="dataStart">1</span> - <span id="dataEnd">10</span> 条,共 <span id="dataTotal">50</span> 条
|
||
</div>
|
||
<div style="display: flex; gap: 10px;">
|
||
<button class="btn btn-secondary btn-sm" id="prevPage">
|
||
<i class="fas fa-chevron-left"></i>
|
||
</button>
|
||
<button class="btn btn-secondary btn-sm" id="nextPage">
|
||
<i class="fas fa-chevron-right"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>数据导出选项</h3>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">导出格式</label>
|
||
<select class="form-control" id="exportFormat">
|
||
<option value="excel">Excel文件 (.xlsx)</option>
|
||
<option value="csv">CSV文件 (.csv)</option>
|
||
<option value="pdf">PDF文件 (.pdf)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">数据范围</label>
|
||
<select class="form-control" id="exportRange">
|
||
<option value="all">全部数据</option>
|
||
<option value="today">今天</option>
|
||
<option value="week">本周</option>
|
||
<option value="month">本月</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">导出字段</label>
|
||
<div class="checkbox-group">
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="fieldName" checked> 姓名
|
||
</label>
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="fieldPosition" checked> 岗位
|
||
</label>
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="fieldContact" checked> 联系方式
|
||
</label>
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="fieldTime" checked> 联系时间
|
||
</label>
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="fieldReply" checked> 回复状态
|
||
</label>
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="fieldWechat" checked> 微信交换
|
||
</label>
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" id="fieldNotes"> 备注
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="text-align: right;">
|
||
<button class="btn btn-success" id="confirmExport">
|
||
<i class="fas fa-file-export"></i>
|
||
开始导出
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 统计分析页面 -->
|
||
<div class="page" id="analytics">
|
||
<div class="header">
|
||
<h2>统计分析</h2>
|
||
<div class="header-controls">
|
||
<select class="form-control" id="analyticsPeriod" style="width: 150px;">
|
||
<option value="today">今天</option>
|
||
<option value="week" selected>本周</option>
|
||
<option value="month">本月</option>
|
||
<option value="quarter">本季度</option>
|
||
<option value="year">本年</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="stats-grid">
|
||
<div class="stat-card">
|
||
<div class="stat-header">
|
||
<div>
|
||
<div class="stat-value" id="analyticsContacts">3,248</div>
|
||
<div class="stat-label">累计联系</div>
|
||
</div>
|
||
<div class="stat-icon icon-blue">
|
||
<i class="fas fa-handshake"></i>
|
||
</div>
|
||
</div>
|
||
<div style="font-size: 13px; color: var(--text-secondary);">
|
||
日均: <span id="dailyContacts">142</span> 人
|
||
</div>
|
||
</div>
|
||
|
||
<div class="stat-card">
|
||
<div class="stat-header">
|
||
<div>
|
||
<div class="stat-value" id="analyticsReplies">487</div>
|
||
<div class="stat-label">收到回复</div>
|
||
</div>
|
||
<div class="stat-icon icon-green">
|
||
<i class="fas fa-comment-dots"></i>
|
||
</div>
|
||
</div>
|
||
<div style="font-size: 13px; color: var(--text-secondary);">
|
||
回复率: <span id="analyticsReplyRate">15.0%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="stat-card">
|
||
<div class="stat-header">
|
||
<div>
|
||
<div class="stat-value" id="analyticsWechat">216</div>
|
||
<div class="stat-label">微信交换</div>
|
||
</div>
|
||
<div class="stat-icon icon-orange">
|
||
<i class="fas fa-weixin"></i>
|
||
</div>
|
||
</div>
|
||
<div style="font-size: 13px; color: var(--text-secondary);">
|
||
成功率: <span id="analyticsWechatRate">44.4%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="stat-card">
|
||
<div class="stat-header">
|
||
<div>
|
||
<div class="stat-value" id="analyticsEfficiency">78%</div>
|
||
<div class="stat-label">系统效率</div>
|
||
</div>
|
||
<div class="stat-icon icon-purple">
|
||
<i class="fas fa-chart-line"></i>
|
||
</div>
|
||
</div>
|
||
<div style="font-size: 13px; color: var(--text-secondary);">
|
||
较上周: <span style="color: #10b981;">↑12%</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>联系趋势分析</h3>
|
||
<div class="header-controls">
|
||
<select class="form-control" id="chartType" style="width: 150px;">
|
||
<option value="line">折线图</option>
|
||
<option value="bar">柱状图</option>
|
||
<option value="pie">饼图</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="chart-container">
|
||
<div class="chart-placeholder">
|
||
<i class="fas fa-chart-bar" style="font-size: 48px; margin-right: 15px;"></i>
|
||
<div>
|
||
<div>联系趋势图表</div>
|
||
<small style="font-size: 14px;">显示每日联系人数和回复率变化</small>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>成功率统计</h3>
|
||
</div>
|
||
<div class="chart-container">
|
||
<div class="chart-placeholder">
|
||
<i class="fas fa-chart-pie" style="font-size: 48px; margin-right: 15px;"></i>
|
||
<div>
|
||
<div>成功率分布图表</div>
|
||
<small style="font-size: 14px;">按岗位、年龄、学历等维度分析</small>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>详细分析报告</h3>
|
||
<div class="header-controls">
|
||
<button class="btn btn-primary" id="generateReport">
|
||
<i class="fas fa-file-pdf"></i>
|
||
生成报告
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<div style="background: var(--bg-color); padding: 20px; border-radius: 8px; margin-top: 10px;">
|
||
<h4 style="margin-bottom: 15px;">本周数据分析</h4>
|
||
<ul style="color: var(--text-secondary); line-height: 1.8;">
|
||
<li>联系总人数:<strong>3,248</strong>人,较上周增长<strong style="color: #10b981;">15%</strong></li>
|
||
<li>平均回复率:<strong>15.0%</strong>,最佳账号回复率达<strong>22.5%</strong></li>
|
||
<li>微信交换成功率:<strong>44.4%</strong>,较上周提升<strong style="color: #10b981;">8%</strong></li>
|
||
<li>最活跃时间段:上午<strong>9:00-11:00</strong>,下午<strong>14:00-16:00</strong></li>
|
||
<li>最有效岗位:<strong>Java开发</strong>(回复率18.2%)、<strong>前端开发</strong>(回复率16.8%)</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 系统设置页面 -->
|
||
<div class="page" id="settings">
|
||
<div class="header">
|
||
<h2>系统设置</h2>
|
||
<div class="header-controls">
|
||
<button class="btn btn-primary" id="saveSettings">
|
||
<i class="fas fa-save"></i>
|
||
保存设置
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="settings-group">
|
||
<h3 style="margin-bottom: 20px;">基本设置</h3>
|
||
|
||
<div class="settings-item">
|
||
<div>
|
||
<div class="settings-label">系统自动更新</div>
|
||
<div class="settings-description">自动下载并安装系统更新</div>
|
||
</div>
|
||
<label class="switch">
|
||
<input type="checkbox" id="autoUpdate" checked>
|
||
<span class="slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="settings-item">
|
||
<div>
|
||
<div class="settings-label">自动备份数据</div>
|
||
<div class="settings-description">每天自动备份用户数据到本地</div>
|
||
</div>
|
||
<label class="switch">
|
||
<input type="checkbox" id="autoBackup" checked>
|
||
<span class="slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="settings-item">
|
||
<div>
|
||
<div class="settings-label">系统通知</div>
|
||
<div class="settings-description">接收系统运行状态和异常通知</div>
|
||
</div>
|
||
<label class="switch">
|
||
<input type="checkbox" id="systemNotifications" checked>
|
||
<span class="slider"></span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="settings-group">
|
||
<h3 style="margin-bottom: 20px;">安全设置</h3>
|
||
|
||
<div class="settings-item">
|
||
<div>
|
||
<div class="settings-label">登录验证</div>
|
||
<div class="settings-description">启用双重验证增强账户安全</div>
|
||
</div>
|
||
<label class="switch">
|
||
<input type="checkbox" id="twoFactorAuth">
|
||
<span class="slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="settings-item">
|
||
<div>
|
||
<div class="settings-label">操作日志</div>
|
||
<div class="settings-description">记录所有关键操作日志</div>
|
||
</div>
|
||
<label class="switch">
|
||
<input type="checkbox" id="operationLogs" checked>
|
||
<span class="slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="settings-item">
|
||
<div>
|
||
<div class="settings-label">数据加密</div>
|
||
<div class="settings-description">加密存储敏感用户数据</div>
|
||
</div>
|
||
<label class="switch">
|
||
<input type="checkbox" id="dataEncryption" checked>
|
||
<span class="slider"></span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="settings-group">
|
||
<h3 style="margin-bottom: 20px;">性能设置</h3>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">最大并发线程数</label>
|
||
<input type="range" class="form-control" id="maxThreads" min="1" max="50" value="20" style="width: 100%;">
|
||
<div style="display: flex; justify-content: space-between; margin-top: 5px;">
|
||
<span>1线程</span>
|
||
<span id="threadValue">20线程</span>
|
||
<span>50线程</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">数据缓存时间</label>
|
||
<select class="form-control" id="cacheTime">
|
||
<option value="5">5分钟</option>
|
||
<option value="15">15分钟</option>
|
||
<option value="30" selected>30分钟</option>
|
||
<option value="60">1小时</option>
|
||
<option value="120">2小时</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="settings-group">
|
||
<h3 style="margin-bottom: 20px;">通知设置</h3>
|
||
|
||
<div class="settings-item">
|
||
<div>
|
||
<div class="settings-label">微信交换通知</div>
|
||
<div class="settings-description">成功交换微信时发送通知</div>
|
||
</div>
|
||
<label class="switch">
|
||
<input type="checkbox" id="wechatNotification" checked>
|
||
<span class="slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="settings-item">
|
||
<div>
|
||
<div class="settings-label">异常报警通知</div>
|
||
<div class="settings-description">系统运行异常时发送报警</div>
|
||
</div>
|
||
<label class="switch">
|
||
<input type="checkbox" id="errorNotification" checked>
|
||
<span class="slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="settings-item">
|
||
<div>
|
||
<div class="settings-label">日报生成通知</div>
|
||
<div class="settings-description">每天生成运行报告并通知</div>
|
||
</div>
|
||
<label class="switch">
|
||
<input type="checkbox" id="dailyReport" checked>
|
||
<span class="slider"></span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>数据库管理</h3>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">数据库类型</label>
|
||
<select class="form-control" id="dbType">
|
||
<option value="mysql">MySQL</option>
|
||
<option value="sqlite" selected>SQLite</option>
|
||
<option value="postgresql">PostgreSQL</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">连接地址</label>
|
||
<input type="text" class="form-control" id="dbHost" value="localhost">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">数据库名称</label>
|
||
<input type="text" class="form-control" id="dbName" value="boss_assistant">
|
||
</div>
|
||
</div>
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">用户名</label>
|
||
<input type="text" class="form-control" id="dbUser" value="admin">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">密码</label>
|
||
<input type="password" class="form-control" id="dbPassword" placeholder="数据库密码">
|
||
</div>
|
||
|
||
<div style="display: flex; gap: 15px; justify-content: flex-end;">
|
||
<button class="btn btn-secondary" id="testDbConnection">
|
||
<i class="fas fa-plug"></i>
|
||
测试连接
|
||
</button>
|
||
<button class="btn btn-primary" id="saveDbSettings">
|
||
<i class="fas fa-database"></i>
|
||
保存数据库设置
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>系统信息</h3>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">系统版本</label>
|
||
<input type="text" class="form-control" value="v2.1.0" readonly>
|
||
</div>
|
||
</div>
|
||
<div class="form-col">
|
||
<div class="form-group">
|
||
<label class="form-label">最后更新</label>
|
||
<input type="text" class="form-control" value="2023-10-15" readonly>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">运行状态</label>
|
||
<div style="display: flex; align-items: center; gap: 10px; margin-top: 10px;">
|
||
<div class="status-dot status-online pulse"></div>
|
||
<span>系统运行正常</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="text-align: center; margin-top: 20px;">
|
||
<button class="btn btn-danger" id="systemRestart">
|
||
<i class="fas fa-redo"></i>
|
||
重启系统
|
||
</button>
|
||
<button class="btn btn-secondary" id="clearCache">
|
||
<i class="fas fa-broom"></i>
|
||
清除缓存
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// 系统数据
|
||
let systemData = {
|
||
accounts: [
|
||
{
|
||
id: 1,
|
||
name: "张三的账号",
|
||
bossAccount: "138****1234",
|
||
threads: 3,
|
||
status: "running",
|
||
todayContacts: 78,
|
||
dailyLimit: 150,
|
||
wechatExchanged: 5,
|
||
selected: true
|
||
},
|
||
{
|
||
id: 2,
|
||
name: "李四的账号",
|
||
bossAccount: "139****5678",
|
||
threads: 2,
|
||
status: "paused",
|
||
todayContacts: 45,
|
||
dailyLimit: 100,
|
||
wechatExchanged: 3,
|
||
selected: false
|
||
},
|
||
{
|
||
id: 3,
|
||
name: "王五的账号",
|
||
bossAccount: "136****9012",
|
||
threads: 4,
|
||
status: "stopped",
|
||
todayContacts: 19,
|
||
dailyLimit: 200,
|
||
wechatExchanged: 1,
|
||
selected: true
|
||
},
|
||
{
|
||
id: 4,
|
||
name: "赵六的账号",
|
||
bossAccount: "137****3456",
|
||
threads: 3,
|
||
status: "running",
|
||
todayContacts: 56,
|
||
dailyLimit: 120,
|
||
wechatExchanged: 4,
|
||
selected: false
|
||
},
|
||
{
|
||
id: 5,
|
||
name: "孙七的账号",
|
||
bossAccount: "135****7890",
|
||
threads: 2,
|
||
status: "stopped",
|
||
todayContacts: 0,
|
||
dailyLimit: 80,
|
||
wechatExchanged: 0,
|
||
selected: false
|
||
}
|
||
],
|
||
tasks: [
|
||
{
|
||
id: 1,
|
||
name: "自动化打招呼任务",
|
||
type: "greeting",
|
||
status: "running",
|
||
description: "每天上午9点开始自动打招呼",
|
||
time: "09:00",
|
||
repeat: "daily",
|
||
accounts: [1, 2]
|
||
},
|
||
{
|
||
id: 2,
|
||
name: "复聊任务",
|
||
type: "rechat",
|
||
status: "paused",
|
||
description: "对未回复的用户进行复聊",
|
||
time: "14:00",
|
||
repeat: "daily",
|
||
accounts: [1, 3]
|
||
},
|
||
{
|
||
id: 3,
|
||
name: "收藏任务",
|
||
type: "collection",
|
||
status: "running",
|
||
description: "收藏有潜力的候选人",
|
||
time: "11:00",
|
||
repeat: "daily",
|
||
accounts: [2]
|
||
},
|
||
{
|
||
id: 4,
|
||
name: "监测消息任务",
|
||
type: "monitoring",
|
||
status: "stopped",
|
||
description: "监测候选人回复消息",
|
||
time: "全天",
|
||
repeat: "daily",
|
||
accounts: [1, 2, 3]
|
||
},
|
||
{
|
||
id: 5,
|
||
name: "周末打招呼任务",
|
||
type: "greeting",
|
||
status: "running",
|
||
description: "周末特别打招呼任务",
|
||
time: "10:00",
|
||
repeat: "weekly",
|
||
accounts: [4]
|
||
}
|
||
],
|
||
scripts: [
|
||
{
|
||
id: 1,
|
||
position: "Java开发",
|
||
type: "first",
|
||
content: "您好,看到您的Java开发经验很丰富,我们公司正在招聘高级Java开发,薪资30-50K,有兴趣了解一下吗?",
|
||
keywords: "Java,经验,薪资"
|
||
},
|
||
{
|
||
id: 2,
|
||
position: "前端开发",
|
||
type: "first",
|
||
content: "您好,我们公司正在招聘资深前端开发,要求React/Vue经验,薪资范围25-40K,福利待遇优厚,方便聊聊吗?",
|
||
keywords: "前端,React,Vue,薪资"
|
||
},
|
||
{
|
||
id: 3,
|
||
position: "Java开发",
|
||
type: "wechat",
|
||
content: "感谢您的回复!我的微信号是 *******,添加后我们可以详细沟通岗位情况和面试安排。",
|
||
keywords: "微信,联系方式"
|
||
},
|
||
{
|
||
id: 4,
|
||
position: "软件测试",
|
||
type: "followup",
|
||
content: "您好,之前和您沟通的测试岗位还在招聘中,我们提供完善的培训和晋升空间,期待您的加入!",
|
||
keywords: "测试,培训,晋升"
|
||
}
|
||
],
|
||
userData: [
|
||
{
|
||
id: 1,
|
||
name: "张明",
|
||
position: "Java开发",
|
||
contact: "138****1111",
|
||
contactTime: "2023-10-15 09:30",
|
||
replyStatus: "已回复",
|
||
wechatExchanged: true
|
||
},
|
||
{
|
||
id: 2,
|
||
name: "李华",
|
||
position: "前端开发",
|
||
contact: "139****2222",
|
||
contactTime: "2023-10-15 10:15",
|
||
replyStatus: "未回复",
|
||
wechatExchanged: false
|
||
},
|
||
{
|
||
id: 3,
|
||
name: "王强",
|
||
position: "Java开发",
|
||
contact: "136****3333",
|
||
contactTime: "2023-10-15 11:20",
|
||
replyStatus: "已回复",
|
||
wechatExchanged: true
|
||
},
|
||
{
|
||
id: 4,
|
||
name: "赵敏",
|
||
position: "软件测试",
|
||
contact: "137****4444",
|
||
contactTime: "2023-10-15 14:05",
|
||
replyStatus: "已回复",
|
||
wechatExchanged: false
|
||
},
|
||
{
|
||
id: 5,
|
||
name: "孙伟",
|
||
position: "产品经理",
|
||
contact: "135****5555",
|
||
contactTime: "2023-10-15 15:40",
|
||
replyStatus: "未回复",
|
||
wechatExchanged: false
|
||
},
|
||
{
|
||
id: 6,
|
||
name: "周婷",
|
||
position: "UI设计",
|
||
contact: "134****6666",
|
||
contactTime: "2023-10-15 16:25",
|
||
replyStatus: "已回复",
|
||
wechatExchanged: true
|
||
},
|
||
{
|
||
id: 7,
|
||
name: "吴刚",
|
||
position: "后端开发",
|
||
contact: "133****7777",
|
||
contactTime: "2023-10-14 09:10",
|
||
replyStatus: "已回复",
|
||
wechatExchanged: true
|
||
},
|
||
{
|
||
id: 8,
|
||
name: "郑爽",
|
||
position: "前端开发",
|
||
contact: "132****8888",
|
||
contactTime: "2023-10-14 11:30",
|
||
replyStatus: "未回复",
|
||
wechatExchanged: false
|
||
},
|
||
{
|
||
id: 9,
|
||
name: "刘洋",
|
||
position: "Java开发",
|
||
contact: "131****9999",
|
||
contactTime: "2023-10-14 14:50",
|
||
replyStatus: "已回复",
|
||
wechatExchanged: true
|
||
},
|
||
{
|
||
id: 10,
|
||
name: "陈静",
|
||
position: "软件测试",
|
||
contact: "130****0000",
|
||
contactTime: "2023-10-14 16:15",
|
||
replyStatus: "已回复",
|
||
wechatExchanged: false
|
||
}
|
||
],
|
||
selectedAccountIds: [1, 3], // 默认选中两个账号
|
||
selectedTaskIds: [], // 选中的任务ID
|
||
logsPaused: false,
|
||
logSimulationInterval: null,
|
||
currentDataPage: 1,
|
||
dataPerPage: 10
|
||
};
|
||
|
||
// 页面切换功能
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
// 初始化所有页面数据
|
||
initDashboard();
|
||
initAccountsPage();
|
||
initFiltersPage();
|
||
initTasksPage();
|
||
initRechatPage();
|
||
initDataPage();
|
||
initAnalyticsPage();
|
||
initSettingsPage();
|
||
|
||
// 页面切换
|
||
document.querySelectorAll('.nav-item').forEach(item => {
|
||
item.addEventListener('click', function() {
|
||
const pageId = this.dataset.page;
|
||
|
||
// 更新导航状态
|
||
document.querySelectorAll('.nav-item').forEach(nav => nav.classList.remove('active'));
|
||
this.classList.add('active');
|
||
|
||
// 切换页面
|
||
document.querySelectorAll('.page').forEach(page => page.classList.remove('active'));
|
||
document.getElementById(pageId).classList.add('active');
|
||
|
||
// 更新标题
|
||
document.querySelector('.header h2').textContent = this.querySelector('span').textContent;
|
||
});
|
||
});
|
||
|
||
// 初始化控制面板日志
|
||
startLogSimulation();
|
||
});
|
||
|
||
// ========== 控制面板相关函数 ==========
|
||
function initDashboard() {
|
||
loadDashboardData();
|
||
|
||
// 刷新数据
|
||
document.getElementById('refreshData').addEventListener('click', refreshDashboardData);
|
||
|
||
// 添加账号
|
||
document.getElementById('addAccountBtn').addEventListener('click', function() {
|
||
addLog('点击添加账号按钮', 'info');
|
||
// 切换到账号管理页面
|
||
document.querySelectorAll('.nav-item').forEach(nav => nav.classList.remove('active'));
|
||
document.querySelector('.nav-item[data-page="accounts"]').classList.add('active');
|
||
document.querySelectorAll('.page').forEach(page => page.classList.remove('active'));
|
||
document.getElementById('accounts').classList.add('active');
|
||
document.querySelector('.header h2').textContent = '账号管理';
|
||
});
|
||
|
||
// 全选/取消全选
|
||
document.getElementById('selectAll').addEventListener('click', selectAllAccounts);
|
||
document.getElementById('clearSelection').addEventListener('click', clearSelection);
|
||
document.getElementById('selectAllCheckbox').addEventListener('click', toggleSelectAll);
|
||
|
||
// 批量操作
|
||
document.getElementById('startSelected').addEventListener('click', startSelectedAccounts);
|
||
document.getElementById('pauseSelected').addEventListener('click', pauseSelectedAccounts);
|
||
document.getElementById('stopSelected').addEventListener('click', stopSelectedAccounts);
|
||
document.getElementById('startAllAccounts').addEventListener('click', startAllAccounts);
|
||
|
||
// 日志控制
|
||
document.getElementById('clearLogs').addEventListener('click', clearLogs);
|
||
document.getElementById('pauseLogs').addEventListener('click', toggleLogPause);
|
||
}
|
||
|
||
function loadDashboardData() {
|
||
// 更新统计数据
|
||
const totalTodayContacts = systemData.accounts.reduce((sum, acc) => sum + acc.todayContacts, 0);
|
||
|
||
document.getElementById('todayContacts').textContent = totalTodayContacts;
|
||
document.getElementById('totalContacts').textContent = '3,248';
|
||
document.getElementById('totalReplies').textContent = '487';
|
||
document.getElementById('replyRate').textContent = '15.0%';
|
||
document.getElementById('totalWechat').textContent = '216';
|
||
document.getElementById('wechatRate').textContent = '44.4%';
|
||
document.getElementById('todayCollections').textContent = '12';
|
||
|
||
// 更新账号表格
|
||
const tableBody = document.getElementById('accountTableBody');
|
||
tableBody.innerHTML = '';
|
||
|
||
systemData.accounts.forEach(account => {
|
||
const isSelected = systemData.selectedAccountIds.includes(account.id);
|
||
const tableRow = createAccountTableRow(account, isSelected);
|
||
tableBody.appendChild(tableRow);
|
||
});
|
||
|
||
// 更新账号数量
|
||
document.getElementById('accountCount').textContent = systemData.accounts.length;
|
||
document.getElementById('taskCount').textContent = systemData.tasks.length;
|
||
|
||
// 更新全选复选框状态
|
||
updateSelectAllCheckbox();
|
||
updateSelectedAccountsInfo();
|
||
}
|
||
|
||
// 创建账号表格行
|
||
function createAccountTableRow(account, isSelected) {
|
||
const row = document.createElement('tr');
|
||
row.className = isSelected ? 'selected' : '';
|
||
row.dataset.accountId = account.id;
|
||
|
||
const statusText = account.status === 'running' ? '运行中' :
|
||
account.status === 'paused' ? '已暂停' : '已停止';
|
||
const statusClass = account.status === 'running' ? 'status-running' :
|
||
account.status === 'paused' ? 'status-paused' : 'status-stopped';
|
||
|
||
const progressPercent = Math.min((account.todayContacts / account.dailyLimit) * 100, 100);
|
||
|
||
row.innerHTML = `
|
||
<td>
|
||
<div class="table-checkbox ${isSelected ? 'checked' : ''}" onclick="toggleAccountSelection(${account.id}, event)"></div>
|
||
</td>
|
||
<td>
|
||
<div style="font-weight: 600;">${account.name}</div>
|
||
<div style="font-size: 12px; color: var(--text-secondary);">ID: ${account.id}</div>
|
||
</td>
|
||
<td>${account.bossAccount}</td>
|
||
<td>
|
||
<div style="font-weight: 600;">${account.threads}线程</div>
|
||
</td>
|
||
<td>
|
||
<div>${account.todayContacts}/${account.dailyLimit}</div>
|
||
<div class="progress-bar">
|
||
<div class="progress-fill" style="width: ${progressPercent}%;"></div>
|
||
</div>
|
||
</td>
|
||
<td>
|
||
<div style="font-weight: 600;">${account.wechatExchanged}</div>
|
||
<div style="font-size: 12px; color: var(--text-secondary);">成功率: ${Math.round((account.wechatExchanged / Math.max(account.todayContacts, 1)) * 100)}%</div>
|
||
</td>
|
||
<td>
|
||
<div class="account-status">
|
||
<div class="status-dot ${account.status === 'running' ? 'status-online' : 'status-offline'}"></div>
|
||
<span class="status-badge ${statusClass}">${statusText}</span>
|
||
</div>
|
||
</td>
|
||
<td>
|
||
<div style="display: flex; gap: 8px;">
|
||
<button class="btn btn-sm ${account.status === 'running' ? 'btn-warning' : 'btn-success'}" onclick="toggleAccountStatus(${account.id})" style="padding: 6px 12px; font-size: 12px;">
|
||
<i class="fas fa-${account.status === 'running' ? 'pause' : 'play'}"></i>
|
||
</button>
|
||
<button class="btn btn-sm btn-secondary" onclick="editAccount(${account.id})" style="padding: 6px 12px; font-size: 12px;">
|
||
<i class="fas fa-edit"></i>
|
||
</button>
|
||
</div>
|
||
</td>
|
||
`;
|
||
|
||
// 点击整行也可以选中(除了操作按钮区域)
|
||
row.addEventListener('click', function(e) {
|
||
if (!e.target.closest('.table-checkbox') &&
|
||
!e.target.closest('button') &&
|
||
!e.target.closest('.btn')) {
|
||
toggleAccountSelection(account.id);
|
||
}
|
||
});
|
||
|
||
return row;
|
||
}
|
||
|
||
// 切换账号选中状态
|
||
function toggleAccountSelection(accountId, event) {
|
||
if (event) event.stopPropagation();
|
||
|
||
const index = systemData.selectedAccountIds.indexOf(accountId);
|
||
|
||
if (index === -1) {
|
||
systemData.selectedAccountIds.push(accountId);
|
||
} else {
|
||
systemData.selectedAccountIds.splice(index, 1);
|
||
}
|
||
|
||
// 更新UI
|
||
const tableRow = document.querySelector(`tr[data-account-id="${accountId}"]`);
|
||
const checkbox = tableRow.querySelector('.table-checkbox');
|
||
|
||
if (index === -1) {
|
||
tableRow.classList.add('selected');
|
||
checkbox.classList.add('checked');
|
||
} else {
|
||
tableRow.classList.remove('selected');
|
||
checkbox.classList.remove('checked');
|
||
}
|
||
|
||
updateSelectedAccountsInfo();
|
||
updateSelectAllCheckbox();
|
||
}
|
||
|
||
// 更新全选复选框状态
|
||
function updateSelectAllCheckbox() {
|
||
const selectAllCheckbox = document.getElementById('selectAllCheckbox');
|
||
const allSelected = systemData.selectedAccountIds.length === systemData.accounts.length;
|
||
|
||
if (allSelected) {
|
||
selectAllCheckbox.classList.add('checked');
|
||
} else {
|
||
selectAllCheckbox.classList.remove('checked');
|
||
}
|
||
}
|
||
|
||
// 切换全选
|
||
function toggleSelectAll() {
|
||
const selectAllCheckbox = document.getElementById('selectAllCheckbox');
|
||
const isCurrentlyChecked = selectAllCheckbox.classList.contains('checked');
|
||
|
||
if (isCurrentlyChecked) {
|
||
// 取消全选
|
||
clearSelection();
|
||
} else {
|
||
// 全选
|
||
selectAllAccounts();
|
||
}
|
||
}
|
||
|
||
// 更新选中账号信息
|
||
function updateSelectedAccountsInfo() {
|
||
const selectedCount = systemData.selectedAccountIds.length;
|
||
|
||
// 获取选中账号的状态
|
||
const selectedAccounts = systemData.accounts.filter(acc =>
|
||
systemData.selectedAccountIds.includes(acc.id)
|
||
);
|
||
|
||
const runningCount = selectedAccounts.filter(acc => acc.status === 'running').length;
|
||
const pausedCount = selectedAccounts.filter(acc => acc.status === 'paused').length;
|
||
const stoppedCount = selectedAccounts.filter(acc => acc.status === 'stopped').length;
|
||
|
||
// 更新显示
|
||
document.getElementById('selectedCount').textContent = `已选择 ${selectedCount} 个账号`;
|
||
document.getElementById('selectedAccountsInfo').textContent = `已选择 ${selectedCount} 个账号`;
|
||
|
||
let statusText = '状态: ';
|
||
if (runningCount > 0) statusText += `${runningCount}运行中 `;
|
||
if (pausedCount > 0) statusText += `${pausedCount}已暂停 `;
|
||
if (stoppedCount > 0) statusText += `${stoppedCount}已停止`;
|
||
|
||
if (selectedCount === 0) statusText = '状态: 未选择账号';
|
||
|
||
document.getElementById('selectedStatusInfo').textContent = statusText;
|
||
}
|
||
|
||
// 全选账号
|
||
function selectAllAccounts() {
|
||
systemData.selectedAccountIds = systemData.accounts.map(acc => acc.id);
|
||
|
||
// 更新UI
|
||
systemData.accounts.forEach(account => {
|
||
const tableRow = document.querySelector(`tr[data-account-id="${account.id}"]`);
|
||
const checkbox = tableRow.querySelector('.table-checkbox');
|
||
|
||
tableRow.classList.add('selected');
|
||
checkbox.classList.add('checked');
|
||
});
|
||
|
||
updateSelectedAccountsInfo();
|
||
updateSelectAllCheckbox();
|
||
addLog('已选择所有账号', 'info');
|
||
}
|
||
|
||
// 清空选择
|
||
function clearSelection() {
|
||
systemData.selectedAccountIds = [];
|
||
|
||
// 更新UI
|
||
systemData.accounts.forEach(account => {
|
||
const tableRow = document.querySelector(`tr[data-account-id="${account.id}"]`);
|
||
const checkbox = tableRow.querySelector('.table-checkbox');
|
||
|
||
tableRow.classList.remove('selected');
|
||
checkbox.classList.remove('checked');
|
||
});
|
||
|
||
updateSelectedAccountsInfo();
|
||
updateSelectAllCheckbox();
|
||
addLog('已清空所有选择', 'info');
|
||
}
|
||
|
||
// 切换账号状态
|
||
function toggleAccountStatus(accountId) {
|
||
const account = systemData.accounts.find(acc => acc.id === accountId);
|
||
|
||
if (account) {
|
||
if (account.status === 'running') {
|
||
account.status = 'paused';
|
||
addLog(`账号"${account.name}"已暂停`, 'warning');
|
||
} else {
|
||
account.status = 'running';
|
||
addLog(`账号"${account.name}"已启动`, 'success');
|
||
}
|
||
|
||
// 重新加载数据
|
||
loadDashboardData();
|
||
updateSelectedAccountsInfo();
|
||
}
|
||
}
|
||
|
||
// 启动选中账号
|
||
function startSelectedAccounts() {
|
||
if (systemData.selectedAccountIds.length === 0) {
|
||
addLog('请先选择要启动的账号', 'warning');
|
||
return;
|
||
}
|
||
|
||
let startedCount = 0;
|
||
systemData.accounts.forEach(account => {
|
||
if (systemData.selectedAccountIds.includes(account.id) && account.status !== 'running') {
|
||
account.status = 'running';
|
||
startedCount++;
|
||
}
|
||
});
|
||
|
||
if (startedCount > 0) {
|
||
addLog(`已启动 ${startedCount} 个选中账号`, 'success');
|
||
loadDashboardData();
|
||
updateSelectedAccountsInfo();
|
||
} else {
|
||
addLog('选中的账号已全部在运行中', 'info');
|
||
}
|
||
}
|
||
|
||
// 暂停选中账号
|
||
function pauseSelectedAccounts() {
|
||
if (systemData.selectedAccountIds.length === 0) {
|
||
addLog('请先选择要暂停的账号', 'warning');
|
||
return;
|
||
}
|
||
|
||
let pausedCount = 0;
|
||
systemData.accounts.forEach(account => {
|
||
if (systemData.selectedAccountIds.includes(account.id) && account.status === 'running') {
|
||
account.status = 'paused';
|
||
pausedCount++;
|
||
}
|
||
});
|
||
|
||
if (pausedCount > 0) {
|
||
addLog(`已暂停 ${pausedCount} 个选中账号`, 'warning');
|
||
loadDashboardData();
|
||
updateSelectedAccountsInfo();
|
||
} else {
|
||
addLog('选中的账号没有正在运行的', 'info');
|
||
}
|
||
}
|
||
|
||
// 停止选中账号
|
||
function stopSelectedAccounts() {
|
||
if (systemData.selectedAccountIds.length === 0) {
|
||
addLog('请先选择要停止的账号', 'warning');
|
||
return;
|
||
}
|
||
|
||
let stoppedCount = 0;
|
||
systemData.accounts.forEach(account => {
|
||
if (systemData.selectedAccountIds.includes(account.id) && account.status !== 'stopped') {
|
||
account.status = 'stopped';
|
||
stoppedCount++;
|
||
}
|
||
});
|
||
|
||
if (stoppedCount > 0) {
|
||
addLog(`已停止 ${stoppedCount} 个选中账号`, 'info');
|
||
loadDashboardData();
|
||
updateSelectedAccountsInfo();
|
||
} else {
|
||
addLog('选中的账号已全部停止', 'info');
|
||
}
|
||
}
|
||
|
||
// 启动全部账号
|
||
function startAllAccounts() {
|
||
// 先全选所有账号
|
||
selectAllAccounts();
|
||
|
||
let startedCount = 0;
|
||
systemData.accounts.forEach(account => {
|
||
if (account.status !== 'running') {
|
||
account.status = 'running';
|
||
startedCount++;
|
||
}
|
||
});
|
||
|
||
if (startedCount > 0) {
|
||
addLog(`已启动全部 ${startedCount} 个账号`, 'success');
|
||
loadDashboardData();
|
||
updateSelectedAccountsInfo();
|
||
} else {
|
||
addLog('所有账号已在运行中', 'info');
|
||
}
|
||
}
|
||
|
||
// 刷新数据
|
||
function refreshDashboardData() {
|
||
// 模拟数据更新
|
||
systemData.accounts.forEach(account => {
|
||
if (account.status === 'running') {
|
||
// 随机增加联系人数
|
||
const increment = Math.floor(Math.random() * 3) + 1;
|
||
account.todayContacts = Math.min(account.todayContacts + increment, account.dailyLimit);
|
||
|
||
// 随机增加微信交换
|
||
if (Math.random() > 0.7 && account.todayContacts > 0) {
|
||
account.wechatExchanged = Math.min(account.wechatExchanged + 1, account.todayContacts);
|
||
}
|
||
}
|
||
});
|
||
|
||
loadDashboardData();
|
||
addLog('数据已刷新', 'info');
|
||
}
|
||
|
||
// 快速操作
|
||
function quickAction(action) {
|
||
switch(action) {
|
||
case 'export':
|
||
addLog('导出今日数据', 'info');
|
||
alert('今日数据导出成功!');
|
||
break;
|
||
case 'pauseAll':
|
||
systemData.accounts.forEach(account => {
|
||
if (account.status === 'running') {
|
||
account.status = 'paused';
|
||
}
|
||
});
|
||
loadDashboardData();
|
||
addLog('已暂停所有任务', 'warning');
|
||
break;
|
||
case 'checkUpdate':
|
||
addLog('检查系统更新', 'info');
|
||
alert('当前已是最新版本!');
|
||
break;
|
||
case 'backup':
|
||
addLog('立即备份数据', 'success');
|
||
alert('数据备份成功!');
|
||
break;
|
||
case 'report':
|
||
addLog('生成日报', 'info');
|
||
alert('日报生成成功!');
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 添加日志
|
||
function addLog(message, type = 'info') {
|
||
const logContainer = document.getElementById('realtimeLogs');
|
||
if (!logContainer) return;
|
||
|
||
const now = new Date();
|
||
const time = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;
|
||
|
||
let typeClass = 'log-info';
|
||
let typeText = '[INFO]';
|
||
|
||
switch(type) {
|
||
case 'success':
|
||
typeClass = 'log-success';
|
||
typeText = '[SUCCESS]';
|
||
break;
|
||
case 'warning':
|
||
typeClass = 'log-warning';
|
||
typeText = '[WARNING]';
|
||
break;
|
||
case 'error':
|
||
typeClass = 'log-error';
|
||
typeText = '[ERROR]';
|
||
break;
|
||
}
|
||
|
||
const logEntry = document.createElement('div');
|
||
logEntry.className = 'log-entry';
|
||
logEntry.innerHTML = `
|
||
<span class="log-time">${time}</span>
|
||
<span class="${typeClass}">${typeText}</span>
|
||
${message}
|
||
`;
|
||
|
||
logContainer.prepend(logEntry);
|
||
|
||
// 限制日志数量
|
||
if (logContainer.children.length > 50) {
|
||
logContainer.removeChild(logContainer.lastChild);
|
||
}
|
||
}
|
||
|
||
// 清空日志
|
||
function clearLogs() {
|
||
document.getElementById('realtimeLogs').innerHTML = '';
|
||
addLog('日志已清空', 'info');
|
||
}
|
||
|
||
// 切换日志暂停
|
||
function toggleLogPause() {
|
||
systemData.logsPaused = !systemData.logsPaused;
|
||
const button = document.getElementById('pauseLogs');
|
||
|
||
if (systemData.logsPaused) {
|
||
button.innerHTML = '<i class="fas fa-play"></i> 继续更新';
|
||
addLog('日志更新已暂停', 'warning');
|
||
} else {
|
||
button.innerHTML = '<i class="fas fa-pause"></i> 暂停更新';
|
||
addLog('日志更新已恢复', 'info');
|
||
}
|
||
}
|
||
|
||
// 模拟日志更新
|
||
function startLogSimulation() {
|
||
if (systemData.logSimulationInterval) {
|
||
clearInterval(systemData.logSimulationInterval);
|
||
}
|
||
|
||
systemData.logSimulationInterval = setInterval(() => {
|
||
if (systemData.logsPaused) return;
|
||
|
||
const runningAccounts = systemData.accounts.filter(acc => acc.status === 'running');
|
||
if (runningAccounts.length === 0) return;
|
||
|
||
// 随机选择一个运行的账号
|
||
const account = runningAccounts[Math.floor(Math.random() * runningAccounts.length)];
|
||
|
||
const actions = [
|
||
{msg: `${account.name}: 向新的候选人发送招呼语`, type: 'info'},
|
||
{msg: `${account.name}: 收到候选人的回复`, type: 'success'},
|
||
{msg: `${account.name}: 与候选人成功交换微信`, type: 'success'},
|
||
{msg: `${account.name}: 检测到冻结账号,已自动跳过`, type: 'warning'},
|
||
{msg: `${account.name}: 发现新消息,正在分析`, type: 'info'},
|
||
{msg: `${account.name}: 完成今日目标${Math.round((account.todayContacts/account.dailyLimit)*100)}%`, type: 'info'},
|
||
{msg: `系统运行正常,${runningAccounts.length}个账号工作中`, type: 'info'}
|
||
];
|
||
|
||
if (Math.random() > 0.3) {
|
||
const action = actions[Math.floor(Math.random() * actions.length)];
|
||
addLog(action.msg, action.type);
|
||
}
|
||
}, 3000);
|
||
}
|
||
|
||
// ========== 账号管理页面 ==========
|
||
function initAccountsPage() {
|
||
loadAccountsTable();
|
||
|
||
// 添加账号按钮
|
||
document.getElementById('addNewAccount').addEventListener('click', function() {
|
||
document.getElementById('addAccountForm').style.display = 'block';
|
||
this.style.display = 'none';
|
||
});
|
||
|
||
// 取消添加账号
|
||
document.getElementById('cancelAddAccount').addEventListener('click', function() {
|
||
document.getElementById('addAccountForm').style.display = 'none';
|
||
document.getElementById('addNewAccount').style.display = 'inline-flex';
|
||
clearAccountForm();
|
||
});
|
||
|
||
// 保存账号
|
||
document.getElementById('saveAccount').addEventListener('click', saveAccount);
|
||
|
||
// 导出账号
|
||
document.getElementById('exportAccounts').addEventListener('click', function() {
|
||
addLog('导出账号数据', 'info');
|
||
alert('账号数据导出成功!');
|
||
});
|
||
}
|
||
|
||
function loadAccountsTable() {
|
||
const tableBody = document.getElementById('accountsTableBody');
|
||
tableBody.innerHTML = '';
|
||
|
||
systemData.accounts.forEach(account => {
|
||
const row = document.createElement('tr');
|
||
row.innerHTML = `
|
||
<td>${account.name}</td>
|
||
<td>${account.bossAccount}</td>
|
||
<td>******</td>
|
||
<td>${account.threads}</td>
|
||
<td>${account.dailyLimit}</td>
|
||
<td>
|
||
<span class="status-badge ${account.status === 'running' ? 'status-running' : account.status === 'paused' ? 'status-paused' : 'status-stopped'}">
|
||
${account.status === 'running' ? '运行中' : account.status === 'paused' ? '已暂停' : '已停止'}
|
||
</span>
|
||
</td>
|
||
<td>
|
||
<div style="display: flex; gap: 8px;">
|
||
<button class="btn btn-sm btn-secondary" onclick="editAccountForm(${account.id})">
|
||
<i class="fas fa-edit"></i>
|
||
</button>
|
||
<button class="btn btn-sm btn-danger" onclick="deleteAccount(${account.id})">
|
||
<i class="fas fa-trash"></i>
|
||
</button>
|
||
</div>
|
||
</td>
|
||
`;
|
||
tableBody.appendChild(row);
|
||
});
|
||
}
|
||
|
||
function clearAccountForm() {
|
||
document.getElementById('accountName').value = '';
|
||
document.getElementById('bossAccount').value = '';
|
||
document.getElementById('accountPassword').value = '';
|
||
document.getElementById('confirmPassword').value = '';
|
||
document.getElementById('threadCount').value = '3';
|
||
document.getElementById('dailyLimit').value = '150';
|
||
document.getElementById('accountNotes').value = '';
|
||
}
|
||
|
||
function saveAccount() {
|
||
const name = document.getElementById('accountName').value;
|
||
const bossAccount = document.getElementById('bossAccount').value;
|
||
const password = document.getElementById('accountPassword').value;
|
||
const confirmPassword = document.getElementById('confirmPassword').value;
|
||
const threads = parseInt(document.getElementById('threadCount').value);
|
||
const dailyLimit = parseInt(document.getElementById('dailyLimit').value);
|
||
|
||
if (!name || !bossAccount || !password) {
|
||
alert('请填写完整的账号信息!');
|
||
return;
|
||
}
|
||
|
||
if (password !== confirmPassword) {
|
||
alert('两次输入的密码不一致!');
|
||
return;
|
||
}
|
||
|
||
// 创建新账号对象
|
||
const newAccount = {
|
||
id: systemData.accounts.length + 1,
|
||
name: name,
|
||
bossAccount: bossAccount,
|
||
threads: threads,
|
||
status: "stopped",
|
||
todayContacts: 0,
|
||
dailyLimit: dailyLimit,
|
||
wechatExchanged: 0,
|
||
selected: false
|
||
};
|
||
|
||
systemData.accounts.push(newAccount);
|
||
|
||
// 更新UI
|
||
loadAccountsTable();
|
||
document.getElementById('addAccountForm').style.display = 'none';
|
||
document.getElementById('addNewAccount').style.display = 'inline-flex';
|
||
clearAccountForm();
|
||
|
||
// 更新账号数量
|
||
document.getElementById('accountCount').textContent = systemData.accounts.length;
|
||
|
||
addLog(`已添加新账号: ${name}`, 'success');
|
||
alert('账号添加成功!');
|
||
}
|
||
|
||
function editAccountForm(accountId) {
|
||
addLog(`编辑账号 ID: ${accountId}`, 'info');
|
||
alert('编辑账号功能开发中...');
|
||
}
|
||
|
||
function deleteAccount(accountId) {
|
||
if (confirm('确定要删除这个账号吗?')) {
|
||
systemData.accounts = systemData.accounts.filter(acc => acc.id !== accountId);
|
||
loadAccountsTable();
|
||
document.getElementById('accountCount').textContent = systemData.accounts.length;
|
||
addLog(`已删除账号 ID: ${accountId}`, 'info');
|
||
}
|
||
}
|
||
|
||
// ========== 筛选设置页面 ==========
|
||
function initFiltersPage() {
|
||
// 保存筛选设置
|
||
document.getElementById('saveFilters').addEventListener('click', function() {
|
||
const minAge = document.getElementById('minAge').value;
|
||
const maxAge = document.getElementById('maxAge').value;
|
||
const education = document.getElementById('educationLevel').value;
|
||
const activity = document.getElementById('activityLevel').value;
|
||
|
||
// 获取选中的岗位
|
||
const positions = [];
|
||
if (document.getElementById('positionJava').checked) positions.push('Java开发');
|
||
if (document.getElementById('positionFrontend').checked) positions.push('前端开发');
|
||
if (document.getElementById('positionBackend').checked) positions.push('后端开发');
|
||
if (document.getElementById('positionTest').checked) positions.push('软件测试');
|
||
if (document.getElementById('positionProduct').checked) positions.push('产品经理');
|
||
if (document.getElementById('positionUI').checked) positions.push('UI设计');
|
||
|
||
// 创建筛选标签
|
||
const filterText = `年龄${minAge}-${maxAge},${education},${activity}`;
|
||
const positionText = positions.length > 0 ? positions.join('/') + ',活跃用户' : '';
|
||
|
||
// 添加到筛选标签区域
|
||
if (positionText) {
|
||
addFilterTag(`${filterText},${positionText}`);
|
||
} else {
|
||
addFilterTag(filterText);
|
||
}
|
||
|
||
addLog('筛选条件已保存', 'success');
|
||
alert('筛选设置保存成功!');
|
||
});
|
||
}
|
||
|
||
function addFilterTag(text) {
|
||
const filterTags = document.getElementById('filterTags');
|
||
const tag = document.createElement('div');
|
||
tag.className = 'filter-tag';
|
||
tag.innerHTML = `
|
||
${text}
|
||
<i class="fas fa-times" onclick="removeFilterTag(this)"></i>
|
||
`;
|
||
filterTags.appendChild(tag);
|
||
}
|
||
|
||
function removeFilterTag(element) {
|
||
element.parentElement.remove();
|
||
}
|
||
|
||
// ========== 任务管理页面 ==========
|
||
function initTasksPage() {
|
||
loadTaskGrid();
|
||
loadTaskSelection();
|
||
|
||
// 创建新任务按钮
|
||
document.getElementById('createNewTask').addEventListener('click', function() {
|
||
document.getElementById('taskForm').style.display = 'block';
|
||
this.style.display = 'none';
|
||
loadAccountSelection();
|
||
});
|
||
|
||
// 取消创建任务
|
||
document.getElementById('cancelTask').addEventListener('click', function() {
|
||
document.getElementById('taskForm').style.display = 'none';
|
||
document.getElementById('createNewTask').style.display = 'inline-flex';
|
||
clearTaskForm();
|
||
});
|
||
|
||
// 保存任务
|
||
document.getElementById('saveTask').addEventListener('click', saveTask);
|
||
|
||
// 任务筛选
|
||
document.getElementById('taskFilter').addEventListener('change', function() {
|
||
loadTaskGrid();
|
||
});
|
||
|
||
// 任务选择相关
|
||
document.getElementById('runSelectedTasks').addEventListener('click', runSelectedTasks);
|
||
document.getElementById('selectAllTasks').addEventListener('click', selectAllTasks);
|
||
document.getElementById('clearTaskSelection').addEventListener('click', clearTaskSelection);
|
||
}
|
||
|
||
function loadTaskGrid() {
|
||
const taskGrid = document.getElementById('taskGrid');
|
||
taskGrid.innerHTML = '';
|
||
|
||
const filter = document.getElementById('taskFilter').value;
|
||
|
||
let filteredTasks = systemData.tasks;
|
||
if (filter !== 'all') {
|
||
filteredTasks = systemData.tasks.filter(task => task.status === filter);
|
||
}
|
||
|
||
filteredTasks.forEach(task => {
|
||
const taskCard = document.createElement('div');
|
||
taskCard.className = 'task-card';
|
||
|
||
let statusClass = '';
|
||
let statusText = '';
|
||
|
||
switch(task.status) {
|
||
case 'running':
|
||
statusClass = 'status-running';
|
||
statusText = '运行中';
|
||
break;
|
||
case 'paused':
|
||
statusClass = 'status-paused';
|
||
statusText = '已暂停';
|
||
break;
|
||
case 'stopped':
|
||
statusClass = 'status-stopped';
|
||
statusText = '已停止';
|
||
break;
|
||
}
|
||
|
||
let typeText = '';
|
||
switch(task.type) {
|
||
case 'greeting':
|
||
typeText = '自动化打招呼';
|
||
break;
|
||
case 'rechat':
|
||
typeText = '复聊任务';
|
||
break;
|
||
case 'collection':
|
||
typeText = '收藏任务';
|
||
break;
|
||
case 'monitoring':
|
||
typeText = '监测消息';
|
||
break;
|
||
}
|
||
|
||
taskCard.innerHTML = `
|
||
<div class="task-card-header">
|
||
<div class="task-card-title">${task.name}</div>
|
||
<div class="task-card-status ${statusClass}">${statusText}</div>
|
||
</div>
|
||
<div class="task-card-body">
|
||
<p>${task.description}</p>
|
||
<div style="margin-top: 10px;">
|
||
<div><small>执行时间: ${task.time}</small></div>
|
||
<div><small>重复周期: ${task.repeat === 'daily' ? '每天' : task.repeat === 'weekly' ? '每周' : '仅一次'}</small></div>
|
||
<div><small>任务类型: ${typeText}</small></div>
|
||
</div>
|
||
</div>
|
||
<div class="task-card-footer">
|
||
<small>ID: ${task.id}</small>
|
||
<div class="task-card-actions">
|
||
<button class="btn btn-sm ${task.status === 'running' ? 'btn-warning' : 'btn-success'}" onclick="toggleTaskStatus(${task.id})">
|
||
<i class="fas fa-${task.status === 'running' ? 'pause' : 'play'}"></i>
|
||
</button>
|
||
<button class="btn btn-sm btn-secondary" onclick="editTask(${task.id})">
|
||
<i class="fas fa-edit"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
taskGrid.appendChild(taskCard);
|
||
});
|
||
}
|
||
|
||
function loadTaskSelection() {
|
||
const selectionArea = document.getElementById('taskSelectionArea');
|
||
selectionArea.innerHTML = '';
|
||
|
||
systemData.tasks.forEach(task => {
|
||
const isSelected = systemData.selectedTaskIds.includes(task.id);
|
||
const div = document.createElement('div');
|
||
div.style.marginBottom = '10px';
|
||
div.innerHTML = `
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" value="${task.id}" ${isSelected ? 'checked' : ''} onchange="toggleTaskSelection(${task.id})">
|
||
${task.name} (${task.type === 'greeting' ? '打招呼' : task.type === 'rechat' ? '复聊' : task.type === 'collection' ? '收藏' : '监测'})
|
||
</label>
|
||
`;
|
||
selectionArea.appendChild(div);
|
||
});
|
||
}
|
||
|
||
function loadAccountSelection() {
|
||
const selectionArea = document.getElementById('accountSelection');
|
||
selectionArea.innerHTML = '';
|
||
|
||
systemData.accounts.forEach(account => {
|
||
const div = document.createElement('div');
|
||
div.innerHTML = `
|
||
<label class="checkbox-label">
|
||
<input type="checkbox" value="${account.id}">
|
||
${account.name} (${account.bossAccount})
|
||
</label>
|
||
`;
|
||
selectionArea.appendChild(div);
|
||
});
|
||
}
|
||
|
||
function clearTaskForm() {
|
||
document.getElementById('taskName').value = '';
|
||
document.getElementById('taskDescription').value = '';
|
||
}
|
||
|
||
function saveTask() {
|
||
const name = document.getElementById('taskName').value;
|
||
const type = document.getElementById('taskType').value;
|
||
const time = document.getElementById('taskTime').value;
|
||
const repeat = document.getElementById('taskRepeat').value;
|
||
const description = document.getElementById('taskDescription').value;
|
||
|
||
if (!name || !description) {
|
||
alert('请填写任务名称和描述!');
|
||
return;
|
||
}
|
||
|
||
// 获取选中的账号
|
||
const selectedAccounts = [];
|
||
document.querySelectorAll('#accountSelection input[type="checkbox"]:checked').forEach(cb => {
|
||
selectedAccounts.push(parseInt(cb.value));
|
||
});
|
||
|
||
// 创建新任务对象
|
||
const newTask = {
|
||
id: systemData.tasks.length + 1,
|
||
name: name,
|
||
type: type,
|
||
status: "stopped",
|
||
description: description,
|
||
time: time,
|
||
repeat: repeat,
|
||
accounts: selectedAccounts
|
||
};
|
||
|
||
systemData.tasks.push(newTask);
|
||
|
||
// 更新UI
|
||
loadTaskGrid();
|
||
loadTaskSelection();
|
||
document.getElementById('taskForm').style.display = 'none';
|
||
document.getElementById('createNewTask').style.display = 'inline-flex';
|
||
clearTaskForm();
|
||
|
||
// 更新任务数量
|
||
document.getElementById('taskCount').textContent = systemData.tasks.length;
|
||
|
||
addLog(`已创建新任务: ${name}`, 'success');
|
||
alert('任务创建成功!');
|
||
}
|
||
|
||
function toggleTaskStatus(taskId) {
|
||
const task = systemData.tasks.find(t => t.id === taskId);
|
||
if (task) {
|
||
if (task.status === 'running') {
|
||
task.status = 'paused';
|
||
addLog(`任务"${task.name}"已暂停`, 'warning');
|
||
} else {
|
||
task.status = 'running';
|
||
addLog(`任务"${task.name}"已启动`, 'success');
|
||
}
|
||
loadTaskGrid();
|
||
}
|
||
}
|
||
|
||
function toggleTaskSelection(taskId) {
|
||
const index = systemData.selectedTaskIds.indexOf(taskId);
|
||
if (index === -1) {
|
||
systemData.selectedTaskIds.push(taskId);
|
||
} else {
|
||
systemData.selectedTaskIds.splice(index, 1);
|
||
}
|
||
}
|
||
|
||
function runSelectedTasks() {
|
||
if (systemData.selectedTaskIds.length === 0) {
|
||
alert('请先选择要运行的任务!');
|
||
return;
|
||
}
|
||
|
||
let count = 0;
|
||
systemData.selectedTaskIds.forEach(taskId => {
|
||
const task = systemData.tasks.find(t => t.id === taskId);
|
||
if (task && task.status !== 'running') {
|
||
task.status = 'running';
|
||
count++;
|
||
}
|
||
});
|
||
|
||
if (count > 0) {
|
||
loadTaskGrid();
|
||
addLog(`已启动 ${count} 个选中任务`, 'success');
|
||
alert(`已成功启动 ${count} 个任务!`);
|
||
} else {
|
||
alert('选中的任务已全部在运行中!');
|
||
}
|
||
}
|
||
|
||
function selectAllTasks() {
|
||
systemData.selectedTaskIds = systemData.tasks.map(task => task.id);
|
||
loadTaskSelection();
|
||
}
|
||
|
||
function clearTaskSelection() {
|
||
systemData.selectedTaskIds = [];
|
||
loadTaskSelection();
|
||
}
|
||
|
||
function editTask(taskId) {
|
||
addLog(`编辑任务 ID: ${taskId}`, 'info');
|
||
alert('编辑任务功能开发中...');
|
||
}
|
||
|
||
// ========== 复聊管理页面 ==========
|
||
function initRechatPage() {
|
||
loadScriptGrid();
|
||
|
||
// 添加话术按钮
|
||
document.getElementById('addScript').addEventListener('click', function() {
|
||
document.getElementById('scriptForm').style.display = 'block';
|
||
this.style.display = 'none';
|
||
});
|
||
|
||
// 取消添加话术
|
||
document.getElementById('cancelScript').addEventListener('click', function() {
|
||
document.getElementById('scriptForm').style.display = 'none';
|
||
document.getElementById('addScript').style.display = 'inline-flex';
|
||
clearScriptForm();
|
||
});
|
||
|
||
// 保存话术
|
||
document.getElementById('saveScript').addEventListener('click', saveScript);
|
||
|
||
// 保存复聊策略
|
||
document.getElementById('saveFilters').addEventListener('click', function() {
|
||
addLog('复聊策略已保存', 'success');
|
||
alert('复聊策略保存成功!');
|
||
});
|
||
}
|
||
|
||
function loadScriptGrid() {
|
||
const scriptGrid = document.getElementById('scriptGrid');
|
||
scriptGrid.innerHTML = '';
|
||
|
||
systemData.scripts.forEach(script => {
|
||
const scriptCard = document.createElement('div');
|
||
scriptCard.className = 'script-card';
|
||
|
||
let typeText = '';
|
||
switch(script.type) {
|
||
case 'first':
|
||
typeText = '首次回复';
|
||
break;
|
||
case 'followup':
|
||
typeText = '跟进回复';
|
||
break;
|
||
case 'wechat':
|
||
typeText = '微信交换';
|
||
break;
|
||
case 'closing':
|
||
typeText = '结束语';
|
||
break;
|
||
}
|
||
|
||
scriptCard.innerHTML = `
|
||
<div class="script-card-header">
|
||
<div class="script-card-title">${script.position} - ${typeText}</div>
|
||
<div>
|
||
<button class="btn btn-sm btn-secondary" onclick="editScript(${script.id})">
|
||
<i class="fas fa-edit"></i>
|
||
</button>
|
||
<button class="btn btn-sm btn-danger" onclick="deleteScript(${script.id})">
|
||
<i class="fas fa-trash"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="script-card-body">
|
||
<p>${script.content}</p>
|
||
</div>
|
||
<div class="script-card-footer">
|
||
<small>关键词: ${script.keywords || '无'}</small>
|
||
</div>
|
||
`;
|
||
|
||
scriptGrid.appendChild(scriptCard);
|
||
});
|
||
}
|
||
|
||
function clearScriptForm() {
|
||
document.getElementById('scriptContent').value = '';
|
||
document.getElementById('scriptKeywords').value = '';
|
||
}
|
||
|
||
function saveScript() {
|
||
const position = document.getElementById('scriptPosition').value;
|
||
const type = document.getElementById('scriptType').value;
|
||
const content = document.getElementById('scriptContent').value;
|
||
const keywords = document.getElementById('scriptKeywords').value;
|
||
|
||
if (!content) {
|
||
alert('请输入回复话术内容!');
|
||
return;
|
||
}
|
||
|
||
// 创建新话术对象
|
||
const newScript = {
|
||
id: systemData.scripts.length + 1,
|
||
position: position,
|
||
type: type,
|
||
content: content,
|
||
keywords: keywords
|
||
};
|
||
|
||
systemData.scripts.push(newScript);
|
||
|
||
// 更新UI
|
||
loadScriptGrid();
|
||
document.getElementById('scriptForm').style.display = 'none';
|
||
document.getElementById('addScript').style.display = 'inline-flex';
|
||
clearScriptForm();
|
||
|
||
addLog(`已添加新话术: ${position} - ${type}`, 'success');
|
||
alert('话术保存成功!');
|
||
}
|
||
|
||
function editScript(scriptId) {
|
||
addLog(`编辑话术 ID: ${scriptId}`, 'info');
|
||
alert('编辑话术功能开发中...');
|
||
}
|
||
|
||
function deleteScript(scriptId) {
|
||
if (confirm('确定要删除这个话术吗?')) {
|
||
systemData.scripts = systemData.scripts.filter(script => script.id !== scriptId);
|
||
loadScriptGrid();
|
||
addLog(`已删除话术 ID: ${scriptId}`, 'info');
|
||
}
|
||
}
|
||
|
||
// ========== 数据管理页面 ==========
|
||
function initDataPage() {
|
||
loadDataTable();
|
||
|
||
// 刷新数据
|
||
document.getElementById('refreshData').addEventListener('click', function() {
|
||
loadDataTable();
|
||
addLog('数据已刷新', 'info');
|
||
});
|
||
|
||
// 导出数据
|
||
document.getElementById('exportData').addEventListener('click', function() {
|
||
addLog('导出数据', 'info');
|
||
alert('数据导出成功!');
|
||
});
|
||
|
||
// 确认导出
|
||
document.getElementById('confirmExport').addEventListener('click', function() {
|
||
const format = document.getElementById('exportFormat').value;
|
||
const range = document.getElementById('exportRange').value;
|
||
|
||
addLog(`导出${range}数据,格式: ${format}`, 'success');
|
||
alert(`数据导出成功!格式: ${format}, 范围: ${range}`);
|
||
});
|
||
|
||
// 搜索数据
|
||
document.getElementById('dataSearch').addEventListener('input', function(e) {
|
||
loadDataTable(e.target.value);
|
||
});
|
||
|
||
// 分页控制
|
||
document.getElementById('prevPage').addEventListener('click', function() {
|
||
if (systemData.currentDataPage > 1) {
|
||
systemData.currentDataPage--;
|
||
loadDataTable();
|
||
}
|
||
});
|
||
|
||
document.getElementById('nextPage').addEventListener('click', function() {
|
||
const totalPages = Math.ceil(systemData.userData.length / systemData.dataPerPage);
|
||
if (systemData.currentDataPage < totalPages) {
|
||
systemData.currentDataPage++;
|
||
loadDataTable();
|
||
}
|
||
});
|
||
}
|
||
|
||
function loadDataTable(searchTerm = '') {
|
||
const tableBody = document.getElementById('dataTableBody');
|
||
tableBody.innerHTML = '';
|
||
|
||
// 筛选数据
|
||
let filteredData = systemData.userData;
|
||
if (searchTerm) {
|
||
filteredData = systemData.userData.filter(user =>
|
||
user.name.includes(searchTerm) ||
|
||
user.position.includes(searchTerm) ||
|
||
user.contact.includes(searchTerm)
|
||
);
|
||
}
|
||
|
||
// 计算分页
|
||
const startIndex = (systemData.currentDataPage - 1) * systemData.dataPerPage;
|
||
const endIndex = Math.min(startIndex + systemData.dataPerPage, filteredData.length);
|
||
const pageData = filteredData.slice(startIndex, endIndex);
|
||
|
||
// 填充表格
|
||
pageData.forEach(user => {
|
||
const row = document.createElement('tr');
|
||
row.innerHTML = `
|
||
<td>${user.id}</td>
|
||
<td>${user.name}</td>
|
||
<td>${user.position}</td>
|
||
<td>${user.contact}</td>
|
||
<td>${user.contactTime}</td>
|
||
<td>
|
||
<span class="status-badge ${user.replyStatus === '已回复' ? 'status-running' : 'status-stopped'}">
|
||
${user.replyStatus}
|
||
</span>
|
||
</td>
|
||
<td>
|
||
<span class="status-badge ${user.wechatExchanged ? 'status-running' : 'status-stopped'}">
|
||
${user.wechatExchanged ? '已交换' : '未交换'}
|
||
</span>
|
||
</td>
|
||
<td>
|
||
<button class="btn btn-sm btn-secondary" onclick="viewUserDetails(${user.id})">
|
||
<i class="fas fa-eye"></i>
|
||
</button>
|
||
</td>
|
||
`;
|
||
tableBody.appendChild(row);
|
||
});
|
||
|
||
// 更新分页信息
|
||
document.getElementById('dataStart').textContent = startIndex + 1;
|
||
document.getElementById('dataEnd').textContent = endIndex;
|
||
document.getElementById('dataTotal').textContent = filteredData.length;
|
||
}
|
||
|
||
function viewUserDetails(userId) {
|
||
addLog(`查看用户详情 ID: ${userId}`, 'info');
|
||
alert(`查看用户 ${userId} 的详细信息功能开发中...`);
|
||
}
|
||
|
||
// ========== 统计分析页面 ==========
|
||
function initAnalyticsPage() {
|
||
// 时间段选择
|
||
document.getElementById('analyticsPeriod').addEventListener('change', function() {
|
||
updateAnalyticsData(this.value);
|
||
});
|
||
|
||
// 图表类型选择
|
||
document.getElementById('chartType').addEventListener('change', function() {
|
||
addLog(`切换图表类型: ${this.value}`, 'info');
|
||
});
|
||
|
||
// 生成报告
|
||
document.getElementById('generateReport').addEventListener('click', function() {
|
||
addLog('生成分析报告', 'success');
|
||
alert('分析报告生成成功!');
|
||
});
|
||
|
||
// 初始化数据
|
||
updateAnalyticsData('week');
|
||
}
|
||
|
||
function updateAnalyticsData(period) {
|
||
// 这里可以添加根据时间段更新数据的逻辑
|
||
addLog(`更新统计分析数据,时间段: ${period}`, 'info');
|
||
}
|
||
|
||
// ========== 系统设置页面 ==========
|
||
function initSettingsPage() {
|
||
// 线程数滑块
|
||
const maxThreads = document.getElementById('maxThreads');
|
||
const threadValue = document.getElementById('threadValue');
|
||
|
||
maxThreads.addEventListener('input', function() {
|
||
threadValue.textContent = this.value + '线程';
|
||
});
|
||
|
||
// 测试数据库连接
|
||
document.getElementById('testDbConnection').addEventListener('click', function() {
|
||
addLog('测试数据库连接', 'info');
|
||
alert('数据库连接测试成功!');
|
||
});
|
||
|
||
// 保存数据库设置
|
||
document.getElementById('saveDbSettings').addEventListener('click', function() {
|
||
addLog('保存数据库设置', 'success');
|
||
alert('数据库设置保存成功!');
|
||
});
|
||
|
||
// 保存所有设置
|
||
document.getElementById('saveSettings').addEventListener('click', function() {
|
||
addLog('保存系统设置', 'success');
|
||
alert('系统设置保存成功!');
|
||
});
|
||
|
||
// 重启系统
|
||
document.getElementById('systemRestart').addEventListener('click', function() {
|
||
if (confirm('确定要重启系统吗?重启期间所有任务将暂停。')) {
|
||
addLog('系统重启中...', 'warning');
|
||
alert('系统正在重启,请稍候...');
|
||
setTimeout(() => {
|
||
addLog('系统重启完成', 'success');
|
||
alert('系统重启完成!');
|
||
}, 2000);
|
||
}
|
||
});
|
||
|
||
// 清除缓存
|
||
document.getElementById('clearCache').addEventListener('click', function() {
|
||
if (confirm('确定要清除系统缓存吗?')) {
|
||
addLog('清除系统缓存', 'info');
|
||
alert('系统缓存已清除!');
|
||
}
|
||
});
|
||
}
|
||
|
||
// 将部分函数暴露给全局作用域
|
||
window.removeFilterTag = removeFilterTag;
|
||
window.toggleTaskSelection = toggleTaskSelection;
|
||
window.toggleTaskStatus = toggleTaskStatus;
|
||
window.editTask = editTask;
|
||
window.editScript = editScript;
|
||
window.deleteScript = deleteScript;
|
||
window.viewUserDetails = viewUserDetails;
|
||
window.toggleAccountSelection = toggleAccountSelection;
|
||
window.toggleAccountStatus = toggleAccountStatus;
|
||
window.editAccount = editAccountForm;
|
||
window.quickAction = quickAction;
|
||
</script>
|
||
</body>
|
||
</html> |