[golang gin框架] 26.Gin 商城项目-前台自定义商品列表模板, 商品详情数据渲染,Markdown语法使用

news2024/10/6 12:35:17

一.前台自定义商品列表模板

当在首页分类点击进入分类商品列表页面时,可以根据后台分类中的分类模板跳转到对应的模板商品列表页面

1.管理后台商品分类模板设置如下图所示

2.代码展示

(1).商品控制器方法Category()完善

修改controllers/frontend/productController.go中的方法Category(), 判断分类模板,如果后台没有设置,则使用默认模板
// 根据商品分类获取分类下面的所有商品数据
func (con ProductController) Category(c *gin.Context) {
    //获取分类id
    cateId, _ := 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 []int
    if 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 int64
    models.DB.Where(where, tempSlice).Table("goods").Count(&count)

    //定义请求的模板
    tpl := "frontend/product/list.html"
    //判断分类模板,如果后台没有设置,则使用默认模板
    if curCate.Template != "" {
        tpl = curCate.Template
    }

    con.Render(c, tpl, gin.H{
        "goodsList":   goodsList,
        "subCate":     subCate,
        "currentCate": curCate,
        "page":        page,
        "totalPages":  math.Ceil(float64(count) / float64(pageSize)),
    })
}

(2).模板页面案例

{{ define "frontend/product/catetest.html" }}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    自定义模板
</body>
</html>
{{end}}

二.商品详情数据渲染,Markdown语法使用

1.后台商品相关页面

先来回顾一下后台商品相关属性功能页面

2.前端相关界面展示

3.路由代码

完善routers/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)
        //商品分类对应的商品列表页面
        defaultRouters.GET("/category:id", frontend.ProductController{}.Category)
        //商品详情页
        defaultRouters.GET("/detail", frontend.ProductController{}.Detail)
        //获取商品图库信息:获取当前商品对应颜色的图片信息
        defaultRouters.GET("/getImgList", frontend.ProductController{}.GetImgList)
    }
}

3.控制器,模型代码

在controllers/frontend/productController.go中增加商品详情等方法

//商品详情
func (con ProductController) Detail(c *gin.Context) {
    //获取商品id
    id, err := models.Int(c.Query("id"))
    //判断商品id是否符合要求
    if err != nil {
        c.Redirect(302, "/")
        c.Abort()
    }
    //1、获取商品信息
    goods := models.Goods{Id: id}
    models.DB.Find(&goods)

    //2、获取关联商品  RelationGoods
    relationGoods := []models.Goods{}
    //把数据库中保存的关联商品id转换成切片类型
    goods.RelationGoods = strings.ReplaceAll(goods.RelationGoods, ",", ",")
    relationIds := strings.Split(goods.RelationGoods, ",")
    //查询关联商品
    models.DB.Where("id in ?", relationIds).Select("id,title,price,goods_version").Find(&relationGoods)

    //3、获取关联赠品 GoodsGift
    goodsGift := []models.Goods{}
    goods.GoodsGift = strings.ReplaceAll(goods.GoodsGift, ",", ",")
    giftIds := strings.Split(goods.GoodsGift, ",")
    models.DB.Where("id in ?", giftIds).Select("id,title,price,goods_version").Find(&goodsGift)

    //4、获取关联颜色 GoodsColor
    goodsColor := []models.GoodsColor{}
    goods.GoodsColor = strings.ReplaceAll(goods.GoodsColor, ",", ",")
    colorIds := strings.Split(goods.GoodsColor, ",")
    models.DB.Where("id in ?", colorIds).Find(&goodsColor)

    //5、获取关联配件 GoodsFitting
    goodsFitting := []models.Goods{}
    goods.GoodsFitting = strings.ReplaceAll(goods.GoodsFitting, ",", ",")
    fittingIds := strings.Split(goods.GoodsFitting, ",")
    models.DB.Where("id in ?", fittingIds).Select("id,title,price,goods_version").Find(&goodsFitting)

    //6、获取商品关联的图片 GoodsImage
    goodsImage := []models.GoodsImage{}
    models.DB.Where("goods_id = ?", goods.Id).Limit(6).Find(&goodsImage)

    //7、获取规格参数信息 GoodsAttr
    goodsAttr := []models.GoodsAttr{}
    models.DB.Where("goods_id = ?", goods.Id).Find(&goodsAttr)

    //8、获取更多属性
    /*
            颜色:红色,白色,黄色 | 尺寸:41,42,43
            切片
            [
                {
                    Cate:"颜色",
                    List:[红色,白色,黄色]
                },
                {
                    Cate:"尺寸",
                    List:[41,42,43]
                }
            ]

        goodsAttrStrSlice[0]    尺寸:41,42,43
                tempSlice[0]    尺寸
                tempSlice[1]    41,42,43

        goodsAttrStrSlice[1]    套餐:套餐1,套餐2

    */

    // 更多属性: goodsAttrStr := "尺寸:41,42,43|套餐:套餐1,套餐2"
    goodsAttrStr := goods.GoodsAttr
    //字符串替换操作
    goodsAttrStr = strings.ReplaceAll(goodsAttrStr, ",", ",")
    goodsAttrStr = strings.ReplaceAll(goodsAttrStr, ":", ":")
    //实例化商品更多属性结构体
    var goodsItemAttrList []models.GoodsItemAttr
    //strings.Contains 判断字符串中有没有冒号(:)
    if strings.Contains(goodsAttrStr, ":") {
        //字符串替换操作:获取属性切片
        goodsAttrStrSlice := strings.Split(goodsAttrStr, "|")
        //创建切片的存储空间
        goodsItemAttrList = make([]models.GoodsItemAttr, len(goodsAttrStrSlice))
        for i := 0; i < len(goodsAttrStrSlice); i++ {
            //strings.Split(s, sep string) 把字符串s按照sep转换成切片
            //拆分 "尺寸:41,42,43
            tempSlice := strings.Split(goodsAttrStrSlice[i], ":")
            goodsItemAttrList[i].Cate = tempSlice[0]
            //拆分 41,42,43
            listSlice := strings.Split(tempSlice[1], ",")
            goodsItemAttrList[i].List = listSlice
        }
    }

    //定义请求的模板
    tpl := "frontend/product/detail.html"
    con.Render(c, tpl, gin.H{
        "goods":             goods,
        "relationGoods":     relationGoods,
        "goodsGift":         goodsGift,
        "goodsColor":        goodsColor,
        "goodsFitting":      goodsFitting,
        "goodsImage":        goodsImage,
        "goodsAttr":         goodsAttr,
        "goodsItemAttrList": goodsItemAttrList,
    })
}

//获取商品对应颜色的图库信息
func (con ProductController) GetImgList(c *gin.Context) {
    //获取商品id
    goodsId, err1 := models.Int(c.Query("goods_id"))
    //获取商品对应的颜色id
    colorId, err2 := models.Int(c.Query("color_id"))

    //查询商品图库信息
    goodsImageList := []models.GoodsImage{}
    err3 := models.DB.Where("goods_id = ? AND color_id = ?", goodsId, colorId).Find(&goodsImageList).Error
    if err1 != nil || err2 != nil || err3 != nil {
        c.JSON(http.StatusOK, gin.H{
            "success": false,
            "result":  "",
            "message": "参数错误",
        })
        return
    }

    //判断 goodsImageList的长度 如果goodsImageList没有数据,那么我们需要返回当前商品所有的图库信息
    if len(goodsImageList) == 0 {
        models.DB.Where("goods_id = ?", goodsId).Find(&goodsImageList)
    }
    c.JSON(http.StatusOK, gin.H{
        "success": true,
        "result":  goodsImageList,
        "message": "获取数据成功",
    })
}
在models/goodsItemAttr.go中定义一个商品更多属性的结构体
package models

//商品更多属性结构体

type GoodsItemAttr struct {
    // 尺寸:41,42,43
    Cate string  //属性类型:  尺寸
    List []string  // 对应的值 [41,42,43]
}

4.main.go,tools.go

在前端渲染数据的时候,需要解析后台Markdown语法数据,这是就需要在models/tools.go中增加调用 Markdown语法的方法,这样就可以解析后台商品 规格与包装属性中的Markdown语法格式:
Markdown 是一种 轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档
当前许多网站都广泛使用 Markdown 来撰写帮助文档或是用于论坛上发表消息
更多语法参考: https://www.runoob.com/markdown/md-lists.html
在解析Markdown语法之前,需要 引入gomarkdown包,操作如下:
在tools.go中import github.com/gomarkdown/markdown,然后在main.go目录下 go mod tidy 更新就可以使用啦
models/tools.go中增加FormatAttr()方法
import (
    "github.com/gomarkdown/markdown"
)

/*
转换markdown格式
str就是markdown语法
例如:
**我是一个三级标题**  <=> <h3>我是一个三级标题</h3>
**我是一个加粗** <=> <strong>我是一个加粗</strong>
*/
func FormatAttr(str string) string {
    tempSlice := strings.Split(str, "\n")
    var tempStr string
    for _, v := range tempSlice {
        md := []byte(v)
        output := markdown.ToHTML(md, nil, nil)
        tempStr += string(output)
    }
    return tempStr
}
增加main.go中的自定义模板函数FormatAttr
//自定义模板函数,必须在r.LoadHTMLGlob前面(只调用,不执行, 可以在html 中使用)
r.SetFuncMap(template.FuncMap{
    "UnixToTime": models.UnixToTime, //注册模板函数
    "Str2Html": models.Str2Html,
    "FormatImg": models.FormatImg,
    "Sub": models.Sub,
    "SubStr": models.SubStr,
    "FormatAttr": models.FormatAttr,
})

5.html代码

渲染商品详情相关数据frontend/product/detail.html
{{ define "frontend/product/detail.html" }}

    {{ template "frontend/public/page_header.html" .}}

    {{ template "frontend/public/middle_nav.html" .}}

    <link rel="stylesheet" href="/static/frontend/css/product.css">

    <div class="jieshao mt20 w">
        <div class="left fl">
            <div class="swiper-container">
                <div class="swiper-wrapper item_focus" id="item_focus">
                    {{range $key,$value := .goodsImage}}
                        <div class="swiper-slide">
                            <img src="{{$value.ImgUrl | FormatImg}}"/>
                        </div>
                    {{end}}
                </div>

                <div class="swiper-pagination"></div>
                <div class="swiper-button-next"></div>
                <div class="swiper-button-prev"></div>
            </div>
        </div>
        <div class="right fr">
            <div class="h3 ml20 mt20">{{.goods.Title}}</div>
            <div class="jianjie mr40 ml20 mt10">{{.goods.SubTitle}}</div>
            <div class="jiage ml20 mt10">{{.goods.Price}}元  <span class="old_price">{{.goods.MarketPrice}}元</span></div>
            {{$goodsId := .goods.Id}}
            {{$relationGoodsLen := len .relationGoods}}
            {{if gt $relationGoodsLen 0}}
                <div class="ft20 ml20 mt20">选择版本</div>
                <div class="xzbb ml20 mt10 clearfix">

                    {{range $key,$value := .relationGoods}}
                        <div class="banben fl {{if eq $value.Id $goodsId}}active{{end}}">
                            <a href="detail?id={{$value.Id}}">
                                <span>{{$value.GoodsVersion}}</span>
                                <span>{{$value.Price}}元</span>
                            </a>
                        </div>
                    {{end}}
                </div>
            {{end}}

            {{$goodsColorLen := len .goodsColor}}
            {{if gt $relationGoodsLen 0}}
                <div class="ft20 ml20 mt10">选择颜色</div>
                <div class="xzbb ml20 mt10 clearfix" id="color_list">
                    {{range $key,$value:=.goodsColor}}
                        <div class="banben fl" goods_id="{{$goodsId}}" color_id="{{$value.Id}}">
                            <span class="yuandian" style="background:{{$value.ColorValue}}"></span>
                            <span class="yanse">{{$value.ColorName}}</span>
                        </div>
                    {{end}}
                </div>
            {{end}}

            {{$goodsItemAttrListLen := len .goodsItemAttrList}}
            {{if gt $goodsItemAttrListLen 0}}
                {{range $key,$value := .goodsItemAttrList}}
                    <div class="ft20 ml20 mt20">{{$value.Cate}}</div>
                    <div class="xzbb ml20 mt10 clearfix">
                        {{range $k,$v := $value.List}}
                            <div class="banben fl">
                                <span>{{$v}}</span>
                            </div>
                        {{end}}

                    </div>
                {{end}}
            {{end}}
            <div class="xqxq mt10 ml20">
                <div class="top1 mt10">
                    <div class="left1 fl">{{.goods.GoodsVersion}} <span id="color_name"></span></div>
                    <div class="right1 fr">{{.goods.Price}}元</div>
                    <div class="clear"></div>
                </div>
                <div class="bot mt20 ft20 ftbc">总计:{{.goods.Price}}元</div>
            </div>
            <div class="xiadan ml20 mt10">
                <input class="jrgwc" type="button" name="jrgwc" value="加入购物车"/>
            </div>
        </div>
        <div class="clear"></div>
    </div>

    <div class="container clearfix">
        <div class="c_left">
            <h2>看了又看</h2>
            <div class="item">
                <a target="_blank" href="#">
                    <img src="/static/upload/20211117/1637139107685884400.jpg"/>
                    <p class="price recommendLookPrice4183081">¥31.90</p>
                    <p>三利 纯棉A类标准简约素雅大浴巾 70×140cm 男女同款 柔软舒适吸水裹身巾 豆绿</p>
                </a>
            </div>
            <div class="item">
                <a target="_blank" href="#">
                    <img src="/static/upload/20211117/1637139107685884400.jpg"/>
                    <p class="price recommendLookPrice4183081">¥31.90</p>
                    <p>三利 纯棉A类标准简约素雅大浴巾 70×140cm 男女同款 柔软舒适吸水裹身巾 豆绿</p>
                </a>
            </div>
            <div class="item">
                <a target="_blank" href="#">
                    <img src="/static/upload/20211117/1637139107685884400.jpg"/>
                    <p class="price recommendLookPrice4183081">¥31.90</p>
                    <p>三利 纯棉A类标准简约素雅大浴巾 70×140cm 男女同款 柔软舒适吸水裹身巾 豆绿</p>
                </a>
            </div>
        </div>

        <div class="c_right">
            <ul class="detail_list clearfix">

                <li class="">详情描述</li>

                <li class="">规格参数</li>

                <li class="">用户评价</li>
            </ul>

            <div class="detail_info">

                <div class="detail_info_item">
                    {{Str2Html .goods.GoodsContent}}
                </div>
                <div class="detail_info_item">
                    <ul>
                        {{range $key,$value:=.goodsAttr}}

                            {{if ne $value.AttributeValue ""}}
                                <li class="row clearfix">

                                    <div class="span5">

                                        <h2>{{$value.AttributeTitle}}</h2>
                                    </div>
                                    <div class="span15">
                                        {{$value.AttributeValue | FormatAttr | Str2Html}}
                                    </div>
                                </li>
                            {{end}}
                        {{end}}
                    </ul>
                </div>

                <div class="detail_info_item">
                    <ul class="comment_list">
                        <li>
                            <div>
                                <img src="https://www.itying.com/themes/itying/images/stars5.gif">
                            </div>
                            <p>这已经是第六部了,一如既往地好用。美中不足得是,尾插和数据线的链接口,用过一段时间,就会有充电接触不良的问题,希望厂家将来有改进。</p>

                            <p class="eval-order-info"> <span class="eval-time">2018-11-18
                                14:00:35</span><span>月岩白</span><span>6GB+64GB</span><span></span></p>

                        </li>
                        <li>
                            <div>
                                <img src="https://www.itying.com/themes/itying/images/stars5.gif">
                            </div>
                            <p>这已经是第六部了,一如既往地好用。美中不足得是,尾插和数据线的链接口,用过一段时间,就会有充电接触不良的问题,希望厂家将来有改进。</p>

                            <p class="eval-order-info"> <span class="eval-time">2018-11-18
                                14:00:35</span><span>月岩白</span><span>6GB+64GB</span><span></span></p>

                        </li>
                        <li>
                            <div>
                                <img src="https://www.itying.com/themes/itying/images/stars5.gif">
                            </div>
                            <p>这已经是第六部了,一如既往地好用。美中不足得是,尾插和数据线的链接口,用过一段时间,就会有充电接触不良的问题,希望厂家将来有改进。</p>

                            <p class="eval-order-info"> <span class="eval-time">2018-11-18
                                14:00:35</span><span>月岩白</span><span>6GB+64GB</span><span></span></p>

                        </li>
                        <li>
                            <div>
                                <img src="https://www.itying.com/themes/itying/images/stars5.gif">
                            </div>
                            <p>这已经是第六部了,一如既往地好用。美中不足得是,尾插和数据线的链接口,用过一段时间,就会有充电接触不良的问题,希望厂家将来有改进。</p>

                            <p class="eval-order-info"> <span class="eval-time">2018-11-18
                                14:00:35</span><span>月岩白</span><span>6GB+64GB</span><span></span></p>

                        </li>
                    </ul>
                </div>
            </div>

        </div>
    </div>

    {{ template "frontend/public/page_footer.html" .}}
    </body>
    </html>
{{end}}

6.js代码

在static/frontend/js/base.js中增加 initProductContentTab()方法-商品详情页面 tab切换(内容,规格参数等; initProductContentColor()方法- 商品详情 颜色选中功能,如果有关联的商品图片,则展示对应的商品图片信息
(function ($) {

    var app = {
        init: function () {

            this.initSwiper();

            this.initNavSlide();

            this.initProductContentTab();

            this.initProductContentColor();

        },
        initSwiper: function () {     // 轮播图切换操作
            new Swiper('.swiper-container', {
                loop: true,
                navigation: {
                    nextEl: '.swiper-button-next',
                    prevEl: '.swiper-button-prev'
                },
                pagination: {
                    el: '.swiper-pagination',
                    clickable: true
                }

            });
        },
        initNavSlide: function () {  // 导航鼠标移上去效果
            $("#nav_list>li").hover(function () {

                $(this).find('.children-list').show();
            }, function () {
                $(this).find('.children-list').hide();
            })

        },
        initProductContentTab: function () {  // 商品详情页面tab切换(内容,规格参数等tab切换)
            $(function () {
                $('.detail_info .detail_info_item:first').addClass('active');
                $('.detail_list li:first').addClass('active');
                $('.detail_list li').click(function () {
                    var index = $(this).index();
                    $(this).addClass('active').siblings().removeClass('active');
                    $('.detail_info .detail_info_item').removeClass('active').eq(index).addClass('active');

                })
            })
        },
        initProductContentColor: function () {  // 商品详情颜色选中功能,如果有关联的商品图片,则展示对应的商品图片信息
            var _that = this;
            $("#color_list .banben").first().addClass("active");
            $("#color_name").html($("#color_list .active .yanse").html())
            $("#color_list .banben").click(function () {
                $(this).addClass("active").siblings().removeClass("active");
                $("#color_name").html($("#color_list .active .yanse").html())
                var goods_id = $(this).attr("goods_id")
                var color_id = $(this).attr("color_id")
                //获取当前商品对应颜色的图片信息
                $.get("/product/getImgList", {"goods_id": goods_id, "color_id": color_id}, function (response) {
                    if (response.success == true) {
                        var swiperStr = ""
                        for (var i = 0; i < response.result.length; i++) {
                            swiperStr += '<div class="swiper-slide"><img src="' + response.result[i].img_url + '"> </div>';
                        }
                        $("#item_focus").html(swiperStr)
                        _that.initSwiper()
                    }
                })
            })
        }
    }

    $(function () {
        app.init();
    })

})($)

[上一节][golang gin框架] 25.Gin 商城项目-配置清除缓存以及前台列表页面数据渲染公共数据

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

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

相关文章

大模型竞逐,再造AI新格局

作者 | 辰纹 来源 | 洞见新研社 “面对AI时代&#xff0c;所有产品都值得用大模型重做一次。” 这是阿里巴巴集团董事会主席兼CEO、阿里云智能集团CEO张勇在2023阿里云峰会上对AIGC&#xff08;生成式AI&#xff09;进化的判断&#xff0c;在这背后则是由ChatGPT为起始点&…

Shiro学习笔记,一篇就够用了

目录 一、Shiro基础 1.1Shiro定义: 1.2Shiro架构: 1.3快速上手: 二、Spring整合Shiro 2.1导入spring整合shiro的依赖 2.2两个配置类 寻找maven版本号:Maven Repository: org.apache.shiro shiro-core (mvnrepository.com) Shiro官网:Apache Shiro | Simple. Java. Securi…

C. Trailing Loves (or L‘oeufs?)(求某个质因子在n的阶乘中的个数 + 思维)

Problem - C - Codeforces Aki喜欢数字&#xff0c;尤其是那些带有尾随零的数字。例如&#xff0c;数字9200有两个尾随零。Aki认为数字拥有的尾随零越多&#xff0c;它就越漂亮。 然而&#xff0c;Aki认为&#xff0c;一个数字拥有的尾随零的数量并不是固定的&#xff0c;而是…

微搭低代码调用第三方API

目录 1 创建项目2 获取实时天气API3 创建APIs4 小程序中调用总结 应粉丝要求&#xff0c;我们本篇介绍一下微搭中如何调用第三方API。我们的应用开发中比较常见的一类需求是开发一个天气的功能&#xff0c;方便用户访问应用的时候实时的看到今天最新的天气情况。 第三方的天气…

虚拟机安装使用经验

1 VMware 跟 VirtualBox 在网络上可以看到很多对比的资料&#xff0c;比如这篇: VirtualBox 和 VMware的区别 VMware 分商业版跟非商业版&#xff0c;我们这里仅讨论非商业版&#xff0c;也就是 VMware Workstation Player&#xff0c;支持在 Linux、Windows、Mac OS 等系统上…

docker容器:Docker consul的容器服务更新与发现

目录 一、Docker consul 1、什么是服务注册与发现 2、什么是consul 3、consul部署 ①实验目的 ②实验环境及拓扑 ③consul配置 ④registrator后端配置 ⑤测试发现功能是否正常 4、consul-template部署 ①准备template nginx模板文件 ②编译安装nginx ③安装templa…

LVS-keepalived

文章目录 一、keepalived1、KEEPALIVED作用2、KEEPALIVED原理3、KEEPALIVED工作模式4、KEEPLIVED问题及优化 二、实验1.LVSKeepalived 高可用群集 总结 一、keepalived 1、KEEPALIVED作用 保证负载均衡的高可用性&#xff0c;完美解决了LVS所有问题&#xff0c;可以检查后端服…

【随笔】转发/转向(服务器重定向,服务器转发,服务器跳转)和重定向(客户端重定向,客户端转发,客户端跳转)

文章目录 1.转发&#xff08;转向&#xff09;和重定向图解2.例子3.区别 1.转发&#xff08;转向&#xff09;和重定向图解 图&#xff1a;转发&#xff08;转向&#xff09; 图&#xff1a;重定向 2.例子 转发&#xff1a;A找B要钱&#xff0c;B没钱&#xff0c;于是B向C…

OSPF路由协议解释

目录 OSPF路由协议OSPF数据包类型OSPF邻区状态OSPF的邻接关系建立过程 路由名词解释OSPF开源项目 OSPF路由协议 OSPF简介 1、&#xff08;Open Shortest Path First&#xff09;&#xff0c;开放式最短路径优先&#xff0c;它属于链路状态路由协议&#xff0c;大部分路由将由O…

ChatGPT进化的过程简介

Chat GPT可以做什么&#xff1f; 分点列条的回答问题 写代码或SQL 翻译 语法检查 ChatGPT官方还未公开论文&#xff0c;ChatGPT有一个“孪生兄弟”InstructGPT&#xff0c;InstructGPT有论文&#xff0c;可以根据InstructGPT论文推导ChatGPT的训练过程&#xff1a; ChatGPT的…

React函数组件语法(N)

文章目录 react学习的说明新的官网全力投入现代React与Hooks React简介概述官网特点生态 React脚手架create-react-app官网创建和启动项目项目结构sass支持 Vite创建和启动项目项目结构常见配置 虚拟DOM什么是虚拟DOM虚拟DOM优缺点优点&#xff1a;缺点&#xff1a; 虚拟DOM实现…

MySQL死锁的原因和处理方法

MySQL死锁的原因和处理方法 表的死锁产生原因解决方案 行级锁死锁产生原因1解决方案1产生原因2产生原因3解决方案 表的死锁 产生原因 用户A访问表A(锁住了表A),然后又访问表B&#xff1b;另一个用户B访问表B(锁住了表B),然后企图访问表A;这时用户A由于用户B已经锁住表B,它必须…

LeetCode349. 两个数组的交集

题目链接 LeetCode349. 两个数组的交集 题目描述 题解 题解一&#xff08;Java&#xff09; 作者&#xff1a;仲景 因为数据范围和长度都限制在1000&#xff0c;所以直接使用数组即可 因为数据范围和长度都在1000内&#xff0c;所以碰到数字可以直接arr[i] i来表示这个数字…

如何有效的开展接口自动化测试,一篇就行

一、简介 接口自动化测试是指使用自动化测试工具和脚本对软件系统中的接口进行测试的过程。其目的是在软件开发过程中&#xff0c;通过对接口的自动化测试来提高测试效率和测试质量&#xff0c;减少人工测试的工作量和测试成本&#xff0c;并且能够快速发现和修复接口错误&…

手写Spring框架---IOC容器实现

目录 框架具备的最基本功能 实现容器前奏 创建注解 提取标记对象 extractPacakgeClass里面需要完成的事情 获取项目类加载器的目的 为什么不让用户传入绝对路径 类加载器ClassLoader 统一资源定位符URL ClassUtil提取标记类 获取包下类集合 装载目标类的集合 获取…

Git相关使用

私人博客 许小墨のBlog —— 菜鸡博客直通车 系列文章完整版&#xff0c;配图更多&#xff0c;CSDN博文图片需要手动上传&#xff0c;因此文章配图较少&#xff0c;看不懂的可以去菜鸡博客参考一下配图&#xff01; 系列文章目录 前端系列文章——传送门 后端系列文章——传送…

APP UI自动化测试思路总结 ,教你彻底学会APP自动化测试

目录 一&#xff0c;开发语言选择 二&#xff0c;UI测试框架选择 1&#xff0c;Appium 2&#xff0c;Airtest 3&#xff0c;选择框架 三&#xff0c;单元测试框架选择 四&#xff0c;测试环境搭建 1&#xff0c;测试电脑选择 2&#xff0c;测试手机选择 3&#xff0c;…

【Redis】Redis管道

面试题 如何优化频繁命令往返造成的性能瓶颈&#xff1f; Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。一个请求会遵循以下步骤&#xff1a; 客户端向服务端发送命令分四步(发送命令→命令排队→命令执行→返回结果)&#xff0c;并监听Socket返回&#xf…

基于matlab仿真相控天线阵列在波束成形MIMO-OFDM系统中的使用

一、前言 本例显示了相控阵在采用波束成形的MIMO-OFDM通信系统中的使用。它使用通信工具箱和相控阵系统工具箱中的组件&#xff0c;对组成发射器和前端接收器组件的辐射元件进行建模&#xff0c;用于MIMO-OFDM通信系统。使用用户指定的参数&#xff0c;您可以根据不同空间位置和…

Django自动化测试平台搭建落地全过程(附视频教程+源码)

目录 前言 一、平台基础架构设计 二、自动化测试工具选择与集成 三、平台功能开发 四、总结 前言 自动化测试在现代软件开发中扮演着至关重要的角色&#xff0c;它可以显著提高测试效率和准确性&#xff0c;并帮助开发团队更快地发布高质量的软件产品。Django作为一种流行…