diff --git a/dashboard/src/components/expression-reviewer.tsx b/dashboard/src/components/expression-reviewer.tsx index 512146ef..40b1d5fd 100644 --- a/dashboard/src/components/expression-reviewer.tsx +++ b/dashboard/src/components/expression-reviewer.tsx @@ -105,27 +105,43 @@ export function ExpressionReviewer({ open, onOpenChange }: ExpressionReviewerPro const loadStats = useCallback(async () => { try { setStatsLoading(true) - const data = await getReviewStats() - setStats(data) + const result = await getReviewStats() + if (result.success) { + setStats(result.data) + } else { + toast({ + title: '错误', + description: result.error, + variant: 'destructive', + }) + } } catch (error) { console.error('加载统计失败:', error) } finally { setStatsLoading(false) } - }, []) + }, [toast]) // 加载列表 const loadList = useCallback(async () => { try { setLoading(true) - const response = await getReviewList({ + const result = await getReviewList({ page, page_size: pageSize, filter_type: filterType, search: search || undefined, }) - setExpressions(response.data) - setTotal(response.total) + if (result.success) { + setExpressions(result.data.data) + setTotal(result.data.total) + } else { + toast({ + title: '加载失败', + description: result.error, + variant: 'destructive', + }) + } } catch (error) { toast({ title: '加载失败', @@ -137,19 +153,19 @@ export function ExpressionReviewer({ open, onOpenChange }: ExpressionReviewerPro } }, [page, pageSize, filterType, search, toast]) - // 加载聊天名称映射 + // 加载聚天名称映射 const loadChatNames = useCallback(async () => { try { - const response = await getChatList() - if (response?.data) { + const result = await getChatList() + if (result.success) { const nameMap = new Map() - response.data.forEach((chat: ChatInfo) => { + result.data.forEach((chat: ChatInfo) => { nameMap.set(chat.chat_id, chat.chat_name) }) setChatNameMap(nameMap) } } catch (error) { - console.error('加载聊天名称失败:', error) + console.error('加载聚天名称失败:', error) } }, []) @@ -158,24 +174,32 @@ export function ExpressionReviewer({ open, onOpenChange }: ExpressionReviewerPro try { setQuickLoading(true) const pageToLoad = append ? quickPage + 1 : quickPage - const response = await getReviewList({ + const result = await getReviewList({ page: pageToLoad, page_size: 20, filter_type: quickFilterType, }) - if (append) { - // 追加模式:拼接数据 - setQuickExpressions(prev => [...prev, ...response.data]) - setQuickPage(pageToLoad) + if (result.success) { + if (append) { + // 追加模式:拼接数据 + setQuickExpressions(prev => [...prev, ...result.data.data]) + setQuickPage(pageToLoad) + } else { + // 替换模式 + setQuickExpressions(result.data.data) + } + + setQuickTotal(result.data.total) + if (resetIndex) { + setQuickCurrentIndex(0) + } } else { - // 替换模式 - setQuickExpressions(response.data) - } - - setQuickTotal(response.total) - if (resetIndex) { - setQuickCurrentIndex(0) + toast({ + title: '加载失败', + description: result.error, + variant: 'destructive', + }) } } catch (error) { toast({ @@ -247,13 +271,22 @@ export function ExpressionReviewer({ open, onOpenChange }: ExpressionReviewerPro setSwipeOffset(rejected ? -400 : 400) try { - const response = await batchReviewExpressions([{ + const result = await batchReviewExpressions([{ id: currentExpr.id, rejected, require_unchecked: quickFilterType === 'unchecked', }]) - if (response.results[0]?.success) { + if (!result.success) { + toast({ + title: '操作失败', + description: result.error, + variant: 'destructive', + }) + return + } + + if (result.data.results[0]?.success) { toast({ title: rejected ? '已拒绝' : '已通过', description: `表达方式 #${currentExpr.id} ${rejected ? '已拒绝' : '已通过'}`, @@ -514,11 +547,20 @@ export function ExpressionReviewer({ open, onOpenChange }: ExpressionReviewerPro try { setProcessingIds((prev) => new Set(prev).add(id)) - const response = await batchReviewExpressions([ + const result = await batchReviewExpressions([ { id, rejected, require_unchecked: filterType === 'unchecked' } ]) - if (response.results[0]?.success) { + if (!result.success) { + toast({ + title: '操作失败', + description: result.error, + variant: 'destructive', + }) + return + } + + if (result.data.results[0]?.success) { toast({ title: rejected ? '已拒绝' : '已通过', description: `表达方式 #${id} ${rejected ? '已拒绝' : '已通过'}`, @@ -529,7 +571,7 @@ export function ExpressionReviewer({ open, onOpenChange }: ExpressionReviewerPro } else { toast({ title: '操作失败', - description: response.results[0]?.message || '未知错误', + description: result.data.results[0]?.message || '未知错误', variant: 'destructive', }) } @@ -568,12 +610,21 @@ export function ExpressionReviewer({ open, onOpenChange }: ExpressionReviewerPro require_unchecked: filterType === 'unchecked', })) - const response = await batchReviewExpressions(items) + const result = await batchReviewExpressions(items) + if (!result.success) { + toast({ + title: '批量审核失败', + description: result.error, + variant: 'destructive', + }) + return + } + toast({ title: '批量审核完成', - description: `成功 ${response.succeeded} 条,失败 ${response.failed} 条`, - variant: response.failed > 0 ? 'destructive' : 'default', + description: `成功 ${result.data.succeeded} 条,失败 ${result.data.failed} 条`, + variant: result.data.failed > 0 ? 'destructive' : 'default', }) // 清空选择并刷新 diff --git a/dashboard/src/lib/expression-api.ts b/dashboard/src/lib/expression-api.ts index 01c25d9b..8937f598 100644 --- a/dashboard/src/lib/expression-api.ts +++ b/dashboard/src/lib/expression-api.ts @@ -12,28 +12,58 @@ import type { ExpressionDeleteResponse, ExpressionStatsResponse, ChatListResponse, + ChatInfo, ReviewStats, ReviewListResponse, BatchReviewItem, BatchReviewResponse, } from '@/types/expression' +import type { ApiResponse } from '@/types/api' const API_BASE = '/api/webui/expression' /** * 获取聊天列表 */ -export async function getChatList(): Promise { +export async function getChatList(): Promise> { const response = await fetchWithAuth(`${API_BASE}/chats`, { }) - + if (!response.ok) { - const error = await response.json() - throw new Error(error.detail || '获取聊天列表失败') + try { + const errorData = await response.json() + return { + success: false, + error: errorData.detail || errorData.message || '获取聊天列表失败', + } + } catch { + return { + success: false, + error: response.statusText || '获取聊天列表失败', + } + } + } + + try { + const data: ChatListResponse = await response.json() + if (data.success) { + return { + success: true, + data: data.data, + } + } else { + return { + success: false, + error: '获取聊天列表失败', + } + } + } catch { + return { + success: false, + error: '无法解析聊天列表响应', + } } - - return response.json() } /** @@ -44,40 +74,96 @@ export async function getExpressionList(params: { page_size?: number search?: string chat_id?: string -}): Promise { +}): Promise> { const queryParams = new URLSearchParams() - + if (params.page) queryParams.append('page', params.page.toString()) if (params.page_size) queryParams.append('page_size', params.page_size.toString()) if (params.search) queryParams.append('search', params.search) if (params.chat_id) queryParams.append('chat_id', params.chat_id) - + const response = await fetchWithAuth(`${API_BASE}/list?${queryParams}`, { }) - + if (!response.ok) { - const error = await response.json() - throw new Error(error.detail || '获取表达方式列表失败') + try { + const errorData = await response.json() + return { + success: false, + error: errorData.detail || errorData.message || '获取表达方式列表失败', + } + } catch { + return { + success: false, + error: response.statusText || '获取表达方式列表失败', + } + } + } + + try { + const data: ExpressionListResponse = await response.json() + if (data.success) { + return { + success: true, + data: data, + } + } else { + return { + success: false, + error: '获取表达方式列表失败', + } + } + } catch { + return { + success: false, + error: '无法解析表达方式列表响应', + } } - - return response.json() } /** * 获取表达方式详细信息 */ -export async function getExpressionDetail(expressionId: number): Promise { +export async function getExpressionDetail(expressionId: number): Promise> { const response = await fetchWithAuth(`${API_BASE}/${expressionId}`, { }) - + if (!response.ok) { - const error = await response.json() - throw new Error(error.detail || '获取表达方式详情失败') + try { + const errorData = await response.json() + return { + success: false, + error: errorData.detail || errorData.message || '获取表达方式详情失败', + } + } catch { + return { + success: false, + error: response.statusText || '获取表达方式详情失败', + } + } + } + + try { + const data: ExpressionDetailResponse = await response.json() + if (data.success) { + return { + success: true, + data: data.data, + } + } else { + return { + success: false, + error: '获取表达方式详情失败', + } + } + } catch { + return { + success: false, + error: '无法解析表达方式详情响应', + } } - - return response.json() } /** @@ -85,19 +171,47 @@ export async function getExpressionDetail(expressionId: number): Promise { +): Promise> { const response = await fetchWithAuth(`${API_BASE}/`, { method: 'POST', body: JSON.stringify(data), }) - + if (!response.ok) { - const error = await response.json() - throw new Error(error.detail || '创建表达方式失败') + try { + const errorData = await response.json() + return { + success: false, + error: errorData.detail || errorData.message || '创建表达方式失败', + } + } catch { + return { + success: false, + error: response.statusText || '创建表达方式失败', + } + } + } + + try { + const responseData: ExpressionCreateResponse = await response.json() + if (responseData.success) { + return { + success: true, + data: responseData.data, + } + } else { + return { + success: false, + error: responseData.message || '创建表达方式失败', + } + } + } catch { + return { + success: false, + error: '无法解析创建表达方式响应', + } } - - return response.json() } /** @@ -106,70 +220,182 @@ export async function createExpression( export async function updateExpression( expressionId: number, data: ExpressionUpdateRequest -): Promise { +): Promise> { const response = await fetchWithAuth(`${API_BASE}/${expressionId}`, { method: 'PATCH', body: JSON.stringify(data), }) - + if (!response.ok) { - const error = await response.json() - throw new Error(error.detail || '更新表达方式失败') + try { + const errorData = await response.json() + return { + success: false, + error: errorData.detail || errorData.message || '更新表达方式失败', + } + } catch { + return { + success: false, + error: response.statusText || '更新表达方式失败', + } + } + } + + try { + const responseData: ExpressionUpdateResponse = await response.json() + if (responseData.success) { + return { + success: true, + data: responseData.data || {}, + } + } else { + return { + success: false, + error: responseData.message || '更新表达方式失败', + } + } + } catch { + return { + success: false, + error: '无法解析更新表达方式响应', + } } - - return response.json() } /** * 删除表达方式 */ -export async function deleteExpression(expressionId: number): Promise { +export async function deleteExpression(expressionId: number): Promise> { const response = await fetchWithAuth(`${API_BASE}/${expressionId}`, { method: 'DELETE', }) - + if (!response.ok) { - const error = await response.json() - throw new Error(error.detail || '删除表达方式失败') + try { + const errorData = await response.json() + return { + success: false, + error: errorData.detail || errorData.message || '删除表达方式失败', + } + } catch { + return { + success: false, + error: response.statusText || '删除表达方式失败', + } + } + } + + try { + const data: ExpressionDeleteResponse = await response.json() + if (data.success) { + return { + success: true, + data: {}, + } + } else { + return { + success: false, + error: data.message || '删除表达方式失败', + } + } + } catch { + return { + success: false, + error: '无法解析删除表达方式响应', + } } - - return response.json() } /** * 批量删除表达方式 */ -export async function batchDeleteExpressions(expressionIds: number[]): Promise { +export async function batchDeleteExpressions(expressionIds: number[]): Promise> { const response = await fetchWithAuth(`${API_BASE}/batch/delete`, { method: 'POST', body: JSON.stringify({ ids: expressionIds }), }) - + if (!response.ok) { - const error = await response.json() - throw new Error(error.detail || '批量删除表达方式失败') + try { + const errorData = await response.json() + return { + success: false, + error: errorData.detail || errorData.message || '批量删除表达方式失败', + } + } catch { + return { + success: false, + error: response.statusText || '批量删除表达方式失败', + } + } + } + + try { + const data: ExpressionDeleteResponse = await response.json() + if (data.success) { + return { + success: true, + data: {}, + } + } else { + return { + success: false, + error: data.message || '批量删除表达方式失败', + } + } + } catch { + return { + success: false, + error: '无法解析批量删除表达方式响应', + } } - - return response.json() } /** * 获取表达方式统计数据 */ -export async function getExpressionStats(): Promise { +export async function getExpressionStats(): Promise> { const response = await fetchWithAuth(`${API_BASE}/stats/summary`, { }) - + if (!response.ok) { - const error = await response.json() - throw new Error(error.detail || '获取统计数据失败') + try { + const errorData = await response.json() + return { + success: false, + error: errorData.detail || errorData.message || '获取统计数据失败', + } + } catch { + return { + success: false, + error: response.statusText || '获取统计数据失败', + } + } + } + + try { + const data: ExpressionStatsResponse = await response.json() + if (data.success) { + return { + success: true, + data: data.data, + } + } else { + return { + success: false, + error: '获取统计数据失败', + } + } + } catch { + return { + success: false, + error: '无法解析统计数据响应', + } } - - return response.json() } // ============ 审核相关 API ============ @@ -177,15 +403,36 @@ export async function getExpressionStats(): Promise { /** * 获取审核统计数据 */ -export async function getReviewStats(): Promise { +export async function getReviewStats(): Promise> { const response = await fetchWithAuth(`${API_BASE}/review/stats`) - + if (!response.ok) { - const error = await response.json() - throw new Error(error.detail || '获取审核统计失败') + try { + const errorData = await response.json() + return { + success: false, + error: errorData.detail || errorData.message || '获取审核统计失败', + } + } catch { + return { + success: false, + error: response.statusText || '获取审核统计失败', + } + } + } + + try { + const data = await response.json() as ReviewStats + return { + success: true, + data: data, + } + } catch { + return { + success: false, + error: '无法解析审核统计响应', + } } - - return response.json() } /** @@ -197,23 +444,51 @@ export async function getReviewList(params: { filter_type?: 'unchecked' | 'passed' | 'rejected' | 'all' search?: string chat_id?: string -}): Promise { +}): Promise> { const queryParams = new URLSearchParams() - + if (params.page) queryParams.append('page', params.page.toString()) if (params.page_size) queryParams.append('page_size', params.page_size.toString()) if (params.filter_type) queryParams.append('filter_type', params.filter_type) if (params.search) queryParams.append('search', params.search) if (params.chat_id) queryParams.append('chat_id', params.chat_id) - + const response = await fetchWithAuth(`${API_BASE}/review/list?${queryParams}`) - + if (!response.ok) { - const error = await response.json() - throw new Error(error.detail || '获取审核列表失败') + try { + const errorData = await response.json() + return { + success: false, + error: errorData.detail || errorData.message || '获取审核列表失败', + } + } catch { + return { + success: false, + error: response.statusText || '获取审核列表失败', + } + } + } + + try { + const data: ReviewListResponse = await response.json() + if (data.success) { + return { + success: true, + data: data, + } + } else { + return { + success: false, + error: '获取审核列表失败', + } + } + } catch { + return { + success: false, + error: '无法解析审核列表响应', + } } - - return response.json() } /** @@ -221,16 +496,44 @@ export async function getReviewList(params: { */ export async function batchReviewExpressions( items: BatchReviewItem[] -): Promise { +): Promise> { const response = await fetchWithAuth(`${API_BASE}/review/batch`, { method: 'POST', body: JSON.stringify({ items }), }) - + if (!response.ok) { - const error = await response.json() - throw new Error(error.detail || '批量审核失败') + try { + const errorData = await response.json() + return { + success: false, + error: errorData.detail || errorData.message || '批量审核失败', + } + } catch { + return { + success: false, + error: response.statusText || '批量审核失败', + } + } + } + + try { + const data: BatchReviewResponse = await response.json() + if (data.success) { + return { + success: true, + data: data, + } + } else { + return { + success: false, + error: '批量审核失败', + } + } + } catch { + return { + success: false, + error: '无法解析批量审核响应', + } } - - return response.json() } diff --git a/dashboard/src/lib/person-api.ts b/dashboard/src/lib/person-api.ts index 1415aa97..2a272ff8 100644 --- a/dashboard/src/lib/person-api.ts +++ b/dashboard/src/lib/person-api.ts @@ -2,6 +2,7 @@ * 人物信息管理 API */ import { fetchWithAuth, getAuthHeaders } from '@/lib/fetch-with-auth' +import type { ApiResponse } from '@/types/api' import type { PersonListResponse, PersonDetailResponse, @@ -9,10 +10,22 @@ import type { PersonUpdateResponse, PersonDeleteResponse, PersonStatsResponse, + PersonInfo, + PersonStats, } from '@/types/person' const API_BASE = '/api/webui/person' +/** + * Person list response with pagination info + */ +export interface PersonListData { + data: PersonInfo[] + total: number + page: number + page_size: number +} + /** * 获取人物信息列表 */ @@ -22,7 +35,7 @@ export async function getPersonList(params: { search?: string is_known?: boolean platform?: string -}): Promise { +}): Promise> { const queryParams = new URLSearchParams() if (params.page) queryParams.append('page', params.page.toString()) @@ -36,27 +49,88 @@ export async function getPersonList(params: { }) if (!response.ok) { - const error = await response.json() - throw new Error(error.detail || '获取人物列表失败') + try { + const errorData = await response.json() + return { + success: false, + error: errorData.detail || errorData.message || '获取人物列表失败', + } + } catch { + return { + success: false, + error: response.statusText || '获取人物列表失败', + } + } } - return response.json() + try { + const data: PersonListResponse = await response.json() + if (data.success) { + return { + success: true, + data: { + data: data.data, + total: data.total, + page: data.page, + page_size: data.page_size, + }, + } + } else { + return { + success: false, + error: '获取人物列表失败', + } + } + } catch { + return { + success: false, + error: 'Failed to parse response', + } + } } /** * 获取人物详细信息 */ -export async function getPersonDetail(personId: string): Promise { +export async function getPersonDetail(personId: string): Promise> { const response = await fetchWithAuth(`${API_BASE}/${personId}`, { headers: getAuthHeaders(), }) if (!response.ok) { - const error = await response.json() - throw new Error(error.detail || '获取人物详情失败') + try { + const errorData = await response.json() + return { + success: false, + error: errorData.detail || errorData.message || '获取人物详情失败', + } + } catch { + return { + success: false, + error: response.statusText || '获取人物详情失败', + } + } } - return response.json() + try { + const data: PersonDetailResponse = await response.json() + if (data.success) { + return { + success: true, + data: data.data, + } + } else { + return { + success: false, + error: '获取人物详情失败', + } + } + } catch { + return { + success: false, + error: 'Failed to parse response', + } + } } /** @@ -65,7 +139,7 @@ export async function getPersonDetail(personId: string): Promise { +): Promise> { const response = await fetchWithAuth(`${API_BASE}/${personId}`, { method: 'PATCH', headers: getAuthHeaders(), @@ -73,56 +147,141 @@ export async function updatePerson( }) if (!response.ok) { - const error = await response.json() - throw new Error(error.detail || '更新人物信息失败') + try { + const errorData = await response.json() + return { + success: false, + error: errorData.detail || errorData.message || '更新人物信息失败', + } + } catch { + return { + success: false, + error: response.statusText || '更新人物信息失败', + } + } } - return response.json() + try { + const data: PersonUpdateResponse = await response.json() + if (data.success && data.data) { + return { + success: true, + data: data.data, + } + } else { + return { + success: false, + error: data.message || '更新人物信息失败', + } + } + } catch { + return { + success: false, + error: 'Failed to parse response', + } + } } /** * 删除人物信息 */ -export async function deletePerson(personId: string): Promise { +export async function deletePerson(personId: string): Promise> { const response = await fetchWithAuth(`${API_BASE}/${personId}`, { method: 'DELETE', headers: getAuthHeaders(), }) if (!response.ok) { - const error = await response.json() - throw new Error(error.detail || '删除人物信息失败') + try { + const errorData = await response.json() + return { + success: false, + error: errorData.detail || errorData.message || '删除人物信息失败', + } + } catch { + return { + success: false, + error: response.statusText || '删除人物信息失败', + } + } } - return response.json() + try { + const data: PersonDeleteResponse = await response.json() + if (data.success) { + return { + success: true, + data: undefined as unknown as void, + } + } else { + return { + success: false, + error: data.message || '删除人物信息失败', + } + } + } catch { + return { + success: false, + error: 'Failed to parse response', + } + } } /** * 获取人物统计数据 */ -export async function getPersonStats(): Promise { +export async function getPersonStats(): Promise> { const response = await fetchWithAuth(`${API_BASE}/stats/summary`, { headers: getAuthHeaders(), }) if (!response.ok) { - const error = await response.json() - throw new Error(error.detail || '获取统计数据失败') + try { + const errorData = await response.json() + return { + success: false, + error: errorData.detail || errorData.message || '获取统计数据失败', + } + } catch { + return { + success: false, + error: response.statusText || '获取统计数据失败', + } + } } - return response.json() + try { + const data: PersonStatsResponse = await response.json() + if (data.success) { + return { + success: true, + data: data.data, + } + } else { + return { + success: false, + error: '获取统计数据失败', + } + } + } catch { + return { + success: false, + error: 'Failed to parse response', + } + } } /** * 批量删除人物信息 */ -export async function batchDeletePersons(personIds: string[]): Promise<{ - success: boolean +export async function batchDeletePersons( + personIds: string[] +): Promise { +}>> { const response = await fetchWithAuth(`${API_BASE}/batch/delete`, { method: 'POST', headers: getAuthHeaders(), @@ -130,9 +289,42 @@ export async function batchDeletePersons(personIds: string[]): Promise<{ }) if (!response.ok) { - const error = await response.json() - throw new Error(error.detail || '批量删除失败') + try { + const errorData = await response.json() + return { + success: false, + error: errorData.detail || errorData.message || '批量删除失败', + } + } catch { + return { + success: false, + error: response.statusText || '批量删除失败', + } + } } - return response.json() + try { + const data = await response.json() + if (data.success) { + return { + success: true, + data: { + message: data.message, + deleted_count: data.deleted_count, + failed_count: data.failed_count, + failed_ids: data.failed_ids, + }, + } + } else { + return { + success: false, + error: data.message || '批量删除失败', + } + } + } catch { + return { + success: false, + error: 'Failed to parse response', + } + } } diff --git a/dashboard/src/routes/index.tsx b/dashboard/src/routes/index.tsx index 39eaa27b..59733566 100644 --- a/dashboard/src/routes/index.tsx +++ b/dashboard/src/routes/index.tsx @@ -161,9 +161,9 @@ function IndexPageContent() { // 获取审核统计 const fetchReviewStats = useCallback(async () => { try { - const data = await getReviewStats() - if (isMountedRef.current) { - setUncheckedCount(data.unchecked) + const result = await getReviewStats() + if (result.success && isMountedRef.current) { + setUncheckedCount(result.data.unchecked) } } catch (error) { console.error('获取审核统计失败:', error) diff --git a/dashboard/src/routes/monitor/use-monitor.ts b/dashboard/src/routes/monitor/use-monitor.ts index ed588b06..b3679122 100644 --- a/dashboard/src/routes/monitor/use-monitor.ts +++ b/dashboard/src/routes/monitor/use-monitor.ts @@ -16,16 +16,16 @@ export function useChatNameMap() { const loadChatNameMap = useCallback(async () => { try { setLoading(true) - const response = await getChatList() - if (response?.data) { + const result = await getChatList() + if (result.success) { const nameMap = new Map() - response.data.forEach((chat: ChatInfo) => { + result.data.forEach((chat: ChatInfo) => { nameMap.set(chat.chat_id, chat.chat_name) }) setChatNameMap(nameMap) } } catch (error) { - console.error('加载聊天列表失败:', error) + console.error('加载聚天列表失败:', error) } finally { setLoading(false) } diff --git a/dashboard/src/routes/person.tsx b/dashboard/src/routes/person.tsx index 18f1d94d..9f6e17f9 100644 --- a/dashboard/src/routes/person.tsx +++ b/dashboard/src/routes/person.tsx @@ -68,15 +68,18 @@ export function PersonManagementPage() { const loadPersons = async () => { try { setLoading(true) - const response = await getPersonList({ + const result = await getPersonList({ page, page_size: pageSize, search: search || undefined, is_known: filterKnown, platform: filterPlatform, }) - setPersons(response.data) - setTotal(response.total) + if (!result.success) { + throw new Error(result.error) + } + setPersons(result.data.data) + setTotal(result.data.total) } catch (error) { toast({ title: '加载失败', @@ -91,9 +94,9 @@ export function PersonManagementPage() { // 加载统计数据 const loadStats = async () => { try { - const response = await getPersonStats() - if (response?.data) { - setStats(response.data) + const result = await getPersonStats() + if (result.success) { + setStats(result.data) } } catch (error) { console.error('加载统计数据失败:', error) @@ -110,8 +113,11 @@ export function PersonManagementPage() { // 查看详情 const handleViewDetail = async (person: PersonInfo) => { try { - const response = await getPersonDetail(person.person_id) - setSelectedPerson(response.data) + const result = await getPersonDetail(person.person_id) + if (!result.success) { + throw new Error(result.error) + } + setSelectedPerson(result.data) setIsDetailDialogOpen(true) } catch (error) { toast({ @@ -131,7 +137,10 @@ export function PersonManagementPage() { // 删除人物 const handleDelete = async (person: PersonInfo) => { try { - await deletePerson(person.person_id) + const result = await deletePerson(person.person_id) + if (!result.success) { + throw new Error(result.error) + } toast({ title: '删除成功', description: `已删除人物信息: ${person.person_name || person.nickname || person.user_id}`, @@ -190,9 +199,12 @@ export function PersonManagementPage() { const handleBatchDelete = async () => { try { const result = await batchDeletePersons(Array.from(selectedPersons)) + if (!result.success) { + throw new Error(result.error) + } toast({ title: '批量删除完成', - description: result.message, + description: result.data.message, }) setSelectedPersons(new Set()) setBatchDeleteDialogOpen(false) @@ -858,7 +870,10 @@ function PersonEditDialog({ try { setSaving(true) - await updatePerson(person.person_id, formData) + const result = await updatePerson(person.person_id, formData) + if (!result.success) { + throw new Error(result.error) + } toast({ title: '保存成功', description: '人物信息已更新', diff --git a/dashboard/src/routes/resource/expression.tsx b/dashboard/src/routes/resource/expression.tsx index d211e732..dbb0795c 100644 --- a/dashboard/src/routes/resource/expression.tsx +++ b/dashboard/src/routes/resource/expression.tsx @@ -72,13 +72,21 @@ export function ExpressionManagementPage() { const loadExpressions = async () => { try { setLoading(true) - const response = await getExpressionList({ + const result = await getExpressionList({ page, page_size: pageSize, search: search || undefined, }) - setExpressions(response.data) - setTotal(response.total) + if (result.success) { + setExpressions(result.data.data) + setTotal(result.data.total) + } else { + toast({ + title: '加载失败', + description: result.error, + variant: 'destructive', + }) + } } catch (error) { toast({ title: '加载失败', @@ -93,9 +101,11 @@ export function ExpressionManagementPage() { // 加载统计数据 const loadStats = async () => { try { - const response = await getExpressionStats() - if (response?.data) { - setStats(response.data) + const result = await getExpressionStats() + if (result.success) { + setStats(result.data) + } else { + console.error('加载统计数据失败:', result.error) } } catch (error) { console.error('加载统计数据失败:', error) @@ -105,28 +115,30 @@ export function ExpressionManagementPage() { // 加载审核统计 const loadReviewStats = async () => { try { - const data = await getReviewStats() - setUncheckedCount(data.unchecked) + const result = await getReviewStats() + if (result.success) { + setUncheckedCount(result.data.unchecked) + } } catch (error) { console.error('加载审核统计失败:', error) } } - // 加载聊天列表 + // 加载聚天列表 const loadChatList = async () => { try { - const response = await getChatList() - if (response?.data) { - setChatList(response.data) - // 构建聊天ID到名称的映射 + const result = await getChatList() + if (result.success) { + setChatList(result.data) + // 构建聚天ID到名称的映射 const nameMap = new Map() - response.data.forEach((chat) => { + result.data.forEach((chat: ChatInfo) => { nameMap.set(chat.chat_id, chat.chat_name) }) setChatNameMap(nameMap) } } catch (error) { - console.error('加载聊天列表失败:', error) + console.error('加载聚天列表失败:', error) } } @@ -147,9 +159,17 @@ export function ExpressionManagementPage() { // 查看详情 const handleViewDetail = async (expression: Expression) => { try { - const response = await getExpressionDetail(expression.id) - setSelectedExpression(response.data) - setIsDetailDialogOpen(true) + const result = await getExpressionDetail(expression.id) + if (result.success) { + setSelectedExpression(result.data) + setIsDetailDialogOpen(true) + } else { + toast({ + title: '加载详情失败', + description: result.error, + variant: 'destructive', + }) + } } catch (error) { toast({ title: '加载详情失败', @@ -168,14 +188,22 @@ export function ExpressionManagementPage() { // 删除表达方式 const handleDelete = async (expression: Expression) => { try { - await deleteExpression(expression.id) - toast({ - title: '删除成功', - description: `已删除表达方式: ${expression.situation}`, - }) - setDeleteConfirmExpression(null) - loadExpressions() - loadStats() + const result = await deleteExpression(expression.id) + if (result.success) { + toast({ + title: '删除成功', + description: `已删除表达方式: ${expression.situation}`, + }) + setDeleteConfirmExpression(null) + loadExpressions() + loadStats() + } else { + toast({ + title: '删除失败', + description: result.error, + variant: 'destructive', + }) + } } catch (error) { toast({ title: '删除失败', @@ -208,15 +236,23 @@ export function ExpressionManagementPage() { // 批量删除 const handleBatchDelete = async () => { try { - await batchDeleteExpressions(Array.from(selectedIds)) - toast({ - title: '批量删除成功', - description: `已删除 ${selectedIds.size} 个表达方式`, - }) - setSelectedIds(new Set()) - setIsBatchDeleteDialogOpen(false) - loadExpressions() - loadStats() + const result = await batchDeleteExpressions(Array.from(selectedIds)) + if (result.success) { + toast({ + title: '批量删除成功', + description: `已删除 ${selectedIds.size} 个表达方式`, + }) + setSelectedIds(new Set()) + setIsBatchDeleteDialogOpen(false) + loadExpressions() + loadStats() + } else { + toast({ + title: '批量删除失败', + description: result.error, + variant: 'destructive', + }) + } } catch (error) { toast({ title: '批量删除失败', @@ -848,7 +884,7 @@ function ExpressionCreateDialog({ if (!formData.situation || !formData.style || !formData.chat_id) { toast({ title: '验证失败', - description: '请填写必填字段:情境、风格和聊天', + description: '请填写必填字段:情境、风格和聚天', variant: 'destructive', }) return @@ -856,18 +892,26 @@ function ExpressionCreateDialog({ try { setSaving(true) - await createExpression(formData) - toast({ - title: '创建成功', - description: '表达方式已创建', - }) - // 重置表单 - setFormData({ - situation: '', - style: '', - chat_id: '', - }) - onSuccess() + const result = await createExpression(formData) + if (result.success) { + toast({ + title: '创建成功', + description: '表达方式已创建', + }) + // 重置表单 + setFormData({ + situation: '', + style: '', + chat_id: '', + }) + onSuccess() + } else { + toast({ + title: '创建失败', + description: result.error, + variant: 'destructive', + }) + } } catch (error) { toast({ title: '创建失败', @@ -988,12 +1032,20 @@ function ExpressionEditDialog({ try { setSaving(true) - await updateExpression(expression.id, formData) - toast({ - title: '保存成功', - description: '表达方式已更新', - }) - onSuccess() + const result = await updateExpression(expression.id, formData) + if (result.success) { + toast({ + title: '保存成功', + description: '表达方式已更新', + }) + onSuccess() + } else { + toast({ + title: '保存失败', + description: result.error, + variant: 'destructive', + }) + } } catch (error) { toast({ title: '保存失败',