LicenseManger/internal/api/upload.go

214 lines
5.1 KiB
Go
Raw Normal View History

2024-11-14 14:55:43 +00:00
package api
import (
"fmt"
"licserver/internal/service"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/gin-gonic/gin"
)
type UploadHandler struct {
uploadService *service.UploadService
}
func NewUploadHandler(uploadService *service.UploadService) *UploadHandler {
return &UploadHandler{uploadService: uploadService}
}
func (h *UploadHandler) UploadFile(c *gin.Context) {
file, err := c.FormFile("file")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "未找到上传文件"})
return
}
deviceUID := c.PostForm("device_uid")
description := c.PostForm("description")
userID := c.GetUint("userID")
upload, err := h.uploadService.UploadFile(file, userID, deviceUID, description)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, upload)
}
func (h *UploadHandler) DownloadFile(c *gin.Context) {
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的文件ID"})
return
}
file, err := h.uploadService.DownloadFile(uint(id))
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "文件不存在"})
return
}
c.FileAttachment(file.FilePath, file.FileName)
}
func (h *UploadHandler) DeleteFile(c *gin.Context) {
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的文件ID"})
return
}
userID := c.GetUint("userID")
if err := h.uploadService.DeleteFile(uint(id), userID); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "文件删除成功"})
}
func (h *UploadHandler) GetDeviceFiles(c *gin.Context) {
deviceUID := c.Param("uid")
files, err := h.uploadService.GetDeviceFiles(deviceUID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, files)
}
func (h *UploadHandler) UploadChunk(c *gin.Context) {
file, err := c.FormFile("chunk")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "未找到上传文件"})
return
}
fileHash := c.PostForm("fileHash")
if fileHash == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "未提供文件哈希"})
return
}
chunkNumber, err := strconv.Atoi(c.PostForm("chunkNumber"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的分片序号"})
return
}
totalChunks, err := strconv.Atoi(c.PostForm("totalChunks"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的总分片数"})
return
}
totalSize, err := strconv.ParseInt(c.PostForm("totalSize"), 10, 64)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的文件大小"})
return
}
filename := c.PostForm("filename")
deviceUID := c.PostForm("deviceUID")
userID := c.GetUint("userID")
err = h.uploadService.UploadChunk(
file,
fileHash,
chunkNumber,
totalChunks,
totalSize,
filename,
userID,
deviceUID,
)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// 检查是否所有分片都已上传
completed, err := h.uploadService.CheckUploadStatus(fileHash)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"message": "分片上传成功",
"completed": completed,
})
}
func (h *UploadHandler) MergeChunks(c *gin.Context) {
fileHash := c.PostForm("fileHash")
if fileHash == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "未提供文件哈希"})
return
}
upload, err := h.uploadService.MergeChunks(fileHash)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"message": "文件合并成功",
"file": upload,
})
}
func (h *UploadHandler) UploadSiteFile(c *gin.Context) {
file, err := c.FormFile("file")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "未找到上传文件"})
return
}
// 检查文件类型
ext := strings.ToLower(filepath.Ext(file.Filename))
allowedExts := map[string]bool{
".jpg": true, ".jpeg": true, ".png": true, ".gif": true,
".ico": true, ".svg": true,
}
if !allowedExts[ext] {
c.JSON(http.StatusBadRequest, gin.H{"error": "不支持的文件类型"})
return
}
// 生成文件名
filename := fmt.Sprintf("site_%s%s", time.Now().Format("20060102150405"), ext)
// 构建目标目录路径
uploadDir := filepath.Join("web", "static", "images")
if err := os.MkdirAll(uploadDir, 0755); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "创建目录失败"})
return
}
// 构建完整的文件路径
filePath := filepath.Join(uploadDir, filename)
// 保存文件
if err := c.SaveUploadedFile(file, filePath); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "保存文件失败"})
return
}
// 返回文件URL使用正斜杠作为URL路径分隔符
fileURL := "/" + strings.Join([]string{"static", "images", filename}, "/")
c.JSON(http.StatusOK, gin.H{
"url": fileURL,
"message": "文件上传成功",
})
}