123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- package controllers
- import (
- "fmt"
- "io"
- "log"
- "mime/multipart"
- "net/http"
- "os"
- "path/filepath"
- "strings"
- "time"
- "xugu_license/internal/global"
- "xugu_license/internal/models"
- "xugu_license/internal/module/xlsx"
- "xugu_license/internal/utils"
- "github.com/gin-gonic/gin"
- )
- type fileInfo struct {
- fileName string
- fileSize int64
- fileMd5 string
- buf *os.File
- mf *multipart.File
- }
- func UploadfileHandler(c *gin.Context) {
- userAny, exists := c.Get("userInfo")
- if !exists {
- c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
- c.Abort()
- return
- }
- userInfo := userAny.(*models.UserInfo)
- //接收文件 //检查文件
- file, err := checkUploadFile(c)
- if err != nil {
- global.Logger.Errorln("检测上传文件不为xlsx格式 ", err.Error())
- c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintln("检测上传文件不为xlsx格式: ", err.Error())})
- return
- }
- //保存文件
- saveFile(file)
- //解析文件
- lics, err := xlsx.XlsxController(file.mf)
- if err != nil {
- global.Logger.Errorln("解析文件失败 ", err.Error())
- c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintln("解析文件失败: ", err.Error())})
- return
- }
- //插入数据到数据库
- for _, lic := range lics {
- err = models.InsertLicenseApplicationAndInfoRow(lic, userInfo.Id, userInfo.Username)
- if err != nil {
- global.Logger.Errorln("插入数据失败 ", err.Error())
- c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintln("插入数据失败: ", err.Error())})
- return
- }
- }
- //生成license
- // for _, lic := range lics {
- // pI := license.ProjectInfo{
- // ProjectName: lic.ProductName,
- // UserName: lic.AssociatedProject,
- // UserAddr: "",
- // SerialNumber: "",
- // }
- // eI := license.EnvironmentInfo{
- // CpuSN: "",
- // BaseboardSN: "",
- // MacAddr: lic.MasterMacAddress,
- // DiskID: "",
- // IPAddr: "",
- // }
- // //判断license类型
- // LicType := utils.SwitchLicenseType(lic.Version)
- // lI := license.LicenseInfo{
- // GenDate: "2024-07-15",
- // ExpireDate: "9999-12-31",
- // LicenseType: LicType,
- // LicenseVersion: 1,
- // HardType: 3,
- // }
- // licStr := license.GenerateLicense(pI, eI, lI)
- // fmt.Println("生成的license为:", licStr)
- // //生成副主节点license
- // var licStr2 []byte
- // if lic.SecondaryMasterMacAddress != "" {
- // eI.MacAddr = lic.SecondaryMasterMacAddress
- // licStr2 = license.GenerateLicense(pI, eI, lI)
- // }
- // xlsx.ExcelToMail(lic, licStr, licStr2)
- // }
- file.buf.Close()
- }
- // UploadFile 处理文件上传
- func checkUploadFile(c *gin.Context) (*fileInfo, error) {
- // 获取上传的文件
- file, err := c.FormFile("file")
- if err != nil {
- global.Logger.Errorln("未收到文件 ", err.Error())
- c.JSON(http.StatusBadRequest, gin.H{"error": "服务器未收到文件"})
- return nil, err
- }
- // 检查文件扩展名是否为xlsx
- ext := strings.ToLower(filepath.Ext(file.Filename))
- if ext != ".xlsx" {
- global.Logger.Errorln("文件格式不为xlsx ", err.Error())
- c.JSON(http.StatusBadRequest, gin.H{"error": "Only .xlsx files are allowed"})
- return nil, err
- }
- // 获取客户端发送的 MD5 值
- clientMd5 := c.PostForm("md5")
- if clientMd5 == "" {
- global.Logger.Errorln("md5不存在 ")
- c.JSON(http.StatusBadRequest, gin.H{"error": "MD5 value is required"})
- return nil, err
- }
- // 计算文件的 MD5 值
- fileMd5, err := utils.CalculateFileHeaderMd5(file)
- if err != nil {
- global.Logger.Errorln("计算文件md5失败 ", err.Error())
- c.JSON(http.StatusInternalServerError, gin.H{"error": "Unable to calculate MD5"})
- return nil, err
- }
- // 比较 MD5 值
- if fileMd5 != clientMd5 {
- // 删除保存的文件
- //os.Remove(filePath)
- global.Logger.Errorln("文件md5不一致 ")
- c.JSON(http.StatusBadRequest, gin.H{"error": "MD5 mismatch"})
- return nil, err
- }
- // 将 *multipart.FileHeader 转换为 *os.File
- tempFile, err := fileHeaderToOsFile(file)
- if err != nil {
- global.Logger.Errorln(" *multipart.FileHeader 转换为 *os.File 失败")
- c.JSON(http.StatusInternalServerError, gin.H{"error": "Unable to convert uploaded file to *os.File"})
- return nil, err
- }
- //defer tempFile.Close()
- c.JSON(http.StatusOK, gin.H{"message": "File uploaded successfully", "file": file.Filename})
- src, err := file.Open()
- if err != nil {
- global.Logger.Errorln("src, err := file.Open()失败 ", err.Error())
- return nil, err
- }
- return &fileInfo{fileName: file.Filename, fileSize: file.Size, fileMd5: fileMd5, buf: tempFile, mf: &src}, nil
- }
- // 保存文件
- func saveFile(file *fileInfo) error {
- // 确保保存文件的目录存在
- saveDir := "files"
- if err := os.MkdirAll(saveDir, os.ModePerm); err != nil {
- log.Fatal(err)
- }
- // 生成新的文件名
- originalFileName := file.fileName
- ext := filepath.Ext(originalFileName)
- name := strings.TrimSuffix(originalFileName, ext)
- timestamp := time.Now().Format("20060102_150405")
- newFileName := utils.GenerateFileName(name, timestamp, ext)
- filePath := filepath.Join(saveDir, newFileName)
- // 保存文件
- // 创建目标文件
- dst, err := os.Create(filePath)
- if err != nil {
- global.Logger.Errorln("创建文件失败", err.Error())
- return err
- }
- defer dst.Close()
- // 将内容从 src 复制到 dst
- fmt.Println("file.buf", file.buf)
- if _, err := io.Copy(dst, file.buf); err != nil {
- global.Logger.Errorln("内容从 src 复制到 dst", err.Error())
- return err
- }
- return nil
- }
- // fileHeaderToOsFile 将 *multipart.FileHeader 转换为 *os.File
- func fileHeaderToOsFile(fileHeader *multipart.FileHeader) (*os.File, error) {
- src, err := fileHeader.Open()
- if err != nil {
- global.Logger.Errorln("*multipart.FileHeader 转换为 *os.File失败", err.Error())
- return nil, err
- }
- defer src.Close()
- // 创建临时文件
- tempFile, err := os.CreateTemp("", "upload-*.xlsx")
- if err != nil {
- global.Logger.Errorln("创建临时文件失败", err.Error())
- return nil, err
- }
- // 将内容从 src 复制到 tempFile
- if _, err := io.Copy(tempFile, src); err != nil {
- global.Logger.Errorln("内容从 src 复制到 tempFile失败", err.Error())
- tempFile.Close()
- return nil, err
- }
- // 将文件指针移回文件开头
- if _, err := tempFile.Seek(0, 0); err != nil {
- tempFile.Close()
- global.Logger.Errorln("将文件指针移回文件开头失败", err.Error())
- return nil, err
- }
- return tempFile, nil
- }
|