一.首页界面展示以及项目结构分析
首页界面展示
项目结构分析
二.代码展示
首页相关模型
首页相关模型如下:
[golang gin框架] 21.Gin 商城项目-导航模块功能
[golang gin框架] 17.Gin 商城项目-商品分类模块, 商品类型模块,商品类型属性模块功能操作
[golang gin框架] 16.Gin 商城项目-商品模块数据表ER图关系分析
[golang gin框架] 15.Gin 商城项目-封装上传图片方法,轮播图的增删改查以及异步修改状态,数量
商品模型Goods.go增加方法GetGoodsByCategory():根据分类id,商品类型获取分类下面的数据
package models//商品表type Goods struct {Id intTitle string //商品标题SubTitle string //附属标题GoodsSn string //商品编号CateId int //商品分类id: goods_cate.idClickCount int //商品点击数量GoodsNumber int //商品库存Price float64 //价格MarketPrice float64 //商品市场价(原价)RelationGoods string //关联商品id,如: 1, 23,55 ,商品id以逗号隔开GoodsAttr string //商品更多属性GoodsVersion string //商品版本GoodsImg string //图片GoodsGift string //商品赠品GoodsFitting string //商品配件GoodsColor string //颜色GoodsKeywords string //SEO关键字GoodsDesc string //SEO商品描述GoodsContent string //商品详情IsDelete int //是否删除IsHot int //是否热销IsBest int //是否精品IsNew int //是否新品GoodsTypeId int //商品类型id,关联GoodsType.IdSort int //排序Status int //状态AddTime int //添加时间
}func (Goods) TableName() string {return "goods"
}/**
根据分类id,商品类型获取分类下面的数据
*/
func GetGoodsByCategory(cateId int, goodsType string, limitNum int) []Goods {//判断是否顶级分类goodsCate := GoodsCate{Id: cateId}DB.Find(&goodsCate)var tempSlice []intif goodsCate.Pid == 0 { // 说明是顶级分类,则需要获取其下面的二级分类goodsCateList := []GoodsCate{}DB.Where("pid = ?", goodsCate.Id).Find(&goodsCate)//把二级分类id存入切片for i := 0; i < len(goodsCateList); i++ {tempSlice = append(tempSlice, goodsCateList[i].Id)}}tempSlice = append(tempSlice, goodsCate.Id)where := "cate_id in ?"//通过商品类型,拼接条件switch goodsType {case "is_best":where += " AND is_best = 1"case "is_hot":where += " AND is_hot = 1"case "is_new":where += " AND is_new = 1"default:break}goodsList := []Goods{}DB.Where(where, tempSlice).Order("sort DESC").Select("id, title, price, goods_img, sub_title").Limit(limitNum).Find(&goodsList)return goodsList
}
2.tools.go工具类代码
增加SubStr截取字符串方法
//SubStr截取字符串
func SubStr(str string, start int, end int) string {rs := []rune(str)rl := len(rs)if start < 0 {start = 0}if start > rl {start = 0}if end < 0 {end = rl}if end > rl {end = rl}if start > end {start, end = end, start}return string(rs[start:end])
}
3.main.go注入上面的方法
//自定义模板函数,必须在r.LoadHTMLGlob前面(只调用,不执行, 可以在html 中使用)r.SetFuncMap(template.FuncMap{"UnixToTime": models.UnixToTime, //注册模板函数"Str2Html": models.Str2Html,"FormatImg": models.FormatImg,"Sub": models.Sub,"SubStr": models.SubStr,})
4.控制器
在controllers/frontend下创建IndexController控制器文件,存放前台首页相关代码
package frontend//首页import ("github.com/gin-gonic/gin""gorm.io/gorm""goshop/models""net/http""strings"
)type IndexController struct {
}func (con IndexController) Index(c *gin.Context) {//获取顶部导航列表topNavList := []models.Nav{}models.DB.Where("status = 1 AND position = 1").Find(&topNavList)//获取网站轮播图数据focusList := []models.Focus{}models.DB.Where("status = 1 AND focus_type = 1").Find(&focusList)//获取分类数据goodsCateList := []models.GoodsCate{}//获取分类列表以及下级分类,并进行排序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)//获取中间导航middleNavList := []models.Nav{}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}//获取手机分类下面的商品phoneList := models.GetGoodsByCategory(23, "best", 10)c.HTML(http.StatusOK, "frontend/index/index.html", gin.H{"topNavList": topNavList,"focusList": focusList,"goodsCateList": goodsCateList,"middleNavList": middleNavList,"phoneList": phoneList,})
}
5.公共的header,footer页面
在templates/frontend/public目录下创建page_header.html(顶部公共html),page_footer.html(底部公共html)
page_header.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>xxxx</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 --><!-- 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="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}}
page_footer.html
<!-- 相当于给模板定义一个名字, define end 必须成对出现 -->
{{ define "frontend/public/page_footer.html" }}<footer class="mt20 center"><div class="mt20">xxx|xxx|xxx|xx书城|xx路由器|视频电话|隐私政策|Select Region</div><div>©xx.com 京ICP证1x07号 京ICP备xxx号 京公网安备xxx号 京网文[2014]0059-xxx9号</div><div>违法和不良信息举报电话:1xx-xxxx-12xx,本网站所列数据,xxxx</div></footer>
{{end}}
6.前台首页
{{ define "frontend/index/index.html" }}{{template "frontend/public/page_header.html" .}}<!-- start banner_y 商品分类 --><div class="banner_y center"><div class="nav"><ul>{{range $key, $value := .goodsCateList }}<li><a href="{{$value.Link}}" target="_blank">{{$value.Title}}</a><div class="pop"><ol class="cate_list clear">{{range $k, $v := $value.GoodsCateItems}}<li><div class="xuangou_left"><a href="{{$v.Link}}" target="_blank" class="clearfix"><div class="img fl"><img src="{{$v.CateImg | FormatImg}}" alt="{{$v.Title}}"></div><span class="fl">{{$v.Title}}</span></a></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 banner --><!-- start danpin --><div class="danpin center"><div class="title center">单品</div><div class="main center"><div class="mingxing fl"><div class="sub_mingxing"><a href=""><img src="/static/frontend/image/pinpai2.png" alt=""></a></div><div class="pinpai"><a href="">xxx</a></div><div class="youhui">5月9日-10日,下单立减200元</div><div class="jiage">1999元</div></div>...<div class="clear"></div></div></div><!-- 手机 --><!--获取手机分类下面的商品信息 --><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><!-- 配件 --><div class="category_item w"><div class="title center">配件</div><div class="main center"><div class="content"><div class="hot fl"><a href=""><img src="/static/frontend/image/peijian1.jpg"></a></div><div class="hot fl"><div class="xinpin"><span>新品</span></div><div class="tu"><a href=""><img src="/static/frontend/image/peijian2.jpg"></a></div><div class="miaoshu"><a href="">小米6 硅胶保护套</a></div><div class="jiage">49元</div><div class="pingjia">372人评价</div><div class="piao"><a href=""><span>发货速度很快!很配小米6!</span><span>来至于mi狼牙的评价</span></a></div></div><div class="hotlast fr"><div class="hongmi"><a href=""><img src="/static/frontend/image/hongmin4.png" alt=""></a></div><div class="liulangengduo"><a href=""><img src="/static/frontend/image/liulangengduo.png" alt=""></a></div> </div><div class="clear"></div></div> </div></div>{{template "frontend/public/page_footer.html" .}}</body>
</html>
{{end}}
6.配置路由
在main.go中引入路由文件,在routers/frontendRouters.go下配置路由
main.go
//分组路由文件
routers.AdminRoutersInit(r)
routers.ApiRoutersInit(r)
routers.FrontendRoutersInit(r)
frontendRouters.go
package routersimport ("goshop/controllers/frontend""github.com/gin-gonic/gin"
)//设置前端路由
func FrontendRoutersInit(r *gin.Engine) {defaultRouters := r.Group("/"){defaultRouters.GET("/", frontend.IndexController{}.Index)}
}
[上一节][golang gin框架] 22.Gin 商城项目-商店设置模块,以及通过反射获取系统设置里面的数据
[下一节][golang gin框架] 24.Gin 商城项目-redis讲解以及操作