当前位置: 首页 > news >正文

[golang gin框架] 17.Gin 商城项目-商品分类模块, 商品类型模块,商品类型属性模块功能操作

一.商品分类的增、删、改、查,以及商品分类的自关联

1.界面展示以及操作说明

列表

商品分类列表展示说明:
(1).增加商品分类按钮
(2).商品分类,以及子分类相关数据列表展示
(3).排序,状态,修改,删除操作处理

新增

编辑

删除

修改状态,排序

2.创建商品分类模型

在controllers/admin下创建GoodsCate.go商品分类控制器
package models//商品分类type GoodsCate struct {Id             intTitle          string  // 标题CateImg        string  // 分类图片Link           string  // 跳转地址Template       string  // 加载的模板: 为空的话加载默认模板, 不为空的话加载自定义模板Pid            int        // 上级id: 为0的话则是顶级分类SubTitle       string    // SEO标题Keywords       string    // SEO关键字Description    string    // SEO描述Sort           int    // 排序Status         int    // 状态: 1 显示, 0 隐藏AddTime        int    // 添加时间GoodsCateItems []GoodsCate `gorm:"foreignKey:pid;references:Id"` // 关联自身,下级分类
}func (GoodsCate) TableName() string {return "goods_cate"
}

3.创建商品分类色控制器

在controllers/admin下创建GoodsCateController.go商品分类控制器
上传图片操作代码见:[golang gin框架] 15.Gin 商城项目-封装上传图片方法,轮播图的增删改查以及异步修改状态,数量
package admin//商品分类import ("github.com/gin-gonic/gin""goshop/models""net/http""strings"
)type GoodsCateController struct {BaseController
}func (con GoodsCateController) Index(c *gin.Context) {//定义一个切片goodsCateList := []models.GoodsCate{}//获取分类列表以及下级分类models.DB.Where("pid = ?", 0).Preload("GoodsCateItems").Find(&goodsCateList)c.HTML(http.StatusOK, "admin/goodsCate/index.html", gin.H{"goodsCateList": goodsCateList,})
}//新增
func (con GoodsCateController) Add(c *gin.Context) {//获取商品分类顶级分类goodsCateList := []models.GoodsCate{}models.DB.Where("pid = ?", 0).Find(&goodsCateList)c.HTML(http.StatusOK, "admin/goodsCate/add.html", gin.H{"goodsCateList": goodsCateList,})
}//新增:提交
func (con GoodsCateController) DoAdd(c *gin.Context) {//获取请求的表单数据title := strings.Trim(c.PostForm("title"), " ")link := strings.Trim(c.PostForm("link"), " ")template := strings.Trim(c.PostForm("template"), " ")pid, err1 := models.Int(c.PostForm("pid"))subTitle := strings.Trim(c.PostForm("subTitle"), " ")keywords := strings.Trim(c.PostForm("keywords"), " ")description := strings.Trim(c.PostForm("description"), " ")sort, err2 := models.Int(c.PostForm("sort"))status, err3 := models.Int(c.PostForm("status"))if err1 != nil || err3 != nil {con.Error(c, "非法请求", "/admin/goodsCate/add")return}if err2 != nil {con.Error(c, "请输入正确的排序值", "/admin/goodsCate/add")return}//文件上传操作imgSrc, err := models.UploadImg(c, "cate_img")if err != nil {con.Error(c, "图片上传失败", "/admin/goodsCate/add")return}//实例化GoodsCate模型goodsCate := models.GoodsCate{Title:       title,Link:        link,Sort:        sort,Status:      status,CateImg:     imgSrc,Template:    template,Pid:         pid,SubTitle:    subTitle,Keywords:    keywords,Description: description,AddTime:     int(models.GetUnix()),}err = models.DB.Create(&goodsCate).Errorif err != nil {con.Error(c, "增加商品失败", "/admin/goodsCate/add")return}con.Success(c, "增加商品成功", "/admin/goodsCate")
}//编辑
func (con GoodsCateController) Edit(c *gin.Context) {//获取角色idid, err := models.Int(c.Query("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/goodsCate")return}//获取商品分类顶级分类goodsCateList := []models.GoodsCate{}models.DB.Where("pid = ?", 0).Find(&goodsCateList)//获取商品goodsCate := models.GoodsCate{Id: id}models.DB.Find(&goodsCate)c.HTML(http.StatusOK, "admin/goodsCate/edit.html", gin.H{"goodsCate":     goodsCate,"goodsCateList": goodsCateList,})
}//编辑:提交
func (con GoodsCateController) DoEdit(c *gin.Context) {//获取提交的表单数据id, err := models.Int(c.PostForm("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/goodsCate")return}//获取请求的表单数据title := strings.Trim(c.PostForm("title"), " ")link := strings.Trim(c.PostForm("link"), " ")template := strings.Trim(c.PostForm("template"), " ")pid, err1 := models.Int(c.PostForm("pid"))subTitle := strings.Trim(c.PostForm("subTitle"), " ")keywords := strings.Trim(c.PostForm("keywords"), " ")description := strings.Trim(c.PostForm("description"), " ")sort, err2 := models.Int(c.PostForm("sort"))status, err3 := models.Int(c.PostForm("status"))if err1 != nil || err3 != nil {con.Error(c, "非法请求", "/admin/goodsCate/add")return}if err2 != nil {con.Error(c, "请输入正确的排序值", "/admin/goodsCate/add")return}//文件上传操作imgSrc, err := models.UploadImg(c, "cate_img")if err != nil {con.Error(c, "图片上传失败", "/admin/goodsCate/add")return}//查询分类是否存在goodsCate := models.GoodsCate{Id: id}models.DB.Find(&goodsCate)if imgSrc != "" {goodsCate.CateImg = imgSrc}goodsCate.Title = titlegoodsCate.Link = linkgoodsCate.Sort = sortgoodsCate.Status = statusgoodsCate.Template = templategoodsCate.Pid = pidgoodsCate.SubTitle = subTitlegoodsCate.Keywords = keywordsgoodsCate.Description = descriptionerr = models.DB.Save(&goodsCate).Errorif err != nil {con.Error(c, "修改数据失败", "/admin/goodsCate/edit?id="+models.String(id))return}con.Success(c, "修改数据成功", "/admin/goodsCate")
}//删除
func (con GoodsCateController) Delete(c *gin.Context) {//获取提交的表单数据id, err := models.Int(c.Query("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/goodsCate")return}//查询数据是否存在goodsCate := models.GoodsCate{Id: id}if goodsCate.Pid == 0 { // 顶级分类goodsCateList := []models.GoodsCate{}models.DB.Where("pid = ? ", goodsCate.Id).Find(&goodsCateList)if len(goodsCateList) > 0 {con.Error(c, "当前分类下存在子分类,请先删除子分类后再来删除这个数据", "/admin/goodsCate")return}}err = models.DB.Delete(&goodsCate).Errorif err != nil {con.Error(c, "删除数据失败", "/admin/goodsCate")return}con.Success(c, "删除数据成功", "/admin/goodsCate")
}

4.创建商品分类html以及js

在templates/admin/goodsCate下创建商品分类相关html
修改状态以及排序操作代码见:[golang gin框架] 15.Gin 商城项目-封装上传图片方法,轮播图的增删改查以及异步修改状态,数量

index.html

{{ define "admin/goodsCate/index.html" }}
{{ template "admin/public/page_header.html" .}}<div class="container-fluid"><div class="row"><div class="panel panel-default"><div class="panel-heading"><a href="/admin/goodsCate/add" class="btn btn-primary">增加商品分类</a></div><!--列表展示--><div class="table-responsive"><table class="table table-bordered"><thead><tr class="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 := .goodsCateList}}                                   <tr><td>{{$value.Title}}</td><td></td><td><span class="chSpanNum" data-id="{{$value.Id}}" data-table="goods_cate" data-field="sort">{{$value.Sort}}</span></td><td class="text-center">{{if eq $value.Status 1}}                              <img src="/static/admin/images/yes.gif"  class="chStatus" data-id="{{$value.Id}}" data-table="goods_cate" data-field="status" />{{else}}<img src="/static/admin/images/no.gif"  class="chStatus" data-id="{{$value.Id}}" data-table="goods_cate" data-field="status" />{{end}}</td>                                                                    <td class="text-center"> <a href="/admin/goodsCate/edit?id={{$value.Id}}" />修改</a>  <a class="delete" href="/admin/goodsCate/delete?id={{$value.Id}}" />删除</a></td></tr>{{range $k,$v := $value.GoodsCateItems}}                <tr><td>  ----{{$v.Title}}</td><td><img src="/{{$v.CateImg}}" width="80" /></td><td class="text-center"><span class="chSpanNum" data-id="{{$v.Id}}" data-table="goods_cate" data-field="sort" data-num="{{$v.Sort}}">{{$v.Sort}}</span></td><td class="text-center">{{if eq $v.Status 1}}                              <img src="/static/admin/images/yes.gif"  class="chStatus" data-id="{{$v.Id}}" data-table="goods_cate" data-field="status" />{{else}}<img src="/static/admin/images/no.gif"  class="chStatus" data-id="{{$v.Id}}" data-table="goods_cate" data-field="status" />{{end}}</td><td class="text-center"> <a href="/admin/goodsCate/edit?id={{$v.Id}}" />修改</a>  <a class="delete" href="/admin/goodsCate/delete?id={{$v.Id}}" />删除</a></td></tr>{{end}}{{end}}</tbody></table></div></div></div>
</div>
</body>
</html>
{{end}}

add.html

{{ define "admin/goodsCate/add.html" }}
{{ template "admin/public/page_header.html" .}}
<div class="container-fluid"><div class="row"><div class="panel panel-default"><div class="panel-heading">增加分类</div><div class="panel-body"><div class="table-responsive input-form"><form action="/admin/goodsCate/doAdd" method="post" enctype="multipart/form-data"><ul><li> <span>分类名称:</span> <input type="text" name="title" class="input" /></li><li> <span>上级分类:</span><select name="pid" id="pid"><option value="0">顶级分类</option>{{range $key,$value := .goodsCateList}}<option value="{{$value.Id}}">{{$value.Title}}</option>{{end}}</select></li>  <li> <span>分类图片:</span>  <input type="file" name="cate_img"/></li>          <li>  <span>跳转地址:</span>  <input type="text" name="link" class="input"/></li> <li>  <span>分类模板:</span> <input type="text" name="template" class="input"/><span>空表示默认模板</span></li><li>  <span>Seo标题:</span> <input type="text" name="sub_title" class="input"/></li><li>  <span>Seo关键词: </span><input type="text" name="keywords" class="input"/></li><li>  <span>Seo描述:</span> <textarea name="description" id="description" cols="84" rows="4"></textarea></li>                   <li>  <span>排  序:</span> <input type="text" name="sort" value="10"/></li>       <li>  <span>状  态:</span> <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></div>
</div>
</body>
</html>
{{end}}

edit.html

{{ define "admin/goodsCate/edit.html" }}
{{ template "admin/public/page_header.html" .}}
<div class="container-fluid"><div class="row"><div class="panel panel-default"><div class="panel-heading">修改分类</div><div class="panel-body"><div class="table-responsive input-form"><form action="/admin/goodsCate/doEdit" method="post" enctype="multipart/form-data"><ul><input type="hidden" name="id"  value="{{.goodsCate.Id}}"><li> <span>分类名称:</span> <input type="text" name="title" class="input" value="{{.goodsCate.Title}}" /></li><li> <span>上级分类:</span>{{$pid := .goodsCate.Pid}}<select name="pid" id="pid"><option value="0">顶级分类</option>{{range $key,$value := .goodsCateList}}     {{if eq $pid $value.Id}}                               <option selected value="{{$value.Id}}">{{$value.Title}}</option>{{else}}<option value="{{$value.Id}}">{{$value.Title}}</option>{{end}}{{end}}</select></li>  <li> <span>分类图片:</span>  <input type="file" name="cate_img"/></li>       {{if ne .goodsCate.CateImg ""}}<img src="/{{.goodsCate.CateImg}}" width="100px" size="60" />{{end}}<li>  <span>跳转地址:</span>  <input type="text" name="link" class="input" value="{{.goodsCate.Link}}"/></li> <li>  <span>分类模板:</span> <input type="text" name="template" class="input" value="{{.goodsCate.Template}}"/><span>空表示默认模板</span></li><li>  <span>Seo标题:</span> <input type="text" name="sub_title" class="input" value="{{.goodsCate.SubTitle}}"/></li><li>  <span>Seo关键词: </span><input type="text" name="keywords" class="input" value="{{.goodsCate.Keywords}}"/></li><li>  <span>Seo描述:</span> <textarea name="description" id="description" cols="84" rows="4">{{.goodsCate.Description}}</textarea></li>                   <li>  <span>排  序:</span> <input type="text" name="sort" value="{{.goodsCate.Sort}}"/></li>       <li>  <span>状  态:</span> <input type="radio" name="status" {{if eq .goodsCate.Status 1}}checked{{end}} value="1" id="a"/> <label for="a">显示</label>   <input type="radio" name="status"  {{if eq .goodsCate.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></div>
</div>
</body>
</html>{{end}}

5.配置路由

在routes/adminRouters.go下增加商品分类路由
//商品分类路由
adminRouters.GET("/goodsCate", admin.GoodsCateController{}.Index)
adminRouters.GET("/goodsCate/add", admin.GoodsCateController{}.Add)
adminRouters.POST("/goodsCate/doAdd", admin.GoodsCateController{}.DoAdd)
adminRouters.GET("/goodsCate/edit", admin.GoodsCateController{}.Edit)
adminRouters.POST("/goodsCate/doEdit", admin.GoodsCateController{}.DoEdit)
adminRouters.GET("/goodsCate/delete", admin.GoodsCateController{}.Delete)

二.商品类型的增、删、改、查

1.界面展示以及操作说明

列表

商品类型列表展示说明:
(1).增加商品类型按钮
(2).商品类型,相关数据列表展示
(3).状态,修改,删除,类型属性操作处理

新增

编辑

删除

修改状态

2.创建商品类型模型

在controllers/admin下创建GoodsType.go商品类型控制器
package models//商品类型type GoodsType struct {Id          intTitle       string  // 类型名称Description string  // 介绍Status      int  // 状态AddTime     int  // 添加时间
}func (GoodsType) TableName() string {return "goods_type"
}

3.创建商品类型控制器

在controllers/admin下创建GoodsTypeController.go商品类型控制器
package adminimport ("goshop/models""net/http""strings""github.com/gin-gonic/gin"
)type GoodsTypeController struct {BaseController
}func (con GoodsTypeController) Index(c *gin.Context) {goodsTypeList := []models.GoodsType{}models.DB.Find(&goodsTypeList)c.HTML(http.StatusOK, "admin/goodsType/index.html", gin.H{"goodsTypeList": goodsTypeList,})}
func (con GoodsTypeController) Add(c *gin.Context) {c.HTML(http.StatusOK, "admin/goodsType/add.html", gin.H{})
}func (con GoodsTypeController) DoAdd(c *gin.Context) {title := strings.Trim(c.PostForm("title"), " ")description := strings.Trim(c.PostForm("description"), " ")status, err1 := models.Int(c.PostForm("status"))if err1 != nil {con.Error(c, "传入的参数不正确", "/admin/goodsType/add")return}if title == "" {con.Error(c, "标题不能为空", "/admin/goodsType/add")return}goodsType := models.GoodsType{Title:       title,Description: description,Status:      status,AddTime:     int(models.GetUnix()),}err := models.DB.Create(&goodsType).Errorif err != nil {con.Error(c, "增加商品类型失败 请重试", "/admin/goodsType/add")} else {con.Success(c, "增加商品类型成功", "/admin/goodsType")}}
func (con GoodsTypeController) Edit(c *gin.Context) {id, err := models.Int(c.Query("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/goodsType")} else {goodsType := models.GoodsType{Id: id}models.DB.Find(&goodsType)c.HTML(http.StatusOK, "admin/goodsType/edit.html", gin.H{"goodsType": goodsType,})}}
func (con GoodsTypeController) DoEdit(c *gin.Context) {id, err1 := models.Int(c.PostForm("id"))title := strings.Trim(c.PostForm("title"), " ")description := strings.Trim(c.PostForm("description"), " ")status, err2 := models.Int(c.PostForm("status"))if err1 != nil || err2 != nil {con.Error(c, "传入数据错误", "/admin/goodsType")return}if title == "" {con.Error(c, "商品类型的标题不能为空", "/admin/goodsType/edit?id="+models.String(id))}goodsType := models.GoodsType{Id: id}models.DB.Find(&goodsType)goodsType.Title = titlegoodsType.Description = descriptiongoodsType.Status = statuserr3 := models.DB.Save(&goodsType).Errorif err3 != nil {con.Error(c, "修改数据失败", "/admin/goodsType/edit?id="+models.String(id))} else {con.Success(c, "修改数据成功", "/admin/goodsType")}
}
func (con GoodsTypeController) Delete(c *gin.Context) {id, err := models.Int(c.Query("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/goodsType")} else {goodsType := models.GoodsType{Id: id}models.DB.Delete(&goodsType)con.Success(c, "删除数据成功", "/admin/goodsType")}
}

4.创建商品类型html以及js

在templates/admin/goodsType下创建商品类型相关html
修改状态操作代码见:[golang gin框架] 15.Gin 商城项目-封装上传图片方法,轮播图的增删改查以及异步修改状态,数量

index.html

{{ define "admin/goodsType/index.html" }}
{{ template "admin/public/page_header.html" .}}
<div class="container-fluid"><div class="row"><div class="panel panel-default"><div class="panel-heading"><div class="pagination" id="pa"></div><a href="/admin/goodsType/add" class="btn btn-primary">增加商品类型</a></div><!--列表展示--><div class="table-responsive"><table class="table table-bordered"><thead><tr class="th"><th>商品类型名称</th><th>商品类型描述</th><th class="text-center">状态</th><th class="text-center">操作</th></tr></thead><tbody>{{range $key,$value := .goodsTypeList}}<tr><td>{{$value.Title}}</td><td>{{$value.Description}}</td><td class="text-center">{{if eq $value.Status 1}}                              <img src="/static/admin/images/yes.gif"  class="chStatus" data-id="{{$value.Id}}" data-table="goods_type" data-field="status" />{{else}}<img src="/static/admin/images/no.gif"  class="chStatus" data-id="{{$value.Id}}" data-table="goods_type" data-field="status" />{{end}}</td><td class="text-center"><a href="/admin/goodsTypeAttribute?id={{$value.Id}}">类型属性</a><a href="/admin/goodsType/edit?id={{$value.Id}}">修改</a>  <a class="delete"href="/admin/goodsType/delete?id={{$value.Id}}">删除</a></td></tr>{{end}}</tbody></table></div></div></div>
</div>
</body>
</html>
{{end}}

add.html

{{ define "admin/goodsType/add.html" }}
{{ template "admin/public/page_header.html" .}}
<div class="container-fluid"><div class="row"><div class="panel panel-default">              <div class="panel-heading">增加商品类型</div><div class="panel-body"><div class="table-responsive input-form"><form action="/admin/goodsType/doAdd" method="post"><ul><li>类型名称: <input type="text" name="title"/></li><li>类型描述:<textarea name="description" cols="60" rows="8"></textarea></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><li><br/><button type="submit" class="btn btn-default">提交</button></li></ul></form></div></div></div></div>
</div>
</body>
</html>
{{end}}

edit.html

{{ define "admin/goodsType/edit.html" }}
{{ template "admin/public/page_header.html" .}}
<div class="container-fluid"><div class="row"><div class="panel panel-default">              <div class="panel-heading">修改商品类型</div><div class="panel-body"><div class="table-responsive input-form"><form action="/admin/goodsType/doEdit" method="post"><ul><input type="hidden" name="id" value="{{.goodsType.Id}}" /><li>类型名称: <input type="text" name="title" value="{{.goodsType.Title}}"/></li><li>类型描述:<textarea name="description" id="" cols="60" rows="8">{{.goodsType.Description}}</textarea></li><li>  状  态: <input type="radio" name="status"  {{if eq .goodsType.Status 1}}checked{{end}} value="1" id="a"/> <label for="a">显示</label>    <input type="radio" name="status" {{if eq .goodsType.Status 0}}checked{{end}}  value="0" id="b"/><label for="b">隐藏</label>  </li><li><li><br/><button type="submit" class="btn btn-default">提交</button></li></ul></form></div></div></div></div>
</div>
</body>
</html>
{{end}}

5.配置路由

在routes/adminRouters.go下配置商品类型路由
//商品类型路由
adminRouters.GET("/goodsType", admin.GoodsTypeController{}.Index)
adminRouters.GET("/goodsType/add", admin.GoodsTypeController{}.Add)
adminRouters.POST("/goodsType/doAdd", admin.GoodsTypeController{}.DoAdd)
adminRouters.GET("/goodsType/edit", admin.GoodsTypeController{}.Edit)
adminRouters.POST("/goodsType/doEdit", admin.GoodsTypeController{}.DoEdit)
adminRouters.GET("/goodsType/delete", admin.GoodsTypeController{}.Delete)

三.商品类型属性的增、删、改、查

1.界面展示以及操作说明

列表

点击商品类型列表中,对应商品类型的类型属性,跳转到商品类型属性列表页面,以电脑类型为例,展示说明:
(1).增加商品类型属性按钮
(2).商品类型属性,相关数据列表展示
(3).排序,状态,修改,删除,操作处理

新增

选择商品类型,以及录入方式 (可以自行增加很多录入方式,具体根据具体业务分析),进行添加

编辑

删除

修改状态

2.创建商品类型属性模型

在controllers/admin下创建GoodsTypeAttribute.go商品类型属性控制器
package models// 商品类型属性设置type GoodsTypeAttribute struct {Id        int `json:"id"`  // HTML页面使用名称CateId    int `json:"cate_id"`   //商品类型id:商品类型表goods_type.idTitle     string `json:"title"`   // 属性名称AttrType  int `json:"attr_type"`   //属性录入方式: 1 单行文本框, 2 多行文本框, 3 从下面列表中选择(一行代表一个可选值)AttrValue string `json:"attr_value"`   //可选值列表Status    int `json:"status"`   // 状态Sort      int `json:"sort"`   //排序AddTime   int `json:"add_time"`   //增加时间
}func (GoodsTypeAttribute) TableName() string {return "goods_type_attribute"
}

3.创建商品类型属性控制器

在controllers/admin下创建GoodsTypeAttributeController.go商品类型属性控制器
package adminimport ("goshop/models""net/http""strings""github.com/gin-gonic/gin"
)type GoodsTypeAttributeController struct {BaseController
}func (con GoodsTypeAttributeController) Index(c *gin.Context) {cateId, err := models.Int(c.Query("id"))if err != nil {con.Error(c, "传入的参数不正确", "/admin/goodsType")return}//获取商品类型属性goodsTypeAttributeList := []models.GoodsTypeAttribute{}models.DB.Where("cate_id=?", cateId).Find(&goodsTypeAttributeList)//获取商品类型属性对应的类型goodsType := models.GoodsType{}models.DB.Where("id=?", cateId).Find(&goodsType)c.HTML(http.StatusOK, "admin/goodsTypeAttribute/index.html", gin.H{"cateId":                 cateId,"goodsTypeAttributeList": goodsTypeAttributeList,"goodsType":              goodsType,})}
func (con GoodsTypeAttributeController) Add(c *gin.Context) {//获取当前商品类型属性对应的类型idcateId, err := models.Int(c.Query("cate_id"))if err != nil {con.Error(c, "传入的参数不正确", "/admin/goodsType")return}//获取所有的商品类型goodsTypeList := []models.GoodsType{}models.DB.Find(&goodsTypeList)c.HTML(http.StatusOK, "admin/goodsTypeAttribute/add.html", gin.H{"goodsTypeList": goodsTypeList,"cateId":        cateId,})
}func (con GoodsTypeAttributeController) DoAdd(c *gin.Context) {title := strings.Trim(c.PostForm("title"), " ")cateId, err1 := models.Int(c.PostForm("cate_id"))attrType, err2 := models.Int(c.PostForm("attr_type"))attrValue := c.PostForm("attr_value")sort, err3 := models.Int(c.PostForm("sort"))if err1 != nil || err2 != nil {con.Error(c, "非法请求", "/admin/goodsType")return}if title == "" {con.Error(c, "商品类型属性名称不能为空", "/admin/goodsTypeAttribute/add?cate_id="+models.String(cateId))return}if err3 != nil {con.Error(c, "排序值不对", "/admin/goodsTypeAttribute/add?cate_id="+models.String(cateId))return}goodsTypeAttr := models.GoodsTypeAttribute{Title:     title,CateId:    cateId,AttrType:  attrType,AttrValue: attrValue,Status:    1,Sort:      sort,AddTime:   int(models.GetUnix()),}err := models.DB.Create(&goodsTypeAttr).Errorif err != nil {con.Error(c, "增加商品类型属性失败 请重试", "/admin/goodsTypeAttribute/add?cate_id="+models.String(cateId))return}con.Success(c, "增加商品类型属性成功", "/admin/goodsTypeAttribute?id="+models.String(cateId))
}func (con GoodsTypeAttributeController) Edit(c *gin.Context) {//获取当前要修改数据的idid, err := models.Int(c.Query("id"))if err != nil {con.Error(c, "传入的参数不正确", "/admin/goodsType")return}//获取当前id对应的商品类型属性goodsTypeAttribute := models.GoodsTypeAttribute{Id: id}models.DB.Find(&goodsTypeAttribute)//获取所有的商品类型goodsTypeList := []models.GoodsType{}models.DB.Find(&goodsTypeList)c.HTML(http.StatusOK, "admin/goodsTypeAttribute/edit.html", gin.H{"goodsTypeAttribute": goodsTypeAttribute,"goodsTypeList":      goodsTypeList,})
}func (con GoodsTypeAttributeController) DoEdit(c *gin.Context) {id, err1 := models.Int(c.PostForm("id"))title := strings.Trim(c.PostForm("title"), " ")cateId, err2 := models.Int(c.PostForm("cate_id"))attrType, err3 := models.Int(c.PostForm("attr_type"))attrValue := c.PostForm("attr_value")sort, err4 := models.Int(c.PostForm("sort"))if err1 != nil || err2 != nil || err3 != nil {con.Error(c, "非法请求", "/admin/goodsType")return}if title == "" {con.Error(c, "商品类型属性名称不能为空", "/admin/goodsTypeAttribute/edit?id="+models.String(id))return}if err4 != nil {con.Error(c, "排序值不对", "/admin/goodsTypeAttribute/edit?id="+models.String(id))return}goodsTypeAttr := models.GoodsTypeAttribute{Id: id}models.DB.Find(&goodsTypeAttr)goodsTypeAttr.Title = titlegoodsTypeAttr.CateId = cateIdgoodsTypeAttr.AttrType = attrTypegoodsTypeAttr.AttrValue = attrValuegoodsTypeAttr.Sort = sorterr := models.DB.Save(&goodsTypeAttr).Errorif err != nil {con.Error(c, "修改数据失败", "/admin/goodsTypeAttribute/edit?id="+models.String(id))return}con.Success(c, "需改数据成功", "/admin/goodsTypeAttribute?id="+models.String(cateId))
}func (con GoodsTypeAttributeController) Delete(c *gin.Context) {id, err1 := models.Int(c.Query("id"))cateId, err2 := models.Int(c.Query("cate_id"))if err1 != nil || err2 != nil {con.Error(c, "传入参数错误", "/admin/goodsType")return}goodsTypeAttr := models.GoodsTypeAttribute{Id: id}models.DB.Delete(&goodsTypeAttr)con.Success(c, "删除数据成功", "/admin/goodsTypeAttribute?id="+models.String(cateId))
}

4.创建商品类型属性html以及js

在templates/admin/goodsTypeAttribute下创建商品类型属性相关html
修改状态以及排序操作代码见:[golang gin框架] 15.Gin 商城项目-封装上传图片方法,轮播图的增删改查以及异步修改状态,数量

index.html

{{ define "admin/goodsTypeAttribute/index.html" }}
{{ template "admin/public/page_header.html" .}}<div class="container-fluid"><div class="row"><div class="panel panel-default"><div class="panel-heading">{{.goodsType.Title}}   <a href="/admin/goodsTypeAttribute/add?cate_id={{.cateId}}" class="btn btn-primary">增加类型属性</a></div><!--列表展示--><div class="table-responsive"><table class="table table-bordered"><thead><tr class="th"><th>属性名称</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>{{$cateTitle := .goodsType.Title}}{{range $key,$value := .goodsTypeAttributeList}}<tr><td>{{$value.Title}}</td><td>{{$cateTitle}}</td><td>{{if eq $value.AttrType 1}}单行文本框{{else if eq $value.AttrType 2}}多行文本框{{else if eq $value.AttrType 3}}select下拉框{{end}}</td><td>{{$value.AttrValue}}</td><td>{{UnixToTime $value.AddTime}}</td><td><span class="chSpanNum" data-id="{{$value.Id}}" data-table="goods_type_attribute" data-field="sort">{{$value.Sort}}</span></td><td class="text-center">{{if eq $value.Status 1}}<img src="/static/admin/images/yes.gif" class="chStatus" data-id="{{$value.Id}}"data-table="goods_type_attribute" data-field="status" />{{else}}<img src="/static/admin/images/no.gif" class="chStatus" data-id="{{$value.Id}}"data-table="goods_type_attribute" data-field="status" />{{end}}</td><td class="text-center"><ahref="/admin/goodsTypeAttribute/edit?id={{$value.Id}}" >修改</a><a class="delete"href="/admin/goodsTypeAttribute/delete?id={{$value.Id}}&cate_id={{$value.CateId}}" >删除</a></td></tr>{{end}}</tbody></table></div></div></div>
</div></body>
</html>
{{end}}

add.html

{{ define "admin/goodsTypeAttribute/add.html" }}
{{ template "admin/public/page_header.html" .}}<div class="container-fluid"><div class="row"><div class="panel panel-default"><div class="panel-heading">增加商品类型属性</div><div class="panel-body"><div class="table-responsive input-form"><form action="/admin/goodsTypeAttribute/doAdd" method="post"><ul><li>  属性名称: <input type="text" name="title" /></li><li>  所属类型:{{$cateId := .cateId}}<select name="cate_id" id="cate_id">{{range $key,$value := .goodsTypeList}}<option {{if eq $cateId $value.Id}} selected {{end}}  value="{{$value.Id}}">{{$value.Title}}</option>  {{end}}</select></li><li>  录入方式:<input type="radio" name="attr_type" value="1" checked="true" id="text" /><labelfor="text">单行文本框</label>  <input type="radio" name="attr_type" value="2" id="textarea" /><labelfor="textarea">多行文本框</label>  <input type="radio" name="attr_type" value="3" id="select" /><labelfor="select">从下面的列表中选择(一行代表一个可选值)</label> </li><li>可选值列表:<textarea name="attr_value" id="attr_value" cols="60" rows="8" disabled="disabled"></textarea></li><li> <span>排  序:</span> <input type="text" name="sort" value="10" /></li><li><br /><button type="submit" class="btn btn-primary">提交</button></li></ul></form></div></div></div></div>
</div>
<script>$(function(){    $("input[name='attr_type").change(function(){// alert($(this).val())if($(this).val()==3){$("#attr_value").attr("disabled",false)}else{$("#attr_value").attr("disabled",true)}})
})
</script>
</body>
</html>{{end}}

edit.html

{{ define "admin/goodsTypeAttribute/edit.html" }}
{{ template "admin/public/page_header.html" .}}<div class="container-fluid"><div class="row"><div class="panel panel-default"><div class="panel-heading">修改商品类型属性</div><div class="panel-body"><div class="table-responsive input-form"><form action="/admin/goodsTypeAttribute/doEdit" method="post"><input type="hidden" name="id" value="{{.goodsTypeAttribute.Id}}" /><ul><li>  属性名称: <input type="text" name="title" value="{{.goodsTypeAttribute.Title}}" /></li><li>  所属类型:{{$cateId := .goodsTypeAttribute.CateId}}<select name="cate_id" id="cate_id">{{range $key,$value := .goodsTypeList}}<option {{if eq $cateId $value.Id}} selected {{end}}  value="{{$value.Id}}">{{$value.Title}}</option>  {{end}}</select></li><li>  录入方式:<input type="radio" name="attr_type" value="1" {{if eq .goodsTypeAttribute.AttrType 1}} checked="true" {{end}} id="text" /><labelfor="text">单行文本框</label>  <input type="radio" name="attr_type" value="2" {{if eq .goodsTypeAttribute.AttrType 2}} checked="true" {{end}}  id="textarea" /><labelfor="textarea">多行文本框</label>  <input type="radio" name="attr_type" value="3" {{if eq .goodsTypeAttribute.AttrType 3}} checked="true" {{end}}  id="select" /><labelfor="select">从下面的列表中选择(一行代表一个可选值)</label> </li><li>可选值列表:<textarea name="attr_value" id="attr_value" cols="60" rows="8" {{if ne .goodsTypeAttribute.AttrType 3}} disabled="disabled" {{end}}>{{.goodsTypeAttribute.AttrValue}}</textarea></li><li> <span>排  序:</span> <input type="text" name="sort" value="{{.goodsTypeAttribute.Sort}}" /></li><li><br /><button type="submit" class="btn btn-primary">提交</button></li></ul></form></div></div></div></div>
</div>
<script>$(function(){    $("input[name='attr_type").change(function(){// alert($(this).val())if($(this).val()==3){$("#attr_value").attr("disabled",false)}else{$("#attr_value").attr("disabled",true)}})
})
</script>
</body>
</html>{{end}}

5.配置路由

在routes/adminRouters.go下配置商品类型路由
//商品类型属性路由adminRouters.GET("/goodsTypeAttribute", admin.GoodsTypeAttributeController{}.Index)adminRouters.GET("/goodsTypeAttribute/add", admin.GoodsTypeAttributeController{}.Add)adminRouters.POST("/goodsTypeAttribute/doAdd", admin.GoodsTypeAttributeController{}.DoAdd)adminRouters.GET("/goodsTypeAttribute/edit", admin.GoodsTypeAttributeController{}.Edit)adminRouters.POST("/goodsTypeAttribute/doEdit", admin.GoodsTypeAttributeController{}.DoEdit)adminRouters.GET("/goodsTypeAttribute/delete", admin.GoodsTypeAttributeController{}.Delete)

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

[下一节][golang gin框架] 18.GoLang 图像处理,剪切图片,生成图片二维码

相关文章:

[golang gin框架] 17.Gin 商城项目-商品分类模块, 商品类型模块,商品类型属性模块功能操作

一.商品分类的增、删、改、查,以及商品分类的自关联1.界面展示以及操作说明列表商品分类列表展示说明:(1).增加商品分类按钮(2).商品分类,以及子分类相关数据列表展示(3).排序,状态,修改,删除操作处理 新增编辑删除修改状态,排序2.创建商品分类模型在controllers/admin下创建Go…...

Redis安装-使用包管理安装Redis

这种在Linux上使用apt-get包管理器安装Redis的方式称为“包管理安装”。这种安装方式使用操作系统的官方软件库来获取和安装软件包&#xff0c;可以自动处理软件包的依赖关系&#xff0c;并确保软件包与系统其他部分兼容。这是一种安全、可靠且方便的安装方式&#xff0c;适用于…...

HTML属性的概念和使用

通过前面的学习&#xff0c;我们已经对 HTML标签 有了简单的认识&#xff0c;知道可以在标签中可以添加一些属性&#xff0c;这些属性包含了标签的额外信息&#xff0c;例如&#xff1a; href 属性可以为 <a> 标签提供链接地址&#xff1b;src 属性可以为 <img> 标…...

ChatGPT基础知识系列之一文说透ChatGPT

ChatGPT基础知识系列之一文说透ChatGPT OpenAI近期发布聊天机器人模型ChatGPT,迅速出圈全网。它以对话方式进行交互。以更贴近人的对话方式与使用者互动,可以回答问题、承认错误、挑战不正确的前提、拒绝不适当的请求。高质量的回答、上瘾式的交互体验,圈内外都纷纷惊呼。 …...

‘go install‘ requires a version when current directory is not in a module

背景 安装好环境之后&#xff0c;跑个helloworld看看 目录结构 workspacepathsrchellohelloworld.go代码&#xff1a; package mainimport "fmt"func main() { fmt.Println("Hello World") }1.使用 go run 命令 - 在命令提示符旁&#xff0c;输入 go …...

蓝桥杯嵌入式第十三届(第二套客观题)

文章目录 前言一、题目1二、题目2三、题目3四、题目4五、题目5六、题目6七、题目7八、题目8九、题目9十、题目10总结前言 本篇文章继续讲解客观题。 一、题目1 这个其实属于送分题,了解嵌入式或者以后想要入行嵌入式的同学应该都对嵌入式特点有所了解。 A. 采用专用微控制…...

FFmpeg进阶:各种输入输出设备

文章目录查看设备列表输入设备介绍输出设备介绍查看设备列表 我们可以通过ffmpeg自带的工具查看系统支持的设备列表信息, 对应的指令如下所示: ffmpeg -devices输入设备介绍 通过配置ffmpeg的输入设备,我们可以访问系统中的某个多媒体设备的数据。下面详细介绍一下各个系统中…...

使用Shell笔记总结

一、变量 1、定义变量不加$符号&#xff0c;使用变量要用$&#xff1b;等号两边不能直接接空格符&#xff1b;通常大写字符为系统默认变量&#xff0c;自行设定变量可以使用小写字符。 2、双引号内的特殊字符如 $ 等&#xff0c;可以保有其符号代表的特性&#xff0c;即可以有…...

反常积分的审敛法

目录 无穷先的反常积分的审敛法 定理1&#xff1a;比较判别法 例题&#xff1a; 比较判别法的极限形式&#xff1a; 例题&#xff1a; 定理3&#xff1a;绝对收敛准则 例题&#xff1a; 无界函数的反常积分收敛法 例题&#xff1a; 无穷先的反常积分的审敛法 定理1&#x…...

python实战应用讲解-【numpy专题篇】numpy常见函数使用示例(十三)(附python示例代码)

目录 Python numpy.ma.mask_or()函数 Python numpy.ma.notmasked_contiguous函数 Python numpy.ma.notmasked_edges()函数 Python numpy.ma.where()函数 Python Numpy MaskedArray.all()函数 Python Numpy MaskedArray.anom()函数 Python Numpy MaskedArray.any()函数 …...

Java设计模式(十九)—— 桥接模式

桥接模式定义如下&#xff1a;将抽象部分与它的实现部分分离&#xff0c;使它们都可以独立地变化。 适合桥接模式的情景如下&#xff1a; 不希望抽象和某些重要的实现代码是绑定关系&#xff0c;可运行时动态决定抽象和实现者都可以继承的方式独立的扩充&#xff0c;程序在运行…...

多线程并发安全问题

文章目录并发安全问题线程安全性死锁定义实现一个死锁查看死锁解决死锁其他线程安全问题单例模式并发安全问题 线程安全性 线程安全是指我们所写的代码在并发情况下使用时&#xff0c;总是能表现出正确的行为&#xff1b;反之&#xff0c;未实现线程安全的代码&#xff0c;表…...

P1005 [NOIP2007 提高组] 矩阵取数游戏

题目描述 帅帅经常跟同学玩一个矩阵取数游戏&#xff1a;对于一个给定的 &#xfffd;&#xfffd;nm 的矩阵&#xff0c;矩阵中的每个元素 &#xfffd;&#xfffd;,&#xfffd;ai,j​ 均为非负整数。游戏规则如下&#xff1a; 每次取数时须从每行各取走一个元素&#xff…...

百度云【人脸识别】

目录 1&#xff1a;百度云【人脸识别云服务】 2&#xff1a;Java-SDK文档 3&#xff1a;项目中测试 1&#xff1a;百度云【人脸识别云服务】 人脸识别云服务 包含实名认证、人脸对比、人脸搜索、活体检测等能力。灵活应用于金融、泛安防等行业场景&#xff0c;满足身份核验…...

强化模板模块

一、非类型模板参数 模板参数分为 类型模板参数(C模板的零基础讲解)和非类型模板参数。 看下面的代码 #define N 10 //T就是类型模板参数 template<class T> class Array { private:T a[N]; }; int main() {Array<int> a1;Array<double> a2;return 0; }上面…...

Vue.js学习详细课程系列--共32节(6 / 6)

Vue.js学习课程&#xff08;6 / 6&#xff09;29. 组件&#xff1a;参数验证知识点组件的数据综合例30. 组件&#xff1a;事件传递知识点v-on$emit综合例31. 组件&#xff1a;slot插槽知识点slot综合例32. 组件&#xff1a;组合slot知识点slot命名综合例29. 组件&#xff1a;参…...

【TFT屏幕】1.44寸彩屏

文章目录一.硬件层——引脚配置的移植二.应用层——显示函数的移植1. 移植显示一个字符函数2. 移植显示数字函数3.叠加方式选择一.硬件层——引脚配置的移植 宏定义的方式&#xff0c;直接修改引脚&#xff0c;实测可直接更改&#xff0c;非常方便移植 /*******************…...

vue3组合式api

文章目录组合式API介绍什么是组合式 API&#xff1f;为什么要有组合式 API&#xff1f;更好的逻辑复用更灵活的代码组织Option ApiOption Api的缺陷Composition Api更好的类型推导更小的生产包体积与选项式 API 的关系取舍组合式 API 是否覆盖了所有场景&#xff1f;可以同时使…...

Maven高级-私服

Maven高级-私服6&#xff0c;私服6.1 私服简介6.2 私服安装步骤1:下载解压步骤2:启动Nexus步骤3:浏览器访问步骤4:首次登录重置密码6.3 私服仓库分类6.4 本地仓库访问私服配置步骤1:私服上配置仓库步骤2:配置本地Maven对私服的访问权限步骤3:配置私服的访问路径6.5 私服资源上传…...

网络优化小结

网络基础知识 OSI七层网络架构 OSI简称Open System Intercnnect&#xff0c;开放式系统互联&#xff0c;是一个国际互联网标准制定的一个组织 应用层 实际应用场景&#xff0c;比如 浏览器、文件传输、电子邮件、文件服务、虚拟终端等&#xff1b; http、FTP、ssh等 表示层…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...