Initial commit

This commit is contained in:
2026-06-30 15:14:37 +08:00
commit 15dab96872
311 changed files with 95639 additions and 0 deletions
+145
View File
@@ -0,0 +1,145 @@
package handler
import (
"encoding/json"
"net/http"
"time"
"git.zkcoi.com/zkcoi/meshray/internal/model"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
// DDNSStatsHandler DDNS 统计处理器
type DDNSStatsHandler struct {
db *gorm.DB
}
// NewDDNSStatsHandler 创建 DDNS 统计处理器
func NewDDNSStatsHandler(db *gorm.DB) *DDNSStatsHandler {
return &DDNSStatsHandler{
db: db,
}
}
// DDNSServiceInfo DDNS 服务信息(返回给前端)
type DDNSServiceInfo struct {
ID string `json:"id"`
Name string `json:"name"`
FullDomain string `json:"full_domain"` // 完整域名:subdomain.domain
CurrentIP string `json:"current_ip"` // 当前 IP
RecordType string `json:"record_type"` // A/AAAA/TXT/CNAME
Enabled bool `json:"enabled"` // 是否启用
Status string `json:"status"` // active/disabled
LastUpdated string `json:"last_updated"` // 最后更新时间
}
// GetDDNSStats 获取 DDNS 统计数据
// @Summary 获取 DDNS 服务统计
// @Tags DDNS
// @Accept json
// @Produce json
// @Success 200 {object} map[string]interface{}
// @Router /api/v1/services/ddns/stats [get]
func (h *DDNSStatsHandler) GetDDNSStats(c *gin.Context) {
// 查询所有 DDNS 全功能模式服务
var services []model.Service
if err := h.db.Where("type = ? AND config_mode = ?", "DDNS", "fullservice").Find(&services).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"code": 500,
"message": "查询 DDNS 服务失败:" + err.Error(),
})
return
}
// 统计数据
total := len(services)
active := 0
// 构建服务列表
serviceList := make([]DDNSServiceInfo, 0, len(services))
for _, svc := range services {
// 判断是否活跃
status := "disabled"
if svc.Enabled {
status = "active"
active++
}
// 构建完整域名
fullDomain := ""
rootDomain := h.getDDNSDomain(svc.DDNSConfigID)
switch svc.RecordType {
case "A", "AAAA":
if svc.Subdomain != "" && rootDomain != "" {
fullDomain = svc.Subdomain + "." + rootDomain
}
case "TXT":
if svc.TXTRecordName != "" && rootDomain != "" {
fullDomain = svc.TXTRecordName + "." + rootDomain
}
case "CNAME":
if svc.Subdomain != "" && rootDomain != "" {
fullDomain = svc.Subdomain + "." + rootDomain
}
}
// 当前 IP
currentIP := svc.TargetIP
if svc.RecordType == "TXT" {
currentIP = "-"
}
// 格式化时间
lastUpdated := ""
if !svc.UpdatedAt.IsZero() {
lastUpdated = svc.UpdatedAt.Format(time.RFC3339)
}
serviceList = append(serviceList, DDNSServiceInfo{
ID: svc.ID,
Name: svc.Name,
FullDomain: fullDomain,
CurrentIP: currentIP,
RecordType: svc.RecordType,
Enabled: svc.Enabled,
Status: status,
LastUpdated: lastUpdated,
})
}
c.JSON(http.StatusOK, gin.H{
"code": 0,
"data": gin.H{
"total": total,
"active": active,
"services": serviceList,
},
"message": "获取成功",
})
}
// getDDNSDomain 获取 DDNS 配置中的根域名(辅助方法)
func (h *DDNSStatsHandler) getDDNSDomain(ddnsConfigID string) string {
if ddnsConfigID == "" {
return ""
}
// 从 ExternalService 表查询 DDNS 配置
var extService model.ExternalService
if err := h.db.Where("id = ?", ddnsConfigID).First(&extService).Error; err != nil {
return ""
}
// 解析 Config JSON 获取 root_domain
var config map[string]interface{}
if err := json.Unmarshal([]byte(extService.Config), &config); err != nil {
return ""
}
if rootDomain, ok := config["root_domain"].(string); ok {
return rootDomain
}
return ""
}