广东省一流高职院校建设专题网站外链购买交易平台
配置清除缓存
当进入前台首页时,会缓存对应的商品相关数据,这时,如果后台修改了商品的相关数据,缓存中的对应数据并没有随之发生改变,这时就需要需改对应的缓存数据,这里有两种方法:
方法一
在管理后台操作直接清除缓存中的所有数据,当再次访问前台首页时,就会先从数据库中获取数据,然后缓存到redis中,代码如下:
(1).界面
点击 清除缓存 按钮,直接清除缓存驱动中的所有数据

(2).增加 清除缓存 按钮
在templates/admin/main/index.html页面,增加 清除缓存 按钮
<ul class="nav navbar-nav navbar-right"><li><a>欢迎您,{{.username}}</a></li><li><a href="/admin/flushAll">清除缓存</a><li><a href="/admin/loginOut">安全退出</a></li>
</ul>
(3).增加路由
在routers/admin/adminRouter.go中增加 清除缓存 路由
adminRouters.GET("/flushAll", admin.MainController{}.FlushAll)
(4).增加清除缓存方法
在controllers/admin/MainController.go中增加清除缓存的方法
//清除缓存
func (con MainController) FlushAll(c *gin.Context) {models.RedisCache.FlushAll()con.Success(c, "清除缓存成功", "/admin")
}
在models /redisCache.go中增加清除缓存方法
//清除缓存
func (r RedisCache) FlushAll() {if redisEnable {RedisDb.FlushAll(ctxRedis)}
}
方法二
在管理后台修改商品相关数据时,就去修改对应的缓存数据,代码:略
2.分类页面数据展示
当从首页点击 商品分类,进入商品分类的 商品展示页面时,会存在和首页共同的 公共数据( 顶部导航、中间导航、左侧分类),那么就可以把公共的代码分离出来,放到 基础控制器(BaseController.go)中,实现 代码的复用;
在商品分类的商品展示页面 展示分类的对应商品,以及 筛选对应分类的商品,和对商品进行 分页操作
1).界面
首页界面

商品分类对应的商品页面: 该页面和首页都有共同的 公共数据( 顶部导航、中间导航、左侧分类)


商品列表

2).代码展示
(1).html
拆分publibc/page_header.html,把中部导航代码单独成一个文件middle_nav.html
index.html中增加 中部导航 代码
创建product/list.html商品页面文件
page_header.html
拆分publibc/page_header.html,把中部导航代码单独成一个文件middle_nav.html
<!-- 相当于给模板定义一个名字, define end 必须成对出现 -->
{{ define "frontend/public/page_header.html" }}<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="author" content="order by dede58.com"/><title>小米商城</title><link rel="stylesheet" type="text/css" href="/static/frontend/css/style.css"><link rel="stylesheet" href="/static/frontend/css/swiper.min.css"><script src="/static/frontend/js/jquery-1.10.1.js"></script><script src="/static/frontend/js/swiper.min.js"></script><script src="/static/frontend/js/base.js"> </script></head><body><!-- start header 顶部导航 --><header><div class="top center"><div class="left fl"><ul><!--获取长度,并计算,看看是否显示最后的 | 画线-->{{ $temp := .topNavList | len }}{{ $navLen := Sub $temp 1 }}{{range $key, $value := .topNavList}}<li><a href="{{$value.Link}}"{{if eq $value.IsOpennew 1 }} target="_blank" {{end}} >{{$value.Title}}</a></li>{{if lt $key $navLen}}<li>|</li>{{end}}{{end}}<div class="clear"></div></ul></div><div class="right fr"><div class="gouwuche fr"><a href="">购物车</a></div><div class="fr"><ul><li><a href="./login.html" target="_blank">登录</a></li><li>|</li><li><a href="./register.html" target="_blank" >注册</a></li><li>|</li><li><a href="">消息通知</a></li></ul></div><div class="clear"></div></div><div class="clear"></div></div></header><!--end header -->
{{end}}
list.html
创建product/list.html商品页面文件
{{ define "frontend/public/middle_nav.html" }}<!-- 中间导航start banner_x --><div class="banner_x center"><a href="/" target="_blank"><div class="logo fl"></div></a><div class="nav fl"><ul class="clearfix" id="nav_list"><li class="link-category"><a href="#">全部商品分类</a><div class="banner_y center"><div class="nav"><ul>{{range $key,$value := .goodsCateList}}<li><!--判断点击分类是否跳转到一个新的链接,如果不是,则跳转到对应的分类商品页面-->{{if eq $value.Link ""}}<a href="category{{$value.Id}}" target="_blank">{{$value.Title}}</a>{{else}}<a href="{{$value.Link}}" target="_blank">{{$value.Title}}</a>{{end}}<div class="pop"><ol class="cate_list clear">{{range $k,$v := $value.GoodsCateItems}}<li><div class="xuangou_left">{{if eq $v.Link ""}}<a href="category{{$v.Id}}" target="_blank"class="clearfix"><div class="img fl"><imgsrc="{{$v.CateImg | FormatImg}}"alt="{{$v.Title}}"></div><span class="fl">{{$v.Title}}</span></a>{{else}}<a href="{{$v.Link}}" target="_blank" class="clearfix"><div class="img fl"><imgsrc="{{$v.CateImg | FormatImg}}"alt="{{$v.Title}}"></div><span class="fl">{{$v.Title}}</span></a>{{end}}</div></li>{{end}}</ol></div></li>{{end}}</ul></div></div></li>{{range $key,$value := .middleNavList}}<li><a href="#" target="_blank">{{$value.Title}}</a><ol class="children-list clearfix">{{range $k,$v := $value.GoodsItems}}<li><a href="#"><img src="{{$v.GoodsImg | FormatImg}}" alt="{{$v.Title}}"/><p>{{$v.Price}}元</p></a></li>{{end}}</ol></li>{{end}}</ul></div><div class="search fr"><form action="" method="post"><div class="text fl"><input type="text" class="shuru" placeholder="6 MIX现货"></div><div class="submit fl"><input type="submit" class="sousuo" value="搜索"/></div><div class="clear"></div></form><div class="clear"></div></div></div><!-- end banner_x -->
{{end}}
index.html
商品首页增加 中部导航 代码, 因为page_header.html中的中部导航代码没有了,已经封装成middle_nav.html代码了,而首页的商品分类和商品页面的商品分类还有点区别,故不会导入public/middle_nav.html中的代码,所以会直接增加 中部导航 代码
{{ define "frontend/index/index.html" }}{{template "frontend/public/page_header.html" .}}<!-- start banner_x 中部导航 --><div class="banner_x center"><a href="./index.html" target="_blank"><div class="logo fl"></div></a><a href=""><div class="ad_top fl"></div></a><div class="nav fl"><ul class="clearfix" id="nav_list">{{range $key, $value := .middleNavList }}<li><a href="{{$value.Link}}" target="_blank">{{$value.Title}}</a><ol class="children-list clearfix">{{range $k, $v := $value.GoodsItems }}<li><a href="#"><img src="{{$v.GoodsImg | FormatImg }}" /><p>{{$v.Price}}</p></a></li>{{end}}</ol></li>{{end}}</ul></div><div class="search fr"><form action="" method="post"><div class="text fl"><input type="text" class="shuru" placeholder="小米6 小米MIX现货"></div><div class="submit fl"><input type="submit" class="sousuo" value="搜索"/></div><div class="clear"></div></form><div class="clear"></div></div></div><!-- end banner_x --><!-- 商品分类 start banner_y --><div class="banner_y center"><div class="nav"><ul>{{range $key, $value := .goodsCateList }}<li>{{if eq $value.Link ""}}<a href="category{{$value.Id}}" target="_blank">{{$value.Title}}</a>{{else}}<a href="{{$value.Link}}" target="_blank">{{$value.Title}}</a>{{end}}<div class="pop"><ol class="cate_list clear">{{range $k, $v := $value.GoodsCateItems}}<li><div class="xuangou_left">{{if eq $v.Link ""}}<a href="category{{$v.Id}}" target="_blank"class="clearfix"><div class="img fl"><imgsrc="{{$v.CateImg | FormatImg}}"alt="{{$v.Title}}"></div><span class="fl">{{$v.Title}}</span></a>{{else}}<a href="{{$v.Link}}" target="_blank" class="clearfix"><div class="img fl"><imgsrc="{{$v.CateImg | FormatImg}}"alt="{{$v.Title}}"></div><span class="fl">{{$v.Title}}</span></a>{{end}}</div></li>{{end}}</ol></div></li>{{end}}</ul></div><!--轮播图--><div class="swiper-container"><div class="swiper-wrapper">{{range $key, $value := .focusList}}<div class="swiper-slide"><a href="{{$value.Link}}" target="_blank"><img src="{{$value.FocusImg | FormatImg}}" alt="{{$value.Title}}" /></a></div>{{end}}</div><!-- Add Arrows --><div class="swiper-button-next"></div><div class="swiper-button-prev"></div></div></div> <!-- 商品分类end --><div class="sub_banner center"><div class="sidebar fl"><div class="fl"><a href=""><img src="/static/frontend/image/hjh_01.gif"></a></div><div class="fl"><a href=""><img src="/static/frontend/image/hjh_02.gif"></a></div><div class="fl"><a href=""><img src="/static/frontend/image/hjh_03.gif"></a></div><div class="fl"><a href=""><img src="/static/frontend/image/hjh_04.gif"></a></div><div class="fl"><a href=""><img src="/static/frontend/image/hjh_05.gif"></a></div><div class="fl"><a href=""><img src="/static/frontend/image/hjh_06.gif"></a></div><div class="clear"></div></div><div class="datu fl"><a href=""><img src="/static/frontend/image/hongmi4x.png" alt=""></a></div><div class="datu fl"><a href=""><img src="/static/frontend/image/xiaomi5.jpg" alt=""></a></div><div class="datu fr"><a href=""><img src="/static/frontend/image/pinghengche.jpg" alt=""></a></div><div class="clear"></div></div><!-- end banner --><!-- 手机 --><div class="category_item w"><div class="title center">手机</div><div class="main center"><div class="category_item_left"><img src="static/itying/image/shouji.jpg" alt="手机"></div><div class="category_item_right">{{range $key,$value := .phoneList}}<div class="hot fl"><div class="xinpin"><span style="background:#fff"></span></div><div class="tu"><a href="#"><img src="{{$value.GoodsImg | FormatImg}}"></a></div><div class="miaoshu"><a href="#">{{$value.Title}}</a></div><div class="jiage">{{$value.Price}}元</div><div class="pingjia">372人评价</div><div class="piao"><a href=""><span>{{SubStr $value.SubTitle 0 4}}</span></a></div></div>{{end}}</div></div></div>{{template "frontend/public/page_footer.html" .}}</body>
</html>
{{end}}
(2).增加商品分类页面路由
defaultRouters.GET("/category:id", frontend.ProductController{}.Category)
(3).基础控制器
在基础控制器BaseController.go中创建公共方法: 加载公共模板方法Render()
package frontend//基础控制器import ("github.com/gin-gonic/gin""gorm.io/gorm""goshop/models""net/http""strings"
)type BaseController struct{}/*
加载公共模板方法
tpl string 模板
data map 请求的数据*/
func (con BaseController) Render(c *gin.Context, tpl string, data map[string]interface{}) {//实例化redisCache结构体redisCache := models.RedisCache{}//获取顶部导航列表topNavList := []models.Nav{}//判断redis中是否存在数据if hasTopNavList := redisCache.Get("topNavList", &topNavList); !hasTopNavList { //不存在数据,则从数据中获取数据,并把数据保存到redismodels.DB.Where("status = 1 AND position = 1").Find(&topNavList)redisCache.Set("topNavList", topNavList, 3600)}//获取分类数据goodsCateList := []models.GoodsCate{}if hasGoodsCateList := redisCache.Get("goodsCateList", &goodsCateList); !hasGoodsCateList {//获取分类列表以及下级分类,并进行排序models.DB.Where("pid = ? AND status = ?", 0, 1).Order("sort DESC").Preload("GoodsCateItems", func(db *gorm.DB) *gorm.DB {return db.Where("goods_cate.status = 1").Order("goods_cate.sort DESC")} ).Find(&goodsCateList)redisCache.Set("goodsCateList", goodsCateList, 3600)}//获取中间导航middleNavList := []models.Nav{}if hasMiddleNavList := redisCache.Get("middleNavList", &middleNavList); !hasMiddleNavList {models.DB.Where("status = ? AND position = ? ", 1, 2).Find(&middleNavList)//循环,获取中间导航对应的商品数据for i:= 0; i < len(middleNavList);i++{//获取管理商品//替换字符串中的中文逗号strings.ReplaceAll()relation := strings.ReplaceAll(middleNavList[i].Relation, ",", ",")//把字符串转换成切片relationIds := strings.Split(relation, ",")//获取对应的商品信息goodsList := []models.Goods{}models.DB.Where("status = ?", 1).Where("id in ?", relationIds).Select("id, title, goods_img, price").Find(&goodsList)middleNavList[i].GoodsItems = goodsList}redisCache.Set("middleNavList", middleNavList, 3600)}renderData := gin.H{"topNavList": topNavList,"goodsCateList": goodsCateList,"middleNavList": middleNavList,}for key, v := range data {renderData[key] = v}c.HTML(http.StatusOK, tpl, renderData)
}
(4).商品控制器
创建ProductController.go控制器,该控制器与商品相关
package frontend//商品相关import ("github.com/gin-gonic/gin""goshop/models""math"
)type ProductController struct {//extend 基础控制器BaseController
}// 根据商品分类获取分类下面的所有商品数据
func (con ProductController) Category(c *gin.Context) {//获取分类idcateId, _ := models.Int(c.Param("id"))//当前页page, _ := models.Int(c.Query("page"))if page == 0 {page = 1}//每一页显示的数量pageSize := 2//获取当前分类curCate := models.GoodsCate{}models.DB.Where("id = ? ", cateId).Find(&curCate)//判断当前分类是否顶级分类,如果是,则获取对应的二级分类,如果不是,则获取对应的兄弟分类subCate := []models.GoodsCate{}var tempSlice []intif curCate.Pid == 0 { // 当前分类是顶级分类,获取对应的二级分类models.DB.Where("pid = ?", cateId).Find(&subCate)//把二级分类id放到切片中for i := 0; i < len(subCate); i++ {tempSlice = append(tempSlice, subCate[i].Id)}} else { // 当前分类是二级分类,获取对应的兄弟分类models.DB.Where("pid = ?", curCate.Pid).Find(&subCate)}//把请求的分类id放入切片tempSlice = append(tempSlice, cateId)//通过上面的分类id,获取商品相关数据goodsList := []models.Goods{}where := "cate_id in ?"models.DB.Where(where, tempSlice).Where("status = ?", 1).Offset((page - 1) * pageSize).Limit(pageSize).Find(&goodsList)//获取总数量var count int64models.DB.Where(where, tempSlice).Table("goods").Count(&count)//定义请求的模板tpl := "frontend/product/list.html"con.Render(c, tpl, gin.H{"goodsList": goodsList, // 商品列表"subCate": subCate, // 选择分类下面的子分类"currentCate": curCate, // 当前分类"page": page, //当前页码数"totalPages": math.Ceil(float64(count) / float64(pageSize)), // 总页面数})
}
[上一节][golang gin框架] 24.Gin 商城项目-redis讲解以及操作