package api import ( "encoding/json" "net/http" "strconv" "github.com/havline/havline/internal/ddns" ) type DDNSHandler struct { svc *ddns.Service } func NewDDNSHandler(svc *ddns.Service) *DDNSHandler { return &DDNSHandler{svc: svc} } type ddnsRequest struct { Provider string `json:"provider"` RootDomain string `json:"root_domain"` RecordName string `json:"record_name"` RecordNames []string `json:"record_names"` Domains []string `json:"domains"` IPv4Enabled *bool `json:"ipv4_enabled"` IPv6Enabled *bool `json:"ipv6_enabled"` Enabled *bool `json:"enabled"` CustomIPv4 string `json:"custom_ipv4"` CustomIPv6 string `json:"custom_ipv6"` APIToken string `json:"api_token"` APITokenID string `json:"api_token_id"` APISecret string `json:"api_secret"` } func (h *DDNSHandler) toInput(req ddnsRequest) ddns.SaveInput { return ddns.SaveInput{ Provider: req.Provider, RootDomain: req.RootDomain, RecordName: req.RecordName, RecordNames: req.RecordNames, Domains: req.Domains, IPv4Enabled: boolDefault(req.IPv4Enabled, true), IPv6Enabled: boolDefault(req.IPv6Enabled, false), Enabled: boolDefault(req.Enabled, true), CustomIPv4: req.CustomIPv4, CustomIPv6: req.CustomIPv6, APIToken: req.APIToken, APITokenID: req.APITokenID, APISecret: req.APISecret, } } func (h *DDNSHandler) List(w http.ResponseWriter, r *http.Request) { var configs []ddns.Config var err error if r.URL.Query().Get("lite") == "1" { configs, err = h.svc.ListLite(r.Context()) } else { configs, err = h.svc.List(r.Context()) } if err != nil { writeError(r, w, http.StatusInternalServerError, "读取 DDNS 配置失败") return } writeJSON(w, http.StatusOK, configs) } func (h *DDNSHandler) Create(w http.ResponseWriter, r *http.Request) { var req ddnsRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeError(r, w, http.StatusBadRequest, "请求格式无效") return } cfg, err := h.svc.Create(r.Context(), h.toInput(req)) if err != nil { writeError(r, w, http.StatusBadRequest, err.Error()) return } writeJSON(w, http.StatusOK, cfg) } func (h *DDNSHandler) Update(w http.ResponseWriter, r *http.Request) { id, err := strconv.ParseInt(r.PathValue("id"), 10, 64) if err != nil { writeError(r, w, http.StatusBadRequest, "无效的配置 ID") return } var req ddnsRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeError(r, w, http.StatusBadRequest, "请求格式无效") return } cfg, err := h.svc.Update(r.Context(), id, h.toInput(req)) if err != nil { writeError(r, w, http.StatusBadRequest, err.Error()) return } writeJSON(w, http.StatusOK, cfg) } func (h *DDNSHandler) Delete(w http.ResponseWriter, r *http.Request) { id, err := strconv.ParseInt(r.PathValue("id"), 10, 64) if err != nil { writeError(r, w, http.StatusBadRequest, "无效的配置 ID") return } if err := h.svc.Delete(r.Context(), id); err != nil { writeError(r, w, http.StatusBadRequest, err.Error()) return } w.WriteHeader(http.StatusNoContent) } func (h *DDNSHandler) Test(w http.ResponseWriter, r *http.Request) { var req struct { ConfigID int64 `json:"config_id"` Provider string `json:"provider"` APIToken string `json:"api_token"` APITokenID string `json:"api_token_id"` APISecret string `json:"api_secret"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeError(r, w, http.StatusBadRequest, "请求格式无效") return } if err := h.svc.Test(r.Context(), ddns.TestInput{ ConfigID: req.ConfigID, Provider: req.Provider, APIToken: req.APIToken, APITokenID: req.APITokenID, APISecret: req.APISecret, }); err != nil { writeError(r, w, http.StatusBadRequest, err.Error()) return } writeJSON(w, http.StatusOK, map[string]string{"message": "连接成功"}) } func (h *DDNSHandler) UpdateOne(w http.ResponseWriter, r *http.Request) { id, err := strconv.ParseInt(r.PathValue("id"), 10, 64) if err != nil { writeError(r, w, http.StatusBadRequest, "无效的配置 ID") return } cfg, err := h.svc.UpdateNow(r.Context(), id) if err != nil { writeError(r, w, http.StatusBadRequest, err.Error()) return } writeJSON(w, http.StatusOK, cfg) } func (h *DDNSHandler) UpdateAll(w http.ResponseWriter, r *http.Request) { configs, err := h.svc.UpdateAll(r.Context()) if err != nil { writeError(r, w, http.StatusBadRequest, err.Error()) return } writeJSON(w, http.StatusOK, configs) }