很好的选择!让我们实现数据归档的管理界面和添加更多的可视化选项。这将使系统更加完善,并为用户提供更丰富的数据分析工具。

第三十六部分:数据归档管理界面和高级可视化

  1. 实现数据归档的管理界面

首先,我们需要创建一个新的路由来处理归档数据的查询和管理。更新 src/routes/admin.ts

import { Elysia, t } from "elysia";
import { db } from "../db";
import { userBehaviorsArchive, conversionsArchive } from "../db/schema";
import { sql } from "drizzle-orm";
 
export const adminRoutes = new Elysia()
  .get("/admin/archive", async ({ set }) => {
    set.headers['Content-Type'] = 'text/html';
    return `
      <h1>Archive Management</h1>
      <div id="archive-stats"></div>
      <div>
        <h2>User Behaviors Archive</h2>
        <table id="user-behaviors-table">
          <thead>
            <tr>
              <th>Date</th>
              <th>Count</th>
            </tr>
          </thead>
          <tbody></tbody>
        </table>
      </div>
      <div>
        <h2>Conversions Archive</h2>
        <table id="conversions-table">
          <thead>
            <tr>
              <th>Date</th>
              <th>Count</th>
              <th>Total Value</th>
            </tr>
          </thead>
          <tbody></tbody>
        </table>
      </div>
      <script>
        async function loadArchiveStats() {
          const response = await fetch('/api/admin/archive-stats');
          const stats = await response.json();
          document.getElementById('archive-stats').innerHTML = \`
            <p>Total archived user behaviors: \${stats.userBehaviorsCount}</p>
            <p>Total archived conversions: \${stats.conversionsCount}</p>
          \`;
        }
 
        async function loadArchiveData() {
          const userBehaviorsResponse = await fetch('/api/admin/user-behaviors-archive');
          const userBehaviorsData = await userBehaviorsResponse.json();
          const userBehaviorsBody = document.querySelector('#user-behaviors-table tbody');
          userBehaviorsBody.innerHTML = userBehaviorsData.map(row => \`
            <tr>
              <td>\${row.date}</td>
              <td>\${row.count}</td>
            </tr>
          \`).join('');
 
          const conversionsResponse = await fetch('/api/admin/conversions-archive');
          const conversionsData = await conversionsResponse.json();
          const conversionsBody = document.querySelector('#conversions-table tbody');
          conversionsBody.innerHTML = conversionsData.map(row => \`
            <tr>
              <td>\${row.date}</td>
              <td>\${row.count}</td>
              <td>$\${row.totalValue.toFixed(2)}</td>
            </tr>
          \`).join('');
        }
 
        loadArchiveStats();
        loadArchiveData();
      </script>
    `;
  })
  .get("/api/admin/archive-stats", async () => {
    const userBehaviorsCount = await db
      .select({ count: sql`count(*)` })
      .from(userBehaviorsArchive)
      .get();
 
    const conversionsCount = await db
      .select({ count: sql`count(*)` })
      .from(conversionsArchive)
      .get();
 
    return {
      userBehaviorsCount: userBehaviorsCount.count,
      conversionsCount: conversionsCount.count,
    };
  })
  .get("/api/admin/user-behaviors-archive", async () => {
    return await db
      .select({
        date: userBehaviorsArchive.date,
        count: sql`count(*)`.as("count"),
      })
      .from(userBehaviorsArchive)
      .groupBy(userBehaviorsArchive.date)
      .orderBy(userBehaviorsArchive.date, "desc")
      .limit(30)
      .all();
  })
  .get("/api/admin/conversions-archive", async () => {
    return await db
      .select({
        date: conversionsArchive.date,
        count: sql`count(*)`.as("count"),
        totalValue: sql`sum(${conversionsArchive.value})`.as("totalValue"),
      })
      .from(conversionsArchive)
      .groupBy(conversionsArchive.date)
      .orderBy(conversionsArchive.date, "desc")
      .limit(30)
      .all();
  });
  1. 添加更多的可视化选项

接下来,我们将添加折线图和柱状图来可视化归档数据。我们将使用 Chart. Js 库来创建这些图表。首先,在 src/views/layouts/main.eta 中添加 Chart. Js:

<!DOCTYPE html>
<html lang="en">
<head>
    <!-- ... 其他头部内容 ... -->
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
    <!-- ... 其他内容 ... -->
</body>
</html>

然后,更新 src/routes/admin.ts 中的 /admin/archive 路由,添加图表:

.get("/admin/archive", async ({ set }) => {
    set.headers['Content-Type'] = 'text/html';
    return `
      <h1>Archive Management</h1>
      <div id="archive-stats"></div>
      <div>
        <h2>User Behaviors Archive</h2>
        <canvas id="user-behaviors-chart"></canvas>
        <table id="user-behaviors-table">
          <!-- ... 表格内容 ... -->
        </table>
      </div>
      <div>
        <h2>Conversions Archive</h2>
        <canvas id="conversions-chart"></canvas>
        <table id="conversions-table">
          <!-- ... 表格内容 ... -->
        </table>
      </div>
      <script>
        async function loadArchiveStats() {
          // ... 保持不变 ...
        }
 
        async function loadArchiveData() {
          const userBehaviorsResponse = await fetch('/api/admin/user-behaviors-archive');
          const userBehaviorsData = await userBehaviorsResponse.json();
          // ... 更新表格的代码保持不变 ...
 
          // 创建用户行为折线图
          new Chart(document.getElementById('user-behaviors-chart'), {
            type: 'line',
            data: {
              labels: userBehaviorsData.map(row => row.date),
              datasets: [{
                label: 'User Behaviors Count',
                data: userBehaviorsData.map(row => row.count),
                borderColor: 'rgb(75, 192, 192)',
                tension: 0.1
              }]
            },
            options: {
              responsive: true,
              scales: {
                y: {
                  beginAtZero: true
                }
              }
            }
          });
 
          const conversionsResponse = await fetch('/api/admin/conversions-archive');
          const conversionsData = await conversionsResponse.json();
          // ... 更新表格的代码保持不变 ...
 
          // 创建转化柱状图
          new Chart(document.getElementById('conversions-chart'), {
            type: 'bar',
            data: {
              labels: conversionsData.map(row => row.date),
              datasets: [{
                label: 'Conversions Count',
                data: conversionsData.map(row => row.count),
                backgroundColor: 'rgba(75, 192, 192, 0.6)'
              }, {
                label: 'Total Value',
                data: conversionsData.map(row => row.totalValue),
                backgroundColor: 'rgba(255, 99, 132, 0.6)',
                yAxisID: 'y1'
              }]
            },
            options: {
              responsive: true,
              scales: {
                y: {
                  beginAtZero: true
                },
                y1: {
                  beginAtZero: true,
                  position: 'right',
                  grid: {
                    drawOnChartArea: false
                  }
                }
              }
            }
          });
        }
 
        loadArchiveStats();
        loadArchiveData();
      </script>
    `;
  })

这些改进实现了以下功能:

  1. 数据归档的管理界面:

    • 创建了一个专门的管理页面来显示归档数据的统计信息
    • 实现了 API 端点来获取归档数据的统计信息和详细数据
    • 使用表格形式展示了归档的用户行为和转化数据
  2. 添加更多的可视化选项:

    • 集成了 Chart. Js 库来创建交互式图表
    • 为用户行为数据创建了折线图,展示随时间变化的趋势
    • 为转化数据创建了柱状图,同时展示转化次数和总价值

主要改进包括:

  • 提供了直观的界面来查看和管理归档数据
  • 使用图表可视化了归档数据,使趋势和模式更容易识别
  • 结合使用表格和图表,既提供了详细数据,又提供了整体趋势的视图

接下来的步骤可以包括:

  1. 添加数据筛选和搜索功能,允许管理员更灵活地查询归档数据
  2. 实现数据导出功能,允许管理员导出选定的归档数据
  3. 添加更多的图表类型,如饼图来展示转化类型的分布
  4. 实现交互式的图表,允许用户通过点击图表元素来查看更详细的信息
  5. 添加数据比较功能,允许管理员比较不同时期的归档数据

你希望继续深入哪个方向,或者有其他想法吗?