refactor(dashboard): migrate plugin-api HTTP functions to ApiResponse pattern

- Migrate 14 HTTP functions in plugin-api.ts to return ApiResponse<T>
  - fetchPluginList, checkGitStatus, getMaimaiVersion
  - getInstalledPlugins, installPlugin, uninstallPlugin, updatePlugin
  - getPluginConfigSchema, getPluginConfig, getPluginConfigRaw
  - updatePluginConfig, updatePluginConfigRaw, resetPluginConfig, togglePlugin
- Update 3 caller files to handle ApiResponse pattern:
  - plugins.tsx: 5 function calls updated
  - plugin-config.tsx: 5 function calls updated
  - plugin-detail.tsx: 5 function calls updated
- All callers now check .success before accessing .data
- Preserve WebSocket and utility functions unchanged
- Build verification: npm run build succeeds with 0 errors
This commit is contained in:
DrSmoothl
2026-03-01 18:06:25 +08:00
parent d4bfc9591c
commit dc7e037582
4 changed files with 446 additions and 269 deletions

View File

@@ -341,16 +341,44 @@ function PluginConfigEditor({ plugin, onBack }: PluginConfigEditorProps) {
const loadConfig = useCallback(async () => {
setLoading(true)
try {
const [schemaData, configData, rawConfigData] = await Promise.all([
const [schemaResult, configResult, rawResult] = await Promise.all([
getPluginConfigSchema(plugin.id),
getPluginConfig(plugin.id),
getPluginConfigRaw(plugin.id)
])
setSchema(schemaData)
setConfig(configData)
setOriginalConfig(JSON.parse(JSON.stringify(configData)))
setSourceCode(rawConfigData)
setOriginalSourceCode(rawConfigData)
if (!schemaResult.success) {
toast({
title: '加载配置架构失败',
description: schemaResult.error,
variant: 'destructive'
})
return
}
if (!configResult.success) {
toast({
title: '加载配置数据失败',
description: configResult.error,
variant: 'destructive'
})
return
}
if (!rawResult.success) {
toast({
title: '加载原始配置失败',
description: rawResult.error,
variant: 'destructive'
})
return
}
setSchema(schemaResult.data)
setConfig(configResult.data)
setOriginalConfig(JSON.parse(JSON.stringify(configResult.data)))
setSourceCode(rawResult.data)
setOriginalSourceCode(rawResult.data)
} catch (error) {
toast({
title: '加载配置失败',
@@ -433,7 +461,15 @@ function PluginConfigEditor({ plugin, onBack }: PluginConfigEditorProps) {
// 重置配置
const handleReset = async () => {
try {
await resetPluginConfig(plugin.id)
const resetResult = await resetPluginConfig(plugin.id)
if (!resetResult.success) {
toast({
title: '重置失败',
description: resetResult.error,
variant: 'destructive'
})
return
}
toast({
title: '配置已重置',
description: '下次加载插件时将使用默认配置'
@@ -452,10 +488,18 @@ function PluginConfigEditor({ plugin, onBack }: PluginConfigEditorProps) {
// 切换启用状态
const handleToggle = async () => {
try {
const result = await togglePlugin(plugin.id)
const toggleResult = await togglePlugin(plugin.id)
if (!toggleResult.success) {
toast({
title: '切换失败',
description: toggleResult.error,
variant: 'destructive'
})
return
}
toast({
title: result.message,
description: result.note
title: toggleResult.data.message,
description: toggleResult.data.note
})
loadConfig()
} catch (error) {
@@ -723,8 +767,16 @@ function PluginConfigPageContent() {
const loadPlugins = async () => {
setLoading(true)
try {
const data = await getInstalledPlugins()
setPlugins(data)
const installedResult = await getInstalledPlugins()
if (!installedResult.success) {
toast({
title: '加载插件列表失败',
description: installedResult.error,
variant: 'destructive'
})
return
}
setPlugins(installedResult.data)
} catch (error) {
toast({
title: '加载插件列表失败',

View File

@@ -131,10 +131,37 @@ export function PluginDetailPage() {
getInstalledPlugins(),
])
setGitStatus(gitStatusResult)
setMaimaiVersion(versionResult)
setIsInstalled(checkPluginInstalled(search.pluginId, installedPlugins))
setInstalledVersion(getInstalledPluginVersion(search.pluginId, installedPlugins))
if (!gitStatusResult.success) {
toast({
title: 'Git 状态检查失败',
description: gitStatusResult.error,
variant: 'destructive',
})
} else {
setGitStatus(gitStatusResult.data)
}
if (!versionResult.success) {
toast({
title: '版本获取失败',
description: versionResult.error,
variant: 'destructive',
})
} else {
setMaimaiVersion(versionResult.data)
}
if (!installedPlugins.success) {
toast({
title: '获取已安装插件失败',
description: installedPlugins.error,
variant: 'destructive',
})
return
}
setIsInstalled(checkPluginInstalled(search.pluginId, installedPlugins.data))
setInstalledVersion(getInstalledPluginVersion(search.pluginId, installedPlugins.data))
} catch (err) {
setError(err instanceof Error ? err.message : '加载失败')
} finally {
@@ -243,7 +270,16 @@ export function PluginDetailPage() {
try {
setOperating(true)
await installPlugin(plugin.id, plugin.manifest.repository_url || '', 'main')
const installResult = await installPlugin(plugin.id, plugin.manifest.repository_url || '', 'main')
if (!installResult.success) {
toast({
title: '安装失败',
description: installResult.error,
variant: 'destructive',
})
return
}
// 记录下载统计
recordPluginDownload(plugin.id).catch((err) => {
@@ -256,9 +292,17 @@ export function PluginDetailPage() {
})
// 重新加载安装状态
const installedPlugins = await getInstalledPlugins()
setIsInstalled(checkPluginInstalled(plugin.id, installedPlugins))
setInstalledVersion(getInstalledPluginVersion(plugin.id, installedPlugins))
const installedPluginsResult = await getInstalledPlugins()
if (!installedPluginsResult.success) {
toast({
title: '获取已安装插件失败',
description: installedPluginsResult.error,
variant: 'destructive',
})
return
}
setIsInstalled(checkPluginInstalled(plugin.id, installedPluginsResult.data))
setInstalledVersion(getInstalledPluginVersion(plugin.id, installedPluginsResult.data))
} catch (error) {
toast({
title: '安装失败',
@@ -277,7 +321,16 @@ export function PluginDetailPage() {
try {
setOperating(true)
await uninstallPlugin(plugin.id)
const uninstallResult = await uninstallPlugin(plugin.id)
if (!uninstallResult.success) {
toast({
title: '卸载失败',
description: uninstallResult.error,
variant: 'destructive',
})
return
}
toast({
title: '卸载成功',
@@ -285,9 +338,17 @@ export function PluginDetailPage() {
})
// 重新加载安装状态
const installedPlugins = await getInstalledPlugins()
setIsInstalled(checkPluginInstalled(plugin.id, installedPlugins))
setInstalledVersion(getInstalledPluginVersion(plugin.id, installedPlugins))
const installedPluginsResult = await getInstalledPlugins()
if (!installedPluginsResult.success) {
toast({
title: '获取已安装插件失败',
description: installedPluginsResult.error,
variant: 'destructive',
})
return
}
setIsInstalled(checkPluginInstalled(plugin.id, installedPluginsResult.data))
setInstalledVersion(getInstalledPluginVersion(plugin.id, installedPluginsResult.data))
} catch (error) {
toast({
title: '卸载失败',
@@ -306,17 +367,34 @@ export function PluginDetailPage() {
try {
setOperating(true)
const result = await updatePlugin(plugin.id, plugin.manifest.repository_url || '', 'main')
const updateResult = await updatePlugin(plugin.id, plugin.manifest.repository_url || '', 'main')
if (!updateResult.success) {
toast({
title: '更新失败',
description: updateResult.error,
variant: 'destructive',
})
return
}
toast({
title: '更新成功',
description: `${plugin.manifest.name} 已从 ${result.old_version} 更新到 ${result.new_version}`,
description: `${plugin.manifest.name} 已从 ${updateResult.data.old_version} 更新到 ${updateResult.data.new_version}`,
})
// 重新加载安装状态
const installedPlugins = await getInstalledPlugins()
setIsInstalled(checkPluginInstalled(plugin.id, installedPlugins))
setInstalledVersion(getInstalledPluginVersion(plugin.id, installedPlugins))
const installedPluginsResult = await getInstalledPlugins()
if (!installedPluginsResult.success) {
toast({
title: '获取已安装插件失败',
description: installedPluginsResult.error,
variant: 'destructive',
})
return
}
setIsInstalled(checkPluginInstalled(plugin.id, installedPluginsResult.data))
setInstalledVersion(getInstalledPluginVersion(plugin.id, installedPluginsResult.data))
} catch (error) {
toast({
title: '更新失败',

View File

@@ -180,34 +180,71 @@ function PluginsPageContent() {
// 3. 检查 Git 状态
if (!isUnmounted) {
const status = await checkGitStatus()
setGitStatus(status)
if (!status.installed) {
const statusResult = await checkGitStatus()
if (!statusResult.success) {
toast({
title: 'Git 未安装',
description: status.error || '请先安装 Git 才能使用插件安装功能',
title: 'Git 状态检查失败',
description: statusResult.error,
variant: 'destructive',
})
setGitStatus({ installed: false, error: statusResult.error })
} else {
setGitStatus(statusResult.data)
if (!statusResult.data.installed) {
toast({
title: 'Git 未安装',
description: statusResult.data.error || '请先安装 Git 才能使用插件安装功能',
variant: 'destructive',
})
}
}
}
// 4. 获取麦麦版本
if (!isUnmounted) {
const version = await getMaimaiVersion()
setMaimaiVersion(version)
const versionResult = await getMaimaiVersion()
if (!versionResult.success) {
toast({
title: '版本获取失败',
description: versionResult.error,
variant: 'destructive',
})
} else {
setMaimaiVersion(versionResult.data)
}
}
// 5. 加载插件列表(包含已安装信息)
if (!isUnmounted) {
try {
setLoading(true)
setError(null)
const data = await fetchPluginList()
const apiResult = await fetchPluginList()
if (!apiResult.success) {
if (!isUnmounted) {
setError(apiResult.error)
toast({
title: '加载失败',
description: apiResult.error,
variant: 'destructive',
})
}
return
}
const data = apiResult.data
if (!isUnmounted) {
// 获取已安装插件列表
const installed = await getInstalledPlugins()
const installedResult = await getInstalledPlugins()
if (!installedResult.success) {
toast({
title: '获取已安装插件失败',
description: installedResult.error,
variant: 'destructive',
})
return
}
const installed = installedResult.data
setInstalledPlugins(installed)
// 将已安装信息合并到插件数据中
@@ -261,16 +298,6 @@ function PluginsPageContent() {
// 6. 加载所有插件的统计数据
loadPluginStats(mergedData)
}
} catch (err) {
if (!isUnmounted) {
const errorMessage = err instanceof Error ? err.message : '加载插件列表失败'
setError(errorMessage)
toast({
title: '加载失败',
description: errorMessage,
variant: 'destructive',
})
}
} finally {
if (!isUnmounted) {
setLoading(false)
@@ -463,12 +490,21 @@ function PluginsPageContent() {
try {
setInstallDialogOpen(false)
await installPlugin(
const installResult = await installPlugin(
installingPlugin.id,
installingPlugin.manifest.repository_url || '',
branch
)
if (!installResult.success) {
toast({
title: '安装失败',
description: installResult.error,
variant: 'destructive',
})
return
}
// 记录下载统计
recordPluginDownload(installingPlugin.id).catch(err => {
console.warn('Failed to record download:', err)
@@ -480,7 +516,16 @@ function PluginsPageContent() {
})
// 重新加载已安装插件列表
const installed = await getInstalledPlugins()
const installedResult = await getInstalledPlugins()
if (!installedResult.success) {
toast({
title: '获取已安装插件失败',
description: installedResult.error,
variant: 'destructive',
})
return
}
const installed = installedResult.data
setInstalledPlugins(installed)
// 重新合并已安装信息到插件列表
@@ -513,7 +558,16 @@ function PluginsPageContent() {
// 卸载插件处理
const handleUninstall = async (plugin: PluginInfo) => {
try {
await uninstallPlugin(plugin.id)
const uninstallResult = await uninstallPlugin(plugin.id)
if (!uninstallResult.success) {
toast({
title: '卸载失败',
description: uninstallResult.error,
variant: 'destructive',
})
return
}
toast({
title: '卸载成功',
@@ -521,7 +575,16 @@ function PluginsPageContent() {
})
// 重新加载已安装插件列表
const installed = await getInstalledPlugins()
const installedResult = await getInstalledPlugins()
if (!installedResult.success) {
toast({
title: '获取已安装插件失败',
description: installedResult.error,
variant: 'destructive',
})
return
}
const installed = installedResult.data
setInstalledPlugins(installed)
// 重新合并已安装信息到插件列表
@@ -561,19 +624,37 @@ function PluginsPageContent() {
}
try {
const result = await updatePlugin(
const updateResult = await updatePlugin(
plugin.id,
plugin.manifest.repository_url || '',
'main'
)
if (!updateResult.success) {
toast({
title: '更新失败',
description: updateResult.error,
variant: 'destructive',
})
return
}
toast({
title: '更新成功',
description: `${plugin.manifest.name} 已从 ${result.old_version} 更新到 ${result.new_version}`,
description: `${plugin.manifest.name} 已从 ${updateResult.data.old_version} 更新到 ${updateResult.data.new_version}`,
})
// 重新加载已安装插件列表
const installed = await getInstalledPlugins()
const installedResult = await getInstalledPlugins()
if (!installedResult.success) {
toast({
title: '获取已安装插件失败',
description: installedResult.error,
variant: 'destructive',
})
return
}
const installed = installedResult.data
setInstalledPlugins(installed)
// 重新合并已安装信息到插件列表