完成了分享下载全部流程

This commit is contained in:
2024-10-12 13:37:49 +08:00
parent e6f5aaa02f
commit 7862b1d88e
11 changed files with 342 additions and 30 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ type BaseCardService struct{}
var BaseCard = &BaseCardService{}
func (*BaseCardService) Create(db *gorm.DB, baseCard models.BaseCard) {
repo.BaseCard.Create(db, &baseCard)
repo.BaseCard.CreateOrSave(db, &baseCard)
}
func (*BaseCardService) Update(db *gorm.DB, updateCard models.BaseCard) {
+145 -1
View File
@@ -1,9 +1,17 @@
package service
import (
"archive/zip"
"context"
"encoding/json"
"fmt"
"fyne.io/fyne/v2/data/binding"
"io"
"net/http"
"os"
"path/filepath"
"time"
"work_cation/cfg"
"work_cation/models"
)
@@ -14,7 +22,13 @@ var Client = &ClientService{}
func (c *ClientService) GetUser(online *models.Online) (*models.Users, error) {
var user models.Users
resp, err := http.Get(online.Url("/user"))
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
}
@@ -29,3 +43,133 @@ func (c *ClientService) GetUser(online *models.Online) (*models.Users, error) {
}
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.Remove(downloadFile)
}
file, err := os.Create(downloadFile)
if err != nil {
return err
}
defer file.Close()
r := Rr{
file: file,
tot: resp.ContentLength,
progress: 0,
oneUp: 0,
progressBind: progress,
}
_, err = io.Copy(&r, resp.Body)
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.Remove(downloadFile)
return nil
}
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
}
+1 -1
View File
@@ -39,7 +39,7 @@ func (*erlangCardService) Create(erlangCard *models.ErlangCards) error {
return global.DB.Transaction(func(tx *gorm.DB) error {
var baseCard = erlangCard.BaseCard
err = repo.BaseCard.Create(global.DB, &baseCard)
err = repo.BaseCard.CreateOrSave(global.DB, &baseCard)
return err
})
}
+1 -1
View File
@@ -49,6 +49,6 @@ func (*ExecFileService) Create(info *models.ExecFiles, chooseDir string) error {
}
return global.DB.Transaction(func(tx *gorm.DB) error {
var baseCard = info.BaseCard
return repo.BaseCard.Create(tx, &baseCard)
return repo.BaseCard.CreateOrSave(tx, &baseCard)
})
}
+80 -1
View File
@@ -1,10 +1,15 @@
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/repo"
@@ -52,11 +57,35 @@ func (s *serverService) StatusOffline() error {
}
func (s *serverService) StartListenServer() error {
router := gin.New()
router := gin.Default()
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)
fmt.Println("card:", card)
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
}
})
srv := &http.Server{
Addr: cfg.T.ServerAddr,
@@ -71,3 +100,53 @@ func (s *serverService) StartListenServer() error {
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
}
+16 -15
View File
@@ -4,13 +4,14 @@ import (
"context"
"fmt"
"github.com/grandcat/zeroconf"
"time"
"slices"
"work_cation/cfg"
"work_cation/models"
)
type zeroconfService struct {
server *zeroconf.Server
server *zeroconf.Server
onlines []models.Online
}
var Zeroconf = &zeroconfService{}
@@ -37,31 +38,31 @@ func (s *zeroconfService) Close() {
}
// FindService 查找被发现服务
func (s *zeroconfService) FindService() (chan *models.Online, error) {
func (s *zeroconfService) FindService() ([]models.Online, error) {
return s.onlines, nil
}
func (s *zeroconfService) StartFindService() error {
resolver, err := zeroconf.NewResolver(nil)
if err != nil {
return nil, err
return err
}
allEntries := make(chan *zeroconf.ServiceEntry)
useEntries := make(chan *models.Online)
go func(results <-chan *zeroconf.ServiceEntry) {
for entry := range results {
fmt.Println(entry.AddrIPv4, entry.ServiceInstanceName())
if entry.ServiceInstanceName() == fmt.Sprintf("%s._http._tcp.local.", cfg.T.ZeroconfKey) {
online, err := models.NewOnline(entry)
if err != nil {
continue
}
useEntries <- online
delOnlines := slices.DeleteFunc(s.onlines, func(item models.Online) bool {
return item.ID == online.ID
})
s.onlines = append(delOnlines, *online)
}
}
}(allEntries)
ctx, cancel := context.WithCancel(context.Background())
err = resolver.Browse(ctx, "_http._tcp", "local.", allEntries)
if err != nil {
cancel()
return nil, err
}
time.AfterFunc(10*time.Second, cancel)
return useEntries, nil
err = resolver.Browse(context.Background(), "_http._tcp", "local.", allEntries)
return err
}