feat: enhance plugin configuration with remote port and schema support
All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 33s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 2m35s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 55s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 3m7s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 1m20s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 1m59s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 1m6s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 2m16s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 1m55s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 1m8s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 2m57s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 1m56s

This commit is contained in:
2026-01-03 23:53:04 +08:00
parent 08262654d6
commit d6bde71c94
8 changed files with 148 additions and 78 deletions

View File

@@ -1,5 +1,5 @@
import { get, post, put, del, getToken } from '../config/axios'
import type { ClientConfig, ClientStatus, ClientDetail, ServerStatus, PluginInfo, StorePluginInfo, PluginConfigResponse, JSPlugin, RuleSchemasMap, LogEntry, LogStreamOptions } from '../types'
import type { ClientConfig, ClientStatus, ClientDetail, ServerStatus, PluginInfo, StorePluginInfo, PluginConfigResponse, JSPlugin, RuleSchemasMap, LogEntry, LogStreamOptions, ConfigField } from '../types'
// 重新导出 token 管理方法
export { getToken, setToken, removeToken } from '../config/axios'
@@ -49,8 +49,8 @@ export const disablePlugin = (name: string) => post(`/plugin/${name}/disable`)
// 扩展商店
export const getStorePlugins = () => get<{ plugins: StorePluginInfo[] }>('/store/plugins')
export const installStorePlugin = (pluginName: string, downloadUrl: string, signatureUrl: string, clientId: string, remotePort?: number) =>
post('/store/install', { plugin_name: pluginName, download_url: downloadUrl, signature_url: signatureUrl, client_id: clientId, remote_port: remotePort || 0 })
export const installStorePlugin = (pluginName: string, downloadUrl: string, signatureUrl: string, clientId: string, remotePort?: number, version?: string, configSchema?: ConfigField[]) =>
post('/store/install', { plugin_name: pluginName, version: version || '', download_url: downloadUrl, signature_url: signatureUrl, client_id: clientId, remote_port: remotePort || 0, config_schema: configSchema || [] })
// 客户端插件配置
export const getClientPluginConfig = (clientId: string, pluginName: string) =>

View File

@@ -112,6 +112,7 @@ export interface StorePluginInfo {
icon?: string
download_url?: string
signature_url?: string
config_schema?: ConfigField[]
}
// JS 插件信息

View File

@@ -86,8 +86,7 @@ const configLoading = ref(false)
const showStoreModal = ref(false)
const storePlugins = ref<StorePluginInfo[]>([])
const storeLoading = ref(false)
const selectedStorePlugin = ref<StorePluginInfo | null>(null)
const storeInstalling = ref(false)
const storeInstalling = ref<string | null>(null) // 正在安装的插件名称
// 日志查看相关
const showLogViewer = ref(false)
@@ -96,7 +95,6 @@ const showLogViewer = ref(false)
const openStoreModal = async () => {
showStoreModal.value = true
storeLoading.value = true
selectedStorePlugin.value = null
try {
const { data } = await getStorePlugins()
storePlugins.value = (data.plugins || []).filter(p => p.download_url)
@@ -113,18 +111,17 @@ const handleInstallStorePlugin = async (plugin: StorePluginInfo) => {
message.error('该插件没有下载地址')
return
}
storeInstalling.value = true
selectedStorePlugin.value = plugin
storeInstalling.value = plugin.name
try {
await installStorePlugin(plugin.name, plugin.download_url, plugin.signature_url || '', clientId)
message.success(`已安装 ${plugin.name}`)
await installStorePlugin(plugin.name, plugin.download_url, plugin.signature_url || '', clientId, 8080, plugin.version, plugin.config_schema)
message.success(`已安装 ${plugin.name},可在配置中修改端口和其他设置`)
showStoreModal.value = false
await loadClient()
} catch (e: any) {
message.error(e.response?.data || '安装失败')
} finally {
storeInstalling.value = false
selectedStorePlugin.value = null
storeInstalling.value = null
}
}
@@ -724,7 +721,7 @@ const handleDeletePlugin = (plugin: ClientPlugin) => {
<n-button
size="small"
type="primary"
:loading="storeInstalling && selectedStorePlugin?.name === plugin.name"
:loading="storeInstalling === plugin.name"
@click="handleInstallStorePlugin(plugin)"
>
安装

View File

@@ -230,13 +230,11 @@ const toggleJSPlugin = async (plugin: JSPlugin) => {
const showInstallModal = ref(false)
const selectedStorePlugin = ref<StorePluginInfo | null>(null)
const selectedClientId = ref('')
const storePluginRemotePort = ref<number | null>(8080)
const installing = ref(false)
const openInstallModal = (plugin: StorePluginInfo) => {
selectedStorePlugin.value = plugin
selectedClientId.value = ''
storePluginRemotePort.value = 8080
showInstallModal.value = true
}
@@ -260,9 +258,11 @@ const handleInstallStorePlugin = async () => {
selectedStorePlugin.value.download_url,
selectedStorePlugin.value.signature_url,
selectedClientId.value,
storePluginRemotePort.value || 0
8080, // 默认端口,可在配置中修改
selectedStorePlugin.value.version,
selectedStorePlugin.value.config_schema
)
message.success(`已安装 ${selectedStorePlugin.value.name} 到客户端`)
message.success(`已安装 ${selectedStorePlugin.value.name},可在客户端配置中修改端口和其他设置`)
showInstallModal.value = false
} catch (e: any) {
message.error(e.response?.data || '安装失败')
@@ -464,16 +464,7 @@ onMounted(() => {
placeholder="选择要安装到的客户端"
:options="onlineClients.map(c => ({ label: c.nickname || c.id, value: c.id }))"
/>
<div>
<p style="margin: 0 0 8px 0; color: #666; font-size: 13px;">远程端口服务端监听端口:</p>
<n-input-number
v-model:value="storePluginRemotePort"
:min="1"
:max="65535"
placeholder="输入端口号"
style="width: 100%;"
/>
</div>
<p style="margin: 0; color: #999; font-size: 12px;">安装后可在客户端详情页配置端口和其他设置</p>
</n-space>
<template #footer>
<n-space justify="end">