package service import ( "archive/zip" "errors" "fmt" "github.com/gin-gonic/gin" "io" "log" "net/http" "os" "path/filepath" "work_cation/cfg" "work_cation/global" "work_cation/models" "work_cation/repo" ) type ServerService struct { Status string server *http.Server Router *gin.Engine } const ( StatusOnline = "online" StatusOffline = "offline" ) var Server = &ServerService{Status: StatusOffline} func (s *ServerService) Online() error { if s.Status == StatusOnline { return nil } // 启动服务发现 user := repo.User.GetUserInfo(global.DB) if err := Zeroconf.Register(user); err != nil { return err } // 修改状态 s.Status = StatusOnline return nil } func (s *ServerService) StatusOffline() error { //if err := s.server.Close(); err != nil { // return err //} // 关闭服务发现 Zeroconf.Close() // 修改状态 s.Status = StatusOffline return nil } func (s *ServerService) StartListenServer() error { router := gin.Default() s.Router = router router.GET("/user", func(c *gin.Context) { user := repo.User.GetUserInfo(global.DB) c.JSON(200, user) }) router.GET("/cards", func(c *gin.Context) { cards := repo.BaseCard.FindAll(global.DB) c.JSON(200, cards) }) router.GET("/download/card/:uuid", func(c *gin.Context) { uuid := c.Param("uuid") card := repo.BaseCard.Find(global.DB, uuid) if card.UUID == "" { c.JSON(404, nil) return } cardPath := filepath.Join(cfg.T.CardDir, card.UUID) // 设置响应头 c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s.zip", uuid)) c.Header("Content-Type", "application/zip") err := zipFolder(cardPath, c.Writer) if err != nil { c.JSON(500, err) return } }) router.POST("/chat", func(c *gin.Context) { user, msg, is := PublicPostCheck(c) if !is { return } message := &models.Message{ Cmd: "chat", User: *user, ChatMessage: *models.NewTextChatMsg( &user.Users, repo.User.GetUserInfo(global.DB).ID, msg["text"].(string)), } global.Send.SendChan <- message c.JSON(200, gin.H{"message": "ok"}) }) srv := &http.Server{ Addr: cfg.T.ServerAddr, Handler: router, } go func() { if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { log.Fatalf("listen: %s\n", err) } }() s.server = srv return nil } func zipFolder(folderPath string, zipFile io.Writer) error { zipWriter := zip.NewWriter(zipFile) defer zipWriter.Close() err := filepath.Walk(folderPath, func(filePath string, info os.FileInfo, err error) error { if err != nil { return err } header, err := zip.FileInfoHeader(info) if err != nil { return err } header.Name, err = filepath.Rel(folderPath, filePath) if err != nil { return err } if info.IsDir() { header.Name += "/" } else { header.Method = zip.Deflate } writer, err := zipWriter.CreateHeader(header) if err != nil { return err } if !info.IsDir() { file, err := os.Open(filePath) if err != nil { return err } defer file.Close() _, err = io.Copy(writer, file) if err != nil { return err } } return nil }) if err != nil { return err } return nil } func PublicPostCheck(c *gin.Context) (*models.UserFollows, map[string]interface{}, bool) { uuid := c.GetHeader("User-User") user := repo.UserFollow.GetUser(global.DB, uuid) if user.Ip != c.ClientIP() { c.JSON(200, gin.H{"message": "对方未关注你"}) return nil, nil, false } var msg = make(map[string]interface{}) if err := c.ShouldBind(&msg); err != nil { c.JSON(200, gin.H{"message": "输入异常"}) return nil, nil, false } return user, msg, true }