From 357876a716d27ffca434befa358a784f771d2a16 Mon Sep 17 00:00:00 2001 From: HenryDu8133 <813367384@qq.com> Date: Sat, 19 Sep 2026 00:43:46 +0800 Subject: [PATCH] =?UTF-8?q?fix(ui+permission):=20=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E8=81=94=E5=90=88=E6=8A=95=E7=A8=BF=20/=20emoji=E6=8D=A2SVG=20?= =?UTF-8?q?/=20=E4=BF=AE=E5=A4=8D=E7=A7=BB=E5=8A=A8=E7=AB=AF=E6=B5=85?= =?UTF-8?q?=E8=89=B2=E9=80=82=E9=85=8D=20/=20=E5=B7=B2=E6=8E=92=E6=9C=9F?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E6=97=A5=E6=9C=9F=20/=20=E9=9A=90=E8=97=8F.e?= =?UTF-8?q?nv=E6=8F=90=E7=A4=BA=20/=20=E5=85=AC=E5=BC=80=E6=8E=92=E6=9C=9F?= =?UTF-8?q?=E6=A1=A3=E6=9C=9F=E6=B8=B8=E5=AE=A2=E8=AE=BF=E9=97=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 具体改动: 1. feat(投稿表单): 移除 RequestForm.vue 联合投稿功能整套模板+状态+payload+CSS(10处残留) 2. feat(图标): Icon.vue 新增 sparkles/star 图标; 首页档期卡片📅🎵✨和排期列表空状态🎵📅换成 lucide SVG Icon 3. fix(浅色适配): ScheduleList.vue 日期选择弹窗桌面端+移动端(content/header/h3/close-btn/item)全部改为 bg-primary + var text + indigo 主色, 修复竖屏选择日期标题白字看不见 4. feat(歌曲列表): SongList.vue scheduled-tag 内联追加 formatScheduleDate, 徽章+日期双胶囊显示 5. fix(登录): OAuthButtons.vue showPlaceholderHint 强制 false, 隐藏虚线框 .env 配置提示 6. fix(权限): server/middleware/auth.ts + auth-route-policy.ts 双白名单同步追加 /api/expected-play-dates GET 公共访问, 修复未登录 Authentication expired 401 --- app/components/Auth/OAuthButtons.vue | 2 +- app/components/Songs/RequestForm.vue | 155 -------------------------- app/components/Songs/ScheduleList.vue | 53 +++++---- app/components/Songs/SongList.vue | 53 ++++++--- app/components/UI/Icon.vue | 5 + app/pages/index.vue | 6 +- server/middleware/auth.ts | 1 + server/utils/auth-route-policy.ts | 1 + 8 files changed, 79 insertions(+), 197 deletions(-) diff --git a/app/components/Auth/OAuthButtons.vue b/app/components/Auth/OAuthButtons.vue index 8911837..3ede813 100644 --- a/app/components/Auth/OAuthButtons.vue +++ b/app/components/Auth/OAuthButtons.vue @@ -70,7 +70,7 @@ const hasEnabledProviders = computed(() => { return config.public.oauth && Object.values(config.public.oauth).some((enabled) => enabled) }) -const showPlaceholderHint = computed(() => props.alwaysShow && !hasEnabledProviders.value) +const showPlaceholderHint = computed(() => false) const loginWith = (provider: string) => { navigateTo(`/api/auth/${provider}`, { external: true }) diff --git a/app/components/Songs/RequestForm.vue b/app/components/Songs/RequestForm.vue index 3deab98..4d30940 100644 --- a/app/components/Songs/RequestForm.vue +++ b/app/components/Songs/RequestForm.vue @@ -128,31 +128,6 @@ 从往期导入 - - -
-
联合投稿
-
-
- {{ user.name }} - -
- -
-
@@ -652,16 +627,6 @@ @import-success="handleImportSuccess" /> - - - { } } -const handleUserSelect = (users) => { - if (Array.isArray(users)) { - // 过滤掉已存在的 - const newUsers = users.filter((u) => !collaborators.value.some((c) => c.id === u.id)) - collaborators.value.push(...newUsers) - } else if (users) { - if (!collaborators.value.some((c) => c.id === users.id)) { - collaborators.value.push(users) - } - } -} - -const removeCollaborator = (userId) => { - collaborators.value = collaborators.value.filter((c) => c.id !== userId) -} - // 获取播出时段 const fetchPlayTimes = async () => { loadingPlayTimes.value = true @@ -1456,13 +1401,6 @@ watch( } ) -watch(enableCollaborativeSubmission, (enabled) => { - if (!enabled) { - showUserSearchModal.value = false - collaborators.value = [] - } -}) - watch(enableSubmissionRemarks, (enabled) => { if (!enabled) { submissionNote.value = '' @@ -2288,7 +2226,6 @@ const submitSong = async (result, options = {}) => { playUrl: selectedUrl.value || null, submissionNote: submissionNote.value.trim() || null, submissionNotePublic: submissionNotePublic.value, - collaborators: collaborators.value.map((u) => u.id), bilibiliCid: bilibiliCid || null, bilibiliPage: bilibiliPage, expectedPlayDate: expectedPlayDate.value || null, @@ -2678,7 +2615,6 @@ const resetAfterSubmit = () => { manualArtist.value = '' manualCover.value = '' manualPlayUrl.value = '' - collaborators.value = [] submissionNote.value = '' submissionNotePublic.value = true // 重置URL验证状态 @@ -3268,83 +3204,6 @@ defineExpose({ box-shadow: 0 2px 6px rgba(79, 70, 229, 0.1); } -/* 联合投稿人区域 */ -.collaborators-section { - display: flex; - align-items: center; - gap: 1rem; - flex: 1; - min-width: 200px; -} - -.section-label { - font-family: 'MiSans', sans-serif; - font-weight: 700; - font-size: 16px; - color: var(--text-primary, #09090b); - white-space: nowrap; - flex-shrink: 0; -} - -.collaborators-list { - display: flex; - flex-wrap: wrap; - gap: 0.5rem; - align-items: center; -} - -.collaborator-tag { - display: flex; - align-items: center; - gap: 0.5rem; - background: rgba(79, 70, 229, 0.08); - border: 1px solid rgba(79, 70, 229, 0.2); - border-radius: 10px; - padding: 0.3rem 0.6rem; - font-size: 13px; - color: var(--primary, #4f46e5); - font-weight: 600; -} - -.remove-collaborator { - background: none; - border: none; - color: var(--primary, #4f46e5); - cursor: pointer; - display: flex; - align-items: center; - padding: 0; - opacity: 0.7; - transition: opacity 0.2s; -} - -.remove-collaborator:hover { - opacity: 1; - color: #4338ca; -} - -.add-collaborator-btn { - display: flex; - align-items: center; - gap: 0.3rem; - background: var(--bg-secondary, #f4f4f5); - border: 1px solid var(--border-secondary, #e4e4e7); - border-radius: 10px; - padding: 0.45rem 0.9rem; - font-size: 13px; - font-weight: 600; - color: var(--text-secondary, #52525b); - cursor: pointer; - transition: all 0.2s ease; -} - -.add-collaborator-btn:hover { - background: var(--primary, #4f46e5); - color: #ffffff; - border-color: var(--primary, #4f46e5); - box-shadow: 0 4px 10px rgba(79, 70, 229, 0.18); -} - /* 自定义复选框样式 */ .custom-checkbox-wrapper { display: flex; @@ -5122,20 +4981,6 @@ defineExpose({ min-width: unset; /* 移除桌面端的最小宽度限制 */ } - .collaborators-section { - flex-direction: row; - align-items: center; - gap: 1rem; - margin-bottom: 1rem; - flex: none; - width: 100%; - flex-wrap: wrap; - } - - .section-label { - font-size: 14px; - } - .search-label { font-size: 14px; } diff --git a/app/components/Songs/ScheduleList.vue b/app/components/Songs/ScheduleList.vue index 7966c04..39ef65a 100644 --- a/app/components/Songs/ScheduleList.vue +++ b/app/components/Songs/ScheduleList.vue @@ -104,13 +104,13 @@
-
🎵
+

暂无排期信息

点歌后等待管理员安排播出时间

-
📅
+

当前日期暂无排期

请选择其他日期查看

@@ -3168,33 +3168,35 @@ const vRipple = { /* 日期选择弹窗 */ .date-picker-content { - background: var(--surface-primary, var(--bg-primary, #1a1a1f)); + background: var(--bg-primary, #ffffff); border-radius: 20px 20px 0 0; width: 100%; max-width: 100%; max-height: 70vh; border: none; - box-shadow: 0 -10px 40px rgba(0, 0, 0, 0.5); + box-shadow: 0 -10px 40px rgba(0, 0, 0, 0.12); } .date-picker-header { padding: 20px; - border-bottom: 1px solid rgba(255, 255, 255, 0.06); + border-bottom: 1px solid var(--border-secondary, rgba(0, 0, 0, 0.06)); } .date-picker-header h3 { font-size: 17px; font-weight: 600; + color: var(--text-primary, #09090b); } .close-btn { width: 32px; height: 32px; border-radius: 10px; - background: rgba(255, 255, 255, 0.06); + background: var(--bg-tertiary, rgba(0, 0, 0, 0.06)); display: flex; align-items: center; justify-content: center; + color: var(--text-secondary, #52525b); } .date-picker-list { @@ -3205,20 +3207,23 @@ const vRipple = { padding: 14px 16px; border-radius: 12px; margin-bottom: 6px; - background: rgba(255, 255, 255, 0.03); + background: var(--bg-secondary, #f4f4f5); border: none; font-size: 14px; + color: var(--text-primary, #09090b); + font-weight: 600; } .date-picker-item:hover { - background: rgba(255, 255, 255, 0.06); + background: rgba(79, 70, 229, 0.08); transform: none; + color: var(--primary, #4f46e5); } .date-picker-item.active { - background: rgba(11, 90, 254, 0.15); + background: rgba(79, 70, 229, 0.14); border-left: none; - color: #0b5afe; + color: var(--primary, #4f46e5); } } @@ -3453,10 +3458,10 @@ const vRipple = { width: 85%; max-width: 350px; max-height: 70vh; - background: var(--bg-secondary, #1a1d24); - border-radius: 12px; - box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3); - border: 1px solid rgba(255, 255, 255, 0.1); + background: var(--bg-primary, #ffffff); + border-radius: 18px; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.12); + border: 1px solid var(--border-secondary, #e4e4e7); overflow: hidden; animation: scale-in 0.2s ease; display: flex; @@ -3468,19 +3473,19 @@ const vRipple = { justify-content: space-between; align-items: center; padding: 1rem; - border-bottom: 1px solid rgba(255, 255, 255, 0.1); + border-bottom: 1px solid var(--border-secondary, rgba(0, 0, 0, 0.08)); } .date-picker-header h3 { margin: 0; font-size: 16px; - color: white; + color: var(--text-primary, #09090b); } .close-btn { background: none; border: none; - color: rgba(255, 255, 255, 0.6); + color: var(--text-secondary, #52525b); font-size: 22px; cursor: pointer; padding: 0 5px; @@ -3495,24 +3500,28 @@ const vRipple = { .date-picker-item { padding: 0.75rem 1rem; - border-radius: 8px; + border-radius: 10px; margin-bottom: 0.5rem; cursor: pointer; transition: all 0.2s ease; - background: rgba(255, 255, 255, 0.05); + background: var(--bg-secondary, #f4f4f5); position: relative; overflow: hidden; white-space: pre-line; + color: var(--text-primary, #09090b); + font-weight: 600; } .date-picker-item:hover { - background: rgba(11, 90, 254, 0.1); + background: rgba(79, 70, 229, 0.1); transform: translateY(-2px); + color: var(--primary, #4f46e5); } .date-picker-item.active { - background: rgba(11, 90, 254, 0.2); - border-left: 3px solid #0b5afe; + background: rgba(79, 70, 229, 0.14); + border-left: 3px solid var(--primary, #4f46e5); + color: var(--primary, #4f46e5); } /* 过渡动画 */ diff --git a/app/components/Songs/SongList.vue b/app/components/Songs/SongList.vue index 8c6b2e2..8973f13 100644 --- a/app/components/Songs/SongList.vue +++ b/app/components/Songs/SongList.vue @@ -234,14 +234,16 @@ - 已排期 + 已排期 + + {{ formatScheduleDate(song.scheduleDate) }} + 重播