refactor(api): migrate expression-api to ApiResponse pattern
- Migrated all 11 functions in expression-api.ts to return Promise<ApiResponse<T>> - Implemented manual response handling following person-api pattern - Properly unwrap nested API responses and re-wrap in ApiResponse - Updated all 16 call sites across 4 files with proper error handling - Fixed type annotations (ChatInfo) in expression.tsx - Build passes successfully with no TypeScript errors - Follows AGENTS.md import conventions and Wave 2 constraints - All HTTP and API-level errors handled consistently via ApiResponse
This commit is contained in:
@@ -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<string, string>()
|
||||
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',
|
||||
})
|
||||
|
||||
// 清空选择并刷新
|
||||
|
||||
@@ -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<ChatListResponse> {
|
||||
export async function getChatList(): Promise<ApiResponse<ChatInfo[]>> {
|
||||
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<ExpressionListResponse> {
|
||||
}): Promise<ApiResponse<ExpressionListResponse>> {
|
||||
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<ExpressionDetailResponse> {
|
||||
export async function getExpressionDetail(expressionId: number): Promise<ApiResponse<any>> {
|
||||
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<Express
|
||||
*/
|
||||
export async function createExpression(
|
||||
data: ExpressionCreateRequest
|
||||
): Promise<ExpressionCreateResponse> {
|
||||
): Promise<ApiResponse<any>> {
|
||||
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<ExpressionUpdateResponse> {
|
||||
): Promise<ApiResponse<any>> {
|
||||
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<ExpressionDeleteResponse> {
|
||||
export async function deleteExpression(expressionId: number): Promise<ApiResponse<any>> {
|
||||
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<ExpressionDeleteResponse> {
|
||||
export async function batchDeleteExpressions(expressionIds: number[]): Promise<ApiResponse<any>> {
|
||||
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<ExpressionStatsResponse> {
|
||||
export async function getExpressionStats(): Promise<ApiResponse<any>> {
|
||||
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<ExpressionStatsResponse> {
|
||||
/**
|
||||
* 获取审核统计数据
|
||||
*/
|
||||
export async function getReviewStats(): Promise<ReviewStats> {
|
||||
export async function getReviewStats(): Promise<ApiResponse<ReviewStats>> {
|
||||
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<ReviewListResponse> {
|
||||
}): Promise<ApiResponse<ReviewListResponse>> {
|
||||
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<BatchReviewResponse> {
|
||||
): Promise<ApiResponse<BatchReviewResponse>> {
|
||||
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()
|
||||
}
|
||||
|
||||
@@ -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<PersonListResponse> {
|
||||
}): Promise<ApiResponse<PersonListData>> {
|
||||
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<PersonDetailResponse> {
|
||||
export async function getPersonDetail(personId: string): Promise<ApiResponse<PersonInfo>> {
|
||||
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<PersonDetailRes
|
||||
export async function updatePerson(
|
||||
personId: string,
|
||||
data: PersonUpdateRequest
|
||||
): Promise<PersonUpdateResponse> {
|
||||
): Promise<ApiResponse<PersonInfo>> {
|
||||
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<PersonDeleteResponse> {
|
||||
export async function deletePerson(personId: string): Promise<ApiResponse<void>> {
|
||||
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<PersonStatsResponse> {
|
||||
export async function getPersonStats(): Promise<ApiResponse<PersonStats>> {
|
||||
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<ApiResponse<{
|
||||
message: string
|
||||
deleted_count: number
|
||||
failed_count: number
|
||||
failed_ids: string[]
|
||||
}> {
|
||||
}>> {
|
||||
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',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<string, string>()
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -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: '人物信息已更新',
|
||||
|
||||
@@ -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<string, string>()
|
||||
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: '保存失败',
|
||||
|
||||
Reference in New Issue
Block a user