feat(admin-ui): 管理后台整体切换为浅色主题(ModernLight) + 新增 lightbulb 图标

1. layout(管理控制台 dashboard.vue): main bg-[#09090b] text-zinc-100 → bg-[#f8fafc] text-zinc-900; header bg-zinc-950/60 border-zinc-800 → bg-white/80 border-zinc-200; 移动菜单按钮/新手引导按钮 text-zinc-300/400 hover:bg-zinc-800 → text-zinc-600 hover:bg-zinc-100 border-zinc-200

2. Admin/Sidebar.vue: bg-[#09090b] border-zinc-800 → bg-white border-zinc-200 + shadow-sm; 标题 text-zinc-100 → 900; activeTab bg-blue-600/10 text-blue-400 → bg-blue-50 text-blue-700 border-blue-200; 未选中 text-zinc-500 hover:text-zinc-200 hover:bg-zinc-800/40 → text-zinc-600 hover:text-zinc-900 hover:bg-zinc-100; 用户卡 avatar/首字母 bg-white/70 border-zinc-200 + 退出按钮 hover:bg-red-50 text-red-600

3. 批量 33 个 Admin 组件硬编码深色原子类 1414 处替换(bg-zinc-9xx / border-zinc-8xx / text-zinc-100,200,300 / shadow-black/ -> 对应 light 版本) + style 块原生 CSS rgba(255,255,255,x) 16 处改为 rgba(0,0,0,x) / var 浅色主题 + 硬编码 bg-[#0c0c0e] / border-white/10 / color:white / surface-primary fallback 对应浅色修正

4. 二轮批量追加: bg-zinc-950 + opacity 变体(80/60/50/40/30/20/10) 共 431 处 → bg-white 对应 opacity 版本;placeholder:text-zinc-800 → 500;text-blue/red/emerald/amber/rose/purple 400 版 → 700/600 深浅一致版;border color /500 /30 → 200;focus:ring /20 → /30;shadow color 阴影降低强度

5. hover:text-white 扫尾: 13 处 DataAnalysisPanel/DatabaseManager/NotificationSender/SemesterManager/SongManagement/UserSongsModal hover 文本从 white → zinc-900;按钮三态从 hover:bg-*600 白字 → hover:bg-*-100/200 对应深字色,和前台 indigo/浅色体系保持一致

6. BlacklistManager 前台可见提示 💡→ <Icon lightbulb amber-600 size=13>;ChangelogManager 徽章色从 emerald-300/blue-300/zinc-400 → emerald-700/blue-700/zinc-600 可读;Icon.vue 新增 lightbulb 分支 stroke 图标

7. 受影响文件: dashboard.vue + Sidebar.vue + Icon.vue + Admin/* (33个组件共 1874 处批量替换 + 20 处手工精细化修正)
This commit is contained in:
2026-09-19 08:30:59 +08:00
parent 357876a716
commit 573e168702
36 changed files with 1023 additions and 1017 deletions
+46 -46
View File
@@ -8,14 +8,14 @@
<Transition name="scale">
<div
v-if="show"
class="bg-zinc-900 border border-zinc-800 rounded-2xl shadow-2xl w-full max-w-lg overflow-hidden flex flex-col max-h-[90vh]"
class="bg-white border border-zinc-200 rounded-2xl shadow-2xl w-full max-w-lg overflow-hidden flex flex-col max-h-[90vh]"
@click.stop
>
<!-- 头部 -->
<div class="flex items-center justify-between p-4 border-b border-zinc-800 shrink-0">
<h3 class="text-sm font-black text-zinc-100 uppercase tracking-widest">下载歌曲</h3>
<div class="flex items-center justify-between p-4 border-b border-zinc-200 shrink-0">
<h3 class="text-sm font-black text-zinc-900 uppercase tracking-widest">下载歌曲</h3>
<button
class="text-zinc-500 hover:text-zinc-300 transition-colors"
class="text-zinc-500 hover:text-zinc-600 transition-colors"
@click="closeDialog"
>
<CloseIcon class="w-5 h-5" />
@@ -36,15 +36,15 @@
class="flex flex-col p-4 rounded-2xl border text-left transition-all relative overflow-hidden group"
:class="[
selectedQuality === option.value
? 'bg-blue-600/10 border-blue-500 shadow-sm'
: 'bg-zinc-950 border-zinc-800 hover:border-zinc-700'
? 'bg-blue-50 border-blue-500 shadow-sm'
: 'bg-white border-zinc-200 hover:border-zinc-200'
]"
@click="selectedQuality = option.value"
>
<div class="flex items-center justify-between mb-1 relative z-10">
<span
class="text-xs font-bold transition-colors"
:class="selectedQuality === option.value ? 'text-blue-400' : 'text-zinc-200'"
:class="selectedQuality === option.value ? 'text-blue-700' : 'text-zinc-700'"
>{{ option.label }}</span
>
<div
@@ -69,16 +69,16 @@
>
</div>
<div class="bg-zinc-950 border border-zinc-800 rounded-2xl p-4 space-y-4">
<div class="bg-white border border-zinc-200 rounded-2xl p-4 space-y-4">
<!-- 合并开关 -->
<div class="flex items-center justify-between">
<div class="flex flex-col">
<span class="text-xs font-bold text-zinc-200">合并为一个文件</span>
<span class="text-xs font-bold text-zinc-700">合并为一个文件</span>
<span class="text-[10px] text-zinc-500">将选中歌曲按顺序合并为单个音频</span>
</div>
<button
class="w-10 h-6 rounded-full transition-colors relative"
:class="mergeSongs ? 'bg-blue-600' : 'bg-zinc-700'"
:class="mergeSongs ? 'bg-blue-600' : 'bg-zinc-200'"
@click="mergeSongs = !mergeSongs"
>
<div
@@ -90,20 +90,20 @@
<!-- 合并设置区域 -->
<Transition name="expand">
<div v-if="mergeSongs" class="space-y-4 pt-4 border-t border-zinc-800/50">
<div v-if="mergeSongs" class="space-y-4 pt-4 border-t border-zinc-200">
<!-- 导出格式选择 -->
<div class="space-y-2">
<div class="flex items-center gap-2">
<Music class="w-3 h-3 text-zinc-500" />
<span class="text-xs font-bold text-zinc-200">导出格式</span>
<span class="text-xs font-bold text-zinc-700">导出格式</span>
</div>
<div class="flex gap-2">
<button
class="flex-1 py-1.5 px-3 rounded-lg border text-[10px] font-bold transition-all"
:class="
exportFormat === 'mp3'
? 'bg-blue-600/10 border-blue-500 text-blue-400'
: 'bg-zinc-900 border-zinc-800 text-zinc-400 hover:border-zinc-700'
? 'bg-blue-50 border-blue-500 text-blue-700'
: 'bg-white border-zinc-200 text-zinc-400 hover:border-zinc-200'
"
@click="exportFormat = 'mp3'"
>
@@ -113,8 +113,8 @@
class="flex-1 py-1.5 px-3 rounded-lg border text-[10px] font-bold transition-all"
:class="
exportFormat === 'wav'
? 'bg-blue-600/10 border-blue-500 text-blue-400'
: 'bg-zinc-900 border-zinc-800 text-zinc-400 hover:border-zinc-700'
? 'bg-blue-50 border-blue-500 text-blue-700'
: 'bg-white border-zinc-200 text-zinc-400 hover:border-zinc-200'
"
@click="exportFormat = 'wav'"
>
@@ -128,10 +128,10 @@
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<Edit3 class="w-3 h-3 text-zinc-500" />
<span class="text-xs font-bold text-zinc-200">自定义文件名</span>
<span class="text-xs font-bold text-zinc-700">自定义文件名</span>
</div>
<button
class="text-[10px] text-blue-400 hover:text-blue-300 transition-colors flex items-center gap-1"
class="text-[10px] text-blue-700 hover:text-blue-300 transition-colors flex items-center gap-1"
:class="{ 'opacity-50 cursor-not-allowed': !customFilename }"
title="保存为默认预设"
@click="saveFilenamePreset"
@@ -145,19 +145,19 @@
v-model="customFilename"
type="text"
placeholder="例如: 第XX期 - {songs}"
class="w-full bg-zinc-900 border border-zinc-800 rounded-xl px-3 py-2 text-xs text-zinc-200 focus:outline-none focus:border-blue-500/50 transition-colors pr-8"
class="w-full bg-white border border-zinc-200 rounded-xl px-3 py-2 text-xs text-zinc-700 focus:outline-none focus:border-blue-500/50 transition-colors pr-8"
>
<!-- 快速插入占位符按钮 -->
<div class="absolute right-2 top-1/2 -translate-y-1/2 flex gap-1">
<button
class="px-1.5 py-0.5 rounded bg-zinc-800 text-[9px] text-zinc-400 hover:text-zinc-200 hover:bg-zinc-700 transition-colors"
class="px-1.5 py-0.5 rounded bg-zinc-100 text-[9px] text-zinc-400 hover:text-zinc-700 hover:bg-zinc-200 transition-colors"
title="插入所有歌名"
@click="insertPlaceholder('{songs}')"
>
{songs}
</button>
<button
class="px-1.5 py-0.5 rounded bg-zinc-800 text-[9px] text-zinc-400 hover:text-zinc-200 hover:bg-zinc-700 transition-colors"
class="px-1.5 py-0.5 rounded bg-zinc-100 text-[9px] text-zinc-400 hover:text-zinc-700 hover:bg-zinc-200 transition-colors"
title="插入当前日期"
@click="insertPlaceholder('{date}')"
>
@@ -168,13 +168,13 @@
<p class="text-[9px] text-zinc-600">
可用占位符:
<code
class="bg-zinc-800 px-1 rounded text-zinc-400 cursor-pointer hover:text-blue-400"
class="bg-zinc-100 px-1 rounded text-zinc-400 cursor-pointer hover:text-blue-700"
@click="insertPlaceholder('{songs}')"
>{songs}</code
>
(所有歌名),
<code
class="bg-zinc-800 px-1 rounded text-zinc-400 cursor-pointer hover:text-blue-400"
class="bg-zinc-100 px-1 rounded text-zinc-400 cursor-pointer hover:text-blue-700"
@click="insertPlaceholder('{date}')"
>{date}</code
>
@@ -184,14 +184,14 @@
<!-- 标准化选项 (仅在合并模式或需要时显示,这里允许单独使用) -->
<div
class="flex items-center justify-between pt-3 border-t border-zinc-800/50"
class="flex items-center justify-between pt-3 border-t border-zinc-200"
>
<div class="flex flex-col">
<div class="flex items-center gap-2">
<span class="text-xs font-bold text-zinc-200">统一音量 (标准化)</span>
<span class="text-xs font-bold text-zinc-700">统一音量 (标准化)</span>
<span
v-if="normalizeAudio"
class="text-[10px] bg-blue-500/10 text-blue-400 px-1.5 py-0.5 rounded border border-blue-500/20"
class="text-[10px] bg-blue-500/10 text-blue-700 px-1.5 py-0.5 rounded border border-blue-200"
>Peak {{ targetDb }}dB</span
>
</div>
@@ -201,7 +201,7 @@
</div>
<div class="flex items-center gap-3">
<button
class="text-[10px] text-blue-400 hover:text-blue-300 transition-colors flex items-center gap-1"
class="text-[10px] text-blue-700 hover:text-blue-300 transition-colors flex items-center gap-1"
title="保存当前音量设置(包括开启状态)为默认"
@click="saveDbPreset"
>
@@ -210,7 +210,7 @@
</button>
<button
class="w-10 h-6 rounded-full transition-colors relative"
:class="normalizeAudio ? 'bg-blue-600' : 'bg-zinc-700'"
:class="normalizeAudio ? 'bg-blue-600' : 'bg-zinc-200'"
@click="normalizeAudio = !normalizeAudio"
>
<div
@@ -232,9 +232,9 @@
min="-10"
max="0"
step="0.5"
class="flex-1 h-1.5 bg-zinc-800 rounded-lg appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-blue-500"
class="flex-1 h-1.5 bg-zinc-100 rounded-lg appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-blue-500"
>
<span class="text-xs font-mono text-zinc-300 w-12 text-right"
<span class="text-xs font-mono text-zinc-600 w-12 text-right"
>{{ targetDb }} dB</span
>
</div>
@@ -255,7 +255,7 @@
>
<div
v-if="estimatedTotalDuration.count > 0"
class="flex items-center gap-1.5 text-[10px] text-blue-400 font-bold bg-blue-500/10 px-2 py-0.5 rounded-full border border-blue-500/20"
class="flex items-center gap-1.5 text-[10px] text-blue-700 font-bold bg-blue-500/10 px-2 py-0.5 rounded-full border border-blue-200"
>
<Clock class="w-3 h-3" />
<span>预估总时长: {{ formatDuration(estimatedTotalDuration.total) }}</span>
@@ -264,7 +264,7 @@
<div class="flex items-center gap-2">
<button
v-if="selectedSongs.size > 0"
class="text-[10px] font-bold text-zinc-500 hover:text-zinc-300 transition-colors flex items-center gap-1"
class="text-[10px] font-bold text-zinc-500 hover:text-zinc-600 transition-colors flex items-center gap-1"
title="预下载选中歌曲到浏览器缓存"
@click="preloadSelectedSongs"
>
@@ -272,7 +272,7 @@
预下载选中
</button>
<button
class="text-[10px] font-bold text-blue-500/80 hover:text-blue-400 transition-colors"
class="text-[10px] font-bold text-blue-500/80 hover:text-blue-700 transition-colors"
@click="toggleSelectAll"
>
{{ isAllSelected ? '取消全选' : '全选' }}
@@ -281,12 +281,12 @@
</div>
<div
class="bg-zinc-950/50 border border-zinc-800/50 rounded-2xl overflow-hidden max-h-[300px] overflow-y-auto custom-scrollbar"
class="bg-white/70 border border-zinc-200 rounded-2xl overflow-hidden max-h-[300px] overflow-y-auto custom-scrollbar"
>
<div
v-for="song in songs"
:key="song.id"
class="w-full flex items-center gap-3 p-3.5 hover:bg-zinc-800/30 transition-all text-left border-b border-zinc-800/30 last:border-0 group relative"
class="w-full flex items-center gap-3 p-3.5 hover:bg-zinc-100/30 transition-all text-left border-b border-zinc-200/30 last:border-0 group relative"
>
<!-- 预下载进度条背景 -->
<div
@@ -310,7 +310,7 @@
:class="[
selectedSongs.has(song.song.id)
? 'bg-blue-600 border-blue-600 shadow-sm'
: 'bg-zinc-900 border-zinc-800 group-hover:border-zinc-700'
: 'bg-white border-zinc-200 group-hover:border-zinc-200'
]"
@click="toggleSongSelection(song.song.id)"
>
@@ -326,7 +326,7 @@
@click="toggleSongSelection(song.song.id)"
>
<div class="flex items-center gap-2">
<p class="text-xs font-bold text-zinc-300 truncate">{{ song.song.title }}</p>
<p class="text-xs font-bold text-zinc-600 truncate">{{ song.song.title }}</p>
<!-- 预下载标记 -->
<div
v-if="
@@ -360,7 +360,7 @@
</button>
<button
v-else
class="p-1.5 rounded-lg hover:bg-blue-500/10 text-zinc-600 hover:text-blue-400 transition-colors"
class="p-1.5 rounded-lg hover:bg-blue-500/10 text-zinc-600 hover:text-blue-700 transition-colors"
title="预下载此歌曲"
@click.stop="preloadSong(song.song)"
>
@@ -378,16 +378,16 @@
<!-- 进度条 -->
<section
v-if="downloading || downloadedCount > 0"
class="space-y-3 pt-4 border-t border-zinc-800/50"
class="space-y-3 pt-4 border-t border-zinc-200"
>
<div
class="flex items-center justify-between text-[10px] font-bold uppercase tracking-wider"
>
<span class="text-zinc-400">{{ mergeSongs ? '处理进度' : '下载进度' }}</span>
<span class="text-blue-400">{{ downloadedCount }} / {{ totalCount }}</span>
<span class="text-blue-700">{{ downloadedCount }} / {{ totalCount }}</span>
</div>
<div
class="h-2 bg-zinc-950 rounded-full overflow-hidden border border-zinc-800/50 relative"
class="h-2 bg-white rounded-full overflow-hidden border border-zinc-200 relative"
>
<div
class="h-full bg-gradient-to-r from-blue-600 to-indigo-500 transition-all duration-300 ease-out relative overflow-hidden"
@@ -402,7 +402,7 @@
</div>
<div class="text-[10px] text-zinc-500 truncate">
<template v-if="downloading">
<span v-if="processingStatus" class="text-blue-400 animate-pulse">{{
<span v-if="processingStatus" class="text-blue-700 animate-pulse">{{
processingStatus
}}</span>
<span v-else>{{
@@ -438,14 +438,14 @@
<!-- 底部按钮 -->
<div
class="p-4 border-t border-zinc-800 bg-zinc-900/50 flex items-center justify-between shrink-0"
class="p-4 border-t border-zinc-200 bg-zinc-50/50 flex items-center justify-between shrink-0"
>
<div class="text-[11px] font-black text-zinc-500 uppercase tracking-widest">
已选择 <span class="text-blue-400">{{ selectedSongs.size }}</span> 首歌曲
已选择 <span class="text-blue-700">{{ selectedSongs.size }}</span> 首歌曲
</div>
<div class="flex items-center gap-2">
<button
class="px-4 py-2 text-xs font-bold text-zinc-500 hover:text-zinc-300 transition-colors uppercase tracking-wider"
class="px-4 py-2 text-xs font-bold text-zinc-500 hover:text-zinc-600 transition-colors uppercase tracking-wider"
:disabled="downloading"
@click="closeDialog"
>
@@ -453,7 +453,7 @@
</button>
<button
v-if="!downloading && downloadedCount > 0"
class="px-6 py-2.5 bg-zinc-800 hover:bg-zinc-700 text-zinc-200 text-xs font-bold rounded-xl border border-zinc-700 transition-all uppercase tracking-wider"
class="px-6 py-2.5 bg-zinc-100 hover:bg-zinc-200 text-zinc-700 text-xs font-bold rounded-xl border border-zinc-200 transition-all uppercase tracking-wider"
@click="closeDialog"
>
关闭