package services import ( "fmt" "strings" "time" "mengyaping-backend/models" "mengyaping-backend/storage" "mengyaping-backend/utils" ) // WebsiteService 网站服务 type WebsiteService struct { storage *storage.Storage } // NewWebsiteService 创建网站服务 func NewWebsiteService() *WebsiteService { return &WebsiteService{ storage: storage.GetStorage(), } } // CreateWebsite 创建网站 func (s *WebsiteService) CreateWebsite(req models.CreateWebsiteRequest) (*models.Website, error) { groups := req.Groups if len(groups) == 0 && req.Group != "" { groups = []string{req.Group} } website := models.Website{ ID: utils.GenerateID(), Name: req.Name, Groups: groups, URLs: make([]models.URLInfo, 0), CreatedAt: time.Now(), UpdatedAt: time.Now(), } for _, url := range req.URLs { urlInfo := models.URLInfo{ ID: utils.GenerateShortID(), URL: url, } website.URLs = append(website.URLs, urlInfo) } if len(req.URLs) > 0 { if utils.IsIntranetURL(req.URLs[0]) { website.Favicon = models.DefaultIntranetFavicon website.IPAddresses = nil } else { if ips, err := utils.ResolveDomainIPs(req.URLs[0]); err == nil { website.IPAddresses = ips } } } if err := s.storage.AddWebsite(website); err != nil { return nil, err } // 立即检测该网站 go GetMonitorService().CheckWebsiteNow(website.ID) return &website, nil } // GetWebsite 获取网站 func (s *WebsiteService) GetWebsite(id string) *models.Website { return s.storage.GetWebsite(id) } // GetAllWebsites 获取所有网站 func (s *WebsiteService) GetAllWebsites() []models.Website { return s.storage.GetWebsites() } // UpdateWebsite 更新网站 func (s *WebsiteService) UpdateWebsite(id string, req models.UpdateWebsiteRequest) (*models.Website, error) { website := s.storage.GetWebsite(id) if website == nil { return nil, nil } if req.Name != "" { website.Name = req.Name } if len(req.Groups) > 0 { website.Groups = req.Groups } else if req.Group != "" { website.Groups = []string{req.Group} } if len(req.URLs) > 0 { // 保留已有URL的ID,添加新URL existingURLs := make(map[string]models.URLInfo) for _, u := range website.URLs { existingURLs[u.URL] = u } newURLs := make([]models.URLInfo, 0) for _, url := range req.URLs { if existing, ok := existingURLs[url]; ok { newURLs = append(newURLs, existing) } else { newURLs = append(newURLs, models.URLInfo{ ID: utils.GenerateShortID(), URL: url, }) } } website.URLs = newURLs website.IPAddresses = nil // URL 变更后清空 IP,等下次检测重新解析 if len(req.URLs) > 0 && utils.IsIntranetURL(req.URLs[0]) { website.Favicon = models.DefaultIntranetFavicon website.IPAddresses = nil } } website.UpdatedAt = time.Now() if err := s.storage.UpdateWebsite(*website); err != nil { return nil, err } return website, nil } // DeleteWebsite 删除网站 func (s *WebsiteService) DeleteWebsite(id string) error { return s.storage.DeleteWebsite(id) } // GetGroups 获取所有分组 func (s *WebsiteService) GetGroups() []models.Group { return s.storage.GetGroups() } // AddGroup 添加分组 func (s *WebsiteService) AddGroup(name string) (*models.Group, error) { name = strings.TrimSpace(name) if name == "" { return nil, fmt.Errorf("分类名称不能为空") } group := models.Group{ ID: utils.GenerateShortID(), Name: name, } if err := s.storage.AddGroup(group); err != nil { return nil, err } return &group, nil } // GetGroup 获取单个分组 func (s *WebsiteService) GetGroup(id string) *models.Group { return s.storage.GetGroupByID(id) } // UpdateGroup 更新分类名称 func (s *WebsiteService) UpdateGroup(id string, name string) (*models.Group, error) { if err := s.storage.UpdateGroup(id, name); err != nil { return nil, err } g := s.storage.GetGroupByID(id) return g, nil } // DeleteGroup 删除分类 func (s *WebsiteService) DeleteGroup(id string) error { return s.storage.DeleteGroup(id) }