后端接收ok
This commit is contained in:
@@ -13,7 +13,11 @@
|
|||||||
"file_mime_err":-51,
|
"file_mime_err":-51,
|
||||||
"file_size_err":-52,
|
"file_size_err":-52,
|
||||||
"file_name_err":-53,
|
"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"`
|
ID uint `gorm:"primaryKey;autoIncrement"`
|
||||||
Name string `gorm:"not null;size:256;index"` // 前端报告的文件名
|
Name string `gorm:"not null;size:256;index"` // 前端报告的文件名
|
||||||
Path string `gorm:"not null;size:300"` //
|
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"`
|
Mime string `gorm:"size:64;index"`
|
||||||
Type string `gorm:"size:64;index"`
|
Type string `gorm:"size:64;index"`
|
||||||
Const uint `gorm:"default:1;index"`
|
Const uint `gorm:"default:1;index"`
|
||||||
|
|||||||
+143
-10
@@ -1,7 +1,11 @@
|
|||||||
package routers
|
package routers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"ops/models"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
@@ -11,22 +15,151 @@ func file_save() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ApiFiles(r *gin.RouterGroup) {
|
func ApiFiles(r *gin.RouterGroup) {
|
||||||
r.POST("/upload", func(ctx *gin.Context) {
|
|
||||||
|
|
||||||
cookie := ctx.PostForm("cookie")
|
//getfile := r.Group("/get") //定义上传组
|
||||||
file, _ := ctx.FormFile("file")
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
upload := r.Group("/upload") //定义上传组
|
||||||
|
//上传文件的总接口,能上传什么文件应该由后端决定,前端仅做相应限制
|
||||||
|
|
||||||
|
upload.POST("/image", func(ctx *gin.Context) {
|
||||||
|
|
||||||
|
cookie := ctx.PostForm("cookie") //首先需要判断用户是否登录
|
||||||
|
|
||||||
//通过cookie获取用户信息
|
//通过cookie获取用户信息
|
||||||
_, err := AuthenticationAuthorityFromCookie(cookie)
|
user, err := AuthenticationAuthorityFromCookie(cookie)
|
||||||
if err == nil {
|
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) // 传入指针
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(file.Filename)
|
|
||||||
fmt.Println(cookie)
|
|
||||||
ReturnJson(ctx, "apiOK", nil)
|
|
||||||
})
|
|
||||||
r.GET("/upload", func(ctx *gin.Context) {
|
|
||||||
ReturnJson(ctx, "apiOK", nil)
|
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
|
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{}) {
|
func ReturnJson(ctx *gin.Context, errMsg string, data map[string]interface{}) {
|
||||||
var errCode = ErrorCode[errMsg]
|
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 {
|
if preview {
|
||||||
ctx.File(file_path)
|
ctx.File(file_info.Path)
|
||||||
} else {
|
} 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:{
|
maxFilesize:{
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 10,
|
default: 10,
|
||||||
}
|
},
|
||||||
|
uploadURL:{
|
||||||
|
type: String,
|
||||||
|
default: "/api/files/upload",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 初始化 Dropzone
|
// 初始化 Dropzone
|
||||||
@@ -41,7 +45,7 @@ const initDropzone = () => {
|
|||||||
|
|
||||||
// 初始化新的实例
|
// 初始化新的实例
|
||||||
dropzoneInstance = new Dropzone(dropzoneElement.value, {
|
dropzoneInstance = new Dropzone(dropzoneElement.value, {
|
||||||
url: "/api/files/upload", // 上传地址
|
url: prop.uploadURL, // 上传地址
|
||||||
// headers: {
|
// headers: {
|
||||||
// user_cookie: "cccc",
|
// user_cookie: "cccc",
|
||||||
// },
|
// },
|
||||||
|
|||||||
@@ -139,13 +139,14 @@ watch(locale, () => {
|
|||||||
>{{ t("purchase_addorder.remarks") }}
|
>{{ t("purchase_addorder.remarks") }}
|
||||||
<span class="form-label-description">0/100</span></label
|
<span class="form-label-description">0/100</span></label
|
||||||
>
|
>
|
||||||
<useDropzone></useDropzone>
|
|
||||||
<textarea
|
<textarea
|
||||||
class="form-control mt-2"
|
class="form-control mt-2 mb-2"
|
||||||
name="example-textarea-input"
|
name="example-textarea-input"
|
||||||
rows="6"
|
rows="6"
|
||||||
:placeholder="t('purchase_addorder.remarks_text')"
|
:placeholder="t('purchase_addorder.remarks_text')"
|
||||||
></textarea>
|
></textarea>
|
||||||
|
<useDropzone acceptedFiles="image/*" uploadURL="/api/files/upload/image" maxFiles="10"></useDropzone>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user