package routers import ( "crypto/sha256" "encoding/hex" "fmt" "io" "net/http" "path" "path/filepath" "saas/models" "github.com/gin-gonic/gin" "github.com/mitchellh/mapstructure" ) func V1_file_api(r *gin.RouterGroup) { r.GET("/", func(ctx *gin.Context) { Return_json(ctx, "json_error", nil) }) //文件api是一定要登录的,直接用中间件判断登录状态 // r.Use(func(ctx *gin.Context) { // Use_is_login(ctx) // }) r.Use(func(ctx *gin.Context) { fmt.Println("file_api") cookie := ctx.PostForm("cookie") var cookie_t models.Cookie if err := mapstructure.Decode(cookie, &cookie_t); err == nil { if cookie_t.Value != "" { cookie_vel := cookie_t.Value fmt.Println(cookie_vel) } } //fmt.Println(cookie) file, err := ctx.FormFile("file") if err == nil { fmt.Println(file) } else { fmt.Println(err) } }) r.POST("/upload", func(ctx *gin.Context) { //先判断有没有登录 //获取中间件处理的结果 _, is_login := ctx.Get("user_info") if is_login { Return_json(ctx, "api_ok", nil) } else { Return_json(ctx, "user_no_sign", nil) } }) //接收头像的接口, r.POST("/avatar", func(ctx *gin.Context) { //返回前端的数据 err_msg := "user_api_error" err_code := Error_code[err_msg] data := map[string]interface{}{} //判断权限是否可以接收 //先判断是否已经登录 //获取中间件处理的结果 is_login, _ := ctx.Get("is_login") if is_login == true { //读取用户id信息 user, _ := ctx.Get("user") //保存这个头像 file, err := ctx.FormFile("file") if err == nil { //限制文件大小 if file.Size > 512 { if file.Size < 1024000 { // 2. 安全获取文件名并处理路径问题 filename := filepath.Base(file.Filename) // 防御性处理路径分隔符 // 3. 获取标准后缀名(含点) extWithDot := filepath.Ext(filename) //判断后缀名类型是否是允许的 if models.Allowed_avatar_ext[extWithDot] { //判断文件mime是否合法 // 打开文件流 src_mime, _ := file.Open() defer src_mime.Close() // 读取前512字节用于MIME检测 buffer := make([]byte, 512) io.ReadFull(src_mime, buffer) // 检测MIME类型 mimeType := http.DetectContentType(buffer) if models.Allowed_avatar_mime[mimeType] { // 打开文件流 src, _ := file.Open() defer src.Close() // 创建SHA256哈希器 hasher := sha256.New() // 计算哈希值 io.Copy(hasher, src) // 获取哈希结果 hashBytes := hasher.Sum(nil) hashString := hex.EncodeToString(hashBytes) new_filename := fmt.Sprintf("%d_%s%s", user.(*models.User).ID, hashString, extWithDot) file.Filename = new_filename //这是上传的真实路径 dst := path.Join("./data/avatar", file.Filename) //这是经过gin路由的路径 gin_dat := path.Join("/avatar", file.Filename) //判断文件是否存在避免重复保存 if models.File_exists(dst) { //fmt.Println("文件存在") err_msg = "api_ok" err_code = Error_code[err_msg] //返回gin路由的路径 data["path"] = gin_dat data["new_path"] = false } else { //fmt.Println("文件no存在") ferr := ctx.SaveUploadedFile(file, dst) if ferr == nil { //文件保存成功 err_msg = "api_ok" err_code = Error_code[err_msg] //返回gin路由的路径 data["path"] = gin_dat data["new_path"] = true } else { err_msg = "file_save_err" err_code = Error_code[err_msg] fmt.Println(ferr) data["err"] = ferr } } } else { err_msg = "file_mime_err" err_code = Error_code[err_msg] } } else { err_msg = "file_type_err" err_code = Error_code[err_msg] } } else { err_msg = "file_size_err" err_code = Error_code[err_msg] } } else { err_msg = "file_size_err" err_code = Error_code[err_msg] } } else { err_msg = "file_get_err" err_code = Error_code[err_msg] } } else { err_msg = "user_no_sign" err_code = Error_code[err_msg] } ctx.JSON(200, map[string]interface{}{ "api": "ok", "err_code": err_code, "err_msg": err_msg, "data": data, }) }) }