[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" .}}
    <div class="table-responsive">
        <table class="table table-bordered">
            <thead>
                <tr class="th">
                    <th>轮播图名称</th>
                    <th>轮播图类型</th>
                    <th>轮播图图片</th>
                    <th>跳转地址</th>
                    <th class="text-center">排序</th>
                    <th class="text-center">状态</th>
                    <th class="text-center">操作</th>
                </tr>
            </thead>
            <tbody>
            {{range $key,$value := .focusList}}
            <tr>
                <td>{{$value.Title}}</td>
                <td>
                    {{if eq $value.FocusType 1}}                    
                    网站
                    {{else if eq $value.FocusType 2}}
                    APP
                    {{else}}
                    小程序
                    {{end}}

                </td>
                <td>
                    {{if ne $value.FocusImg ""}}
                        <img src="/{{$value.FocusImg}}" width="200"  />
                    {{end}}
                </td>
                <td>{{$value.Link}}</td>
                <td class="text-center">
                    <span class="chSpanNum"  data-id="{{$value.Id}}" data-table="focus" data-field="sort">{{$value.Sort}}</span>
                </td>
                <td align="center">
                    {{if eq $value.Status 1}}
                    <img class="chStatus" data-id="{{$value.Id}}" data-table="focus" data-field="status" src="/static/admin/images/yes.gif" />
                    {{else}}
                    <img class="chStatus" data-id="{{$value.Id}}" data-table="focus" data-field="status" src="/static/admin/images/no.gif" />
                    {{end}}
                </td>
                <td class="text-center">
                    <a href="/admin/focus/edit?id={{$value.Id}}" />修改</a>
                    <a class="delete" href="/admin/focus/delete?id={{$value.Id}}" />删除</a>
                </td>
            </tr>
            {{end}}
            </tbody>
        </table>
    </div>
</body>
</html>
{{end}}

add.html

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

<div class="panel panel-default">
    <div class="panel-heading">
        增加轮播图
    </div>
    <div class="panel-body">
        <div class="table-responsive input-form">
            <form action="/admin/focus/doAdd" method="post" enctype="multipart/form-data">
                <ul>
                    <li>  名  称: <input type="text" name="title"/></li>
                    <li>  类  型: 
                        <select name="focus_type" id="type">
                            <option value="1">网站</option>
                            <option value="2">APP</option>
                            <option value="3">小程序</option>
                        </select>
                    </li>                   
                    <li>  跳转地址: <input type="text" name="link"/></li>
                    <li>  轮 播 图: <input type="file" name="focus_img"/></li>                            

                    <li>  排  序: <input type="text" name="sort" value="100"/></li>

                    <li>  状  态: 
                        <input type="radio" name="status" checked value="1" id="a"/> <label for="a">显示</label>    
                        
                        <input type="radio" name="status" value="0" id="b"/><label for="b">隐藏</label>  </li>
                    <li>
                        <br/>
                        <button type="submit" class="btn btn-primary">提交</button>
                    </li>
                </ul>
            </form>
        </div>
    </div>
</div>
</body>
</html>
{{end}}

edit.html

{{ define "admin/focus/edit.html" }}
{{ template "admin/public/page_header.html" .}}
<div class="panel panel-default">
    <div class="panel-heading">
       修改轮播图
    </div>
    <div class="panel-body">
        <div class="table-responsive input-form">
            <form action="/admin/focus/doEdit" method="post" enctype="multipart/form-data">
                <input type="hidden" name="id" value="{{.focus.Id}}"/>
                <ul>
                    <li>  名  称: <input type="text" name="title" value="{{.focus.Title}}"/></li>
                    <li>  类  型: 
                        <select name="focus_type" id="type">
                            <option {{if eq .focus.FocusType 1}} selected {{end}} value="1">网站</option>
                            <option {{if eq .focus.FocusType 2}} selected {{end}} value="2">APP</option>
                            <option {{if eq .focus.FocusType 3}} selected {{end}} value="3">小程序</option>
                        </select>
                    </li>                   
                    <li>  跳转地址: <input type="text" name="link"  value="{{.focus.Link}}"/></li>
                    <li>  轮 播 图: 
                        <input type="file" name="focus_img" />
                        {{if ne .focus.FocusImg ""}}
                            <img src="/{{.focus.FocusImg}}" width="200" />
                        {{end}}
                    </li>                            

                    <li>  排  序: <input type="text" name="sort" value="{{.focus.Sort}}"/></li>

                    <li>  状  态: 
                        <input type="radio" name="status" {{if eq .focus.Status 1}} checked {{end}}  value="1" id="a"/> <label for="a">显示</label>    
                        
                        <input type="radio" name="status" {{if eq .focus.Status 0}} checked {{end}} value="0" id="b"/><label for="b">隐藏</label>  </li>
                    <li>
                        <br/>
                        <button type="submit" class="btn btn-primary">提交</button>
                    </li>
                </ul>
            </form>
        </div>
    </div>
</div>
</body>
</html>
{{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.界面展示如下

列表

新增

编辑

删除

三.封装公共Api接口

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


{{ define "admin/focus/index.html" }}
{{ template "admin/public/page_header.html" .}}
    <div class="table-responsive">
        <table class="table table-bordered">
            <thead>
                <tr class="th">
                    <th>轮播图名称</th>
                    <th>轮播图类型</th>
                    <th>轮播图图片</th>
                    <th>跳转地址</th>
                    <th class="text-center">排序</th>
                    <th class="text-center">状态</th>
                    <th class="text-center">操作</th>
                </tr>
            </thead>
            <tbody>
            {{range $key,$value := .focusList}}
            <tr>
                <td>{{$value.Title}}</td>
                <td>
                    {{if eq $value.FocusType 1}}                    
                    网站
                    {{else if eq $value.FocusType 2}}
                    APP
                    {{else}}
                    小程序
                    {{end}}

                </td>
                <td>
                    {{if ne $value.FocusImg ""}}
                        <img src="/{{$value.FocusImg}}" width="200"  />
                    {{end}}
                </td>
                <td>{{$value.Link}}</td>
                <td class="text-center">
                    <!-- 排序 -->
                    <span class="chSpanNum"  data-id="{{$value.Id}}" data-table="focus" data-field="sort">{{$value.Sort}}</span>
                </td>
                <td align="center">
                    <!-- 状态 -->
                    {{if eq $value.Status 1}}
                    <img class="chStatus" data-id="{{$value.Id}}" data-table="focus" data-field="status" src="/static/admin/images/yes.gif" />
                    {{else}}
                    <img class="chStatus" data-id="{{$value.Id}}" data-table="focus" data-field="status" src="/static/admin/images/no.gif" />
                    {{end}}
                </td>
                <td class="text-center">
                    <a href="/admin/focus/edit?id={{$value.Id}}" />修改</a>
                    <a class="delete" href="/admin/focus/delete?id={{$value.Id}}" />删除</a>
                </td>
            </tr>
            {{end}}
            </tbody>
        </table>
    </div>
</body>
</html>
{{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=$("<input value='' />");
        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=$("<input value='' />");
            var input = $("<input style='width:60px'  value='' />");
            // 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管理

[下一节][golang gin框架] 16.Gin 商城项目-商品模块数据表ER图关系分析

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值