🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 【GoWeb开发实战Gin框架】微博项目实战-文件上传和图片展示功能 # 文件上传和图片展示 我们希望点击图片按钮的时候,可以显示已经上传的图片。 ## 一、创建数据表 首先我们要在数据库中创建数据表,要想存储图片,我们需要图片的id,图片的路径位置,图片的名字等等。所在在utils工具包下的mysqlUtil.go文件中,添加创建数据表的方法: ~~~go //--------图片-------- func CreateTableWithAlbum() { sql := `create table if not exists album( id int(4) primary key auto_increment not null, filepath varchar(255), filename varchar(64), status int(4), createtime int(10) );` ModifyDB(sql) } ~~~ 并且在初始化数据库的方法中进行调用: ~~~go func InitMysql() { fmt.Println("InitMysql....") if db == nil { db, _ = sql.Open("mysql", "root:hanru1314@tcp(127.0.0.1:3306)/blogweb_gin") CreateTableWithUser() CreateTableWithArticle() CreateTableWithAlbum() } } ~~~ ## 二、上传文件 ### 2.1 AlbumController 然后我们创建一个新的go文件,album\_controller.go ~~~go package controllers import ( "github.com/gin-gonic/gin" "net/http" ) func AlbumGet(c *gin.Context) { //获取session islogin := GetSession(c) c.HTML(http.StatusOK, "album.html", gin.H{"IsLogin": islogin}) } ~~~ ### 2.2 View 接下来我们去写html页面,在views目录下创建一个新的html页面(album.html): ~~~html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>相册</title> <script src="../static/js/lib/jquery-3.3.1.min.js"></script> <script src="../static/js/lib/jquery.url.js"></script> <script src="../static/js/blog.js"></script> <link href="../static/css/blogsheet.css" rel="stylesheet"> </head> <body> {{template "nav.html" .}} <div id="main"> <form method="post" enctype="multipart/form-data"> <input type="file" id="album-upload-file" name="upload"> <input type="button" id="album-upload-button" value="提交文件"> </form> </div> </body> </html> ~~~ 然后我们需要编写点击按钮之后的脚本代码,在blog.js文件中继续添加脚本: ~~~go //文件 $("#album-upload-button").click(function () { var filedata = $("#album-upload-file").val(); if (filedata.length <= 0) { alert("请选择文件!"); return } //文件上传通过Formdata去储存文件的数据 var data = new FormData() data.append("upload", $("#album-upload-file")[0].files[0]); alert(data) var urlStr = "/upload" $.ajax({ url: urlStr, type: "post", dataType: "json", contentType: false, data: data, processData: false, success: function (data, status) { alert(":data:" + data.message); if (data.code == 1) { setTimeout(function () { window.location.href = "/album" }, 1000) } }, error: function (data, status) { alert("err:" + data.message + ":" + status) } }) }) ~~~ ### 2.3 UploadController 此时我们需要新建一个文件上传的controller,upload\_controller.go ~~~go package controllers import ( "fmt" "time" "path/filepath" "os" "github.com/gin-gonic/gin" "net/http" "blogweb_gin/models" ) func UploadPost(c *gin.Context) { fmt.Println("fileupload...") fileHeader, err := c.FormFile("upload") if err != nil { responseErr(c, err) return } fmt.Println("name:", fileHeader.Filename, fileHeader.Size) now := time.Now() fmt.Println("ext:", filepath.Ext(fileHeader.Filename)) fileType := "other" //判断后缀为图片的文件,如果是图片我们才存入到数据库中 fileExt := filepath.Ext(fileHeader.Filename) if fileExt == ".jpg" || fileExt == ".png" || fileExt == ".gif" || fileExt == ".jpeg" { fileType = "img" } //文件夹路径 fileDir := fmt.Sprintf("static/upload/%s/%d/%d/%d", fileType, now.Year(), now.Month(), now.Day()) //ModePerm是0777,这样拥有该文件夹路径的执行权限 err = os.MkdirAll(fileDir, os.ModePerm) if err != nil { responseErr(c, err) return } //文件路径 timeStamp := time.Now().Unix() fileName := fmt.Sprintf("%d-%s", timeStamp, fileHeader.Filename) filePathStr := filepath.Join(fileDir, fileName) //将浏览器客户端上传的文件拷贝到本地路径的文件里面,此处也可以使用io操作 c.SaveUploadedFile(fileHeader,filePathStr) if fileType == "img" { album := models.Album{0, filePathStr, fileName, 0, timeStamp} models.InsertAlbum(album) } c.JSON(http.StatusOK, gin.H{"code": 1, "message": "上传成功"}) } func responseErr(c *gin.Context, err error) { c.JSON(http.StatusOK, gin.H{"code": 0, "message": err}) } ~~~ 最后要注册路由: ~~~go //相册 router.GET("/album",controllers.AlbumGet) //文件上传 router.POST("/upload",controllers.UploadPost) ~~~ ### 2.4 Model 接下来我们创建一个新的model,album\_model.go文件: ~~~go type Album struct { Id int Filepath string Filename string Status int Createtime int64 } ~~~ 我们需要在album\_model.go文件中,添加插入数据的方法: ~~~go //-------插入图片--------------- func InsertAlbum(album Album) (int64, error) { return database.ModifyDB("insert into album(filepath,filename,status,createtime)values(?,?,?,?)", album.Filepath, album.Filename, album.Status, album.Createtime) } ~~~ ### 2.5 运行 重启项目后,点击图片按钮,然后选择一张图片: ![gin_yunxing73](http://image.chaindesk.cn/gin_yunxing73.png/mark) 点击提交文件按钮后,可以上传图片了。 ![gin_yunxing74](http://image.chaindesk.cn/gin_yunxing74.png/mark) 我们可以查询一下数据库: ![gin_yunxing75](http://image.chaindesk.cn/gin_yunxing75.png/mark) 发现已经添加了一条数据,打开项目目录,查看一下上传的文件: ![gin_yunxing76](http://image.chaindesk.cn/gin_yunxing76.png/mark) ## 三、查看图片 通过上面的操作已经能够上传文件了,那么如何显示文件呢?当点击图片标签的时候,除了有上传操作,还应该可以显示已经存储的图片。 ### 3.1 Model 我们现在album\_model.go文件中,添加查找图片数据的方法: ~~~go //--------查询图片---------- func FindAllAlbums() ([]Album, error) { rows, err := database.QueryDB("select id,filepath,filename,status,createtime from album") if err != nil { return nil, err } var albums []Album for rows.Next() { id := 0 filepath := "" filename := "" status := 0 var createtime int64 createtime = 0 rows.Scan(&id, &filepath, &filename, &status, &createtime) album := Album{id, filepath, filename, status, createtime} albums = append(albums, album) } return albums, nil } ~~~ ### 3.2 Controller 接下来,我们修改album\_controller.go文件中的AlbumGet()方法, ~~~go func AlbumGet(c *gin.Context) { //获取session islogin := GetSession(c) albums,_ := models.FindAllAlbums() c.HTML(http.StatusOK, "album.html", gin.H{"IsLogin": islogin,"Album":albums}) } ~~~ ### 3.3 View 最后我们还要修改一下html页面,在album.html中,添加以下内容: ~~~html <div id="album-box"> {{range .Album}} <div class="album-item" style='background-image: url("{{.Filepath}}");'></div> {{end}} </div> ~~~ ### 3.4 运行 我们上传几张图片后,刷新页面,点击图片按钮: ![gin_yunxing77](http://image.chaindesk.cn/gin_yunxing77.png/mark)