mirror of
https://gitlab.52pay.top/go/easygoadmin.git
synced 2025-09-26 19:33:29 +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{}
|
||||
|
||||
func (c *uploadCtl) UploadImage(ctx *gin.Context) {
|
||||
func (u *uploadCtl) UploadImage(ctx *gin.Context) {
|
||||
// 调用上传方法
|
||||
result, err := service.Upload.UploadImage(ctx)
|
||||
if err != nil {
|
||||
@@ -40,3 +40,33 @@ func (c *uploadCtl) UploadImage(ctx *gin.Context) {
|
||||
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 (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gitlab.52pay.top/go/easygoadmin/app/model"
|
||||
"gitlab.52pay.top/go/easygoadmin/utils"
|
||||
"gitlab.52pay.top/go/easygoadmin/utils/gconv"
|
||||
"gitlab.52pay.top/go/easygoadmin/utils/gregex"
|
||||
"gitlab.52pay.top/go/easygoadmin/utils/gstr"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
@@ -33,39 +35,42 @@ type FileInfo struct {
|
||||
FileType string `json:"fileType"`
|
||||
}
|
||||
|
||||
func (s *uploadService) UploadImage(ctx *gin.Context) (FileInfo, error) {
|
||||
if utils.AppDebug() {
|
||||
return FileInfo{}, errors.New("演示环境,暂无权限操作")
|
||||
}
|
||||
// 获取文件(注意这个地方的file要和html模板中的name一致)
|
||||
file, err := ctx.FormFile("file")
|
||||
func (s *uploadService) UploadImage2Db(ctx *gin.Context, typ string) (result FileInfo, err error) {
|
||||
ginFile, fileExt, err := getFile(ctx)
|
||||
if err != nil {
|
||||
return FileInfo{}, errors.New("上传文件不能为空")
|
||||
return
|
||||
}
|
||||
//获取文件名称
|
||||
fmt.Println(file.Filename)
|
||||
//文件大小
|
||||
fmt.Println(file.Size)
|
||||
//获取文件的后缀名
|
||||
fileExt := path.Ext(file.Filename)
|
||||
fmt.Println(fileExt)
|
||||
file, err := ginFile.Open()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
body, err := io.ReadAll(file)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
// 允许上传文件后缀
|
||||
allowExt := "jpg,gif,png,bmp,jpeg,JPG"
|
||||
// 检查上传文件后缀
|
||||
if !checkFileExt(fileExt, allowExt) {
|
||||
return FileInfo{}, errors.New("上传文件格式不正确,文件后缀只允许为:" + allowExt + "的文件")
|
||||
}
|
||||
// 允许文件上传最大值
|
||||
allowSize := "1M"
|
||||
// 检查上传文件大小
|
||||
isvalid, err := checkFileSize(file.Size, allowSize)
|
||||
func (s *uploadService) UploadImage(ctx *gin.Context) (FileInfo, error) {
|
||||
file, fileExt, err := getFile(ctx)
|
||||
if err != nil {
|
||||
return FileInfo{}, err
|
||||
}
|
||||
if !isvalid {
|
||||
return FileInfo{}, errors.New("上传文件大小不得超过:" + allowSize)
|
||||
}
|
||||
|
||||
// 临时存储目录
|
||||
savePath := utils.TempPath() + "/" + time.Now().Format("20060102")
|
||||
@@ -139,3 +144,39 @@ func checkFileSize(fileSize int64, maxSize string) (bool, error) {
|
||||
}
|
||||
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] + `
|
||||
,mark:` + cropRateStr + ` //选取比例
|
||||
,area:['750px','500px'] //弹窗宽度
|
||||
,url: "/upload/uploadImage"
|
||||
,url: "/upload/uploadImage2Db/` + name + `"
|
||||
,done: function(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/toolkits/file v0.0.0-20160325033739-a5b3c5147e07
|
||||
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
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
xorm.io/builder v0.3.9 // indirect
|
||||
|
@@ -17,6 +17,15 @@ var (
|
||||
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 {
|
||||
once.Do(func() {
|
||||
@@ -34,6 +43,7 @@ func Instance() *config {
|
||||
|
||||
type config struct {
|
||||
Database database
|
||||
Mongodb mongodb
|
||||
Logger logger
|
||||
EasyGoAdmin easygoadmin
|
||||
RedisCfg redisCfg
|
||||
@@ -47,6 +57,15 @@ type database struct {
|
||||
Prev string
|
||||
}
|
||||
|
||||
type mongodb struct {
|
||||
Host string
|
||||
Port int
|
||||
User string
|
||||
Password string
|
||||
Database string
|
||||
Prev string
|
||||
}
|
||||
|
||||
type redisCfg struct {
|
||||
Addr string
|
||||
Port int64
|
||||
|
@@ -56,6 +56,14 @@ func init() {
|
||||
{
|
||||
// 上传图片
|
||||
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()
|
||||
if config == nil {
|
||||
return
|
||||
}
|
||||
var err error
|
||||
XormDb, err = xorm.NewEngine("mysql", config.Database.Master)
|
||||
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