mirror of
https://gitlab.52pay.top/go/easygoadmin.git
synced 2025-09-27 03:48:27 +08:00
fix: 增加基于mongodb的图片模型
增加基于mongodb的图片模型
This commit is contained in:
44
app/controller/img.go
Normal file
44
app/controller/img.go
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"gitlab.52pay.top/go/easygoadmin/app/model"
|
||||||
|
"gitlab.52pay.top/go/easygoadmin/utils/common"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Img = new(img)
|
||||||
|
|
||||||
|
type img struct{}
|
||||||
|
|
||||||
|
func (c *img) Image(ctx *gin.Context) {
|
||||||
|
mode := ctx.Param("mode")
|
||||||
|
if mode == "" {
|
||||||
|
ctx.JSON(http.StatusOK, common.JsonResult{
|
||||||
|
Code: -1,
|
||||||
|
Msg: "业务类型不能为空",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
filename := ctx.Param("filename")
|
||||||
|
if filename == "" {
|
||||||
|
ctx.JSON(http.StatusOK, common.JsonResult{
|
||||||
|
Code: -1,
|
||||||
|
Msg: "业务类型不能为空",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
image := &model.UserImage{}
|
||||||
|
err := image.GetByPath(fmt.Sprintf("%s/%s", mode, filename))
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(http.StatusOK, common.JsonResult{
|
||||||
|
Code: -1,
|
||||||
|
Msg: "图片不存在",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
contentType := http.DetectContentType(image.Image)
|
||||||
|
ctx.Data(200, contentType, image.Image)
|
||||||
|
}
|
@@ -19,7 +19,7 @@ var Upload = new(uploadCtl)
|
|||||||
|
|
||||||
type uploadCtl struct{}
|
type uploadCtl struct{}
|
||||||
|
|
||||||
func (c *uploadCtl) UploadImage(ctx *gin.Context) {
|
func (u *uploadCtl) UploadImage(ctx *gin.Context) {
|
||||||
// 调用上传方法
|
// 调用上传方法
|
||||||
result, err := service.Upload.UploadImage(ctx)
|
result, err := service.Upload.UploadImage(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -40,3 +40,33 @@ func (c *uploadCtl) UploadImage(ctx *gin.Context) {
|
|||||||
Data: result,
|
Data: result,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *uploadCtl) UploadImage2Db(ctx *gin.Context) {
|
||||||
|
typ := ctx.Param("typ")
|
||||||
|
if typ == "" {
|
||||||
|
ctx.JSON(http.StatusOK, common.JsonResult{
|
||||||
|
Code: -1,
|
||||||
|
Msg: "业务类型不能为空",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 调用上传方法
|
||||||
|
result, err := service.Upload.UploadImage2Db(ctx, typ)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(http.StatusOK, common.JsonResult{
|
||||||
|
Code: -1,
|
||||||
|
Msg: err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拼接图片地址
|
||||||
|
result.FileUrl = utils.GetImageUrl(result.FileUrl)
|
||||||
|
|
||||||
|
// 返回结果
|
||||||
|
ctx.JSON(http.StatusOK, common.JsonResult{
|
||||||
|
Code: 0,
|
||||||
|
Msg: "上传成功",
|
||||||
|
Data: result,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
95
app/model/user_image.go
Normal file
95
app/model/user_image.go
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"gitlab.52pay.top/go/easygoadmin/library/cfg"
|
||||||
|
"gitlab.52pay.top/go/easygoadmin/utils"
|
||||||
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var userImageTable *mongo.Collection
|
||||||
|
var ctx context.Context
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
config := cfg.Instance()
|
||||||
|
tableName := fmt.Sprintf("%suser_images", config.Mongodb.Prev)
|
||||||
|
userImageTable = utils.Mongodb.Collection(tableName)
|
||||||
|
ctx = context.Background()
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserImage struct {
|
||||||
|
_id primitive.ObjectID
|
||||||
|
Image []byte
|
||||||
|
Model string
|
||||||
|
MId string
|
||||||
|
FileType string
|
||||||
|
Attr string
|
||||||
|
Created time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserImage) Insert() (string, error) {
|
||||||
|
result, err := userImageTable.InsertOne(ctx, u)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
u._id = result.InsertedID.(primitive.ObjectID)
|
||||||
|
return u.Id(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserImage) Get(id string) error {
|
||||||
|
objectId, err := primitive.ObjectIDFromHex(id)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("输入ID非法,err: %s", err.Error())
|
||||||
|
}
|
||||||
|
result := userImageTable.FindOne(ctx, bson.D{{"_id", objectId}})
|
||||||
|
if result == nil {
|
||||||
|
return fmt.Errorf("查询失败")
|
||||||
|
}
|
||||||
|
if result.Err() != nil {
|
||||||
|
return fmt.Errorf("查询失败, err: %s", result.Err())
|
||||||
|
}
|
||||||
|
if err := result.Decode(u); err != nil {
|
||||||
|
return fmt.Errorf("解析失败,err: %s", err.Error())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserImage) Id() string {
|
||||||
|
return u._id.Hex()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserImage) FileName() string {
|
||||||
|
return fmt.Sprintf("%s%s", u.Id(), u.FileType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserImage) Url() string {
|
||||||
|
return fmt.Sprintf("/img/%s/%s", u.Model, u.FileName())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserImage) GetByPath(path string) error {
|
||||||
|
parts := strings.Split(path, "/")
|
||||||
|
if len(parts) != 2 {
|
||||||
|
return fmt.Errorf("路径非法%s", path)
|
||||||
|
}
|
||||||
|
mode := parts[0]
|
||||||
|
subPars := strings.Split(parts[1], ".")
|
||||||
|
if len(subPars) != 2 {
|
||||||
|
return fmt.Errorf("文件格式非法%s", path)
|
||||||
|
}
|
||||||
|
id := subPars[0]
|
||||||
|
fileExt := "." + subPars[1]
|
||||||
|
err := u.Get(id)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("图片读取错误,err: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if fileExt != u.FileType || mode != u.Model {
|
||||||
|
return fmt.Errorf("图片不存在")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@@ -8,12 +8,14 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"gitlab.52pay.top/go/easygoadmin/app/model"
|
||||||
"gitlab.52pay.top/go/easygoadmin/utils"
|
"gitlab.52pay.top/go/easygoadmin/utils"
|
||||||
"gitlab.52pay.top/go/easygoadmin/utils/gconv"
|
"gitlab.52pay.top/go/easygoadmin/utils/gconv"
|
||||||
"gitlab.52pay.top/go/easygoadmin/utils/gregex"
|
"gitlab.52pay.top/go/easygoadmin/utils/gregex"
|
||||||
"gitlab.52pay.top/go/easygoadmin/utils/gstr"
|
"gitlab.52pay.top/go/easygoadmin/utils/gstr"
|
||||||
|
"io"
|
||||||
|
"mime/multipart"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -33,39 +35,42 @@ type FileInfo struct {
|
|||||||
FileType string `json:"fileType"`
|
FileType string `json:"fileType"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *uploadService) UploadImage(ctx *gin.Context) (FileInfo, error) {
|
func (s *uploadService) UploadImage2Db(ctx *gin.Context, typ string) (result FileInfo, err error) {
|
||||||
if utils.AppDebug() {
|
ginFile, fileExt, err := getFile(ctx)
|
||||||
return FileInfo{}, errors.New("演示环境,暂无权限操作")
|
|
||||||
}
|
|
||||||
// 获取文件(注意这个地方的file要和html模板中的name一致)
|
|
||||||
file, err := ctx.FormFile("file")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return FileInfo{}, errors.New("上传文件不能为空")
|
return
|
||||||
}
|
}
|
||||||
//获取文件名称
|
file, err := ginFile.Open()
|
||||||
fmt.Println(file.Filename)
|
if err != nil {
|
||||||
//文件大小
|
return
|
||||||
fmt.Println(file.Size)
|
}
|
||||||
//获取文件的后缀名
|
body, err := io.ReadAll(file)
|
||||||
fileExt := path.Ext(file.Filename)
|
if err != nil {
|
||||||
fmt.Println(fileExt)
|
return
|
||||||
|
}
|
||||||
|
image := model.UserImage{
|
||||||
|
Image: body,
|
||||||
|
Model: typ,
|
||||||
|
FileType: fileExt,
|
||||||
|
Created: time.Now(),
|
||||||
|
}
|
||||||
|
_, err = image.Insert()
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
return FileInfo{
|
||||||
|
FileName: image.FileName(),
|
||||||
|
FileSize: int64(len(image.Image)),
|
||||||
|
FileUrl: image.Url(),
|
||||||
|
FileType: image.FileType,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// 允许上传文件后缀
|
func (s *uploadService) UploadImage(ctx *gin.Context) (FileInfo, error) {
|
||||||
allowExt := "jpg,gif,png,bmp,jpeg,JPG"
|
file, fileExt, err := getFile(ctx)
|
||||||
// 检查上传文件后缀
|
|
||||||
if !checkFileExt(fileExt, allowExt) {
|
|
||||||
return FileInfo{}, errors.New("上传文件格式不正确,文件后缀只允许为:" + allowExt + "的文件")
|
|
||||||
}
|
|
||||||
// 允许文件上传最大值
|
|
||||||
allowSize := "1M"
|
|
||||||
// 检查上传文件大小
|
|
||||||
isvalid, err := checkFileSize(file.Size, allowSize)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return FileInfo{}, err
|
return FileInfo{}, err
|
||||||
}
|
}
|
||||||
if !isvalid {
|
|
||||||
return FileInfo{}, errors.New("上传文件大小不得超过:" + allowSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 临时存储目录
|
// 临时存储目录
|
||||||
savePath := utils.TempPath() + "/" + time.Now().Format("20060102")
|
savePath := utils.TempPath() + "/" + time.Now().Format("20060102")
|
||||||
@@ -139,3 +144,39 @@ func checkFileSize(fileSize int64, maxSize string) (bool, error) {
|
|||||||
}
|
}
|
||||||
return cfSize >= fileSize, nil
|
return cfSize >= fileSize, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getFile(ctx *gin.Context) (*multipart.FileHeader, string, error) {
|
||||||
|
if utils.AppDebug() {
|
||||||
|
return nil, "", errors.New("演示环境,暂无权限操作")
|
||||||
|
}
|
||||||
|
// 获取文件(注意这个地方的file要和html模板中的name一致)
|
||||||
|
file, err := ctx.FormFile("file")
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", errors.New("上传文件不能为空")
|
||||||
|
}
|
||||||
|
//获取文件名称
|
||||||
|
//fmt.Println(file.Filename)
|
||||||
|
//文件大小
|
||||||
|
//fmt.Println(file.Size)
|
||||||
|
//获取文件的后缀名
|
||||||
|
fileExt := path.Ext(file.Filename)
|
||||||
|
//fmt.Println(fileExt)
|
||||||
|
|
||||||
|
// 允许上传文件后缀
|
||||||
|
allowExt := "jpg,gif,png,bmp,jpeg,JPG"
|
||||||
|
// 检查上传文件后缀
|
||||||
|
if !checkFileExt(fileExt, allowExt) {
|
||||||
|
return nil, "", errors.New("上传文件格式不正确,文件后缀只允许为:" + allowExt + "的文件")
|
||||||
|
}
|
||||||
|
// 允许文件上传最大值
|
||||||
|
allowSize := "1M"
|
||||||
|
// 检查上传文件大小
|
||||||
|
isvalid, err := checkFileSize(file.Size, allowSize)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
if !isvalid {
|
||||||
|
return nil, "", errors.New("上传文件大小不得超过:" + allowSize)
|
||||||
|
}
|
||||||
|
return file, fileExt, nil
|
||||||
|
}
|
||||||
|
@@ -118,7 +118,7 @@ layui.use(['upload','croppers'],function(){
|
|||||||
,saveH:` + cropArr[1] + `
|
,saveH:` + cropArr[1] + `
|
||||||
,mark:` + cropRateStr + ` //选取比例
|
,mark:` + cropRateStr + ` //选取比例
|
||||||
,area:['750px','500px'] //弹窗宽度
|
,area:['750px','500px'] //弹窗宽度
|
||||||
,url: "/upload/uploadImage"
|
,url: "/upload/uploadImage2Db/` + name + `"
|
||||||
,done: function(url){
|
,done: function(url){
|
||||||
//上传完毕回调
|
//上传完毕回调
|
||||||
$('#` + name + `').val(url);
|
$('#` + name + `').val(url);
|
||||||
|
2
go.mod
2
go.mod
@@ -31,8 +31,8 @@ require (
|
|||||||
github.com/tebeka/strftime v0.1.5 // indirect
|
github.com/tebeka/strftime v0.1.5 // indirect
|
||||||
github.com/toolkits/file v0.0.0-20160325033739-a5b3c5147e07
|
github.com/toolkits/file v0.0.0-20160325033739-a5b3c5147e07
|
||||||
github.com/x-cray/logrus-prefixed-formatter v0.5.2
|
github.com/x-cray/logrus-prefixed-formatter v0.5.2
|
||||||
|
go.mongodb.org/mongo-driver v1.11.0 // indirect
|
||||||
go.opentelemetry.io/otel v1.8.0 // indirect
|
go.opentelemetry.io/otel v1.8.0 // indirect
|
||||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect
|
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
|
||||||
golang.org/x/text v0.3.7 // indirect
|
golang.org/x/text v0.3.7 // indirect
|
||||||
xorm.io/builder v0.3.9 // indirect
|
xorm.io/builder v0.3.9 // indirect
|
||||||
|
@@ -17,6 +17,15 @@ var (
|
|||||||
once sync.Once
|
once sync.Once
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func InstanceByPath(filePath string) *config {
|
||||||
|
var conf config
|
||||||
|
if _, err := toml.DecodeFile(filePath, &conf); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
instance = &conf
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
|
||||||
// 获取配置文档实例
|
// 获取配置文档实例
|
||||||
func Instance() *config {
|
func Instance() *config {
|
||||||
once.Do(func() {
|
once.Do(func() {
|
||||||
@@ -34,6 +43,7 @@ func Instance() *config {
|
|||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
Database database
|
Database database
|
||||||
|
Mongodb mongodb
|
||||||
Logger logger
|
Logger logger
|
||||||
EasyGoAdmin easygoadmin
|
EasyGoAdmin easygoadmin
|
||||||
RedisCfg redisCfg
|
RedisCfg redisCfg
|
||||||
@@ -47,6 +57,15 @@ type database struct {
|
|||||||
Prev string
|
Prev string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type mongodb struct {
|
||||||
|
Host string
|
||||||
|
Port int
|
||||||
|
User string
|
||||||
|
Password string
|
||||||
|
Database string
|
||||||
|
Prev string
|
||||||
|
}
|
||||||
|
|
||||||
type redisCfg struct {
|
type redisCfg struct {
|
||||||
Addr string
|
Addr string
|
||||||
Port int64
|
Port int64
|
||||||
|
@@ -56,6 +56,14 @@ func init() {
|
|||||||
{
|
{
|
||||||
// 上传图片
|
// 上传图片
|
||||||
upload.POST("/uploadImage", controller.Upload.UploadImage)
|
upload.POST("/uploadImage", controller.Upload.UploadImage)
|
||||||
|
// 上传图片,存到mongoDb
|
||||||
|
upload.POST("/uploadImage2Db/:typ", controller.Upload.UploadImage2Db)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mongodb图片 */
|
||||||
|
img := router.Group("img")
|
||||||
|
{
|
||||||
|
img.GET("/:mode/:filename", controller.Img.Image)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 登录注册 */
|
/* 登录注册 */
|
||||||
|
42
user_image_test.go
Normal file
42
user_image_test.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"gitlab.52pay.top/go/easygoadmin/app/model"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUserImage_Insert(t *testing.T) {
|
||||||
|
image := &model.UserImage{
|
||||||
|
Image: []byte("test image"),
|
||||||
|
Created: time.Now(),
|
||||||
|
}
|
||||||
|
_, err := image.Insert()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
t.Log("insert ok, id is", image.Id())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUserImage_Get(t *testing.T) {
|
||||||
|
image := &model.UserImage{
|
||||||
|
Image: []byte("test image"),
|
||||||
|
Model: "test",
|
||||||
|
MId: "123",
|
||||||
|
Created: time.Now(),
|
||||||
|
}
|
||||||
|
_, err := image.Insert()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
image2 := new(model.UserImage)
|
||||||
|
err = image2.Get(image.Id())
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
fmt.Println(image2.Model)
|
||||||
|
}
|
@@ -22,6 +22,9 @@ func init() {
|
|||||||
|
|
||||||
// 获取配置实例
|
// 获取配置实例
|
||||||
config := cfg.Instance()
|
config := cfg.Instance()
|
||||||
|
if config == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
var err error
|
var err error
|
||||||
XormDb, err = xorm.NewEngine("mysql", config.Database.Master)
|
XormDb, err = xorm.NewEngine("mysql", config.Database.Master)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
42
utils/mongodb.go
Normal file
42
utils/mongodb.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"gitlab.52pay.top/go/easygoadmin/library/cfg"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Mongodb *mongo.Database
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
logrus.Info("初始化并连接mongodb")
|
||||||
|
config := cfg.Instance()
|
||||||
|
uri := fmt.Sprintf("mongodb://%s:%s@%s:%d",
|
||||||
|
config.Mongodb.User,
|
||||||
|
config.Mongodb.Password,
|
||||||
|
config.Mongodb.Host,
|
||||||
|
config.Mongodb.Port)
|
||||||
|
clientOpt := options.Client().
|
||||||
|
ApplyURI(uri)
|
||||||
|
cli, err := mongo.Connect(context.Background(), clientOpt)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("mongo数据库连接错误:%v", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通过engine.Ping()来进行数据库的连接测试是否可以连接到数据库。
|
||||||
|
err = cli.Ping(context.Background(), nil)
|
||||||
|
if err == nil {
|
||||||
|
logrus.Info("mongo数据库连接成功")
|
||||||
|
//关闭连接
|
||||||
|
//defer XormDb.Close()
|
||||||
|
} else {
|
||||||
|
logrus.Errorf("mongo数据库连接错误:%v", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Mongodb = cli.Database(config.Mongodb.Database)
|
||||||
|
}
|
Reference in New Issue
Block a user