[golang gin框架] 15.Gin 商城项目-封装上传图片方法,轮播图的增删改查以及异步修改状态,数量

一.封装上传图片方法

在models/tools.go文件下封装一个上传图片的方法
//图片上传
func UploadImg(c *gin.Context, picName string) (string, error) {
   //1.获取上传文件
    file, err := c.FormFile(picName)
    //判断上传文件上否存在
    if err != nil { //说明上传文件不存在
        return "", nil
    }
    //2.获取后缀名,判断后缀是否正确: .jpg,.png,.gif,.jpeg
    extName := path.Ext(file.Filename)
    //设置后缀map
    allowExtMap := map[string]bool{
        ".jpg":  true,
        ".png":  true,
        ".gif":  true,
        ".jpeg": true,
    }
    //判断后缀是否合法
    if _, ok := allowExtMap[extName]; !ok {
        return "", errors.New("文件后缀名不合法")
    }
    //3.创建图片保存目录 ./static/upload/20230203
    //获取日期
    day := GetDay()
    //拼接目录
    dir := "./static/upload/" + day
    //创建目录:MkdirAll 目录不存在,会一次性创建多层
    err = os.MkdirAll(dir, 0666)
    if err != nil {
        return "", err
    }
    //4.生成文件名称和文件保存目录: models.GetUnixNano() 获取时间戳(int64) 纳秒:防止速度过快而上传图片失败; strconv.FormatInt() 把时间戳(int64)转换成字符串
    filename := strconv.FormatInt(GetUnixNano(), 10) + extName
    //5.执行上传
    dst := path.Join(dir, filename)
    //上传文件到指定目录
    c.SaveUploadedFile(file, dst)
    return dst, nil
}

//获取年月日
func GetDay() string {
    template := "20060102"
    return time.Now().Format(template)
}

二.轮播图的增删改查

  1. 创建轮播图模型

在models目录下创建focus.go轮播图模型
package models

//轮播图

type Focus struct {
    Id        int
    Title     string
    FocusType int  // 1 网站, 2 app, 3 小程序
    FocusImg  string
    Link      string
    Sort      int
    Status    int
    AddTime   int
}

func (Focus) TableName() string {
    return "focus"
}

2.创建轮播图控制器

在controllers/admin下创建FocusController.go轮播图控制器
package admin

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "goshop/models"
    "net/http"
    "os"
    "strings"
)

type FocusController struct {
    BaseController
}

func (con FocusController) Index(c *gin.Context) {
    //获取轮播图列表
    focusList := []models.Focus{}
    models.DB.Find(&focusList)
    c.HTML(http.StatusOK, "admin/focus/index.html", gin.H{
        "focusList": focusList,
    })
}

func (con FocusController) Add(c *gin.Context) {
    c.HTML(http.StatusOK, "admin/focus/add.html", gin.H{})
}

func (con FocusController) DoAdd(c *gin.Context) {
    //获取请求的表单数据
    title := strings.Trim(c.PostForm("title"), " ")
    focusType, err1 := models.Int(c.PostForm("focus_type"))
    link := strings.Trim(c.PostForm("link"), " ")
    sort, err2 := models.Int(c.PostForm("sort"))
    status, err3 := models.Int(c.PostForm("status"))

    if err1 != nil || err3 != nil {
        con.Error(c, "非法请求", "/admin/focus/add")
        return
    }
    if err2 != nil {
        con.Error(c, "请输入正确的排序值", "/admin/focus/add")
        return
    }

    //文件上传操作
    focusImgSrc, err := models.UploadImg(c, "focus_img")
    if err != nil {
        con.Error(c, "图片上传失败", "/admin/focus/add")
        return
    }
    //实例化focus模型
    focus := models.Focus{
        Title:     title,
        FocusType: focusType,
        FocusImg:  focusImgSrc,
        Link:      link,
        Sort:      sort,
        Status:    status,
        AddTime:   int(models.GetUnix()),
    }
    err = models.DB.Create(&focus).Error
    if err != nil {
        con.Error(c, "增加轮播图失败", "/admin/focus/add")
        return
    }
    con.Success(c, "增加轮播图成功", "/admin/focus")
}

func (con FocusController) Edit(c *gin.Context) {
    //获取要修改的轮播图id
    id, err := models.Int(c.Query("id"))
    if err != nil {
        con.Error(c, "传入数据错误", "/admin/focus")
        return
    }
    focus := models.Focus{Id: id}
    models.DB.Find(&focus)

    c.HTML(http.StatusOK, "admin/focus/edit.html", gin.H{
        "focus": focus,
    })
}

func (con FocusController) DoEdit(c *gin.Context) {
    //获取请求的表单数据
    id, err := models.Int(c.PostForm("id"))
    title := strings.Trim(c.PostForm("title"), " ")
    focusType, err1 := models.Int(c.PostForm("focus_type"))
    link := strings.Trim(c.PostForm("link"), " ")
    sort, err2 := models.Int(c.PostForm("sort"))
    status, err3 := models.Int(c.PostForm("status"))

    if err != nil || err1 != nil || err3 != nil {
        con.Error(c, "非法请求", "/admin/focus")
        return
    }
    if err2 != nil {
        con.Error(c, "请输入正确的排序值", "/admin/focus/edit?id="+models.String(id))
        return
    }
    //文件上传操作
    focusImgSrc, err11 := models.UploadImg(c, "focus_img")
    if err11 != nil {
        con.Error(c, "图片上传失败", "/admin/focus/edit?id="+models.String(id))
        return
    }

    focus := models.Focus{Id: id}
    models.DB.Find(&focus)

    focus.Title = title
    focus.FocusType = focusType
    focus.Status = status
    focus.Sort = sort
    focus.Link = link
    if focusImgSrc != "" {
        focus.FocusImg = focusImgSrc
    }
    err4 := models.DB.Save(&focus).Error
    if err4 != nil {
        con.Error(c, "修改轮播图失败", "/admin/focus/edit?id="+models.String(id))
        return
    }
    con.Success(c, "修改轮播图成功", "/admin/focus")

}

//删除
func (con FocusController) Delete(c *gin.Context) {
    //获取提交的表单数据
    id, err := models.Int(c.Query("id"))
    if err != nil {
        con.Error(c, "传入数据错误", "/admin/focus")
        return
    }

    //查询数据是否存在
    focus := models.Focus{Id: id}
    models.DB.Find(&focus)
    //需要对文件进行删除吗?
    if focus.FocusImg != "" {
        fmt.Println(focus.FocusImg)
        os.Remove(focus.FocusImg)
    }
    err = models.DB.Delete(&focus).Error
    if err != nil {
        con.Error(c, "删除数据失败", "/admin/focus")
        return
    }

    con.Success(c, "删除数据成功", "/admin/focus")
}

3.创建轮播图html

在templates/admin/focus下创建轮播图相关html

index.html


{{ define "admin/focus/index.html" }}
{{ template "admin/public/page_header.html" .}}
    
{{range $key,$value := .focusList}} {{end}}
轮播图名称 轮播图类型 轮播图图片 跳转地址 排序 状态 操作
{{$value.Title}} {{if eq $value.FocusType 1}} 网站 {{else if eq $value.FocusType 2}} APP {{else}} 小程序 {{end}} {{if ne $value.FocusImg ""}} {{end}} {{$value.Link}} {{$value.Sort}} {{if eq $value.Status 1}} {{else}} {{end}} 修改 删除
{{end}}

add.html

{{ define "admin/focus/add.html" }}
{{ template "admin/public/page_header.html" .}}

增加轮播图
  • 名  称:
  • 类  型:
  • 跳转地址:
  • 轮 播 图:
  • 排  序:
  • 状  态:  

{{end}}

edit.html

{{ define "admin/focus/edit.html" }}
{{ template "admin/public/page_header.html" .}}
修改轮播图
  • 名  称:
  • 类  型:
  • 跳转地址:
  • 轮 播 图: {{if ne .focus.FocusImg ""}} {{end}}
  • 排  序:
  • 状  态:  

{{end}}

4.配置路由

在routes/adminRouters.go下配置轮播图路由
package routers

import (
    "goshop/controllers/admin"
    "goshop/middlewares"
    "github.com/gin-gonic/gin"
)

//设置admin后台路由
func AdminRoutersInit(r *gin.Engine) {
    //路由分组: 配置全局中间件:middlewares.InitMiddleware
    adminRouters := r.Group("/admin", middlewares.InitAdminAuthMiddleware)
    {
        //后台首页
        adminRouters.GET("/", admin.MainController{}.Index)
        adminRouters.GET("/welcome", admin.MainController{}.Welcome)

        //登录页面
        adminRouters.GET("/login", admin.LoginController{}.Index) // 实例化控制器,并访问其中方法
        adminRouters.POST("/doLogin", admin.LoginController{}.DoIndex)
        adminRouters.GET("/loginOut", admin.LoginController{}.LoginOut)

        //验证码
        adminRouters.GET("/captcha", admin.LoginController{}.Captcha)

        //管理员路由
        adminRouters.GET("/manager", admin.ManagerController{}.Index)
        adminRouters.GET("/manager/add", admin.ManagerController{}.Add)
        adminRouters.POST("/manager/doAdd", admin.ManagerController{}.DoAdd)
        adminRouters.GET("/manager/edit", admin.ManagerController{}.Edit)
        adminRouters.POST("/manager/doEdit", admin.ManagerController{}.DoEdit)
        adminRouters.GET("/manager/delete", admin.ManagerController{}.Delete)

        //轮播图路由
        adminRouters.GET("/focus", admin.FocusController{}.Index)
        adminRouters.GET("/focus/add", admin.FocusController{}.Add)
        adminRouters.POST("/focus/doAdd", admin.FocusController{}.DoAdd)
        adminRouters.GET("/focus/edit", admin.FocusController{}.Edit)
        adminRouters.POST("/focus/doEdit", admin.FocusController{}.DoEdit)
        adminRouters.GET("/focus/delete", admin.FocusController{}.Delete)

        //角色路由
        adminRouters.GET("/role", admin.RoleController{}.Index)
        adminRouters.GET("/role/add", admin.RoleController{}.Add)
        adminRouters.POST("/role/doAdd", admin.RoleController{}.DoAdd)
        adminRouters.GET("/role/edit", admin.RoleController{}.Edit)
        adminRouters.POST("/role/doEdit", admin.RoleController{}.DoEdit)
        adminRouters.GET("/role/delete", admin.RoleController{}.Delete)
        adminRouters.GET("/role/auth", admin.RoleController{}.Auth)
        adminRouters.POST("/role/doAuth", admin.RoleController{}.DoAuth)

        //权限路由
        adminRouters.GET("/access", admin.AccessController{}.Index)
        adminRouters.GET("/access/add", admin.AccessController{}.Add)
        adminRouters.POST("/access/doAdd", admin.AccessController{}.DoAdd)
        adminRouters.GET("/access/edit", admin.AccessController{}.Edit)
        adminRouters.POST("/access/doEdit", admin.AccessController{}.DoEdit)
        adminRouters.GET("/access/delete", admin.AccessController{}.Delete)
    }
}

5.界面展示如下

列表

[golang gin框架] 15.Gin 商城项目-封装上传图片方法,轮播图的增删改查以及异步修改状态,数量_第1张图片

新增

[golang gin框架] 15.Gin 商城项目-封装上传图片方法,轮播图的增删改查以及异步修改状态,数量_第2张图片

编辑

[golang gin框架] 15.Gin 商城项目-封装上传图片方法,轮播图的增删改查以及异步修改状态,数量_第3张图片

删除

[golang gin框架] 15.Gin 商城项目-封装上传图片方法,轮播图的增删改查以及异步修改状态,数量_第4张图片

三.封装公共Api接口

封装公共Api接口,实现公共的ajax: 异步修改状态, 异步修改排序
以轮播图为例:
当点击状态图标时,修改状态图标(正常/失效)
当点击排序栏时,生成焦点文本框,输入排序数字,鼠标点击其他地方,失去焦点时,发送请求,修改排序
  1. index.html页面修改排序,状态相关代码


{{ define "admin/focus/index.html" }}
{{ template "admin/public/page_header.html" .}}
    
{{range $key,$value := .focusList}} {{end}}
轮播图名称 轮播图类型 轮播图图片 跳转地址 排序 状态 操作
{{$value.Title}} {{if eq $value.FocusType 1}} 网站 {{else if eq $value.FocusType 2}} APP {{else}} 小程序 {{end}} {{if ne $value.FocusImg ""}} {{end}} {{$value.Link}} {{$value.Sort}} {{if eq $value.Status 1}} {{else}} {{end}} 修改 删除
{{end}}
  1. static/admin/js/base.js增加修改排序,状态的方法

$(function () {
    baseApp.init();
    //当窗口重置时,重新计算窗口高度
    $(window).resize(function () {
        baseApp.resizeIframe();
    })
})

var baseApp = {
    init: function () {
        this.initAside()
        this.confirmDelete()
        this.resizeIframe()
        this.changeStatus()
        this.changeNum()
    },
    initAside: function () { //左侧菜单栏隐藏显示子栏
        $(".aside h4").click(function () {
            $(this).sibling("ul").slideToggle();
        })
    },
    resizeIframe: function() {  // 设置iframe高度
        $("rightMain").height($(window).height()-80)
    },
    confirmDelete: function () { // 删除提示
        $(".delete").click(function () {
            var flag = confirm("确定要删除该项?")
            return flag
        })
    },
    changeStatus: function () { // 改变状态
        //点击事件
        $(".chStatus").click(function () {
            var $this = $(this);
            var id = $this.attr("data-id");
            var table = $this.attr("data-table");
            var field = $this.attr("data-field");
            console.log(field);
            $.get("/admin/changeStatus", {id: id, table: table, field: field}, function (res) {
                if (res.success) {
                    if ($this.attr("src").indexOf("yes") != -1){
                        $this.attr("src", "/static/admin/images/no.gif");
                    } else {
                        $this.attr("src", "/static/admin/images/yes.gif");
                    }
                } else {
                    alert(res.message);
                }
            })
        })
    },
    changeNum: function () {  // 修改排序数字
        /*
        1、获取el里面的值  var spanNum=$(this).html()
        2、创建一个input的dom节点   var input=$("");
        3、把input放在el里面   $(this).html(input);
        4、让input获取焦点  给input赋值    $(input).trigger('focus').val(val);
        5、点击input的时候阻止冒泡
        $(input).click(function(e){
            e.stopPropagation();
        })
        6、鼠标离开的时候给span赋值,并触发ajax请求
        $(input).blur(function(){
            var inputNum=$(this).val();
            spanEl.html(inputNum);
            触发ajax请求

        })
        */

        $(".chSpanNum").click(function () {
            // 1、获取el 以及el里面的属性值
            var id = $(this).attr("data-id")
            var table = $(this).attr("data-table")
            var field = $(this).attr("data-field")
            var num = $(this).html().trim()
            var spanEl = $(this)
            //2、创建一个input的dom节点   var input=$("");
            var input = $("");
            // 3、把input放在el里面   $(this).html(input);
            $(this).html(input);
            //4、让input获取焦点  给input赋值    $(input).trigger('focus').val(val);
            $(input).trigger("focus").val(num);
            //5、点击input的时候阻止冒泡
            $(input).click(function (e) {
                e.stopPropagation();
            })
            //6、鼠标离开的时候给span赋值,并触发ajax请求
            $(input).blur(function () {
                var inputNum = $(this).val()
                spanEl.html(inputNum)
                //触发ajax请求
                $.get("/admin/changeNum", { id: id, table: table, field: field, num: inputNum }, function (response) {
                    if (response.success) {
                        alert(response.message)
                    } else {
                        alert(response.message)
                    }
                })
            })
        })
    }
}
  1. 封装公共api接口方法

在controllers/MainController.go文件中封装公共方法:改变状态,改变排序
//公共方法:改变表状态的
func (con MainController) ChangeStatus(c *gin.Context) {
    id, err := models.Int(c.Query("id"))
    if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "success": false,
            "message": "id参数错误",
        })
        return
    }
    table := c.Query("table")
    field := c.Query("field")

    //修改
    err1 := models.DB.Exec("update "+ table +" set " + field + " = ABS(" + field + " - 1) where id = ?", id).Error
    if err1 != nil {
        c.JSON(http.StatusOK, gin.H{
            "success": false,
            "message": "修改失败,请重试",
        })
        return
    }
    c.JSON(http.StatusOK, gin.H{
        "success": true,
        "message": "操作成功",
    })
}


//公共方法:改变排序数字
func (con MainController) ChangeNum(c *gin.Context) {
    id, err := models.Int(c.Query("id"))
    if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "success": false,
            "message": "id参数错误",
        })
        return
    }
    table := c.Query("table")
    field := c.Query("field")
    num := c.Query("num")

    //修改
    err1 := models.DB.Exec("update "+ table +" set " + field + " = " + num + " where id = ?", id).Error
    if err1 != nil {
        c.JSON(http.StatusOK, gin.H{
            "success": false,
            "message": "修改失败,请重试",
        })
        return
    }
    c.JSON(http.StatusOK, gin.H{
        "success": true,
        "message": "操作成功",
    })
}

4.配置路由

在routers/adminRouters.go中配置修改状态以及修改排序的路由
adminRouters.GET("/changeStatus", admin.MainController{}.ChangeStatus)
adminRouters.GET("/changeNum", admin.MainController{}.ChangeNum)

[上一节][golang gin框架] 14.Gin 商城项目-RBAC管理

你可能感兴趣的:(#,gin框架开发,golang,change_status,change_sort,UploadImg)