From 81729bc718f768c3d3a239ac0291919320d5d22b Mon Sep 17 00:00:00 2001 From: Havoc412 <2993167370@qq.com> Date: Fri, 18 Oct 2024 20:51:40 +0800 Subject: [PATCH] add upload dir_name --- app/http/controller/web/upload_controller.go | 9 ++++++++- .../common/upload_files/upload_files.go | 15 +++++++++++++++ config/config.yml | 4 ++-- routers/web.go | 2 -- .../81a7b72779ac672f600f921d98e6eab9.jpg | Bin 633320 -> 0 bytes 5 files changed, 25 insertions(+), 5 deletions(-) delete mode 100644 storage/app/uploaded/2024_10/81a7b72779ac672f600f921d98e6eab9.jpg diff --git a/app/http/controller/web/upload_controller.go b/app/http/controller/web/upload_controller.go index db80a55..53a039a 100644 --- a/app/http/controller/web/upload_controller.go +++ b/app/http/controller/web/upload_controller.go @@ -16,7 +16,14 @@ type Upload struct { // // 开始上传 func (u *Upload) StartUpload(context *gin.Context) { - savePath := variable.BasePath + variable.ConfigYml.GetString("FileUploadSetting.UploadFileSavePath") + // TODO 如果之后要存储到 Linux 服务器上特殊路径下,就需要修改这里。 + dir_name := context.GetString(consts.ValidatorPrefix + "dir_name") + // 检查 dir_name 是否以 / 结尾,如果不是则补充一个 / + if len(dir_name) > 0 && dir_name[len(dir_name)-1] != '/' { + dir_name += "/" + } + + savePath := variable.BasePath + variable.ConfigYml.GetString("FileUploadSetting.UploadFileSavePath") + dir_name if r, finnalSavePath := upload_file.Upload(context, savePath); r == true { response.Success(context, consts.CurdStatusOkMsg, finnalSavePath) } else { diff --git a/app/http/validator/common/upload_files/upload_files.go b/app/http/validator/common/upload_files/upload_files.go index 437bfe3..20b63b6 100644 --- a/app/http/validator/common/upload_files/upload_files.go +++ b/app/http/validator/common/upload_files/upload_files.go @@ -4,6 +4,7 @@ import ( "catface/app/global/consts" "catface/app/global/variable" "catface/app/http/controller/web" + "catface/app/http/validator/core/data_transfer" "catface/app/utils/files" "catface/app/utils/response" "strconv" @@ -13,10 +14,24 @@ import ( ) type UpFiles struct { + DirName string `form:"dir_name" json:"dir_name"` } // 文件上传公共模块表单参数验证器 func (u UpFiles) CheckParams(context *gin.Context) { + // 1.基本的验证规则没有通过 + if err := context.ShouldBind(&u); err != nil { + response.ValidatorError(context, err) + return + } + // 该函数主要是将本结构体的字段(成员)按照 consts.ValidatorPrefix+ json标签对应的 键 => 值 形式绑定在上下文,便于下一步(控制器)可以直接通过 context.Get(键) 获取相关值 + extraAddBindDataContext := data_transfer.DataAddContext(u, consts.ValidatorPrefix, context) + if extraAddBindDataContext == nil { + response.ErrorSystem(context, "animialList表单验证器json化失败", "") + return + } + + // 2. File 内容的验证; tmpFile, err := context.FormFile(variable.ConfigYml.GetString("FileUploadSetting.UploadFileField")) // file 是一个文件结构体(文件对象) var isPass bool //获取文件发生错误,可能上传了空文件等 diff --git a/config/config.yml b/config/config.yml index 510aef8..fad66c2 100644 --- a/config/config.yml +++ b/config/config.yml @@ -57,8 +57,8 @@ SnowFlake: FileUploadSetting: Size: 32 #设置上传文件的最大值,单位:M,注意: 如果go前置nginx服务器,nginx 默认限制文件上传大小为 50 M ,用户上传文件限制还需要继续修改 nginx 配置 UploadFileField: "file" #post上传文件时,表单的键名 - UploadFileSavePath: "/storage/app/uploaded/" #上传文件保存在路径, 该路径与 BasePath 进行拼接使用 - UploadFileReturnPath: "/public/storage/uploaded/" # 文件上后返回的路径,由于程序会自动创建软连接,自动将资源定位到实际路径,所有资源的访问入口建议都从public开始 + UploadFileSavePath: "/public/nginx/" #上传文件保存在路径, 该路径与 BasePath 进行拼接使用 + UploadFileReturnPath: "" # 文件上后返回的路径,由于程序会自动创建软连接,自动将资源定位到实际路径,所有资源的访问入口建议都从public开始 AllowMimeType: #允许的文件mime类型列表 - "image/jpeg" #jpg、jpeg图片格式 - "image/png" #png图片格式 diff --git a/routers/web.go b/routers/web.go index c6748d5..10e772e 100644 --- a/routers/web.go +++ b/routers/web.go @@ -3,12 +3,10 @@ package routers import ( "catface/app/global/consts" "catface/app/global/variable" - // "catface/app/http/controller/captcha" // 验证码组件 // "catface/app/http/middleware/authorization" "catface/app/http/middleware/cors" validatorFactory "catface/app/http/validator/core/factory" - // TODO validatorFactory "catface/app/http/validator/core/factory" "catface/app/utils/gin_release" "net/http" diff --git a/storage/app/uploaded/2024_10/81a7b72779ac672f600f921d98e6eab9.jpg b/storage/app/uploaded/2024_10/81a7b72779ac672f600f921d98e6eab9.jpg deleted file mode 100644 index a77cf6194aff2c314ff2030e17cdf6221e9b3647..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 633320 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