uu531 commited on
Commit
778e097
·
verified ·
1 Parent(s): 343b47b

Add 1 files

Browse files
Files changed (1) hide show
  1. index.html +716 -3
index.html CHANGED
@@ -3,7 +3,7 @@
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
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <style>
@@ -80,13 +80,404 @@
80
  background-color: #10b981;
81
  border-color: #10b981;
82
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  </style>
84
  </head>
85
  <body class="bg-gray-50 min-h-screen">
86
- <div class="container mx-auto px-4 py-8 max-w-3xl">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  <!-- 标题 -->
88
  <header class="mb-8 text-center">
89
- <h1 class="text-3xl font-bold text-gray-900 mb-2">任务清单</h1>
 
 
 
90
  <p class="text-gray-600">专注当下,高效生活</p>
91
  <div class="mt-6 relative">
92
  <input
@@ -188,13 +579,49 @@
188
  const remainingTasks = document.getElementById('remainingTasks');
189
  const dueTodayTasks = document.getElementById('dueTodayTasks');
190
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  // 状态
192
  let tasks = JSON.parse(localStorage.getItem('tasks')) || [];
193
  let currentFilter = 'all';
 
 
 
 
 
 
 
194
 
195
  // 初始化
 
196
  renderTasks();
197
  updateStats();
 
 
 
198
 
199
  // 事件监听
200
  addTaskBtn.addEventListener('click', addTask);
@@ -209,6 +636,27 @@
209
 
210
  clearCompleted.addEventListener('click', clearCompletedTasks);
211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  // 功能函数
213
  function addTask() {
214
  const taskText = newTaskInput.value.trim();
@@ -495,6 +943,271 @@
495
  localStorage.setItem('tasks', JSON.stringify(tasks));
496
  }
497
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
498
  // 辅助函数
499
  function formatDate(dateString) {
500
  if (!dateString) return '';
 
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
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <style>
 
80
  background-color: #10b981;
81
  border-color: #10b981;
82
  }
83
+
84
+ /* Logo样式 */
85
+ .todo-logo {
86
+ display: inline-flex;
87
+ align-items: center;
88
+ justify-content: center;
89
+ position: relative;
90
+ font-weight: 800;
91
+ font-size: 2.5rem;
92
+ color: #1f2937;
93
+ margin-bottom: 0.5rem;
94
+ }
95
+
96
+ .todo-logo span {
97
+ position: relative;
98
+ z-index: 2;
99
+ padding: 0 0.5rem;
100
+ }
101
+
102
+ .todo-logo::before {
103
+ content: '';
104
+ position: absolute;
105
+ width: 100%;
106
+ height: 1rem;
107
+ background: linear-gradient(90deg, rgba(239,68,68,0.3), rgba(245,158,11,0.3), rgba(16,185,129,0.3));
108
+ bottom: 0.5rem;
109
+ left: 0;
110
+ z-index: 1;
111
+ transform: skewY(-2deg);
112
+ }
113
+
114
+ .todo-logo .dot {
115
+ color: #ef4444;
116
+ font-size: 3rem;
117
+ line-height: 1;
118
+ margin-left: -0.5rem;
119
+ }
120
+
121
+ /* 暗夜模式 */
122
+ .dark-mode {
123
+ background-color: #111827;
124
+ color: #e5e7eb;
125
+ }
126
+
127
+ .dark-mode .todo-logo {
128
+ color: #e5e7eb;
129
+ }
130
+
131
+ .dark-mode .todo-logo::before {
132
+ background: linear-gradient(90deg, rgba(239,68,68,0.5), rgba(245,158,11,0.5), rgba(16,185,129,0.5));
133
+ }
134
+
135
+ .dark-mode input,
136
+ .dark-mode select,
137
+ .dark-mode .task-item {
138
+ background-color: #1f2937;
139
+ color: #e5e7eb;
140
+ border-color: #374151;
141
+ }
142
+
143
+ .dark-mode .priority-normal {
144
+ background-color: #1f2937;
145
+ }
146
+
147
+ .dark-mode .task-text {
148
+ color: #e5e7eb;
149
+ }
150
+
151
+ .dark-mode .completed .task-text {
152
+ color: #9ca3af;
153
+ }
154
+
155
+ .dark-mode .bg-white {
156
+ background-color: #1f2937;
157
+ border-color: #374151;
158
+ }
159
+
160
+ .dark-mode .text-gray-600 {
161
+ color: #9ca3af;
162
+ }
163
+
164
+ .dark-mode .border-gray-200 {
165
+ border-color: #374151;
166
+ }
167
+
168
+ .dark-mode .hover\:bg-gray-100:hover {
169
+ background-color: #374151;
170
+ }
171
+
172
+ .dark-mode .text-gray-700 {
173
+ color: #e5e7eb;
174
+ }
175
+
176
+ .dark-mode .text-gray-500 {
177
+ color: #9ca3af;
178
+ }
179
+
180
+ .dark-mode .text-gray-300 {
181
+ color: #6b7280;
182
+ }
183
+
184
+ /* 设置面板 */
185
+ .settings-panel {
186
+ position: fixed;
187
+ top: 0;
188
+ right: -400px;
189
+ width: 380px;
190
+ height: 100vh;
191
+ background-color: white;
192
+ box-shadow: -5px 0 15px rgba(0,0,0,0.1);
193
+ transition: right 0.3s ease;
194
+ z-index: 1000;
195
+ padding: 20px;
196
+ overflow-y: auto;
197
+ }
198
+
199
+ .dark-mode .settings-panel {
200
+ background-color: #1f2937;
201
+ color: #e5e7eb;
202
+ }
203
+
204
+ .settings-panel.open {
205
+ right: 0;
206
+ }
207
+
208
+ .settings-overlay {
209
+ position: fixed;
210
+ top: 0;
211
+ left: 0;
212
+ right: 0;
213
+ bottom: 0;
214
+ background-color: rgba(0,0,0,0.5);
215
+ z-index: 999;
216
+ opacity: 0;
217
+ pointer-events: none;
218
+ transition: opacity 0.3s ease;
219
+ }
220
+
221
+ .settings-overlay.active {
222
+ opacity: 1;
223
+ pointer-events: all;
224
+ }
225
+
226
+ /* 音乐播放器 */
227
+ .music-sidebar {
228
+ position: fixed;
229
+ top: 0;
230
+ right: -400px;
231
+ width: 380px;
232
+ height: 100vh;
233
+ background-color: white;
234
+ box-shadow: -5px 0 15px rgba(0,0,0,0.1);
235
+ transition: right 0.3s ease;
236
+ z-index: 998;
237
+ display: flex;
238
+ flex-direction: column;
239
+ }
240
+
241
+ .dark-mode .music-sidebar {
242
+ background-color: #1f2937;
243
+ color: #e5e7eb;
244
+ }
245
+
246
+ .music-sidebar.open {
247
+ right: 0;
248
+ }
249
+
250
+ .music-header {
251
+ padding: 20px;
252
+ border-bottom: 1px solid #e5e7eb;
253
+ display: flex;
254
+ justify-content: space-between;
255
+ align-items: center;
256
+ }
257
+
258
+ .dark-mode .music-header {
259
+ border-bottom-color: #374151;
260
+ }
261
+
262
+ .music-content {
263
+ flex: 1;
264
+ overflow-y: auto;
265
+ padding: 20px;
266
+ }
267
+
268
+ .music-player {
269
+ padding: 15px;
270
+ border-top: 1px solid #e5e7eb;
271
+ }
272
+
273
+ .dark-mode .music-player {
274
+ border-top-color: #374151;
275
+ }
276
+
277
+ .progress-container {
278
+ width: 100%;
279
+ height: 3px;
280
+ background-color: #eee;
281
+ margin-bottom: 10px;
282
+ }
283
+
284
+ .dark-mode .progress-container {
285
+ background-color: #374151;
286
+ }
287
+
288
+ .progress-bar {
289
+ height: 100%;
290
+ background-color: #ef4444;
291
+ width: 0%;
292
+ }
293
+
294
+ .player-controls {
295
+ display: flex;
296
+ justify-content: space-between;
297
+ align-items: center;
298
+ margin-bottom: 10px;
299
+ }
300
+
301
+ .player-info {
302
+ margin-bottom: 15px;
303
+ }
304
+
305
+ .music-title {
306
+ font-weight: bold;
307
+ white-space: nowrap;
308
+ overflow: hidden;
309
+ text-overflow: ellipsis;
310
+ }
311
+
312
+ .music-artist {
313
+ font-size: 0.8rem;
314
+ color: #666;
315
+ }
316
+
317
+ .dark-mode .music-artist {
318
+ color: #9ca3af;
319
+ }
320
+
321
+ /* 主内容区域 */
322
+ .main-content {
323
+ transition: margin-right 0.3s ease;
324
+ }
325
+
326
+ .main-content.sidebar-open {
327
+ margin-right: 400px;
328
+ }
329
+
330
+ /* 音乐列表项 */
331
+ .music-item {
332
+ padding: 10px;
333
+ border-bottom: 1px solid #e5e7eb;
334
+ display: flex;
335
+ justify-content: space-between;
336
+ align-items: center;
337
+ cursor: pointer;
338
+ }
339
+
340
+ .dark-mode .music-item {
341
+ border-bottom-color: #374151;
342
+ }
343
+
344
+ .music-item:hover {
345
+ background-color: #f3f4f6;
346
+ }
347
+
348
+ .dark-mode .music-item:hover {
349
+ background-color: #374151;
350
+ }
351
+
352
+ /* 登录按钮 */
353
+ .netease-login-btn {
354
+ display: inline-block;
355
+ padding: 8px 15px;
356
+ background-color: #e60026;
357
+ color: white;
358
+ border-radius: 4px;
359
+ font-size: 14px;
360
+ text-decoration: none;
361
+ transition: background-color 0.2s;
362
+ }
363
+
364
+ .netease-login-btn:hover {
365
+ background-color: #c50020;
366
+ }
367
  </style>
368
  </head>
369
  <body class="bg-gray-50 min-h-screen">
370
+ <!-- 设置按钮 -->
371
+ <div class="fixed top-4 right-4 z-50 flex space-x-2">
372
+ <button id="musicToggleBtn" class="p-3 rounded-full bg-gray-900 text-white hover:bg-gray-800 transition-colors shadow-lg">
373
+ <i class="fas fa-music"></i>
374
+ </button>
375
+ <button id="settingsBtn" class="p-3 rounded-full bg-gray-900 text-white hover:bg-gray-800 transition-colors shadow-lg">
376
+ <i class="fas fa-cog"></i>
377
+ </button>
378
+ </div>
379
+
380
+ <!-- 设置面板 -->
381
+ <div class="settings-overlay" id="settingsOverlay"></div>
382
+
383
+ <div class="settings-panel" id="settingsPanel">
384
+ <div class="flex justify-between items-center mb-6">
385
+ <h2 class="text-xl font-bold">设置</h2>
386
+ <button id="closeSettings" class="text-gray-500 hover:text-gray-700">
387
+ <i class="fas fa-times"></i>
388
+ </button>
389
+ </div>
390
+
391
+ <div class="mb-6">
392
+ <h3 class="text-lg font-semibold mb-3">主题</h3>
393
+ <div class="flex items-center justify-between">
394
+ <span>暗夜模式</span>
395
+ <label class="relative inline-flex items-center cursor-pointer">
396
+ <input type="checkbox" id="darkModeToggle" class="sr-only peer">
397
+ <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-gray-800"></div>
398
+ </label>
399
+ </div>
400
+ </div>
401
+
402
+ <div class="mb-6">
403
+ <h3 class="text-lg font-semibold mb-3">网易云音乐</h3>
404
+ <div class="mb-4">
405
+ <label class="block text-sm text-gray-600 mb-1">网易云音乐网址</label>
406
+ <div class="flex">
407
+ <input type="text" id="neteaseUrl" placeholder="https://music.163.com" value="https://music.163.com" class="flex-1 px-4 py-2 rounded-l-lg border border-gray-300 focus:outline-none focus:border-gray-500">
408
+ <a id="neteaseLoginBtn" href="https://music.163.com" target="_blank" class="netease-login-btn px-4 py-2 rounded-r-lg">
409
+ <i class="fas fa-sign-in-alt mr-1"></i> 登录
410
+ </a>
411
+ </div>
412
+ </div>
413
+
414
+ <div class="mb-4">
415
+ <label class="block text-sm text-gray-600 mb-1">搜索歌曲</label>
416
+ <div class="flex">
417
+ <input type="text" id="musicSearch" placeholder="输入歌曲名" class="flex-1 px-4 py-2 rounded-l-lg border border-gray-300 focus:outline-none focus:border-gray-500">
418
+ <button id="searchMusicBtn" class="px-4 py-2 bg-gray-900 text-white rounded-r-lg hover:bg-gray-800">
419
+ <i class="fas fa-search"></i>
420
+ </button>
421
+ </div>
422
+ </div>
423
+
424
+ <div id="musicResults" class="max-h-60 overflow-y-auto border border-gray-200 rounded-lg">
425
+ <!-- 音乐搜索结果将显示在这里 -->
426
+ <div class="text-center py-8 text-gray-500">
427
+ <i class="fas fa-music text-2xl mb-2 text-gray-300"></i>
428
+ <p>搜索你喜欢的音乐</p>
429
+ </div>
430
+ </div>
431
+ </div>
432
+ </div>
433
+
434
+ <!-- 音乐侧边栏 -->
435
+ <div class="music-sidebar" id="musicSidebar">
436
+ <div class="music-header">
437
+ <h2 class="text-xl font-bold">音乐播放器</h2>
438
+ <button id="closeMusicSidebar" class="text-gray-500 hover:text-gray-700">
439
+ <i class="fas fa-times"></i>
440
+ </button>
441
+ </div>
442
+
443
+ <div class="music-content" id="musicContent">
444
+ <div class="text-center py-8 text-gray-500">
445
+ <i class="fas fa-music text-2xl mb-2 text-gray-300"></i>
446
+ <p>从设置中搜索音乐开始播放</p>
447
+ </div>
448
+ </div>
449
+
450
+ <div class="music-player">
451
+ <div class="progress-container">
452
+ <div class="progress-bar" id="progressBar"></div>
453
+ </div>
454
+
455
+ <div class="player-info">
456
+ <div class="music-title" id="musicTitle">未播放</div>
457
+ <div class="music-artist" id="musicArtist">-</div>
458
+ </div>
459
+
460
+ <div class="player-controls">
461
+ <button id="prevBtn" class="text-gray-900 hover:text-gray-700">
462
+ <i class="fas fa-step-backward"></i>
463
+ </button>
464
+ <button id="playPauseBtn" class="text-gray-900 hover:text-gray-700 text-xl">
465
+ <i class="fas fa-play"></i>
466
+ </button>
467
+ <button id="nextBtn" class="text-gray-900 hover:text-gray-700">
468
+ <i class="fas fa-step-forward"></i>
469
+ </button>
470
+ </div>
471
+ </div>
472
+ </div>
473
+
474
+ <div class="container mx-auto px-4 py-8 max-w-3xl main-content" id="mainContent">
475
  <!-- 标题 -->
476
  <header class="mb-8 text-center">
477
+ <div class="todo-logo">
478
+ <span>任务管理</span>
479
+ <span class="dot">.</span>
480
+ </div>
481
  <p class="text-gray-600">专注当下,高效生活</p>
482
  <div class="mt-6 relative">
483
  <input
 
579
  const remainingTasks = document.getElementById('remainingTasks');
580
  const dueTodayTasks = document.getElementById('dueTodayTasks');
581
 
582
+ // 设置相关元素
583
+ const settingsBtn = document.getElementById('settingsBtn');
584
+ const settingsPanel = document.getElementById('settingsPanel');
585
+ const settingsOverlay = document.getElementById('settingsOverlay');
586
+ const closeSettings = document.getElementById('closeSettings');
587
+ const darkModeToggle = document.getElementById('darkModeToggle');
588
+ const musicToggleBtn = document.getElementById('musicToggleBtn');
589
+ const musicSidebar = document.getElementById('musicSidebar');
590
+ const closeMusicSidebar = document.getElementById('closeMusicSidebar');
591
+ const musicContent = document.getElementById('musicContent');
592
+ const neteaseUrl = document.getElementById('neteaseUrl');
593
+ const neteaseLoginBtn = document.getElementById('neteaseLoginBtn');
594
+
595
+ // 音乐播放器相关元素
596
+ const musicSearch = document.getElementById('musicSearch');
597
+ const searchMusicBtn = document.getElementById('searchMusicBtn');
598
+ const musicResults = document.getElementById('musicResults');
599
+ const playPauseBtn = document.getElementById('playPauseBtn');
600
+ const prevBtn = document.getElementById('prevBtn');
601
+ const nextBtn = document.getElementById('nextBtn');
602
+ const musicTitle = document.getElementById('musicTitle');
603
+ const musicArtist = document.getElementById('musicArtist');
604
+ const progressBar = document.getElementById('progressBar');
605
+ const mainContent = document.getElementById('mainContent');
606
+
607
  // 状态
608
  let tasks = JSON.parse(localStorage.getItem('tasks')) || [];
609
  let currentFilter = 'all';
610
+ let isDarkMode = localStorage.getItem('darkMode') === 'true';
611
+ let currentMusicIndex = -1;
612
+ let musicList = [];
613
+ let audio = new Audio();
614
+ let isPlaying = false;
615
+ let progressInterval;
616
+ let neteaseMusicUrl = localStorage.getItem('neteaseMusicUrl') || 'https://music.163.com';
617
 
618
  // 初始化
619
+ initDarkMode();
620
  renderTasks();
621
  updateStats();
622
+ setupMusicPlayer();
623
+ neteaseUrl.value = neteaseMusicUrl;
624
+ updateNeteaseLoginBtn();
625
 
626
  // 事件监听
627
  addTaskBtn.addEventListener('click', addTask);
 
636
 
637
  clearCompleted.addEventListener('click', clearCompletedTasks);
638
 
639
+ // 设置面板事件
640
+ settingsBtn.addEventListener('click', openSettings);
641
+ closeSettings.addEventListener('click', closeSettingsPanel);
642
+ settingsOverlay.addEventListener('click', closeSettingsPanel);
643
+ darkModeToggle.addEventListener('change', toggleDarkMode);
644
+ musicToggleBtn.addEventListener('click', toggleMusicSidebar);
645
+ closeMusicSidebar.addEventListener('click', closeMusicSidebarPanel);
646
+
647
+ // 网易云音乐设置
648
+ neteaseUrl.addEventListener('change', updateNeteaseUrl);
649
+
650
+ // 音乐播放器事件
651
+ searchMusicBtn.addEventListener('click', searchMusic);
652
+ musicSearch.addEventListener('keypress', function(e) {
653
+ if (e.key === 'Enter') searchMusic();
654
+ });
655
+
656
+ playPauseBtn.addEventListener('click', togglePlayPause);
657
+ prevBtn.addEventListener('click', playPrevious);
658
+ nextBtn.addEventListener('click', playNext);
659
+
660
  // 功能函数
661
  function addTask() {
662
  const taskText = newTaskInput.value.trim();
 
943
  localStorage.setItem('tasks', JSON.stringify(tasks));
944
  }
945
 
946
+ // 设置面板功能
947
+ function openSettings() {
948
+ settingsPanel.classList.add('open');
949
+ settingsOverlay.classList.add('active');
950
+ mainContent.classList.add('sidebar-open');
951
+ }
952
+
953
+ function closeSettingsPanel() {
954
+ settingsPanel.classList.remove('open');
955
+ settingsOverlay.classList.remove('active');
956
+ mainContent.classList.remove('sidebar-open');
957
+ }
958
+
959
+ function toggleMusicSidebar() {
960
+ if (musicSidebar.classList.contains('open')) {
961
+ closeMusicSidebarPanel();
962
+ } else {
963
+ openMusicSidebar();
964
+ }
965
+ }
966
+
967
+ function openMusicSidebar() {
968
+ musicSidebar.classList.add('open');
969
+ mainContent.classList.add('sidebar-open');
970
+ }
971
+
972
+ function closeMusicSidebarPanel() {
973
+ musicSidebar.classList.remove('open');
974
+ mainContent.classList.remove('sidebar-open');
975
+ }
976
+
977
+ function initDarkMode() {
978
+ if (isDarkMode) {
979
+ document.body.classList.add('dark-mode');
980
+ darkModeToggle.checked = true;
981
+ } else {
982
+ document.body.classList.remove('dark-mode');
983
+ darkModeToggle.checked = false;
984
+ }
985
+ }
986
+
987
+ function toggleDarkMode() {
988
+ isDarkMode = !isDarkMode;
989
+ localStorage.setItem('darkMode', isDarkMode);
990
+ initDarkMode();
991
+ }
992
+
993
+ // 网易云音乐设置
994
+ function updateNeteaseUrl() {
995
+ neteaseMusicUrl = neteaseUrl.value.trim();
996
+ if (neteaseMusicUrl === '') {
997
+ neteaseMusicUrl = 'https://music.163.com';
998
+ neteaseUrl.value = neteaseMusicUrl;
999
+ }
1000
+ localStorage.setItem('neteaseMusicUrl', neteaseMusicUrl);
1001
+ updateNeteaseLoginBtn();
1002
+ }
1003
+
1004
+ function updateNeteaseLoginBtn() {
1005
+ neteaseLoginBtn.href = neteaseMusicUrl;
1006
+ }
1007
+
1008
+ // 音乐播放器功能
1009
+ function setupMusicPlayer() {
1010
+ audio.addEventListener('ended', playNext);
1011
+ audio.addEventListener('timeupdate', updateProgress);
1012
+
1013
+ // 从本地存储加载播放列表
1014
+ const savedPlaylist = localStorage.getItem('musicPlaylist');
1015
+ if (savedPlaylist) {
1016
+ musicList = JSON.parse(savedPlaylist);
1017
+ renderMusicList();
1018
+ }
1019
+
1020
+ // 从本地存储加载当前播放索引
1021
+ const savedIndex = localStorage.getItem('currentMusicIndex');
1022
+ if (savedIndex !== null) {
1023
+ currentMusicIndex = parseInt(savedIndex);
1024
+ if (currentMusicIndex >= 0 && currentMusicIndex < musicList.length) {
1025
+ updateMusicInfo();
1026
+ }
1027
+ }
1028
+ }
1029
+
1030
+ function renderMusicList() {
1031
+ if (musicList.length === 0) {
1032
+ musicContent.innerHTML = '<div class="text-center py-8 text-gray-500"><i class="fas fa-music text-2xl mb-2 text-gray-300"></i><p>从设置中搜索音乐开始播放</p></div>';
1033
+ return;
1034
+ }
1035
+
1036
+ musicContent.innerHTML = '';
1037
+ musicList.forEach((song, index) => {
1038
+ const songElement = document.createElement('div');
1039
+ songElement.className = 'music-item';
1040
+ songElement.innerHTML = `
1041
+ <div>
1042
+ <div class="font-medium">${song.title}</div>
1043
+ <div class="text-sm text-gray-600">${song.artist}</div>
1044
+ </div>
1045
+ ${currentMusicIndex === index ? '<i class="fas fa-volume-up text-blue-500"></i>' : '<i class="fas fa-play text-gray-500"></i>'}
1046
+ `;
1047
+
1048
+ songElement.addEventListener('click', () => {
1049
+ playSong(index);
1050
+ });
1051
+
1052
+ musicContent.appendChild(songElement);
1053
+ });
1054
+ }
1055
+
1056
+ function searchMusic() {
1057
+ const query = musicSearch.value.trim();
1058
+ if (query === '') return;
1059
+
1060
+ // 模拟网易云音乐API请求
1061
+ // 在实际应用中,这里应该是一个真实的API请求
1062
+ musicResults.innerHTML = '<div class="text-center py-4"><i class="fas fa-spinner fa-spin"></i> 搜索中...</div>';
1063
+
1064
+ // 模拟延迟
1065
+ setTimeout(() => {
1066
+ // 模拟搜索结果
1067
+ const mockResults = [
1068
+ { id: 1, title: '晴天', artist: '周杰伦', url: 'https://music.163.com/song/media/outer/url?id=186436.mp3' },
1069
+ { id: 2, title: '夜曲', artist: '周杰伦', url: 'https://music.163.com/song/media/outer/url?id=186001.mp3' },
1070
+ { id: 3, title: '七里香', artist: '周杰伦', url: 'https://music.163.com/song/media/outer/url?id=185879.mp3' },
1071
+ { id: 4, title: '稻香', artist: '周杰伦', url: 'https://music.163.com/song/media/outer/url?id=287035.mp3' },
1072
+ { id: 5, title: '告白气球', artist: '周杰伦', url: 'https://music.163.com/song/media/outer/url?id=418603077.mp3' }
1073
+ ];
1074
+
1075
+ // 过滤结果
1076
+ const filteredResults = mockResults.filter(song =>
1077
+ song.title.includes(query) || song.artist.includes(query)
1078
+ );
1079
+
1080
+ if (filteredResults.length === 0) {
1081
+ musicResults.innerHTML = '<div class="text-center py-8 text-gray-500">没有找到相关歌曲</div>';
1082
+ return;
1083
+ }
1084
+
1085
+ musicResults.innerHTML = '';
1086
+ filteredResults.forEach((song, index) => {
1087
+ const songElement = document.createElement('div');
1088
+ songElement.className = 'p-3 border-b border-gray-200 hover:bg-gray-100 cursor-pointer flex justify-between items-center';
1089
+ songElement.innerHTML = `
1090
+ <div>
1091
+ <div class="font-medium">${song.title}</div>
1092
+ <div class="text-sm text-gray-600">${song.artist}</div>
1093
+ </div>
1094
+ <i class="fas fa-play text-gray-500"></i>
1095
+ `;
1096
+
1097
+ songElement.addEventListener('click', () => {
1098
+ playSong(index, filteredResults);
1099
+ });
1100
+
1101
+ musicResults.appendChild(songElement);
1102
+ });
1103
+
1104
+ // 更新播放列表
1105
+ musicList = filteredResults;
1106
+ localStorage.setItem('musicPlaylist', JSON.stringify(musicList));
1107
+ renderMusicList();
1108
+ }, 1000);
1109
+ }
1110
+
1111
+ function playSong(index, playlist = musicList) {
1112
+ if (index < 0 || index >= playlist.length) return;
1113
+
1114
+ currentMusicIndex = index;
1115
+ const song = playlist[currentMusicIndex];
1116
+
1117
+ audio.src = song.url;
1118
+ audio.play()
1119
+ .then(() => {
1120
+ isPlaying = true;
1121
+ updatePlayPauseIcon();
1122
+ updateMusicInfo();
1123
+ startProgressUpdate();
1124
+ renderMusicList();
1125
+
1126
+ // 保存当前播放索引
1127
+ localStorage.setItem('currentMusicIndex', currentMusicIndex);
1128
+ })
1129
+ .catch(error => {
1130
+ console.error('播放失败:', error);
1131
+ alert('播放失败,请稍后再试');
1132
+ });
1133
+ }
1134
+
1135
+ function togglePlayPause() {
1136
+ if (audio.src) {
1137
+ if (isPlaying) {
1138
+ audio.pause();
1139
+ } else {
1140
+ audio.play();
1141
+ }
1142
+ isPlaying = !isPlaying;
1143
+ updatePlayPauseIcon();
1144
+
1145
+ if (isPlaying) {
1146
+ startProgressUpdate();
1147
+ } else {
1148
+ stopProgressUpdate();
1149
+ }
1150
+ } else if (musicList.length > 0) {
1151
+ // 如果没有正在播放的歌曲,但有播放列表,播放第一首
1152
+ playSong(0);
1153
+ }
1154
+ }
1155
+
1156
+ function playPrevious() {
1157
+ if (musicList.length === 0) return;
1158
+
1159
+ let newIndex = currentMusicIndex - 1;
1160
+ if (newIndex < 0) {
1161
+ newIndex = musicList.length - 1; // 循环到最后一首
1162
+ }
1163
+
1164
+ playSong(newIndex);
1165
+ }
1166
+
1167
+ function playNext() {
1168
+ if (musicList.length === 0) return;
1169
+
1170
+ let newIndex = currentMusicIndex + 1;
1171
+ if (newIndex >= musicList.length) {
1172
+ newIndex = 0; // 循环到第一首
1173
+ }
1174
+
1175
+ playSong(newIndex);
1176
+ }
1177
+
1178
+ function updatePlayPauseIcon() {
1179
+ playPauseBtn.innerHTML = isPlaying ? '<i class="fas fa-pause"></i>' : '<i class="fas fa-play"></i>';
1180
+ }
1181
+
1182
+ function updateMusicInfo() {
1183
+ if (currentMusicIndex >= 0 && currentMusicIndex < musicList.length) {
1184
+ const song = musicList[currentMusicIndex];
1185
+ musicTitle.textContent = song.title;
1186
+ musicArtist.textContent = song.artist;
1187
+ } else {
1188
+ musicTitle.textContent = '未播放';
1189
+ musicArtist.textContent = '-';
1190
+ }
1191
+ }
1192
+
1193
+ function updateProgress() {
1194
+ if (audio.duration) {
1195
+ const progress = (audio.currentTime / audio.duration) * 100;
1196
+ progressBar.style.width = `${progress}%`;
1197
+ }
1198
+ }
1199
+
1200
+ function startProgressUpdate() {
1201
+ stopProgressUpdate();
1202
+ progressInterval = setInterval(updateProgress, 1000);
1203
+ }
1204
+
1205
+ function stopProgressUpdate() {
1206
+ if (progressInterval) {
1207
+ clearInterval(progressInterval);
1208
+ }
1209
+ }
1210
+
1211
  // 辅助函数
1212
  function formatDate(dateString) {
1213
  if (!dateString) return '';