[golang gin框架] 23.Gin 商城项目-前台templates模板分离,首页,顶部导航,轮播图 左侧分类数据渲染

news2024/10/7 14:31:39

一.首页界面展示以及项目结构分析

  1. 首页界面展示

  1. 项目结构分析

二.代码展示

  1. 首页相关模型

首页相关模型如下:
[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            int
    Title         string  //商品标题
    SubTitle      string  //附属标题
    GoodsSn       string  //商品编号
    CateId        int     //商品分类id: goods_cate.id
    ClickCount    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.Id
    Sort          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 []int
    if 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 routers

import (
    "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 商城项目-商店设置模块,以及通过反射获取系统设置里面的数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/412653.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023中国程序员薪酬报告出炉,你拖后腿了吗?

程序员薪资高已是公认的事实&#xff0c;但是具体高到什么程度呢&#xff1f;近期&#xff0c;全球人力服务公司 Michael Page Internatioal 就发布了《2023 中国大陆薪酬报告》&#xff0c;揭示了中国程序员的薪酬情况。 该报告中一共调研了国内 7 个行业以及 6 大城市不同职…

Doris的基本概述

目录 Doris是什么 使用场景 技术概述 Doris是什么 由百度大数据部研发&#xff0c;之前加做百度palo&#xff0c;20118年共享到Apache社区后&#xff0c;更名Doris一个现代化的MPP分析型数据库产品 支持压秒级别响应架构非常简洁&#xff0c;易于运维支持10PB以上的超大数据…

企业数字化转型全是坑?这几篇数字化转型成功案例,减少70%损失

这篇给大家整理了200企业数字化转型案例合集&#xff0c;涵盖了制造、建筑、教育、零售、互联网等10行业的大中小型企业数字化转型思路&#xff0c;希望对大家有所帮助。 案例全部整合在这篇文章中&#xff0c;点击即可查看>>数字化干货资料合集&#xff01; 01 首先&…

【FineReport】帆软报表平台的安装与连接 SAP HANA 数据库

【FineReport】帆软报表平台的安装与连接 SAP HANA 数据库1、下载帆软2、安装软件3、连接HANA4、访问数据1、下载帆软 &#xff08;1&#xff09;帆软最新版本软件下载地址&#xff1a;https://www.finereport.com/product/download 此处&#xff0c;以下载FineReport v11.0 …

设计模式 : 构造型 —— 单例模式

单例模式 Creational Patterns/Singleton.md belien/DesignPattern-23 (gitee.com) Singleton Pattern&#xff0c;属于创建型设计模式&#xff0c;这种模式涉及到一个单一的类&#xff0c;该类负责创建自己的对象&#xff0c;同时确保只有单个对象被创建&#xff0c;这个类提…

PHY- PHY芯片概述

1 PHY概述 关于Internet Protocal的分层模型可以参考文章 :【Internet Protocal-OSI模型中的网络分层模型】,下面我们讲讲底层以太网控制器和收发器的知识。其主要是处理OSI模型中的物理层和链路层的事情。 在CAN/CANFD、FlexRay等总线中,有控制器Controller和收发器Transc…

【三十天精通Vue 3】第五天 Vue 3指令详解

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: 三十天精通 Vue 3 文章目录引言一、Vue 3 指令概述1.1 指令的简介1.2 指令的分类1.3 指令的语…

基于消息调度优化启动速度方案实践

背景 在抖音的技术博客 https://juejin.cn/post/7080065015197204511#heading-10中&#xff0c;其介绍了通过修改消息队列顺序实现冷启动优化的方案&#xff0c;不过并未对其具体实现展开详细说明。 本文是对其技术方案的思考验证及实现。 详细代码见github: https://github.c…

PMO在企业项目管理中起到的重要性

在现代企业中&#xff0c;项目管理助力企业在激烈的市场竞争中获得成功&#xff0c;而这需要一个专业化的项目管理办公室&#xff08;PMO&#xff09;来确保项目的顺利实施。在企业项目管理中&#xff0c;PMO扮演着至关重要的角色&#xff0c;下文我们将对其的重要作用进行探讨…

docker+jenkins+maven+git构建聚合项目,实现自动化部署,走了800个坑

流程 主要的逻辑就是Docker上安装jenkins&#xff0c;然后拉取git上的代码&#xff0c;把git上的代码用Maven打包成jar包&#xff0c;然后在docker运行 这个流程上的难点 一个是聚合项目有可能Maven install的时候失败。 解决办法&#xff1a;在基础模块的pom文件上添加 <…

【配电网故障重构SOP】基于二阶锥松弛的加光伏风机储能进行的配电网故障处理和重构【考虑最优潮流】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

uniapp即时通讯sdk哪个好?

UniApp 是什么? UniApp 是一种跨平台移动应用开发框架&#xff0c;可以使用 Vue.js 语法开发支持 Android、iOS 和桌面浏览器的应用。 UniApp 即时通讯功能如何实现? 对于实现即时通讯功能&#xff0c;您可以使用以下2种方法: 1、使用 websocket 实现即时通讯。Websocket 是一…

x210官方uboot配置编译

1、在linux源生目录下配置编译 (1)X210移植过的uboot在开发板光盘的BSP中。 (2)BSP就是board support package(板级支持包&#xff0c;一般由开发板供应商提供)&#xff0c;里面的内容就是这个开发板的所有相关的源代码、文档、教程等。 (3)将整个BSP打包文件弄到linux的源生目…

Linux的vi编辑器常见命令总结

注&#xff1a;本文中的给定模式或者模式等词中模式所指是指的一个词语并无其他意思。例如给定模式查找定位指的是查找到给定词的定位。 三种方式的关系图 命令方式和插入方式之间可以相互转换&#xff0c;命令方式和ex转义方式也可以相互转换。但是插入方式和ex转义方式之间不…

Python 小型项目大全 61~65

六十一、ROT13 密码 原文&#xff1a;http://inventwithpython.com/bigbookpython/project61.html ROT13 密码是最简单的加密算法之一&#xff0c;代表“旋转 13 个空格”密码将字母A到Z表示为数字 0 到 25&#xff0c;加密后的字母距离明文字母 13 个空格&#xff1a; A变成N&…

MyBatis 03 -MyBatis动态SQL与分页插件

动态SQL与分页插件 动态SQL与分页插件动态SQL与分页插件1 动态SQL1.1 < sql >1.2 < if >1.3 < where >1.4 < set >1.5 < choose >1.6 < trim >1.7 < foreach >2 mybatis缓存2.1 一级缓存2.2 二级缓存3 分页插件3.1 概念3.2 访问与下…

没有什么壁纸比这里的更绝美精致了吧,我一天换一张

嗨&#xff0c;这里是清安&#xff0c;本章来学习学习获取精美壁纸。视频教程&#xff1a;https://b23.tv/iR7bOFF源码&#xff1a;https://gitee.com/qinganan_admin/reptile-case/tree/master/%E5%A3%81%E7%BA%B8本视频还会有第二期&#xff0c;代码也会有第二份&#xff0c;…

类ChatGPT项目的部署与微调(上):从LLaMA到Alpaca、Vicuna、BELLE

前言 近期&#xff0c;除了研究ChatGPT背后的各种技术细节 不断看论文(至少100篇&#xff0c;100篇目录见此&#xff1a;ChatGPT相关技术必读论文100篇)&#xff0c;还开始研究一系列开源模型(包括各自对应的模型架构、训练方法、训练数据、本地私有化部署、硬件配置要求、微…

Python | 蓝桥杯进阶第三卷——动态规划

欢迎交流学习~~ 专栏&#xff1a; 蓝桥杯Python组刷题日寄 蓝桥杯进阶系列&#xff1a; &#x1f3c6; Python | 蓝桥杯进阶第一卷——字符串 &#x1f50e; Python | 蓝桥杯进阶第二卷——贪心 &#x1f49d; Python | 蓝桥杯进阶第三卷——动态规划 ✈️ Python | 蓝桥杯进阶…

精通Python(基础篇)——流程控制语句

流程控制语句 文章目录流程控制语句1️⃣简介2️⃣条件判断⚜️关系运算符⚜️逻辑运算符⚜️if语句⚜️if...else 语句⚜️if...elif...else语句⚜️match...case3️⃣循环结构⚜️while⚜️while...else语句⚜️for⚜️for...else语句4️⃣退出循环⚜️continue⚜️break1️⃣…