智慧水务管理系统 - 精河县供水工程综合管理平台

index.html 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>远程团队协作工具 - 首页</title>
  7. <script src="https://cdn.tailwindcss.com"></script>
  8. </head>
  9. <body class="bg-gray-50 min-h-screen">
  10. <nav class="bg-purple-600 text-white shadow-lg">
  11. <div class="container mx-auto px-4 py-4">
  12. <div class="flex justify-between items-center">
  13. <div class="flex items-center space-x-3"><span class="text-2xl">🤝</span><h1 class="text-xl font-bold">远程团队协作工具</h1></div>
  14. <div class="flex space-x-4">
  15. <a href="/" class="bg-purple-500 px-3 py-2 rounded">首页</a>
  16. <a href="/documents" class="hover:bg-purple-500 px-3 py-2 rounded">文档</a>
  17. <a href="/tasks" class="hover:bg-purple-500 px-3 py-2 rounded">任务</a>
  18. </div>
  19. </div>
  20. </div>
  21. </nav>
  22. <main class="container mx-auto px-4 py-8">
  23. <div class="mb-8"><h2 class="text-3xl font-bold text-gray-800">📊 数据看板</h2><p class="text-gray-600 mt-2">异步协作效率统计</p></div>
  24. <div class="grid grid-cols-1 md:grid-cols-5 gap-6 mb-8">
  25. <div class="bg-white rounded-lg shadow p-6"><div><p class="text-gray-500 text-sm">团队成员</p><p id="totalUsers" class="text-3xl font-bold text-purple-600">-</p></div><div class="text-4xl">👥</div></div>
  26. <div class="bg-white rounded-lg shadow p-6"><div><p class="text-gray-500 text-sm">协作文档</p><p id="totalDocuments" class="text-3xl font-bold text-blue-600">-</p></div><div class="text-4xl">📄</div></div>
  27. <div class="bg-white rounded-lg shadow p-6"><div><p class="text-gray-500 text-sm">总任务数</p><p id="totalTasks" class="text-3xl font-bold text-green-600">-</p></div><div class="text-4xl">✅</div></div>
  28. <div class="bg-white rounded-lg shadow p-6"><div><p class="text-gray-500 text-sm">进行中</p><p id="pendingTasks" class="text-3xl font-bold text-orange-600">-</p></div><div class="text-4xl">⏳</div></div>
  29. <div class="bg-white rounded-lg shadow p-6"><div><p class="text-gray-500 text-sm">今日到期</p><p id="todayTasks" class="text-3xl font-bold text-red-600">-</p></div><div class="text-4xl">📅</div></div>
  30. </div>
  31. <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
  32. <div class="bg-white rounded-lg shadow p-6">
  33. <h3 class="text-lg font-semibold mb-4">🚀 快捷操作</h3>
  34. <div class="grid grid-cols-2 gap-3">
  35. <button onclick="location.href='/documents'" class="bg-blue-600 text-white px-4 py-3 rounded-lg hover:bg-blue-700">📄 新建文档</button>
  36. <button onclick="location.href='/tasks'" class="bg-green-600 text-white px-4 py-3 rounded-lg hover:bg-green-700">✅ 创建任务</button>
  37. <button onclick="createDemoDoc()" class="bg-purple-600 text-white px-4 py-3 rounded-lg hover:bg-purple-700">📝 创建示例</button>
  38. <button onclick="createDemoTask()" class="bg-orange-600 text-white px-4 py-3 rounded-lg hover:bg-orange-700">🎯 添加示例任务</button>
  39. </div>
  40. </div>
  41. <div class="bg-white rounded-lg shadow p-6">
  42. <div class="flex justify-between items-center mb-4"><h3 class="text-lg font-semibold">🔔 通知</h3><span id="notifCount" class="bg-red-500 text-white text-xs px-2 py-1 rounded-full">0</span></div>
  43. <div id="notifList" class="space-y-3"><p class="text-gray-500 text-center py-8">加载中...</p></div>
  44. </div>
  45. </div>
  46. </main>
  47. <script>
  48. async function loadStats() {
  49. const res = await fetch('/api/stats/overview');
  50. const data = await res.json();
  51. if (data.success) {
  52. document.getElementById('totalUsers').textContent = data.data.totalUsers;
  53. document.getElementById('totalDocuments').textContent = data.data.totalDocuments;
  54. document.getElementById('totalTasks').textContent = data.data.totalTasks;
  55. document.getElementById('pendingTasks').textContent = data.data.pendingTasks;
  56. document.getElementById('todayTasks').textContent = data.data.todayTasks;
  57. }
  58. }
  59. async function loadNotifications() {
  60. const res = await fetch('/api/notifications?user_id=1&unread=true');
  61. const data = await res.json();
  62. const container = document.getElementById('notifList');
  63. const countEl = document.getElementById('notifCount');
  64. if (data.success && data.data.length > 0) {
  65. countEl.textContent = data.data.length;
  66. container.innerHTML = data.data.slice(0, 5).map(n => `
  67. <div class="flex items-center justify-between p-3 bg-blue-50 rounded-lg">
  68. <div class="flex-1"><p class="text-sm text-blue-800">${n.title}</p><p class="text-xs text-blue-600">${new Date(n.created_at).toLocaleString('zh-CN')}</p></div>
  69. <button onclick="markRead(${n.id})" class="text-blue-600 hover:underline text-sm ml-3">已读</button>
  70. </div>
  71. `).join('');
  72. } else {
  73. countEl.textContent = '0';
  74. container.innerHTML = '<p class="text-gray-500 text-center py-8">暂无新通知 ✅</p>';
  75. }
  76. }
  77. async function markRead(id) {
  78. await fetch(`/api/notifications/${id}/read`, { method: 'PUT' });
  79. loadNotifications();
  80. }
  81. async function createDemoDoc() {
  82. const res = await fetch('/api/documents', {
  83. method: 'POST',
  84. headers: { 'Content-Type': 'application/json' },
  85. body: JSON.stringify({ title: '示例文档_' + Date.now(), content: '这是一个示例协作文档', owner_id: 1, is_public: true })
  86. });
  87. const result = await res.json();
  88. if (result.success) { alert('✅ 示例文档创建成功'); loadStats(); }
  89. }
  90. async function createDemoTask() {
  91. const res = await fetch('/api/tasks', {
  92. method: 'POST',
  93. headers: { 'Content-Type': 'application/json' },
  94. body: JSON.stringify({ title: '示例任务_' + Date.now(), description: '这是一个示例任务', creator_id: 1, priority: 'medium' })
  95. });
  96. const result = await res.json();
  97. if (result.success) { alert('✅ 示例任务创建成功'); loadStats(); }
  98. }
  99. document.addEventListener('DOMContentLoaded', () => { loadStats(); loadNotifications(); });
  100. </script>
  101. </body>
  102. </html>