package oss import ( "fmt" "net/http" "os" "path/filepath" "time" "gitea.com/bitwsd/document_ai/config" "gitea.com/bitwsd/document_ai/internal/storage/dao" "gitea.com/bitwsd/document_ai/pkg/common" "gitea.com/bitwsd/document_ai/pkg/constant" "gitea.com/bitwsd/document_ai/pkg/oss" "gitea.com/bitwsd/document_ai/pkg/utils" "github.com/gin-gonic/gin" "gorm.io/gorm" ) func GetPostObjectSignature(ctx *gin.Context) { policyToken, err := oss.GetPolicyToken() if err != nil { ctx.JSON(http.StatusOK, common.ErrorResponse(ctx, common.CodeSystemError, err.Error())) return } ctx.JSON(http.StatusOK, common.SuccessResponse(ctx, policyToken)) } // GetSignatureURL handles the request to generate a signed URL for a file upload. // @Summary Generate signed URL for file upload // @Description This endpoint generates a signed URL for uploading a file to the OSS (Object Storage Service). // @Tags file // @Accept json // @Produce json // @Param hash query string true "Hash value of the file" // @Success 200 {object} common.Response{data=map[string]string{"sign_url":string, "repeat":bool, "path":string}} "Signed URL generated successfully" // @Failure 200 {object} common.Response "Error response" // @Router /signature_url [get] func GetSignatureURL(ctx *gin.Context) { userID := ctx.GetInt64(constant.ContextUserID) type Req struct { FileHash string `json:"file_hash" binding:"required"` FileName string `json:"file_name" binding:"required"` } req := Req{} err := ctx.BindJSON(&req) if err != nil { ctx.JSON(http.StatusOK, common.ErrorResponse(ctx, common.CodeParamError, "param error")) return } taskDao := dao.NewRecognitionTaskDao() sess := dao.DB.WithContext(ctx) task, err := taskDao.GetTaskByFileURL(sess, userID, req.FileHash) if err != nil && err != gorm.ErrRecordNotFound { ctx.JSON(http.StatusOK, common.ErrorResponse(ctx, common.CodeDBError, "failed to get task")) return } if task.ID != 0 { ctx.JSON(http.StatusOK, common.SuccessResponse(ctx, gin.H{"sign_url": "", "repeat": true, "path": task.FileURL})) return } extend := filepath.Ext(req.FileName) if extend == "" { ctx.JSON(http.StatusOK, common.ErrorResponse(ctx, common.CodeParamError, "invalid file name")) return } if !utils.InArray(extend, []string{".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".webp"}) { ctx.JSON(http.StatusOK, common.ErrorResponse(ctx, common.CodeParamError, "invalid file type")) return } path := filepath.Join(oss.FormulaDir, fmt.Sprintf("%s%s", utils.NewUUID(), extend)) url, err := oss.GetPolicyURL(ctx, path) if err != nil { ctx.JSON(http.StatusOK, common.ErrorResponse(ctx, common.CodeSystemError, err.Error())) return } ctx.JSON(http.StatusOK, common.SuccessResponse(ctx, gin.H{"sign_url": url, "repeat": false, "path": path})) } func UploadFile(ctx *gin.Context) { if err := os.MkdirAll(config.GlobalConfig.UploadDir, 0755); err != nil { ctx.JSON(http.StatusOK, common.ErrorResponse(ctx, common.CodeSystemError, "Failed to create upload directory")) return } // Get file from form file, err := ctx.FormFile("file") if err != nil { ctx.JSON(http.StatusOK, common.ErrorResponse(ctx, common.CodeParamError, "File is required")) return } // Generate unique filename with timestamp ext := filepath.Ext(file.Filename) filename := fmt.Sprintf("%d%s", time.Now().UnixNano(), ext) filepath := filepath.Join(config.GlobalConfig.UploadDir, filename) // Save file if err := ctx.SaveUploadedFile(file, filepath); err != nil { ctx.JSON(http.StatusOK, common.ErrorResponse(ctx, common.CodeSystemError, "Failed to save file")) return } // Return success with file path ctx.JSON(http.StatusOK, common.SuccessResponse(ctx, gin.H{"sign_url": filepath})) }