Files
Havline/internal/api/ddns_handler.go
T
mrlee 278f8267b7 chore: 初始提交 Fonu 1.0.2
- 公网反代:Nginx 状态卡片(版本 / 运行状态 / 配置校验 / 端口监听)
- 部署设置第一、二梯队(HTTPS 开关、安全头、限流、连接数、仅中国大陆 IP)
- 隧道检测兼容 frps v0.68 / v0.71(V2 与旧版端点)
- 恢复被清空的 internal/frp/store.go、internal/api/ddns_handler.go、web/src/views/DdnsView.vue
2026-09-23 09:40:59 +08:00

158 lines
4.3 KiB
Go

package api
import (
"encoding/json"
"net/http"
"strconv"
"github.com/fonu/fonu/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"`
}
_ = json.NewDecoder(r.Body).Decode(&req)
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)
}