|
@@ -3,6 +3,7 @@ package simulation_service
|
|
|
import (
|
|
|
"archive/zip"
|
|
|
"context"
|
|
|
+ "encoding/json"
|
|
|
"fmt"
|
|
|
"github.com/cloudwego/hertz/pkg/app"
|
|
|
"github.com/cloudwego/hertz/pkg/protocol/consts"
|
|
@@ -331,3 +332,160 @@ func AddSimulationRecord(ctx context.Context, c *app.RequestContext) {
|
|
|
}
|
|
|
c.JSON(consts.StatusOK, entity.HttpResult{Status: true, Code: "", Message: "仿真测试记录添加成功"})
|
|
|
}
|
|
|
+
|
|
|
+// QueryEvalRecord 查询算法评价记录(根据场景id及时间戳)
|
|
|
+// @router /simulation/query/eval/record [GET]
|
|
|
+func QueryEvalRecord(ctx context.Context, c *app.RequestContext) {
|
|
|
+ sceneId := c.Query("sceneId")
|
|
|
+ fmt.Println("sceneId", sceneId)
|
|
|
+
|
|
|
+ testTime := c.Query("testTime")
|
|
|
+ fmt.Println("testTime", testTime)
|
|
|
+
|
|
|
+ records, err := mysql.QuerySimulationTestRecords(ctx, sceneId, testTime)
|
|
|
+ if err != nil {
|
|
|
+ c.JSON(consts.StatusOK, entity.HttpResult{Status: false, Code: "", Message: "仿真测试记录查询失败", Details: ""})
|
|
|
+ return
|
|
|
+ }
|
|
|
+ output, err := json.Marshal(records)
|
|
|
+ if err != nil {
|
|
|
+ c.JSON(consts.StatusOK, entity.HttpResult{Status: false, Code: "", Message: "仿真测试记录查询失败", Details: ""})
|
|
|
+ return
|
|
|
+ }
|
|
|
+ c.JSON(consts.StatusOK, entity.HttpResult{Status: true, Code: "", Message: "仿真测试记录查询成功", Details: string(output)})
|
|
|
+}
|
|
|
+
|
|
|
+// DownloadFileByKeys 给定object key数组从oss下载(打包)文件
|
|
|
+// @router /simulation/download/oss/key [POST]
|
|
|
+func DownloadFileByKeys(ctx context.Context, c *app.RequestContext) {
|
|
|
+ sceneId := c.Query("sceneId")
|
|
|
+ fmt.Println("sceneId", sceneId)
|
|
|
+
|
|
|
+ typeName := c.Query("typeName")
|
|
|
+ fmt.Println("typeName", typeName)
|
|
|
+
|
|
|
+ var req []string
|
|
|
+ err := c.BindAndValidate(&req)
|
|
|
+ if err != nil {
|
|
|
+ c.String(consts.StatusBadRequest, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ fmt.Println("req", req)
|
|
|
+ if len(req) == 0 {
|
|
|
+ c.JSON(consts.StatusBadRequest, entity.HttpResult{Status: false, Code: "", Message: "请求数据为空。"})
|
|
|
+ } else if len(req) == 1 { // 只有一条数据则直接下载文件
|
|
|
+ objectKey := req[0]
|
|
|
+ // 从OSS下载文件
|
|
|
+ reader, err := config.OssBucket.GetObject(objectKey)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
|
|
|
+ return
|
|
|
+ }
|
|
|
+ defer reader.Close()
|
|
|
+
|
|
|
+ // 设置响应头
|
|
|
+ c.Response.Header.Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, filepath.Base(objectKey)))
|
|
|
+ c.Response.Header.Set("Content-Type", "binary/octet-stream")
|
|
|
+
|
|
|
+ // 将文件流式传输回客户端
|
|
|
+ data, err := io.ReadAll(reader)
|
|
|
+ if err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+ if _, err := c.Write(data); err != nil {
|
|
|
+ c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
|
|
|
+ return
|
|
|
+ }
|
|
|
+ } else { // 多条数据先打包后下载文件
|
|
|
+ fileName := sceneId + "_" + typeName + ".zip"
|
|
|
+ filePath, tmpDir, err := generateZipByKey(ctx, req, fileName)
|
|
|
+ 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)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 根据object keys生成压缩包
|
|
|
+func generateZipByKey(ctx context.Context, keys []string, fileName string) (file string, tmpDir string, err error) {
|
|
|
+ // 创建临时文件夹
|
|
|
+ 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下载文件到根目录
|
|
|
+ for _, file := range keys {
|
|
|
+ err = config.OssBucket.GetObjectToFile(file, filepath.Join(baseDir, filepath.Base(file)))
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("Error downloading file:", file, err)
|
|
|
+ return "", "", err
|
|
|
+ }
|
|
|
+ }
|
|
|
+ c_log.GlobalLogger.Info("下载oss文件到根目录 - 成功")
|
|
|
+
|
|
|
+ // 创建压缩文件
|
|
|
+ zipPath := filepath.Join(tmpDir, fileName)
|
|
|
+ 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
|
|
|
+}
|