feat(api): 添加从商店安装插件功能
All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 30s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 50s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 49s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 58s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 45s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 57s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 51s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 1m7s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 51s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 45s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 58s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 51s
All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 30s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 50s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 49s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 58s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 45s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 57s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 51s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 1m7s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 51s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 45s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 58s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 51s
- 添加 /store/install API 端点用于从商店安装插件 - 实现 StorePluginInstallRequest 请求结构体 - 添加 handleStoreInstall 处理函数实现插件下载和安装逻辑 - 在客户端视图中添加商店插件安装模态框和相关功能 - 在插件视图中添加商店插件安装按钮和安装到客户端功能 - 添加 installStorePlugin API 函数用于前端调用 - 实现客户端在线状态检查和插件安装流程
This commit is contained in:
@@ -131,6 +131,7 @@ func RegisterRoutes(r *Router, app AppInterface) {
|
||||
api.HandleFunc("/plugins", h.handlePlugins)
|
||||
api.HandleFunc("/plugin/", h.handlePlugin)
|
||||
api.HandleFunc("/store/plugins", h.handleStorePlugins)
|
||||
api.HandleFunc("/store/install", h.handleStoreInstall)
|
||||
api.HandleFunc("/client-plugin/", h.handleClientPlugin)
|
||||
api.HandleFunc("/js-plugin/", h.handleJSPlugin)
|
||||
api.HandleFunc("/js-plugins", h.handleJSPlugins)
|
||||
@@ -582,6 +583,13 @@ type StorePluginInfo struct {
|
||||
DownloadURL string `json:"download_url,omitempty"`
|
||||
}
|
||||
|
||||
// StorePluginInstallRequest 从商店安装插件的请求
|
||||
type StorePluginInstallRequest struct {
|
||||
PluginName string `json:"plugin_name"`
|
||||
DownloadURL string `json:"download_url"`
|
||||
ClientID string `json:"client_id"`
|
||||
}
|
||||
|
||||
// handleStorePlugins 处理扩展商店插件列表
|
||||
func (h *APIHandler) handleStorePlugins(rw http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
@@ -625,6 +633,71 @@ func (h *APIHandler) handleStorePlugins(rw http.ResponseWriter, r *http.Request)
|
||||
})
|
||||
}
|
||||
|
||||
// handleStoreInstall 从商店安装插件到客户端
|
||||
func (h *APIHandler) handleStoreInstall(rw http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(rw, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
var req StorePluginInstallRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
http.Error(rw, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if req.PluginName == "" || req.DownloadURL == "" || req.ClientID == "" {
|
||||
http.Error(rw, "plugin_name, download_url and client_id required", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// 检查客户端是否在线
|
||||
online, _, _ := h.server.GetClientStatus(req.ClientID)
|
||||
if !online {
|
||||
http.Error(rw, "client not online", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// 下载插件
|
||||
client := &http.Client{Timeout: 30 * time.Second}
|
||||
resp, err := client.Get(req.DownloadURL)
|
||||
if err != nil {
|
||||
http.Error(rw, "Failed to download plugin: "+err.Error(), http.StatusBadGateway)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
http.Error(rw, "Plugin download failed with status: "+resp.Status, http.StatusBadGateway)
|
||||
return
|
||||
}
|
||||
|
||||
source, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
http.Error(rw, "Failed to read plugin: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// 安装到客户端
|
||||
installReq := JSPluginInstallRequest{
|
||||
PluginName: req.PluginName,
|
||||
Source: string(source),
|
||||
RuleName: req.PluginName,
|
||||
AutoStart: true,
|
||||
}
|
||||
|
||||
if err := h.server.InstallJSPluginToClient(req.ClientID, installReq); err != nil {
|
||||
http.Error(rw, "Failed to install plugin: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
h.jsonResponse(rw, map[string]interface{}{
|
||||
"status": "ok",
|
||||
"plugin": req.PluginName,
|
||||
"client": req.ClientID,
|
||||
})
|
||||
}
|
||||
|
||||
// handleClientPlugin 处理客户端插件配置
|
||||
// 路由: /api/client-plugin/{clientID}/{pluginName}/config
|
||||
func (h *APIHandler) handleClientPlugin(rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
Reference in New Issue
Block a user