package simulation_service import ( "archive/zip" "context" "fmt" "github.com/cloudwego/hertz/pkg/app" "io" "net/http" "os" "path/filepath" "pji_desktop_http/biz/dal/mysql" "pji_desktop_http/common/config" "pji_desktop_http/common/config/c_log" "pji_desktop_http/common/util" ) // DownloadSimulationZipFile 根据请求id从oss拉取并打包仿真测试所需要的文件 // @router /simulation/download/zipfile [GET] func DownloadSimulationZipFile(ctx context.Context, c *app.RequestContext) { id := c.Query("id") fmt.Println(id) // 根据id生成用于地图更新的压缩包 filePath, tmpDir, err := generateSimulationZipById(ctx, id) if err != nil { c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()}) } fmt.Println("filePath", filePath) // 检查文件是否存在 if _, err := os.Stat(filePath); os.IsNotExist(err) { c.JSON(http.StatusNotFound, map[string]string{"error": "File not found"}) return } // 打开文件 f, err := os.Open(filePath) if err != nil { c.JSON(http.StatusInternalServerError, map[string]string{"error": "Failed to open file"}) return } defer f.Close() // 设置响应头 c.Response.Header.Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, filepath.Base(filePath))) c.Response.Header.Set("Content-Type", "binary/octet-stream") // 将文件流式传输回客户端 data, err := io.ReadAll(f) if err != nil { panic(err) } if _, err := c.Write(data); err != nil { c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } defer os.RemoveAll(tmpDir) } // 根据id生成用于仿真测试的压缩包 func generateSimulationZipById(ctx context.Context, id string) (file string, tmpDir string, err error) { // 根据id获取对应的oss文件列表 allFileList, err := util.GetExactedMapFileById(id) //fmt.Println("Filtered Strings:", fileList) if err != nil { return } // 创建临时文件夹 tmpDir, err = os.MkdirTemp("", "temp-download-*") fmt.Println("tmpDir:", tmpDir) if err != nil { fmt.Println("Error creating temporary directory:", err) return "", "", err } c_log.GlobalLogger.Info("创建下载-临时文件夹:", tmpDir) // 创建根文件夹(文件打包的根目录) baseDir := filepath.Join(tmpDir, "data") if err := os.Mkdir(baseDir, 0755); err != nil { fmt.Println("Error creating subdirectory:", err) return "", "", err } c_log.GlobalLogger.Info("创建文件打包根目录:", baseDir) // 从oss下载data.zip文件到根目录(data.zip中的mapBuf文件夹包含map.pgm, map.yaml) // 过滤特定后缀的文件列表 simulationFileList := util.FilterBySuffixes(allFileList, config.SimulationFiltersuffixes...) // 从oss下载文件到 根目录 for _, file := range simulationFileList { err = config.OssBucket.GetObjectToFile(file, filepath.Join(baseDir, filepath.Base(file))) if err != nil { fmt.Println("Error downloading mapBuf file:", err) return "", "", err } } c_log.GlobalLogger.Info("下载data.zip文件到根目录 - 成功") // 下载world文件 // 查询状态 world, err := mysql.QueryWorld(ctx, id) if err != nil || world == nil { // 文件不存在 c_log.GlobalLogger.Info("world文件不存在 - 跳过") } else { // 文件存在 // 下载文件 worldURL := world.WorldURL err = config.OssBucket.GetObjectToFile(worldURL, filepath.Join(baseDir, filepath.Base(worldURL))) if err != nil { fmt.Println("Error downloading world file:", err) return "", "", err } c_log.GlobalLogger.Info("下载world文件到根目录 - 成功") } // 创建压缩文件 zipPath := filepath.Join(tmpDir, "simulationFile-"+id+".zip") zipFile, err := os.Create(zipPath) if err != nil { fmt.Println("Error creating ZIP file:", err) return "", "", err } defer zipFile.Close() zipWriter := zip.NewWriter(zipFile) defer zipWriter.Close() // 压缩文件夹 if err := util.AddDirToZip(baseDir, zipWriter); err != nil { fmt.Println("Error adding directory to ZIP:", err) return "", "", err } fmt.Println("ZIP file created successfully.") c_log.GlobalLogger.Info("创建压缩文件 - 成功") return zipPath, tmpDir, nil }