package service import ( "archive/zip" "bytes" "context" "encoding/json" "fmt" "fyne.io/fyne/v2/data/binding" "github.com/gin-gonic/gin" "io" "net/http" "os" "path/filepath" "time" "work_cation/cfg" "work_cation/global" "work_cation/models" "work_cation/repo" ) type ClientService struct { } var Client = &ClientService{} func (c *ClientService) GetUser(online *models.Online) (*models.Users, error) { var user models.Users ctx, carnal := context.WithTimeout(context.TODO(), time.Millisecond*500) defer carnal() res, err := http.NewRequestWithContext(ctx, "", online.Url("/user"), nil) if err != nil { return nil, err } resp, err := http.DefaultClient.Do(res) if err != nil { return nil, err } defer resp.Body.Close() data, err := io.ReadAll(resp.Body) if err != nil { return nil, err } err = json.Unmarshal(data, &user) if err != nil { return nil, err } return &user, nil } func (c *ClientService) GetCards(online *models.Online) ([]models.BaseCard, error) { var cards []models.BaseCard ctx, carnal := context.WithTimeout(context.TODO(), time.Millisecond*500) defer carnal() res, err := http.NewRequestWithContext(ctx, "", online.Url("/cards"), nil) if err != nil { return nil, err } resp, err := http.DefaultClient.Do(res) if err != nil { return nil, err } defer resp.Body.Close() data, err := io.ReadAll(resp.Body) if err != nil { return nil, err } err = json.Unmarshal(data, &cards) if err != nil { return nil, err } return cards, nil } func (c *ClientService) Download(online *models.Online, uuid string, progress binding.Float) error { resp, err := http.Get(online.Url("/download/card/" + uuid)) if err != nil { return err } defer resp.Body.Close() downloadFile := filepath.Join(cfg.T.CardDir, fmt.Sprintf("%s.zip", uuid)) _, err = os.Stat(downloadFile) if err == nil { os.RemoveAll(downloadFile) } file, err := os.Create(downloadFile) if err != nil { return err } r := Rr{ file: file, tot: resp.ContentLength, progress: 0, oneUp: 0, progressBind: progress, } _, err = io.Copy(&r, resp.Body) file.Close() if err != nil { return err } // 解压 destDir := filepath.Join(cfg.T.CardDir, uuid) _ = os.RemoveAll(destDir) if err = unzipFile(downloadFile, destDir); err != nil { return err } _ = os.RemoveAll(downloadFile) return nil } func (c *ClientService) Chat(online *models.Online, text string) (string, error) { var user = repo.User.GetUserInfo(global.DB) ctx, carnal := context.WithTimeout(context.TODO(), time.Millisecond*500) defer carnal() b, err := json.Marshal(gin.H{"text": text, "uuid": user.ID}) if err != nil { return "", err } res, err := http.NewRequestWithContext(ctx, "POST", online.Url("/chat"), bytes.NewBuffer(b)) if err != nil { return "", err } res.Header.Set("Content-Type", "application/json") res.Header.Set("User-ID", user.ID) resp, err := http.DefaultClient.Do(res) if err != nil { return "", err } defer resp.Body.Close() data, err := io.ReadAll(resp.Body) var msg = make(map[string]any) if err = json.Unmarshal(data, &msg); err != nil { return "", err } return msg["message"].(string), err } type Rr struct { file *os.File tot int64 progress int64 oneUp int progressBind binding.Float } func (r *Rr) Write(p []byte) (n int, err error) { n, err = r.file.Write(p) if err != nil { return } r.progress += int64(n) nowUp := int(r.progress * 100 / r.tot) if nowUp != r.oneUp { r.progressBind.Set(float64(nowUp)) r.oneUp = nowUp } return } func unzipFile(zipFile, destDir string) error { // 打开ZIP文件 r, err := zip.OpenReader(zipFile) if err != nil { return err } defer r.Close() // 创建目标目录 err = os.MkdirAll(destDir, os.ModePerm) if err != nil { return err } // 遍历ZIP文件中的文件并解压缩到目标目录 for _, f := range r.File { rc, err := f.Open() if err != nil { return err } // 创建文件 path := filepath.Join(destDir, f.Name) if f.FileInfo().IsDir() { os.MkdirAll(path, os.ModePerm) } else { // 创建文件 file, err := os.Create(path) if err != nil { return err } _, err = io.Copy(file, rc) if err != nil { return err } file.Close() } rc.Close() } return nil }