后端接收ok
This commit is contained in:
@@ -13,7 +13,11 @@
|
||||
"file_mime_err":-51,
|
||||
"file_size_err":-52,
|
||||
"file_name_err":-53,
|
||||
"file_get_err":-54
|
||||
"file_get_err":-54,
|
||||
"file_hash_err":-55,
|
||||
"file_save_err":-56,
|
||||
"file_not_found":-57,
|
||||
"file_part_err":-58
|
||||
|
||||
|
||||
}
|
||||
@@ -16,7 +16,7 @@ type TabFileInfo_ struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement"`
|
||||
Name string `gorm:"not null;size:256;index"` // 前端报告的文件名
|
||||
Path string `gorm:"not null;size:300"` //
|
||||
Sha256 string `gorm:"not null;size:256;index"` //
|
||||
Sha256 string `gorm:"not null;size:64;index"` //
|
||||
Mime string `gorm:"size:64;index"`
|
||||
Type string `gorm:"size:64;index"`
|
||||
Const uint `gorm:"default:1;index"`
|
||||
|
||||
+146
-13
@@ -1,7 +1,11 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"ops/models"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -11,22 +15,151 @@ func file_save() {
|
||||
}
|
||||
|
||||
func ApiFiles(r *gin.RouterGroup) {
|
||||
r.POST("/upload", func(ctx *gin.Context) {
|
||||
|
||||
cookie := ctx.PostForm("cookie")
|
||||
file, _ := ctx.FormFile("file")
|
||||
//通过cookie获取用户信息
|
||||
_, err := AuthenticationAuthorityFromCookie(cookie)
|
||||
if err == nil {
|
||||
//getfile := r.Group("/get") //定义上传组
|
||||
r.GET("/:mode/:hash", func(ctx *gin.Context) {
|
||||
hash := ctx.Param("hash")
|
||||
mode := ctx.Param("mode")
|
||||
// filename := ctx.Param("filename")
|
||||
// fmt.Println(filename)
|
||||
|
||||
download := false
|
||||
isPartOK := false
|
||||
|
||||
if mode == "get" {
|
||||
isPartOK = true
|
||||
download = true
|
||||
}
|
||||
if mode == "download" {
|
||||
isPartOK = true
|
||||
download = false
|
||||
}
|
||||
if isPartOK {
|
||||
file_info := models.TabFileInfo_{
|
||||
Sha256: hash,
|
||||
}
|
||||
if models.DB.Where(&file_info).First(&file_info).Error == nil {
|
||||
ReturnFile(ctx, &file_info, download)
|
||||
} else {
|
||||
//fmt.Println("not fund")
|
||||
ReturnJson(ctx, "file_not_found", nil)
|
||||
}
|
||||
} else {
|
||||
ReturnJson(ctx, "file_part_err", nil)
|
||||
}
|
||||
|
||||
fmt.Println(file.Filename)
|
||||
fmt.Println(cookie)
|
||||
ReturnJson(ctx, "apiOK", nil)
|
||||
})
|
||||
r.GET("/upload", func(ctx *gin.Context) {
|
||||
ReturnJson(ctx, "apiOK", nil)
|
||||
})
|
||||
|
||||
upload := r.Group("/upload") //定义上传组
|
||||
//上传文件的总接口,能上传什么文件应该由后端决定,前端仅做相应限制
|
||||
|
||||
upload.POST("/image", func(ctx *gin.Context) {
|
||||
|
||||
cookie := ctx.PostForm("cookie") //首先需要判断用户是否登录
|
||||
|
||||
//通过cookie获取用户信息
|
||||
user, err := AuthenticationAuthorityFromCookie(cookie)
|
||||
if err == nil {
|
||||
file, err := ctx.FormFile("file")
|
||||
|
||||
if err == nil {
|
||||
if file.Filename != "" {
|
||||
//限制文件大小
|
||||
if file.Size > 512 {
|
||||
if file.Size < int64(models.ConfigsFile.MaxSize) {
|
||||
|
||||
//判断文件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)
|
||||
file_extname := models.ConfigsFile.AllowImageMime[mimeType]
|
||||
if file_extname != "" {
|
||||
filename := filepath.Base(file.Filename) // 防御性处理路径分隔符
|
||||
// 计算哈希值
|
||||
hash_str, err := models.SHA256HashFile(file)
|
||||
if err == nil {
|
||||
//fmt.Println(hash_str)
|
||||
//fmt.Println(filename)
|
||||
//这是上传的真实路径
|
||||
dst := path.Join(models.ConfigsFile.Pahts["image"], hash_str)
|
||||
//fmt.Println(dst)
|
||||
//判断文件是否存在避免重复保存
|
||||
if models.FileExists(dst) {
|
||||
//fmt.Println("文件存在")
|
||||
|
||||
} else {
|
||||
//fmt.Println("文件no存在")
|
||||
ferr := ctx.SaveUploadedFile(file, dst)
|
||||
if ferr == nil {
|
||||
//文件保存成功
|
||||
|
||||
} else {
|
||||
|
||||
ReturnJson(ctx, "file_save_err", nil)
|
||||
ctx.Abort() //end
|
||||
return
|
||||
}
|
||||
}
|
||||
//记录到数据库
|
||||
//先检查数据库有没有数据
|
||||
fund_file_info := models.TabFileInfo_{
|
||||
Name: filename,
|
||||
Sha256: hash_str,
|
||||
Mime: mimeType,
|
||||
Type: "image",
|
||||
UserID: user.ID,
|
||||
}
|
||||
fund_file_info2 := models.TabFileInfo_{}
|
||||
|
||||
models.DB.Where(&fund_file_info).Find(&fund_file_info2)
|
||||
|
||||
if fund_file_info2.ID != 0 {
|
||||
fund_file_info2.Const += 1
|
||||
models.DB.Where(&fund_file_info).Updates(&fund_file_info2)
|
||||
} else {
|
||||
fund_file_info.Path = dst
|
||||
models.DB.Create(&fund_file_info) // 传入指针
|
||||
}
|
||||
|
||||
ReturnJson(ctx, "apiOK", nil)
|
||||
|
||||
} else {
|
||||
ReturnJson(ctx, "file_hash_err", nil)
|
||||
}
|
||||
|
||||
} else {
|
||||
ReturnJson(ctx, "file_mime_err", nil)
|
||||
}
|
||||
} else {
|
||||
ReturnJson(ctx, "file_size_err", nil)
|
||||
}
|
||||
|
||||
} else {
|
||||
ReturnJson(ctx, "file_size_err", nil)
|
||||
}
|
||||
|
||||
} else {
|
||||
ReturnJson(ctx, "file_name_err", nil)
|
||||
}
|
||||
|
||||
} else {
|
||||
ReturnJson(ctx, "file_get_err", nil)
|
||||
}
|
||||
|
||||
} else {
|
||||
ReturnJson(ctx, "userCookieError", nil)
|
||||
}
|
||||
|
||||
ReturnJson(ctx, "apiErr", nil)
|
||||
})
|
||||
|
||||
// r.GET("/upload", func(ctx *gin.Context) {
|
||||
// ReturnJson(ctx, "apiOK", nil)
|
||||
// })
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package routers
|
||||
|
||||
import "github.com/gin-gonic/gin"
|
||||
import (
|
||||
"ops/models"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func ReturnJson(ctx *gin.Context, errMsg string, data map[string]interface{}) {
|
||||
var errCode = ErrorCode[errMsg]
|
||||
@@ -23,12 +27,12 @@ func ReturnJson(ctx *gin.Context, errMsg string, data map[string]interface{}) {
|
||||
|
||||
}
|
||||
|
||||
func Return_file(ctx *gin.Context, file_path string, preview bool) {
|
||||
func ReturnFile(ctx *gin.Context, file_info *models.TabFileInfo_, preview bool) {
|
||||
if preview {
|
||||
ctx.File(file_path)
|
||||
ctx.File(file_info.Path)
|
||||
} else {
|
||||
//需要从数据库拉取原始文件名
|
||||
//ctx.FileAttachment(file_info.Path, file_info.Name)
|
||||
ctx.FileAttachment(file_info.Path, file_info.Name)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,11 @@ const prop= defineProps({
|
||||
maxFilesize:{
|
||||
type: Number,
|
||||
default: 10,
|
||||
}
|
||||
},
|
||||
uploadURL:{
|
||||
type: String,
|
||||
default: "/api/files/upload",
|
||||
},
|
||||
});
|
||||
|
||||
// 初始化 Dropzone
|
||||
@@ -41,7 +45,7 @@ const initDropzone = () => {
|
||||
|
||||
// 初始化新的实例
|
||||
dropzoneInstance = new Dropzone(dropzoneElement.value, {
|
||||
url: "/api/files/upload", // 上传地址
|
||||
url: prop.uploadURL, // 上传地址
|
||||
// headers: {
|
||||
// user_cookie: "cccc",
|
||||
// },
|
||||
|
||||
@@ -139,13 +139,14 @@ watch(locale, () => {
|
||||
>{{ t("purchase_addorder.remarks") }}
|
||||
<span class="form-label-description">0/100</span></label
|
||||
>
|
||||
<useDropzone></useDropzone>
|
||||
<textarea
|
||||
class="form-control mt-2"
|
||||
class="form-control mt-2 mb-2"
|
||||
name="example-textarea-input"
|
||||
rows="6"
|
||||
:placeholder="t('purchase_addorder.remarks_text')"
|
||||
></textarea>
|
||||
<useDropzone acceptedFiles="image/*" uploadURL="/api/files/upload/image" maxFiles="10"></useDropzone>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user