feat(songs): 歌曲管理支持批量驳回、投稿留言自动审查与排期范围可见性过滤
构建并部署 BYW VoiceHub / Preflight 语法与构建检查 (push) Failing after 6m31s
构建并部署 BYW VoiceHub / 构建并推送容器镜像 (push) Skipped
构建并部署 BYW VoiceHub / 部署到生产服务器 (push) Failing after 4s

- 新增 /api/admin/songs/batch-reject.post 批量驳回接口(事务清排期/投票/扣接纳数/黑名单去重/异步通知)
- requireSongAdmin 三角色校验 + createApiError 统一错误包装
- scheduleDaysBefore/After 四字段排期可见范围限制(开放 API 与公开排期接口三处缓存路径 + DB 条件过滤)
- submissionNoteAutoModeration 基于黑名单 KEYWORD/LANGUAGE/GENRE 自动判定留言 publicStatus,命中自动关闭 submissionNotePublic
- 更新 songs/request.post 与 songs/[id]/update.put 接入自动审查逻辑
This commit is contained in:
2026-09-06 17:03:20 +08:00
parent 43e2a05666
commit bd8df1f026
53 changed files with 10486 additions and 245 deletions
+34 -2
View File
@@ -19,7 +19,9 @@ const siteConfig = ref({
siteVersion: '',
submissionGuidelines: '',
icpNumber: '',
gonganNumber: ''
gonganNumber: '',
defaultTheme: null,
enabledThemes: null
})
const isLoaded = ref(false)
@@ -57,7 +59,9 @@ export const useSiteConfig = () => {
gonganNumber: '',
enableReplayRequests: false,
enableCollaborativeSubmission: true,
enableSubmissionRemarks: false
enableSubmissionRemarks: false,
defaultTheme: 'System',
enabledThemes: '["System","ClassicDark","ClassicLight","ModernLight"]'
}
isLoaded.value = true
} finally {
@@ -96,6 +100,32 @@ export const useSiteConfig = () => {
const enableSubmissionRemarks = computed(() => siteConfig.value.enableSubmissionRemarks === true)
const smtpEnabled = computed(() => !!siteConfig.value.smtpEnabled)
function parseEnabledThemes(raw) {
if (Array.isArray(raw)) return raw.filter(Boolean)
if (typeof raw === 'string') {
const s = raw.trim()
if (!s) return []
if (s.startsWith('[') || s.startsWith('{')) {
try {
const parsed = JSON.parse(s)
if (Array.isArray(parsed)) return parsed.filter(Boolean)
if (parsed && Array.isArray(parsed.items)) return parsed.items.filter(Boolean)
} catch (_) {
// fallback to comma split
}
}
return s.split(',').map((x) => x.trim()).filter(Boolean)
}
return []
}
const defaultTheme = computed(() =>
typeof siteConfig.value.defaultTheme === 'string' && siteConfig.value.defaultTheme
? siteConfig.value.defaultTheme
: null
)
const enabledThemes = computed(() => parseEnabledThemes(siteConfig.value.enabledThemes))
// 初始化配置(仅在客户端执行)
const initSiteConfig = async () => {
if (typeof window !== 'undefined' && !isLoaded.value) {
@@ -126,6 +156,8 @@ export const useSiteConfig = () => {
enableCollaborativeSubmission,
enableSubmissionRemarks,
smtpEnabled,
defaultTheme,
enabledThemes,
fetchSiteConfig,
initSiteConfig,
refreshSiteConfig