feat: update plugin handling to use unique PluginID across client and server interactions
Some checks failed
Build Multi-Platform Binaries / build-frontend (push) Successful in 56s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 7m28s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 2m44s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 7m27s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 1m18s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 5m49s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 2m17s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 5m4s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 5m57s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 4m36s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Failing after 13m47s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Failing after 26m24s

This commit is contained in:
2026-01-04 21:31:36 +08:00
parent 78982a26b0
commit 02f8c521c2
12 changed files with 143 additions and 57 deletions

View File

@@ -30,17 +30,17 @@ export const installPluginsToClient = (id: string, plugins: string[]) =>
// 规则配置模式
export const getRuleSchemas = () => get<RuleSchemasMap>('/rule-schemas')
// 客户端插件控制
export const startClientPlugin = (clientId: string, pluginName: string, ruleName: string) =>
post(`/client/${clientId}/plugin/${pluginName}/start`, { rule_name: ruleName })
export const stopClientPlugin = (clientId: string, pluginName: string, ruleName: string) =>
post(`/client/${clientId}/plugin/${pluginName}/stop`, { rule_name: ruleName })
export const restartClientPlugin = (clientId: string, pluginName: string, ruleName: string) =>
post(`/client/${clientId}/plugin/${pluginName}/restart`, { rule_name: ruleName })
export const deleteClientPlugin = (clientId: string, pluginName: string) =>
post(`/client/${clientId}/plugin/${pluginName}/delete`)
export const updateClientPluginConfigWithRestart = (clientId: string, pluginName: string, ruleName: string, config: Record<string, string>, restart: boolean) =>
post(`/client/${clientId}/plugin/${pluginName}/config`, { rule_name: ruleName, config, restart })
// 客户端插件控制(使用 pluginID
export const startClientPlugin = (clientId: string, pluginId: string, ruleName: string) =>
post(`/client/${clientId}/plugin/${pluginId}/start`, { rule_name: ruleName })
export const stopClientPlugin = (clientId: string, pluginId: string, ruleName: string) =>
post(`/client/${clientId}/plugin/${pluginId}/stop`, { rule_name: ruleName })
export const restartClientPlugin = (clientId: string, pluginId: string, ruleName: string) =>
post(`/client/${clientId}/plugin/${pluginId}/restart`, { rule_name: ruleName })
export const deleteClientPlugin = (clientId: string, pluginId: string) =>
post(`/client/${clientId}/plugin/${pluginId}/delete`)
export const updateClientPluginConfigWithRestart = (clientId: string, pluginId: string, ruleName: string, config: Record<string, string>, restart: boolean) =>
post(`/client/${clientId}/plugin/${pluginId}/config`, { rule_name: ruleName, config, restart })
// 插件管理
export const getPlugins = () => get<PluginInfo[]>('/plugins')
@@ -71,6 +71,23 @@ export const updateJSPluginConfig = (name: string, config: Record<string, string
export const setJSPluginEnabled = (name: string, enabled: boolean) =>
post(`/js-plugin/${name}/${enabled ? 'enable' : 'disable'}`)
// 插件 API 代理(通过 pluginID 调用插件自定义 API
export const callPluginAPI = <T = any>(clientId: string, pluginId: string, method: string, route: string, body?: any) => {
const path = `/client/${clientId}/plugin-api/${pluginId}${route.startsWith('/') ? route : '/' + route}`
switch (method.toUpperCase()) {
case 'GET':
return get<T>(path)
case 'POST':
return post<T>(path, body)
case 'PUT':
return put<T>(path, body)
case 'DELETE':
return del<T>(path)
default:
return get<T>(path)
}
}
// 更新管理
export interface UpdateInfo {
available: boolean

View File

@@ -11,11 +11,13 @@ export interface ProxyRule {
// 客户端已安装的插件
export interface ClientPlugin {
id: string // 插件实例唯一 ID
name: string
version: string
enabled: boolean
running: boolean
config?: Record<string, string>
remote_port?: number // 远程监听端口
}
// 插件配置字段

View File

@@ -278,7 +278,7 @@ const handleStartPlugin = async (plugin: ClientPlugin) => {
const rule = rules.value.find(r => r.type === plugin.name)
const ruleName = rule?.name || plugin.name
try {
await startClientPlugin(clientId, plugin.name, ruleName)
await startClientPlugin(clientId, plugin.id, ruleName)
message.success(`已启动 ${plugin.name}`)
plugin.running = true
} catch (e: any) {
@@ -292,7 +292,7 @@ const handleRestartPlugin = async (plugin: ClientPlugin) => {
const rule = rules.value.find(r => r.type === plugin.name)
const ruleName = rule?.name || plugin.name
try {
await restartClientPlugin(clientId, plugin.name, ruleName)
await restartClientPlugin(clientId, plugin.id, ruleName)
message.success(`已重启 ${plugin.name}`)
plugin.running = true
} catch (e: any) {
@@ -305,7 +305,7 @@ const handleStopPlugin = async (plugin: ClientPlugin) => {
const rule = rules.value.find(r => r.type === plugin.name)
const ruleName = rule?.name || plugin.name
try {
await stopClientPlugin(clientId, plugin.name, ruleName)
await stopClientPlugin(clientId, plugin.id, ruleName)
message.success(`已停止 ${plugin.name}`)
plugin.running = false
} catch (e: any) {
@@ -316,7 +316,7 @@ const handleStopPlugin = async (plugin: ClientPlugin) => {
const toggleClientPlugin = async (plugin: ClientPlugin) => {
const newEnabled = !plugin.enabled
const updatedPlugins = clientPlugins.value.map(p =>
p.name === plugin.name ? { ...p, enabled: newEnabled } : p
p.id === plugin.id ? { ...p, enabled: newEnabled } : p
)
try {
await updateClient(clientId, {
@@ -377,7 +377,7 @@ const handleDeletePlugin = (plugin: ClientPlugin) => {
negativeText: '取消',
onPositiveClick: async () => {
try {
await deleteClientPlugin(clientId, plugin.name)
await deleteClientPlugin(clientId, plugin.id)
message.success(`已删除 ${plugin.name}`)
await loadClient()
} catch (e: any) {
@@ -596,7 +596,7 @@ const handleDeletePlugin = (plugin: ClientPlugin) => {
</tr>
</thead>
<tbody>
<tr v-for="plugin in clientPlugins" :key="plugin.name">
<tr v-for="plugin in clientPlugins" :key="plugin.id">
<td>{{ plugin.name }}</td>
<td>v{{ plugin.version }}</td>
<td>