|
|
@@ -0,0 +1,848 @@
|
|
|
+<!DOCTYPE html>
|
|
|
+<html lang="zh-CN">
|
|
|
+<head>
|
|
|
+ <meta charset="UTF-8">
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
|
+ <title>经营数据仪表板</title>
|
|
|
+ <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
|
|
+ <style>
|
|
|
+ * {
|
|
|
+ margin: 0;
|
|
|
+ padding: 0;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ body {
|
|
|
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
|
+ background: #f5f6fa;
|
|
|
+ color: #2d3436;
|
|
|
+ padding: 0;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .container {
|
|
|
+ max-width: 100%;
|
|
|
+ margin: 0 auto;
|
|
|
+ padding: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .header {
|
|
|
+ background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
|
|
|
+ color: white;
|
|
|
+ padding: 16px;
|
|
|
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
|
|
+ position: sticky;
|
|
|
+ top: 0;
|
|
|
+ z-index: 100;
|
|
|
+ }
|
|
|
+
|
|
|
+ .header h1 {
|
|
|
+ font-size: 20px;
|
|
|
+ font-weight: 600;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .date-switcher {
|
|
|
+ display: flex;
|
|
|
+ gap: 8px;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .date-picker-input {
|
|
|
+ flex: 1;
|
|
|
+ padding: 8px 12px;
|
|
|
+ background: white;
|
|
|
+ border: none;
|
|
|
+ border-radius: 6px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #2d3436;
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+
|
|
|
+ .date-btn {
|
|
|
+ padding: 8px 12px;
|
|
|
+ background: rgba(255,255,255,0.2);
|
|
|
+ border: 1px solid rgba(255,255,255,0.3);
|
|
|
+ color: white;
|
|
|
+ border-radius: 6px;
|
|
|
+ cursor: pointer;
|
|
|
+ font-size: 13px;
|
|
|
+ transition: all 0.3s;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+
|
|
|
+ .date-btn.active {
|
|
|
+ background: white;
|
|
|
+ color: #e74c3c;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+
|
|
|
+ .tab-container {
|
|
|
+ background: white;
|
|
|
+ padding: 12px;
|
|
|
+ border-bottom: 1px solid #e1e8ed;
|
|
|
+ display: flex;
|
|
|
+ gap: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .tab-btn {
|
|
|
+ flex: 1;
|
|
|
+ padding: 10px;
|
|
|
+ background: #f5f6fa;
|
|
|
+ border: none;
|
|
|
+ border-radius: 6px;
|
|
|
+ cursor: pointer;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #636e72;
|
|
|
+ transition: all 0.3s;
|
|
|
+ }
|
|
|
+
|
|
|
+ .tab-btn.active {
|
|
|
+ background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+
|
|
|
+ .content {
|
|
|
+ padding: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .section {
|
|
|
+ background: white;
|
|
|
+ border-radius: 12px;
|
|
|
+ padding: 16px;
|
|
|
+ margin-bottom: 16px;
|
|
|
+ box-shadow: 0 2px 8px rgba(0,0,0,0.06);
|
|
|
+ }
|
|
|
+
|
|
|
+ .section-title {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #2d3436;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ padding-bottom: 8px;
|
|
|
+ border-bottom: 2px solid #e74c3c;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .section-title::before {
|
|
|
+ content: '';
|
|
|
+ width: 4px;
|
|
|
+ height: 16px;
|
|
|
+ background: #e74c3c;
|
|
|
+ margin-right: 8px;
|
|
|
+ border-radius: 2px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .metrics-grid {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: 1fr 1fr;
|
|
|
+ gap: 12px;
|
|
|
+ margin-top: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .metric-card {
|
|
|
+ background: #f8f9fa;
|
|
|
+ padding: 12px;
|
|
|
+ border-radius: 8px;
|
|
|
+ border-left: 3px solid #e74c3c;
|
|
|
+ }
|
|
|
+
|
|
|
+ .metric-label {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #636e72;
|
|
|
+ margin-bottom: 4px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .metric-value {
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #2d3436;
|
|
|
+ }
|
|
|
+
|
|
|
+ .metric-value.positive {
|
|
|
+ color: #00b894;
|
|
|
+ }
|
|
|
+
|
|
|
+ .metric-value.negative {
|
|
|
+ color: #d63031;
|
|
|
+ }
|
|
|
+
|
|
|
+ .table-container {
|
|
|
+ overflow-x: auto;
|
|
|
+ margin-top: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .data-table {
|
|
|
+ width: 100%;
|
|
|
+ border-collapse: collapse;
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .data-table th {
|
|
|
+ background: #f8f9fa;
|
|
|
+ padding: 10px 8px;
|
|
|
+ text-align: left;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #636e72;
|
|
|
+ border-bottom: 2px solid #e1e8ed;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+
|
|
|
+ .data-table td {
|
|
|
+ padding: 10px 8px;
|
|
|
+ border-bottom: 1px solid #e1e8ed;
|
|
|
+ color: #2d3436;
|
|
|
+ }
|
|
|
+
|
|
|
+ .data-table tr:hover {
|
|
|
+ background: #f8f9fa;
|
|
|
+ }
|
|
|
+
|
|
|
+ .badge {
|
|
|
+ display: inline-block;
|
|
|
+ padding: 4px 8px;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 11px;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+
|
|
|
+ .badge.success {
|
|
|
+ background: #d4edda;
|
|
|
+ color: #155724;
|
|
|
+ }
|
|
|
+
|
|
|
+ .badge.warning {
|
|
|
+ background: #fff3cd;
|
|
|
+ color: #856404;
|
|
|
+ }
|
|
|
+
|
|
|
+ .badge.danger {
|
|
|
+ background: #f8d7da;
|
|
|
+ color: #721c24;
|
|
|
+ }
|
|
|
+
|
|
|
+ .subsection {
|
|
|
+ margin-top: 16px;
|
|
|
+ padding-top: 16px;
|
|
|
+ border-top: 1px dashed #dfe6e9;
|
|
|
+ }
|
|
|
+
|
|
|
+ .subsection-title {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #636e72;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ @media (max-width: 480px) {
|
|
|
+ .metrics-grid {
|
|
|
+ grid-template-columns: 1fr;
|
|
|
+ }
|
|
|
+
|
|
|
+ .data-table {
|
|
|
+ font-size: 11px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .data-table th,
|
|
|
+ .data-table td {
|
|
|
+ padding: 8px 4px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 模态框样式 */
|
|
|
+ .modal {
|
|
|
+ display: none;
|
|
|
+ position: fixed;
|
|
|
+ z-index: 1000;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ background-color: rgba(0,0,0,0.5);
|
|
|
+ animation: fadeIn 0.3s;
|
|
|
+ }
|
|
|
+
|
|
|
+ @keyframes fadeIn {
|
|
|
+ from { opacity: 0; }
|
|
|
+ to { opacity: 1; }
|
|
|
+ }
|
|
|
+
|
|
|
+ .modal-content {
|
|
|
+ background-color: white;
|
|
|
+ margin: 10% auto;
|
|
|
+ padding: 20px;
|
|
|
+ border-radius: 12px;
|
|
|
+ width: 90%;
|
|
|
+ max-width: 500px;
|
|
|
+ position: relative;
|
|
|
+ animation: slideIn 0.3s;
|
|
|
+ }
|
|
|
+
|
|
|
+ @keyframes slideIn {
|
|
|
+ from {
|
|
|
+ transform: translateY(-50px);
|
|
|
+ opacity: 0;
|
|
|
+ }
|
|
|
+ to {
|
|
|
+ transform: translateY(0);
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .modal-header {
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #2d3436;
|
|
|
+ margin-bottom: 16px;
|
|
|
+ padding-bottom: 12px;
|
|
|
+ border-bottom: 2px solid #e74c3c;
|
|
|
+ }
|
|
|
+
|
|
|
+ .close {
|
|
|
+ color: #636e72;
|
|
|
+ float: right;
|
|
|
+ font-size: 28px;
|
|
|
+ font-weight: bold;
|
|
|
+ line-height: 20px;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: color 0.3s;
|
|
|
+ }
|
|
|
+
|
|
|
+ .close:hover {
|
|
|
+ color: #e74c3c;
|
|
|
+ }
|
|
|
+
|
|
|
+ .chart-container {
|
|
|
+ position: relative;
|
|
|
+ height: 250px;
|
|
|
+ margin-top: 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .clickable {
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.3s;
|
|
|
+ }
|
|
|
+
|
|
|
+ .clickable:hover {
|
|
|
+ background: #fff5f5;
|
|
|
+ transform: scale(1.02);
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+</head>
|
|
|
+<body>
|
|
|
+ <div class="container">
|
|
|
+ <div class="header">
|
|
|
+ <h1>📊 经营数据仪表板</h1>
|
|
|
+ <div class="date-switcher">
|
|
|
+ <input type="date" class="date-picker-input" id="datePicker" value="">
|
|
|
+ <button class="date-btn active" onclick="switchDate('day')">当日</button>
|
|
|
+ <button class="date-btn" onclick="switchDate('month')">本月</button>
|
|
|
+ <button class="date-btn" onclick="switchDate('year')">当年</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="tab-container">
|
|
|
+ <button class="tab-btn active" onclick="switchTab('overview')">总体数据</button>
|
|
|
+ <button class="tab-btn" onclick="switchTab('operations')">运营指标</button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="content">
|
|
|
+ <!-- 公司总体经营数据 -->
|
|
|
+ <div id="overview-content" class="tab-content">
|
|
|
+ <!-- 存量业务 -->
|
|
|
+ <div class="section">
|
|
|
+ <div class="section-title">存量业务</div>
|
|
|
+ <div class="metrics-grid">
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">资产估值</div>
|
|
|
+ <div class="metric-value">¥8,520万</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">年收入目标</div>
|
|
|
+ <div class="metric-value">¥2,400万</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">预估成本</div>
|
|
|
+ <div class="metric-value">¥1,680万</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">预估净利润</div>
|
|
|
+ <div class="metric-value positive">¥720万</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="subsection">
|
|
|
+ <div class="subsection-title">实际数据</div>
|
|
|
+ <div class="metrics-grid">
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">实际收入</div>
|
|
|
+ <div class="metric-value">¥186.5万</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">实际成本</div>
|
|
|
+ <div class="metric-value">¥128.3万</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">实际利润</div>
|
|
|
+ <div class="metric-value positive">¥58.2万</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 增量业务 -->
|
|
|
+ <div class="section">
|
|
|
+ <div class="section-title">增量业务</div>
|
|
|
+ <div class="metrics-grid">
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">收入</div>
|
|
|
+ <div class="metric-value">¥45.8万</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">运营成本</div>
|
|
|
+ <div class="metric-value">¥18.6万</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">投放成本</div>
|
|
|
+ <div class="metric-value">¥15.2万</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">当下利润</div>
|
|
|
+ <div class="metric-value positive">¥12.0万</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 公司财务现金流 -->
|
|
|
+ <div class="section">
|
|
|
+ <div class="section-title">公司财务现金流</div>
|
|
|
+ <div class="metrics-grid">
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">收款</div>
|
|
|
+ <div class="metric-value positive">¥232.3万</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">支出</div>
|
|
|
+ <div class="metric-value negative">¥162.1万</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card" style="grid-column: 1 / -1;">
|
|
|
+ <div class="metric-label">账户现金流</div>
|
|
|
+ <div class="metric-value positive">¥70.2万</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 运营指标 -->
|
|
|
+ <div id="operations-content" class="tab-content" style="display: none;">
|
|
|
+ <!-- 存量 -->
|
|
|
+ <div class="section">
|
|
|
+ <div class="section-title">存量业务</div>
|
|
|
+
|
|
|
+ <div class="subsection-title">运营指标</div>
|
|
|
+ <div class="table-container">
|
|
|
+ <table class="data-table">
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <th>项目</th>
|
|
|
+ <th>收入</th>
|
|
|
+ <th>总粉丝</th>
|
|
|
+ <th>留存粉丝</th>
|
|
|
+ <th>当日掉粉</th>
|
|
|
+ <th>日活率</th>
|
|
|
+ <th>月活率</th>
|
|
|
+ <th>ARPU值</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ <tr>
|
|
|
+ <td>短剧存量</td>
|
|
|
+ <td>¥68.5万</td>
|
|
|
+ <td>125,680</td>
|
|
|
+ <td>118,520</td>
|
|
|
+ <td>-356</td>
|
|
|
+ <td><span class="badge success">32.5%</span></td>
|
|
|
+ <td><span class="badge success">68.2%</span></td>
|
|
|
+ <td>¥5.78</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td>小说存量</td>
|
|
|
+ <td>¥52.3万</td>
|
|
|
+ <td>98,520</td>
|
|
|
+ <td>95,280</td>
|
|
|
+ <td>-258</td>
|
|
|
+ <td><span class="badge success">28.6%</span></td>
|
|
|
+ <td><span class="badge success">65.8%</span></td>
|
|
|
+ <td>¥5.31</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td>无双存量</td>
|
|
|
+ <td>¥65.7万</td>
|
|
|
+ <td>158,620</td>
|
|
|
+ <td>152,360</td>
|
|
|
+ <td>-412</td>
|
|
|
+ <td><span class="badge warning">25.3%</span></td>
|
|
|
+ <td><span class="badge success">62.5%</span></td>
|
|
|
+ <td>¥4.31</td>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="subsection">
|
|
|
+ <div class="subsection-title">封禁情况</div>
|
|
|
+ <div class="metrics-grid">
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">总客服数</div>
|
|
|
+ <div class="metric-value">186</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">当日新增封禁</div>
|
|
|
+ <div class="metric-value negative">8</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card clickable" style="grid-column: 1 / -1;" onclick="showBanChart('stock')">
|
|
|
+ <div class="metric-label">在封客服数量 <span style="font-size: 11px; color: #e74c3c;">▼ 点击查看7日趋势</span></div>
|
|
|
+ <div class="metric-value">23</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 增量 -->
|
|
|
+ <div class="section">
|
|
|
+ <div class="section-title">增量业务</div>
|
|
|
+
|
|
|
+ <div class="subsection-title">投放指标</div>
|
|
|
+ <div class="metrics-grid">
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">投放消耗</div>
|
|
|
+ <div class="metric-value">¥15.2万</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">新增粉丝数</div>
|
|
|
+ <div class="metric-value positive">12,580</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">新增粉价</div>
|
|
|
+ <div class="metric-value">¥12.08</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">当日留存率</div>
|
|
|
+ <div class="metric-value positive">82.5%</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card" style="grid-column: 1 / -1;">
|
|
|
+ <div class="metric-label">首日ROI</div>
|
|
|
+ <div class="metric-value positive">1.35</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="subsection">
|
|
|
+ <div class="subsection-title">运营指标</div>
|
|
|
+ <div style="display: flex; gap: 8px; margin-bottom: 12px;">
|
|
|
+ <button class="date-btn active" onclick="switchUserType('new')" style="flex: 1; background: rgba(231, 76, 60, 0.2); border: 1px solid rgba(231, 76, 60, 0.3); color: #e74c3c;">新用户(45天内)</button>
|
|
|
+ <button class="date-btn" onclick="switchUserType('old')" style="flex: 1; background: rgba(231, 76, 60, 0.2); border: 1px solid rgba(231, 76, 60, 0.3); color: #e74c3c;">老用户(45天以上)</button>
|
|
|
+ </div>
|
|
|
+ <div class="table-container" id="newUserTable">
|
|
|
+ <table class="data-table">
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <th>项目</th>
|
|
|
+ <th>收入</th>
|
|
|
+ <th>总粉丝</th>
|
|
|
+ <th>留存粉丝</th>
|
|
|
+ <th>掉粉率</th>
|
|
|
+ <th>日活率</th>
|
|
|
+ <th>月活率</th>
|
|
|
+ <th>ARPU值</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ <tr>
|
|
|
+ <td>新无双增量</td>
|
|
|
+ <td>¥28.6万</td>
|
|
|
+ <td>52,360</td>
|
|
|
+ <td>48,520</td>
|
|
|
+ <td><span class="badge warning">7.3%</span></td>
|
|
|
+ <td><span class="badge success">42.8%</span></td>
|
|
|
+ <td><span class="badge success">76.5%</span></td>
|
|
|
+ <td>¥5.89</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td>新无双存量</td>
|
|
|
+ <td>¥17.2万</td>
|
|
|
+ <td>28,650</td>
|
|
|
+ <td>26,380</td>
|
|
|
+ <td><span class="badge success">3.2%</span></td>
|
|
|
+ <td><span class="badge success">38.6%</span></td>
|
|
|
+ <td><span class="badge success">72.3%</span></td>
|
|
|
+ <td>¥6.52</td>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+ <div class="table-container" id="oldUserTable" style="display: none;">
|
|
|
+ <table class="data-table">
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <th>项目</th>
|
|
|
+ <th>收入</th>
|
|
|
+ <th>总粉丝</th>
|
|
|
+ <th>留存粉丝</th>
|
|
|
+ <th>掉粉率</th>
|
|
|
+ <th>日活率</th>
|
|
|
+ <th>月活率</th>
|
|
|
+ <th>ARPU值</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ <tr>
|
|
|
+ <td>新无双增量</td>
|
|
|
+ <td>¥15.8万</td>
|
|
|
+ <td>38,250</td>
|
|
|
+ <td>36,180</td>
|
|
|
+ <td><span class="badge success">5.4%</span></td>
|
|
|
+ <td><span class="badge success">35.2%</span></td>
|
|
|
+ <td><span class="badge success">68.9%</span></td>
|
|
|
+ <td>¥4.13</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td>新无双存量</td>
|
|
|
+ <td>¥22.3万</td>
|
|
|
+ <td>45,820</td>
|
|
|
+ <td>43,650</td>
|
|
|
+ <td><span class="badge success">4.7%</span></td>
|
|
|
+ <td><span class="badge success">31.8%</span></td>
|
|
|
+ <td><span class="badge success">65.2%</span></td>
|
|
|
+ <td>¥4.87</td>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="subsection">
|
|
|
+ <div class="subsection-title">封禁情况</div>
|
|
|
+ <div class="metrics-grid">
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">总客服数</div>
|
|
|
+ <div class="metric-value">92</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-label">当日新增封禁</div>
|
|
|
+ <div class="metric-value negative">3</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card clickable" style="grid-column: 1 / -1;" onclick="showBanChart('increment')">
|
|
|
+ <div class="metric-label">在封客服数量 <span style="font-size: 11px; color: #e74c3c;">▼ 点击查看7日趋势</span></div>
|
|
|
+ <div class="metric-value">11</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 图表模态框 -->
|
|
|
+ <div id="chartModal" class="modal">
|
|
|
+ <div class="modal-content">
|
|
|
+ <div class="modal-header">
|
|
|
+ <span class="close" onclick="closeChart()">×</span>
|
|
|
+ <span id="chartTitle">在封客服数量 - 7日趋势</span>
|
|
|
+ </div>
|
|
|
+ <div class="chart-container">
|
|
|
+ <canvas id="banChart"></canvas>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <script>
|
|
|
+ // 初始化日期选择器为当日
|
|
|
+ document.addEventListener('DOMContentLoaded', function() {
|
|
|
+ const datePicker = document.getElementById('datePicker');
|
|
|
+ const today = new Date().toISOString().split('T')[0];
|
|
|
+ datePicker.value = today;
|
|
|
+ });
|
|
|
+
|
|
|
+ function switchDate(type) {
|
|
|
+ const buttons = document.querySelectorAll('.date-btn');
|
|
|
+ buttons.forEach(btn => btn.classList.remove('active'));
|
|
|
+ event.target.classList.add('active');
|
|
|
+
|
|
|
+ const datePicker = document.getElementById('datePicker');
|
|
|
+ const today = new Date();
|
|
|
+
|
|
|
+ // 根据类型设置日期
|
|
|
+ if (type === 'day') {
|
|
|
+ datePicker.value = today.toISOString().split('T')[0];
|
|
|
+ } else if (type === 'month') {
|
|
|
+ // 设置为本月第一天
|
|
|
+ const firstDay = new Date(today.getFullYear(), today.getMonth(), 1);
|
|
|
+ datePicker.value = firstDay.toISOString().split('T')[0];
|
|
|
+ } else if (type === 'year') {
|
|
|
+ // 设置为当年第一天
|
|
|
+ const firstDay = new Date(today.getFullYear(), 0, 1);
|
|
|
+ datePicker.value = firstDay.toISOString().split('T')[0];
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('切换到:', type, '日期:', datePicker.value);
|
|
|
+ }
|
|
|
+
|
|
|
+ function switchTab(tab) {
|
|
|
+ const tabButtons = document.querySelectorAll('.tab-btn');
|
|
|
+ tabButtons.forEach(btn => btn.classList.remove('active'));
|
|
|
+ event.target.classList.add('active');
|
|
|
+
|
|
|
+ // 隐藏所有内容
|
|
|
+ document.getElementById('overview-content').style.display = 'none';
|
|
|
+ document.getElementById('operations-content').style.display = 'none';
|
|
|
+
|
|
|
+ // 显示选中的内容
|
|
|
+ if (tab === 'overview') {
|
|
|
+ document.getElementById('overview-content').style.display = 'block';
|
|
|
+ } else if (tab === 'operations') {
|
|
|
+ document.getElementById('operations-content').style.display = 'block';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function switchUserType(type) {
|
|
|
+ const buttons = event.target.parentElement.querySelectorAll('.date-btn');
|
|
|
+ buttons.forEach(btn => btn.classList.remove('active'));
|
|
|
+ event.target.classList.add('active');
|
|
|
+
|
|
|
+ const newUserTable = document.getElementById('newUserTable');
|
|
|
+ const oldUserTable = document.getElementById('oldUserTable');
|
|
|
+
|
|
|
+ if (type === 'new') {
|
|
|
+ newUserTable.style.display = 'block';
|
|
|
+ oldUserTable.style.display = 'none';
|
|
|
+ } else if (type === 'old') {
|
|
|
+ newUserTable.style.display = 'none';
|
|
|
+ oldUserTable.style.display = 'block';
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('切换用户类型:', type);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 图表相关功能
|
|
|
+ let currentChart = null;
|
|
|
+
|
|
|
+ function showBanChart(type) {
|
|
|
+ const modal = document.getElementById('chartModal');
|
|
|
+ modal.style.display = 'block';
|
|
|
+
|
|
|
+ // 销毁旧图表
|
|
|
+ if (currentChart) {
|
|
|
+ currentChart.destroy();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 准备数据
|
|
|
+ let data, title;
|
|
|
+ if (type === 'stock') {
|
|
|
+ title = '存量业务 - 在封客服数量 7日趋势';
|
|
|
+ data = {
|
|
|
+ labels: ['12/21', '12/22', '12/23', '12/24', '12/25', '12/26', '12/27'],
|
|
|
+ datasets: [{
|
|
|
+ label: '在封客服数',
|
|
|
+ data: [18, 20, 22, 25, 21, 23, 23],
|
|
|
+ borderColor: '#e74c3c',
|
|
|
+ backgroundColor: 'rgba(231, 76, 60, 0.1)',
|
|
|
+ tension: 0.4,
|
|
|
+ fill: true,
|
|
|
+ pointRadius: 5,
|
|
|
+ pointHoverRadius: 7,
|
|
|
+ pointBackgroundColor: '#e74c3c',
|
|
|
+ pointBorderColor: '#fff',
|
|
|
+ pointBorderWidth: 2
|
|
|
+ }]
|
|
|
+ };
|
|
|
+ } else {
|
|
|
+ title = '增量业务 - 在封客服数量 7日趋势';
|
|
|
+ data = {
|
|
|
+ labels: ['12/21', '12/22', '12/23', '12/24', '12/25', '12/26', '12/27'],
|
|
|
+ datasets: [{
|
|
|
+ label: '在封客服数',
|
|
|
+ data: [8, 9, 10, 12, 11, 10, 11],
|
|
|
+ borderColor: '#e74c3c',
|
|
|
+ backgroundColor: 'rgba(231, 76, 60, 0.1)',
|
|
|
+ tension: 0.4,
|
|
|
+ fill: true,
|
|
|
+ pointRadius: 5,
|
|
|
+ pointHoverRadius: 7,
|
|
|
+ pointBackgroundColor: '#e74c3c',
|
|
|
+ pointBorderColor: '#fff',
|
|
|
+ pointBorderWidth: 2
|
|
|
+ }]
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ document.getElementById('chartTitle').textContent = title;
|
|
|
+
|
|
|
+ // 创建图表
|
|
|
+ const ctx = document.getElementById('banChart').getContext('2d');
|
|
|
+ currentChart = new Chart(ctx, {
|
|
|
+ type: 'line',
|
|
|
+ data: data,
|
|
|
+ options: {
|
|
|
+ responsive: true,
|
|
|
+ maintainAspectRatio: false,
|
|
|
+ plugins: {
|
|
|
+ legend: {
|
|
|
+ display: false
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
|
|
+ padding: 12,
|
|
|
+ titleColor: '#fff',
|
|
|
+ bodyColor: '#fff',
|
|
|
+ borderColor: '#e74c3c',
|
|
|
+ borderWidth: 1
|
|
|
+ }
|
|
|
+ },
|
|
|
+ scales: {
|
|
|
+ y: {
|
|
|
+ beginAtZero: true,
|
|
|
+ ticks: {
|
|
|
+ precision: 0,
|
|
|
+ font: {
|
|
|
+ size: 12
|
|
|
+ }
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ color: 'rgba(0, 0, 0, 0.05)'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ x: {
|
|
|
+ ticks: {
|
|
|
+ font: {
|
|
|
+ size: 11
|
|
|
+ }
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ display: false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ function closeChart() {
|
|
|
+ const modal = document.getElementById('chartModal');
|
|
|
+ modal.style.display = 'none';
|
|
|
+ if (currentChart) {
|
|
|
+ currentChart.destroy();
|
|
|
+ currentChart = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 点击模态框外部关闭
|
|
|
+ window.onclick = function(event) {
|
|
|
+ const modal = document.getElementById('chartModal');
|
|
|
+ if (event.target == modal) {
|
|
|
+ closeChart();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ </script>
|
|
|
+</body>
|
|
|
+</html>
|