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:
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user