fix: improve admin moderation errors

Show detailed Supabase error payloads in the admin console and use direct equality for single-image moderation updates to make approval failures easier to diagnose.
This commit is contained in:
2026-05-22 21:54:54 +08:00
parent 9150a17097
commit cc65395b59
+27 -7
View File
@@ -148,6 +148,23 @@ function formatCoordinate(value: number | null) {
return value === null ? '未记录' : value.toFixed(2) return value === null ? '未记录' : value.toFixed(2)
} }
function getErrorMessage(error: unknown, fallback: string) {
if (!error || typeof error !== 'object') return fallback
const payload = error as {
message?: unknown
code?: unknown
details?: unknown
hint?: unknown
}
const parts = [
typeof payload.message === 'string' ? payload.message : '',
typeof payload.code === 'string' ? `错误码:${payload.code}` : '',
typeof payload.details === 'string' ? payload.details : '',
typeof payload.hint === 'string' ? `提示:${payload.hint}` : '',
].filter(Boolean)
return parts.length ? parts.join('') : fallback
}
function todayIsoStart() { function todayIsoStart() {
const date = new Date() const date = new Date()
date.setHours(0, 0, 0, 0) date.setHours(0, 0, 0, 0)
@@ -287,12 +304,15 @@ async function updateCloudStatus(ids: string[], status: CloudStatus) {
loadError.value = '' loadError.value = ''
try { try {
const { data, error } = await supabase let query = supabase
.from('clouds') .from('clouds')
.update({ status }) .update({ status })
.in('id', ids)
.select('id') .select('id')
query = ids.length === 1 ? query.eq('id', ids[0]) : query.in('id', ids)
const { data, error } = await query
if (error) throw error if (error) throw error
if ((data || []).length !== ids.length) { if ((data || []).length !== ids.length) {
throw new Error('部分图片状态没有写入数据库,请检查管理员 UPDATE RLS policy。') throw new Error('部分图片状态没有写入数据库,请检查管理员 UPDATE RLS policy。')
@@ -303,7 +323,7 @@ async function updateCloudStatus(ids: string[], status: CloudStatus) {
await fetchStats() await fetchStats()
message.success(`${status === 'approved' ? '通过' : '拒绝'} ${ids.length} 张图片`) message.success(`${status === 'approved' ? '通过' : '拒绝'} ${ids.length} 张图片`)
} catch (error) { } catch (error) {
const text = error instanceof Error ? error.message : '审核操作失败' const text = getErrorMessage(error, '审核操作失败')
loadError.value = text loadError.value = text
message.error(text) message.error(text)
} finally { } finally {
@@ -332,7 +352,7 @@ async function toggleImageVisibility(cloud: AdminCloud) {
await fetchStats() await fetchStats()
message.success(nextHidden ? '图片已设为隐藏' : '图片已恢复公开') message.success(nextHidden ? '图片已设为隐藏' : '图片已恢复公开')
} catch (error) { } catch (error) {
const text = error instanceof Error ? error.message : '可见性更新失败' const text = getErrorMessage(error, '可见性更新失败')
loadError.value = text loadError.value = text
message.error(text) message.error(text)
} finally { } finally {
@@ -355,7 +375,7 @@ async function deleteImage(cloud: AdminCloud) {
await fetchStats() await fetchStats()
message.success('图片已删除') message.success('图片已删除')
} catch (error) { } catch (error) {
const text = error instanceof Error ? error.message : '图片删除失败' const text = getErrorMessage(error, '图片删除失败')
loadError.value = text loadError.value = text
message.error(text) message.error(text)
} finally { } finally {
@@ -387,7 +407,7 @@ async function updateUserRole(user: Profile, role: Profile['role']) {
users.value = users.value.map(item => (item.id === user.id ? { ...item, role } : item)) users.value = users.value.map(item => (item.id === user.id ? { ...item, role } : item))
message.success('用户角色已更新') message.success('用户角色已更新')
} catch (error) { } catch (error) {
const text = error instanceof Error ? error.message : '用户角色更新失败' const text = getErrorMessage(error, '用户角色更新失败')
loadError.value = text loadError.value = text
message.error(text) message.error(text)
} finally { } finally {
@@ -420,7 +440,7 @@ async function toggleUserDisabled(user: Profile) {
users.value = users.value.map(item => (item.id === user.id ? { ...item, is_disabled: nextDisabled } : item)) users.value = users.value.map(item => (item.id === user.id ? { ...item, is_disabled: nextDisabled } : item))
message.success(nextDisabled ? '用户已禁用' : '用户已恢复') message.success(nextDisabled ? '用户已禁用' : '用户已恢复')
} catch (error) { } catch (error) {
const text = error instanceof Error ? error.message : '用户状态更新失败' const text = getErrorMessage(error, '用户状态更新失败')
loadError.value = text loadError.value = text
message.error(text) message.error(text)
} finally { } finally {