Files
work_cation/service/client.go
T

207 lines
4.2 KiB
Go

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-UserID", 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
}