@@ -304,8 +304,24 @@ func (h *TunnelHandler) HandleUpdateTunnel(w http.ResponseWriter, r *http.Reques
304304 return
305305 }
306306
307- var req tunnel.UpdateTunnelRequest
308- if err := json .NewDecoder (r .Body ).Decode (& req ); err != nil {
307+ // 尝试解析为创建/替换请求体(与创建接口保持一致)
308+ var rawCreate struct {
309+ Name string `json:"name"`
310+ EndpointID int64 `json:"endpointId"`
311+ Mode string `json:"mode"`
312+ TunnelAddress string `json:"tunnelAddress"`
313+ TunnelPort json.RawMessage `json:"tunnelPort"`
314+ TargetAddress string `json:"targetAddress"`
315+ TargetPort json.RawMessage `json:"targetPort"`
316+ TLSMode string `json:"tlsMode"`
317+ CertPath string `json:"certPath"`
318+ KeyPath string `json:"keyPath"`
319+ LogLevel string `json:"logLevel"`
320+ Min json.RawMessage `json:"min"`
321+ Max json.RawMessage `json:"max"`
322+ }
323+
324+ if err := json .NewDecoder (r .Body ).Decode (& rawCreate ); err != nil {
309325 w .WriteHeader (http .StatusBadRequest )
310326 json .NewEncoder (w ).Encode (tunnel.TunnelResponse {
311327 Success : false ,
@@ -314,21 +330,76 @@ func (h *TunnelHandler) HandleUpdateTunnel(w http.ResponseWriter, r *http.Reques
314330 return
315331 }
316332
317- req .ID = tunnelID
333+ // 如果请求体包含 EndpointID 和 Mode,则认定为"替换"逻辑,否则执行原 Update 逻辑
334+ if rawCreate .EndpointID != 0 && rawCreate .Mode != "" {
335+ // 1. 获取旧 instanceId
336+ instanceID , err := h .tunnelService .GetInstanceIDByTunnelID (tunnelID )
337+ if err != nil {
338+ w .WriteHeader (http .StatusBadRequest )
339+ json .NewEncoder (w ).Encode (tunnel.TunnelResponse {Success : false , Error : err .Error ()})
340+ return
341+ }
318342
319- if err := h .tunnelService .UpdateTunnel (req ); err != nil {
320- w .WriteHeader (http .StatusBadRequest )
321- json .NewEncoder (w ).Encode (tunnel.TunnelResponse {
322- Success : false ,
323- Error : err .Error (),
324- })
343+ // 2. 删除旧实例(回收站=true)
344+ if err := h .tunnelService .DeleteTunnelAndWait (instanceID , 3 * time .Second , true ); err != nil {
345+ w .WriteHeader (http .StatusBadRequest )
346+ json .NewEncoder (w ).Encode (tunnel.TunnelResponse {Success : false , Error : "编辑实例失败,遭遇无法删除旧实例: " + err .Error ()})
347+ return
348+ }
349+ log .Infof ("[API.%v] 编辑实例=>删除旧实例: %v" , rawCreate .EndpointID , instanceID )
350+
351+ // 工具函数解析 int 字段
352+ parseInt := func (j json.RawMessage ) (int , error ) {
353+ if j == nil {
354+ return 0 , nil
355+ }
356+ var i int
357+ if err := json .Unmarshal (j , & i ); err == nil {
358+ return i , nil
359+ }
360+ var s string
361+ if err := json .Unmarshal (j , & s ); err == nil {
362+ return strconv .Atoi (s )
363+ }
364+ return 0 , strconv .ErrSyntax
365+ }
366+
367+ tunnelPort , _ := parseInt (rawCreate .TunnelPort )
368+ targetPort , _ := parseInt (rawCreate .TargetPort )
369+ minVal , _ := parseInt (rawCreate .Min )
370+ maxVal , _ := parseInt (rawCreate .Max )
371+
372+ createReq := tunnel.CreateTunnelRequest {
373+ Name : rawCreate .Name ,
374+ EndpointID : rawCreate .EndpointID ,
375+ Mode : rawCreate .Mode ,
376+ TunnelAddress : rawCreate .TunnelAddress ,
377+ TunnelPort : tunnelPort ,
378+ TargetAddress : rawCreate .TargetAddress ,
379+ TargetPort : targetPort ,
380+ TLSMode : tunnel .TLSMode (rawCreate .TLSMode ),
381+ CertPath : rawCreate .CertPath ,
382+ KeyPath : rawCreate .KeyPath ,
383+ LogLevel : tunnel .LogLevel (rawCreate .LogLevel ),
384+ Min : minVal ,
385+ Max : maxVal ,
386+ }
387+
388+ newTunnel , err := h .tunnelService .CreateTunnel (createReq )
389+ if err != nil {
390+ w .WriteHeader (http .StatusBadRequest )
391+ json .NewEncoder (w ).Encode (tunnel.TunnelResponse {Success : false , Error : "编辑实例失败,无法创建新实例: " + err .Error ()})
392+ return
393+ }
394+ log .Infof ("[API.%v] 编辑实例=>创建新实例: %v" , rawCreate .EndpointID , newTunnel .InstanceID )
395+
396+ json .NewEncoder (w ).Encode (tunnel.TunnelResponse {Success : true , Message : "编辑实例成功" , Tunnel : newTunnel })
325397 return
326398 }
327399
328- json .NewEncoder (w ).Encode (tunnel.TunnelResponse {
329- Success : true ,
330- Message : "隧道更新成功" ,
331- })
400+ // -------- 原局部更新逻辑 ----------
401+ w .WriteHeader (http .StatusBadRequest )
402+ json .NewEncoder (w ).Encode (tunnel.TunnelResponse {Success : false , Error : "不支持的更新请求" })
332403}
333404
334405// HandleGetTunnelLogs GET /api/tunnel-logs
0 commit comments