collabdocchat 2.4.3 → 2.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/package.json +2 -2
  2. package/scripts/add-button-hover.js +58 -0
  3. package/scripts/add-missing-braces.js +27 -0
  4. package/scripts/add-missing-functions.js +2 -0
  5. package/scripts/add-more-features.js +2 -0
  6. package/scripts/add-user-functions.js +2 -0
  7. package/scripts/auto-publish.js +2 -0
  8. package/scripts/beautify-buttons.js +47 -0
  9. package/scripts/beautify-ui.js +269 -0
  10. package/scripts/check-brackets.js +50 -0
  11. package/scripts/check-encoding.js +2 -0
  12. package/scripts/check-syntax.js +2 -0
  13. package/scripts/delete-orphan-block.js +27 -0
  14. package/scripts/find-buttons.js +22 -0
  15. package/scripts/find-duplicate.js +2 -0
  16. package/scripts/find-extra-brace.js +63 -0
  17. package/scripts/find-sidebar-buttons.js +23 -0
  18. package/scripts/fix-file-end.js +46 -0
  19. package/scripts/fix-help.js +2 -0
  20. package/scripts/fix-issues-step1.js +2 -0
  21. package/scripts/fix-issues-step2.js +2 -0
  22. package/scripts/fix-issues-step3.js +2 -0
  23. package/scripts/fix-issues-step4.js +2 -0
  24. package/scripts/fix-optimized-views.js +2 -0
  25. package/scripts/fix-settings.js +2 -0
  26. package/scripts/fix-syntax-error.js +38 -0
  27. package/scripts/fix-workflow.js +2 -0
  28. package/scripts/refactor-step1.js +2 -0
  29. package/scripts/refactor-step2.js +2 -0
  30. package/scripts/refactor-step3.js +2 -0
  31. package/scripts/refactor-step4.js +2 -0
  32. package/scripts/refactor-step5.js +2 -0
  33. package/scripts/refactor-step6.js +2 -0
  34. package/scripts/refactor-step7.js +2 -0
  35. package/scripts/remove-orphan-code.js +57 -0
  36. package/scripts/update-port-user.js +2 -0
  37. package/scripts/update-port.js +2 -0
  38. package/server/index.js +4 -0
  39. package/server/index.js.bak +97 -0
  40. package/server/models/Document.js +5 -0
  41. package/server/models/KnowledgeBase.js +259 -254
  42. package/server/models/Poll.js +97 -0
  43. package/server/routes/ai.js +391 -327
  44. package/server/routes/audit.js +61 -0
  45. package/server/routes/documents.js +74 -5
  46. package/server/routes/export.js +171 -10
  47. package/server/routes/files.js +27 -4
  48. package/server/routes/knowledge.js +31 -22
  49. package/server/routes/messages.js +142 -0
  50. package/server/routes/polls.js +241 -0
  51. package/server/routes/tasks.js +1 -0
  52. package/server/routes/workflows.js +27 -0
  53. package/server/utils/auditLogger.js +268 -238
  54. package/src/pages/admin-dashboard.js +1395 -261
  55. package/src/pages/admin-dashboard.js.audit-optimize.bak +4134 -0
  56. package/src/pages/admin-dashboard.js.bak +4041 -0
  57. package/src/pages/admin-dashboard.js.broken.bak +4099 -0
  58. package/src/pages/admin-dashboard.js.comprehensive.bak +4099 -0
  59. package/src/pages/admin-dashboard.js.escape.bak +4099 -0
  60. package/src/pages/admin-dashboard.js.final-final-fix.bak +4099 -0
  61. package/src/pages/admin-dashboard.js.final-fix.bak +4099 -0
  62. package/src/pages/admin-dashboard.js.final.bak +4099 -0
  63. package/src/pages/admin-dashboard.js.indent-fix.bak +4099 -0
  64. package/src/pages/admin-dashboard.js.last-fix.bak +4099 -0
  65. package/src/pages/admin-dashboard.js.line595-fix.bak +4099 -0
  66. package/src/pages/admin-dashboard.js.pre-manual-fix.bak +4099 -0
  67. package/src/pages/admin-dashboard.js.syntax.bak +4099 -0
  68. package/src/pages/admin-dashboard.js.test.bak +4099 -0
  69. package/src/pages/optimized-task-detail-original.js +838 -0
  70. package/src/pages/optimized-task-detail.js +324 -22
  71. package/src/pages/optimized-task-detail.js.bak +1162 -0
  72. package/src/pages/poll-detail-enhanced.js +394 -0
  73. package/src/pages/update-poll-display.js +380 -0
  74. package/src/pages/user-dashboard.js +1860 -1006
  75. package/src/services/api.js +326 -265
  76. package/src/services/auth.js +54 -54
  77. package/src/services/websocket.js +88 -80
  78. package/src/pages/simplified-workflows.js +0 -652
  79. package/src/utils/ai-assistant.js +0 -1384
@@ -0,0 +1,838 @@
1
+ // 优化后的任务详情界面
2
+ // 使用卡片式布局,提升视觉效果和信息层次
3
+
4
+ function renderOptimizedTaskDetail(task, container) {
5
+ container.innerHTML = `
6
+ <div class="task-detail-view-modern">
7
+ <!-- 头部区域 -->
8
+ <div class="task-detail-header-modern">
9
+ <div class="task-header-left">
10
+ <h2>${task.title}</h2>
11
+ <div class="task-badges">
12
+ <span class="status-badge-modern status-${task.status}">
13
+ ${getStatusIcon(task.status)} ${getStatusText(task.status)}
14
+ </span>
15
+ ${task.priority ? `<span class="priority-badge-modern priority-${task.priority}">
16
+ ${getPriorityIcon(task.priority)} ${task.priority}
17
+ </span>` : ''}
18
+ </div>
19
+ </div>
20
+ <button class="btn-close-modern" id="closeTaskDetail">
21
+ <span>�?/span>
22
+ </button>
23
+ </div>
24
+
25
+ <!-- 任务基本信息卡片 -->
26
+ <div class="task-info-card-modern">
27
+ <h3 class="card-title-modern">
28
+ <span class="card-icon">📋</span> 任务信息
29
+ </h3>
30
+ <div class="task-info-grid-modern">
31
+ <div class="info-item-modern">
32
+ <div class="info-label-modern">
33
+ <span class="label-icon">👤</span> 任务组长
34
+ </div>
35
+ <div class="info-value-modern">${task.assignedTo || '未分�?}</div>
36
+ </div>
37
+
38
+ <div class="info-item-modern">
39
+ <div class="info-label-modern">
40
+ <span class="label-icon">👥</span> 所属群�? </div>
41
+ <div class="info-value-modern">${task.group || '未指�?}</div>
42
+ </div>
43
+
44
+ <div class="info-item-modern">
45
+ <div class="info-label-modern">
46
+ <span class="label-icon">📅</span> 截止日期
47
+ </div>
48
+ <div class="info-value-modern">${task.deadline ? new Date(task.deadline).toLocaleString() : '�?}</div>
49
+ </div>
50
+
51
+ <div class="info-item-modern">
52
+ <div class="info-label-modern">
53
+ <span class="label-icon">🕐</span> 创建时间
54
+ </div>
55
+ <div class="info-value-modern">${new Date(task.createdAt).toLocaleString()}</div>
56
+ </div>
57
+ </div>
58
+
59
+ ${task.description ? `
60
+ <div class="task-description-modern">
61
+ <div class="info-label-modern">
62
+ <span class="label-icon">📝</span> 任务描述
63
+ </div>
64
+ <div class="description-content-modern">${task.description}</div>
65
+ </div>
66
+ ` : ''}
67
+ </div>
68
+
69
+ <!-- 完成统计卡片 -->
70
+ <div class="task-stats-card-modern">
71
+ <h3 class="card-title-modern">
72
+ <span class="card-icon">📊</span> 完成统计
73
+ </h3>
74
+ <div class="stats-grid-modern">
75
+ <div class="stat-item-modern stat-total">
76
+ <div class="stat-icon-modern">👥</div>
77
+ <div class="stat-content-modern">
78
+ <div class="stat-label-modern">总人�?/div>
79
+ <div class="stat-value-modern">${task.members?.length || 0}</div>
80
+ </div>
81
+ </div>
82
+
83
+ <div class="stat-item-modern stat-completed">
84
+ <div class="stat-icon-modern">�?/div>
85
+ <div class="stat-content-modern">
86
+ <div class="stat-label-modern">已完�?/div>
87
+ <div class="stat-value-modern">${task.completedCount || 0}</div>
88
+ </div>
89
+ </div>
90
+
91
+ <div class="stat-item-modern stat-pending">
92
+ <div class="stat-icon-modern">�?/div>
93
+ <div class="stat-content-modern">
94
+ <div class="stat-label-modern">未完�?/div>
95
+ <div class="stat-value-modern">${(task.members?.length || 0) - (task.completedCount || 0)}</div>
96
+ </div>
97
+ </div>
98
+
99
+ <div class="stat-item-modern stat-progress">
100
+ <div class="stat-icon-modern">📈</div>
101
+ <div class="stat-content-modern">
102
+ <div class="stat-label-modern">完成�?/div>
103
+ <div class="stat-value-modern">${calculateProgress(task)}%</div>
104
+ </div>
105
+ </div>
106
+ </div>
107
+
108
+ <!-- 进度�?-->
109
+ <div class="progress-bar-container-modern">
110
+ <div class="progress-bar-modern">
111
+ <div class="progress-fill-modern" style="width: ${calculateProgress(task)}%">
112
+ <span class="progress-text-modern">${calculateProgress(task)}%</span>
113
+ </div>
114
+ </div>
115
+ </div>
116
+ </div>
117
+
118
+ <!-- 投票结果卡片(如果有投票�?-->
119
+ ${task.poll ? renderPollResults(task.poll) : ''}
120
+
121
+ <!-- 成员完成情况卡片 -->
122
+ <div class="task-members-card-modern">
123
+ <h3 class="card-title-modern">
124
+ <span class="card-icon">👥</span> 成员完成情况
125
+ </h3>
126
+ <div class="members-list-modern">
127
+ ${task.members?.map(member => renderMemberItem(member)).join('') || '<div class="empty-state-modern">暂无成员</div>'}
128
+ </div>
129
+ </div>
130
+
131
+ <!-- 操作按钮区域 -->
132
+ <div class="task-actions-modern">
133
+ <button class="btn-action-modern btn-edit" id="editTask">
134
+ <span>✏️</span> 编辑任务
135
+ </button>
136
+ <button class="btn-action-modern btn-complete" id="completeTask">
137
+ <span>�?/span> 标记完成
138
+ </button>
139
+ <button class="btn-action-modern btn-delete" id="deleteTask">
140
+ <span>🗑�?/span> 删除任务
141
+ </button>
142
+ </div>
143
+ </div>
144
+ `;
145
+
146
+ // 添加样式
147
+ addTaskDetailStyles();
148
+
149
+ // 绑定事件
150
+ setupTaskDetailEvents(task, container);
151
+ }
152
+
153
+ // 渲染投票结果
154
+ function renderPollResults(poll) {
155
+ if (!poll || !poll.options) return '';
156
+
157
+ const totalVotes = poll.options.reduce((sum, opt) => sum + (opt.votes || 0), 0);
158
+
159
+ return `
160
+ <div class="task-poll-card-modern">
161
+ <h3 class="card-title-modern">
162
+ <span class="card-icon">📊</span> 投票结果
163
+ </h3>
164
+ <div class="poll-question-modern">${poll.question || '投票'}</div>
165
+ <div class="poll-options-modern">
166
+ ${poll.options.map(option => {
167
+ const percentage = totalVotes > 0 ? Math.round((option.votes || 0) / totalVotes * 100) : 0;
168
+ return `
169
+ <div class="poll-option-modern">
170
+ <div class="poll-option-header-modern">
171
+ <span class="poll-option-text-modern">${option.text}</span>
172
+ <span class="poll-option-count-modern">${option.votes || 0} �?(${percentage}%)</span>
173
+ </div>
174
+ <div class="poll-option-bar-modern">
175
+ <div class="poll-option-fill-modern" style="width: ${percentage}%"></div>
176
+ </div>
177
+ </div>
178
+ `;
179
+ }).join('')}
180
+ </div>
181
+ <div class="poll-total-modern">总投票数: ${totalVotes}</div>
182
+ </div>
183
+ `;
184
+ }
185
+
186
+ // 渲染成员�?function renderMemberItem(member) {
187
+ const isCompleted = member.completed || member.status === 'completed';
188
+ const completedTime = member.completedAt ? new Date(member.completedAt).toLocaleString() : '未完�?;
189
+
190
+ return `
191
+ <div class="member-item-modern ${isCompleted ? 'completed' : 'pending'}">
192
+ <div class="member-avatar-modern">
193
+ ${member.username ? member.username[0].toUpperCase() : '?'}
194
+ </div>
195
+ <div class="member-info-modern">
196
+ <div class="member-name-modern">${member.username || '未知用户'}</div>
197
+ <div class="member-time-modern">
198
+ ${isCompleted ? `�?${completedTime}` : '�?待完�?}
199
+ </div>
200
+ </div>
201
+ <div class="member-status-modern">
202
+ ${isCompleted ?
203
+ '<span class="status-badge-small completed">已完�?/span>' :
204
+ '<span class="status-badge-small pending">未完�?/span>'}
205
+ </div>
206
+ </div>
207
+ `;
208
+ }
209
+
210
+ // 计算完成进度
211
+ function calculateProgress(task) {
212
+ if (!task.members || task.members.length === 0) return 0;
213
+ const completed = task.completedCount || 0;
214
+ return Math.round((completed / task.members.length) * 100);
215
+ }
216
+
217
+ // 获取状态图�?function getStatusIcon(status) {
218
+ const icons = {
219
+ 'pending': '�?,
220
+ 'in_progress': '🔄',
221
+ 'completed': '�?,
222
+ 'terminated': '�?
223
+ };
224
+ return icons[status] || '📋';
225
+ }
226
+
227
+ // 获取状态文�?function getStatusText(status) {
228
+ const texts = {
229
+ 'pending': '待处�?,
230
+ 'in_progress': '进行�?,
231
+ 'completed': '已完�?,
232
+ 'terminated': '已终�?
233
+ };
234
+ return texts[status] || '未知';
235
+ }
236
+
237
+ // 获取优先级图�?function getPriorityIcon(priority) {
238
+ const icons = {
239
+ 'high': '🔴',
240
+ 'medium': '🟡',
241
+ 'low': '🟢'
242
+ };
243
+ return icons[priority] || '�?;
244
+ }
245
+
246
+ // 添加样式
247
+ function addTaskDetailStyles() {
248
+ if (document.getElementById('task-detail-modern-styles')) return;
249
+
250
+ const style = document.createElement('style');
251
+ style.id = 'task-detail-modern-styles';
252
+ style.textContent = `
253
+ .task-detail-view-modern {
254
+ background: linear-gradient(135deg, var(--bg-dark) 0%, rgba(99,102,241,0.03) 100%);
255
+ border-radius: 20px;
256
+ padding: 0;
257
+ max-width: 1200px;
258
+ max-height: 85vh;
259
+ margin: 0 auto;
260
+ animation: fadeInUp 0.5s ease;
261
+ overflow-y: auto;
262
+ overflow-x: hidden;
263
+ }
264
+
265
+ /* 滚动条样�?*/
266
+ .task-detail-view-modern::-webkit-scrollbar {
267
+ width: 8px;
268
+ }
269
+
270
+ .task-detail-view-modern::-webkit-scrollbar-track {
271
+ background: var(--bg-dark);
272
+ border-radius: 10px;
273
+ }
274
+
275
+ .task-detail-view-modern::-webkit-scrollbar-thumb {
276
+ background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
277
+ border-radius: 10px;
278
+ }
279
+
280
+ .task-detail-view-modern::-webkit-scrollbar-thumb:hover {
281
+ background: linear-gradient(135deg, var(--secondary) 0%, var(--primary) 100%);
282
+ }
283
+
284
+ .task-detail-header-modern {
285
+ display: flex;
286
+ justify-content: space-between;
287
+ align-items: flex-start;
288
+ padding: 30px;
289
+ background: linear-gradient(135deg, var(--bg-card) 0%, rgba(99,102,241,0.05) 100%);
290
+ border-radius: 20px 20px 0 0;
291
+ border-bottom: 2px solid var(--border);
292
+ }
293
+
294
+ .task-header-left h2 {
295
+ margin: 0 0 12px;
296
+ font-size: 28px;
297
+ font-weight: 800;
298
+ color: var(--text-primary);
299
+ }
300
+
301
+ .task-badges {
302
+ display: flex;
303
+ gap: 10px;
304
+ flex-wrap: wrap;
305
+ }
306
+
307
+ .status-badge-modern {
308
+ padding: 8px 16px;
309
+ border-radius: 20px;
310
+ font-size: 14px;
311
+ font-weight: 600;
312
+ display: inline-flex;
313
+ align-items: center;
314
+ gap: 6px;
315
+ }
316
+
317
+ .status-badge-modern.status-pending {
318
+ background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
319
+ color: white;
320
+ }
321
+
322
+ .status-badge-modern.status-in_progress {
323
+ background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
324
+ color: white;
325
+ }
326
+
327
+ .status-badge-modern.status-completed {
328
+ background: linear-gradient(135deg, #10b981 0%, #059669 100%);
329
+ color: white;
330
+ }
331
+
332
+ .status-badge-modern.status-terminated {
333
+ background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
334
+ color: white;
335
+ }
336
+
337
+ .priority-badge-modern {
338
+ padding: 8px 16px;
339
+ border-radius: 20px;
340
+ font-size: 14px;
341
+ font-weight: 600;
342
+ background: var(--bg-dark);
343
+ color: var(--text-primary);
344
+ border: 2px solid var(--border);
345
+ display: inline-flex;
346
+ align-items: center;
347
+ gap: 6px;
348
+ }
349
+
350
+ .btn-close-modern {
351
+ width: 40px;
352
+ height: 40px;
353
+ border-radius: 50%;
354
+ background: var(--bg-dark);
355
+ border: 2px solid var(--border);
356
+ color: var(--text-secondary);
357
+ font-size: 24px;
358
+ cursor: pointer;
359
+ transition: all 0.3s ease;
360
+ display: flex;
361
+ align-items: center;
362
+ justify-content: center;
363
+ }
364
+
365
+ .btn-close-modern:hover {
366
+ background: var(--danger);
367
+ border-color: var(--danger);
368
+ color: white;
369
+ transform: rotate(90deg);
370
+ }
371
+
372
+ .task-info-card-modern,
373
+ .task-stats-card-modern,
374
+ .task-poll-card-modern,
375
+ .task-members-card-modern {
376
+ background: var(--bg-card);
377
+ border: 1px solid var(--border);
378
+ border-radius: 16px;
379
+ padding: 24px;
380
+ margin: 20px 30px;
381
+ transition: all 0.3s ease;
382
+ }
383
+
384
+ .task-info-card-modern:hover,
385
+ .task-stats-card-modern:hover,
386
+ .task-poll-card-modern:hover,
387
+ .task-members-card-modern:hover {
388
+ box-shadow: 0 8px 24px rgba(99,102,241,0.15);
389
+ border-color: var(--primary);
390
+ }
391
+
392
+ .card-title-modern {
393
+ margin: 0 0 20px;
394
+ font-size: 20px;
395
+ font-weight: 700;
396
+ color: var(--text-primary);
397
+ display: flex;
398
+ align-items: center;
399
+ gap: 10px;
400
+ }
401
+
402
+ .card-icon {
403
+ font-size: 24px;
404
+ }
405
+
406
+ .task-info-grid-modern {
407
+ display: grid;
408
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
409
+ gap: 20px;
410
+ margin-bottom: 20px;
411
+ }
412
+
413
+ .info-item-modern {
414
+ background: var(--bg-dark);
415
+ border: 1px solid var(--border);
416
+ border-radius: 12px;
417
+ padding: 16px;
418
+ transition: all 0.3s ease;
419
+ }
420
+
421
+ .info-item-modern:hover {
422
+ background: rgba(99,102,241,0.05);
423
+ border-color: var(--primary);
424
+ transform: translateY(-2px);
425
+ }
426
+
427
+ .info-label-modern {
428
+ font-size: 13px;
429
+ color: var(--text-secondary);
430
+ margin-bottom: 8px;
431
+ font-weight: 600;
432
+ display: flex;
433
+ align-items: center;
434
+ gap: 6px;
435
+ }
436
+
437
+ .label-icon {
438
+ font-size: 16px;
439
+ }
440
+
441
+ .info-value-modern {
442
+ font-size: 16px;
443
+ color: var(--text-primary);
444
+ font-weight: 600;
445
+ }
446
+
447
+ .task-description-modern {
448
+ margin-top: 20px;
449
+ padding-top: 20px;
450
+ border-top: 1px solid var(--border);
451
+ }
452
+
453
+ .description-content-modern {
454
+ background: var(--bg-dark);
455
+ border: 1px solid var(--border);
456
+ border-radius: 12px;
457
+ padding: 16px;
458
+ margin-top: 12px;
459
+ line-height: 1.6;
460
+ color: var(--text-primary);
461
+ }
462
+
463
+ .stats-grid-modern {
464
+ display: grid;
465
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
466
+ gap: 16px;
467
+ margin-bottom: 20px;
468
+ }
469
+
470
+ .stat-item-modern {
471
+ background: linear-gradient(135deg, var(--bg-dark) 0%, rgba(99,102,241,0.05) 100%);
472
+ border: 2px solid var(--border);
473
+ border-radius: 12px;
474
+ padding: 20px;
475
+ display: flex;
476
+ align-items: center;
477
+ gap: 16px;
478
+ transition: all 0.3s ease;
479
+ }
480
+
481
+ .stat-item-modern:hover {
482
+ transform: translateY(-5px);
483
+ box-shadow: 0 8px 24px rgba(99,102,241,0.2);
484
+ }
485
+
486
+ .stat-item-modern.stat-total {
487
+ border-color: rgba(99,102,241,0.5);
488
+ }
489
+
490
+ .stat-item-modern.stat-completed {
491
+ border-color: rgba(16,185,129,0.5);
492
+ }
493
+
494
+ .stat-item-modern.stat-pending {
495
+ border-color: rgba(239,68,68,0.5);
496
+ }
497
+
498
+ .stat-item-modern.stat-progress {
499
+ border-color: rgba(245,158,11,0.5);
500
+ }
501
+
502
+ .stat-icon-modern {
503
+ width: 50px;
504
+ height: 50px;
505
+ border-radius: 12px;
506
+ background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
507
+ display: flex;
508
+ align-items: center;
509
+ justify-content: center;
510
+ font-size: 24px;
511
+ flex-shrink: 0;
512
+ }
513
+
514
+ .stat-content-modern {
515
+ flex: 1;
516
+ }
517
+
518
+ .stat-label-modern {
519
+ font-size: 13px;
520
+ color: var(--text-secondary);
521
+ margin-bottom: 6px;
522
+ font-weight: 600;
523
+ text-transform: uppercase;
524
+ letter-spacing: 0.5px;
525
+ }
526
+
527
+ .stat-value-modern {
528
+ font-size: 28px;
529
+ font-weight: 800;
530
+ color: var(--text-primary);
531
+ }
532
+
533
+ .progress-bar-container-modern {
534
+ margin-top: 20px;
535
+ }
536
+
537
+ .progress-bar-modern {
538
+ width: 100%;
539
+ height: 40px;
540
+ background: var(--bg-dark);
541
+ border-radius: 20px;
542
+ overflow: hidden;
543
+ border: 2px solid var(--border);
544
+ position: relative;
545
+ }
546
+
547
+ .progress-fill-modern {
548
+ height: 100%;
549
+ background: linear-gradient(90deg, var(--primary) 0%, var(--secondary) 100%);
550
+ border-radius: 18px;
551
+ transition: width 0.6s ease;
552
+ display: flex;
553
+ align-items: center;
554
+ justify-content: center;
555
+ position: relative;
556
+ box-shadow: 0 0 20px rgba(99,102,241,0.5);
557
+ }
558
+
559
+ .progress-text-modern {
560
+ color: white;
561
+ font-weight: 700;
562
+ font-size: 16px;
563
+ text-shadow: 0 2px 4px rgba(0,0,0,0.3);
564
+ }
565
+
566
+ .poll-question-modern {
567
+ font-size: 16px;
568
+ font-weight: 600;
569
+ color: var(--text-primary);
570
+ margin-bottom: 20px;
571
+ padding: 16px;
572
+ background: var(--bg-dark);
573
+ border-radius: 12px;
574
+ border-left: 4px solid var(--primary);
575
+ }
576
+
577
+ .poll-options-modern {
578
+ display: flex;
579
+ flex-direction: column;
580
+ gap: 16px;
581
+ margin-bottom: 20px;
582
+ }
583
+
584
+ .poll-option-modern {
585
+ background: var(--bg-dark);
586
+ border: 1px solid var(--border);
587
+ border-radius: 12px;
588
+ padding: 16px;
589
+ transition: all 0.3s ease;
590
+ }
591
+
592
+ .poll-option-modern:hover {
593
+ border-color: var(--primary);
594
+ transform: translateX(5px);
595
+ }
596
+
597
+ .poll-option-header-modern {
598
+ display: flex;
599
+ justify-content: space-between;
600
+ align-items: center;
601
+ margin-bottom: 12px;
602
+ }
603
+
604
+ .poll-option-text-modern {
605
+ font-size: 15px;
606
+ font-weight: 600;
607
+ color: var(--text-primary);
608
+ }
609
+
610
+ .poll-option-count-modern {
611
+ font-size: 14px;
612
+ font-weight: 700;
613
+ color: var(--text-secondary);
614
+ }
615
+
616
+ .poll-option-bar-modern {
617
+ width: 100%;
618
+ height: 8px;
619
+ background: var(--bg-hover);
620
+ border-radius: 4px;
621
+ overflow: hidden;
622
+ }
623
+
624
+ .poll-option-fill-modern {
625
+ height: 100%;
626
+ background: linear-gradient(90deg, var(--primary) 0%, var(--secondary) 100%);
627
+ border-radius: 4px;
628
+ transition: width 0.6s ease;
629
+ }
630
+
631
+ .poll-total-modern {
632
+ text-align: center;
633
+ font-size: 14px;
634
+ color: var(--text-secondary);
635
+ font-weight: 600;
636
+ }
637
+
638
+ .members-list-modern {
639
+ display: flex;
640
+ flex-direction: column;
641
+ gap: 12px;
642
+ }
643
+
644
+ .member-item-modern {
645
+ display: flex;
646
+ align-items: center;
647
+ gap: 16px;
648
+ padding: 16px;
649
+ background: var(--bg-dark);
650
+ border: 2px solid var(--border);
651
+ border-radius: 12px;
652
+ transition: all 0.3s ease;
653
+ }
654
+
655
+ .member-item-modern:hover {
656
+ background: rgba(99,102,241,0.05);
657
+ border-color: var(--primary);
658
+ transform: translateX(5px);
659
+ }
660
+
661
+ .member-item-modern.completed {
662
+ border-left: 4px solid var(--success);
663
+ background: linear-gradient(90deg, rgba(16,185,129,0.1) 0%, transparent 100%);
664
+ }
665
+
666
+ .member-item-modern.pending {
667
+ border-left: 4px solid var(--danger);
668
+ background: linear-gradient(90deg, rgba(239,68,68,0.08) 0%, transparent 100%);
669
+ }
670
+
671
+ .member-avatar-modern {
672
+ width: 50px;
673
+ height: 50px;
674
+ border-radius: 50%;
675
+ background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
676
+ display: flex;
677
+ align-items: center;
678
+ justify-content: center;
679
+ font-size: 20px;
680
+ font-weight: 700;
681
+ color: white;
682
+ flex-shrink: 0;
683
+ }
684
+
685
+ .member-info-modern {
686
+ flex: 1;
687
+ }
688
+
689
+ .member-name-modern {
690
+ font-size: 16px;
691
+ font-weight: 600;
692
+ color: var(--text-primary);
693
+ margin-bottom: 4px;
694
+ }
695
+
696
+ .member-time-modern {
697
+ font-size: 13px;
698
+ color: var(--text-secondary);
699
+ }
700
+
701
+ .member-status-modern {
702
+ flex-shrink: 0;
703
+ }
704
+
705
+ .status-badge-small {
706
+ padding: 6px 12px;
707
+ border-radius: 12px;
708
+ font-size: 12px;
709
+ font-weight: 600;
710
+ }
711
+
712
+ .status-badge-small.completed {
713
+ background: linear-gradient(135deg, #10b981 0%, #059669 100%);
714
+ color: white;
715
+ }
716
+
717
+ .status-badge-small.pending {
718
+ background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
719
+ color: white;
720
+ }
721
+
722
+ .task-actions-modern {
723
+ display: flex;
724
+ gap: 12px;
725
+ padding: 30px;
726
+ background: var(--bg-card);
727
+ border-radius: 0 0 20px 20px;
728
+ border-top: 2px solid var(--border);
729
+ flex-wrap: wrap;
730
+ }
731
+
732
+ .btn-action-modern {
733
+ flex: 1;
734
+ min-width: 150px;
735
+ padding: 14px 24px;
736
+ border: none;
737
+ border-radius: 12px;
738
+ font-size: 15px;
739
+ font-weight: 600;
740
+ cursor: pointer;
741
+ transition: all 0.3s ease;
742
+ display: flex;
743
+ align-items: center;
744
+ justify-content: center;
745
+ gap: 8px;
746
+ }
747
+
748
+ .btn-action-modern span {
749
+ font-size: 18px;
750
+ }
751
+
752
+ .btn-edit {
753
+ background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
754
+ color: white;
755
+ }
756
+
757
+ .btn-complete {
758
+ background: linear-gradient(135deg, #10b981 0%, #059669 100%);
759
+ color: white;
760
+ }
761
+
762
+ .btn-delete {
763
+ background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
764
+ color: white;
765
+ }
766
+
767
+ .btn-action-modern:hover {
768
+ transform: translateY(-3px);
769
+ box-shadow: 0 8px 24px rgba(0,0,0,0.3);
770
+ }
771
+
772
+ .empty-state-modern {
773
+ text-align: center;
774
+ padding: 40px;
775
+ color: var(--text-secondary);
776
+ font-size: 15px;
777
+ }
778
+
779
+ @media (max-width: 768px) {
780
+ .task-detail-header-modern {
781
+ flex-direction: column;
782
+ gap: 20px;
783
+ }
784
+
785
+ .task-info-grid-modern {
786
+ grid-template-columns: 1fr;
787
+ }
788
+
789
+ .stats-grid-modern {
790
+ grid-template-columns: repeat(2, 1fr);
791
+ }
792
+
793
+ .task-actions-modern {
794
+ flex-direction: column;
795
+ }
796
+
797
+ .btn-action-modern {
798
+ width: 100%;
799
+ }
800
+ }
801
+ `;
802
+ document.head.appendChild(style);
803
+ }
804
+
805
+ // 设置事件监听
806
+ function setupTaskDetailEvents(task, container) {
807
+ // 关闭按钮
808
+ container.querySelector('#closeTaskDetail')?.addEventListener('click', () => {
809
+ container.closest('.modal')?.remove();
810
+ });
811
+
812
+ // 编辑任务
813
+ container.querySelector('#editTask')?.addEventListener('click', () => {
814
+ alert('编辑任务功能');
815
+ // 这里可以打开编辑表单
816
+ });
817
+
818
+ // 标记完成
819
+ container.querySelector('#completeTask')?.addEventListener('click', async () => {
820
+ if (confirm('确定要标记此任务为已完成吗?')) {
821
+ // 调用 API 标记完成
822
+ alert('任务已标记为完成');
823
+ }
824
+ });
825
+
826
+ // 删除任务
827
+ container.querySelector('#deleteTask')?.addEventListener('click', async () => {
828
+ if (confirm('确定要删除此任务吗?此操作不可撤销�?)) {
829
+ // 调用 API 删除任务
830
+ alert('任务已删�?);
831
+ container.closest('.modal')?.remove();
832
+ }
833
+ });
834
+ }
835
+
836
+ // 导出函数供其他模块使�?export { renderOptimizedTaskDetail };
837
+
838
+