[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的方式称为“包管理安装”。这种安装方式使用操作系统的官方软件库来获取和安装软件包,可以自动处理软件包的依赖关系,并确保软件包与系统其他部分兼容。这是一种安全、可靠且方便的安装方式,适用于…...
HTML属性的概念和使用
通过前面的学习,我们已经对 HTML标签 有了简单的认识,知道可以在标签中可以添加一些属性,这些属性包含了标签的额外信息,例如: href 属性可以为 <a> 标签提供链接地址;src 属性可以为 <img> 标…...
ChatGPT基础知识系列之一文说透ChatGPT
ChatGPT基础知识系列之一文说透ChatGPT OpenAI近期发布聊天机器人模型ChatGPT,迅速出圈全网。它以对话方式进行交互。以更贴近人的对话方式与使用者互动,可以回答问题、承认错误、挑战不正确的前提、拒绝不适当的请求。高质量的回答、上瘾式的交互体验,圈内外都纷纷惊呼。 …...
‘go install‘ requires a version when current directory is not in a module
背景 安装好环境之后,跑个helloworld看看 目录结构 workspacepathsrchellohelloworld.go代码: package mainimport "fmt"func main() { fmt.Println("Hello World") }1.使用 go run 命令 - 在命令提示符旁,输入 go …...
蓝桥杯嵌入式第十三届(第二套客观题)
文章目录 前言一、题目1二、题目2三、题目3四、题目4五、题目5六、题目6七、题目7八、题目8九、题目9十、题目10总结前言 本篇文章继续讲解客观题。 一、题目1 这个其实属于送分题,了解嵌入式或者以后想要入行嵌入式的同学应该都对嵌入式特点有所了解。 A. 采用专用微控制…...
FFmpeg进阶:各种输入输出设备
文章目录查看设备列表输入设备介绍输出设备介绍查看设备列表 我们可以通过ffmpeg自带的工具查看系统支持的设备列表信息, 对应的指令如下所示: ffmpeg -devices输入设备介绍 通过配置ffmpeg的输入设备,我们可以访问系统中的某个多媒体设备的数据。下面详细介绍一下各个系统中…...
使用Shell笔记总结
一、变量 1、定义变量不加$符号,使用变量要用$;等号两边不能直接接空格符;通常大写字符为系统默认变量,自行设定变量可以使用小写字符。 2、双引号内的特殊字符如 $ 等,可以保有其符号代表的特性,即可以有…...
反常积分的审敛法
目录 无穷先的反常积分的审敛法 定理1:比较判别法 例题: 比较判别法的极限形式: 例题: 定理3:绝对收敛准则 例题: 无界函数的反常积分收敛法 例题: 无穷先的反常积分的审敛法 定理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设计模式(十九)—— 桥接模式
桥接模式定义如下:将抽象部分与它的实现部分分离,使它们都可以独立地变化。 适合桥接模式的情景如下: 不希望抽象和某些重要的实现代码是绑定关系,可运行时动态决定抽象和实现者都可以继承的方式独立的扩充,程序在运行…...
多线程并发安全问题
文章目录并发安全问题线程安全性死锁定义实现一个死锁查看死锁解决死锁其他线程安全问题单例模式并发安全问题 线程安全性 线程安全是指我们所写的代码在并发情况下使用时,总是能表现出正确的行为;反之,未实现线程安全的代码,表…...
P1005 [NOIP2007 提高组] 矩阵取数游戏
题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的 ��nm 的矩阵,矩阵中的每个元素 ��,�ai,j 均为非负整数。游戏规则如下: 每次取数时须从每行各取走一个元素ÿ…...
百度云【人脸识别】
目录 1:百度云【人脸识别云服务】 2:Java-SDK文档 3:项目中测试 1:百度云【人脸识别云服务】 人脸识别云服务 包含实名认证、人脸对比、人脸搜索、活体检测等能力。灵活应用于金融、泛安防等行业场景,满足身份核验…...
强化模板模块
一、非类型模板参数 模板参数分为 类型模板参数(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学习课程(6 / 6)29. 组件:参数验证知识点组件的数据综合例30. 组件:事件传递知识点v-on$emit综合例31. 组件:slot插槽知识点slot综合例32. 组件:组合slot知识点slot命名综合例29. 组件:参…...
【TFT屏幕】1.44寸彩屏
文章目录一.硬件层——引脚配置的移植二.应用层——显示函数的移植1. 移植显示一个字符函数2. 移植显示数字函数3.叠加方式选择一.硬件层——引脚配置的移植 宏定义的方式,直接修改引脚,实测可直接更改,非常方便移植 /*******************…...
vue3组合式api
文章目录组合式API介绍什么是组合式 API?为什么要有组合式 API?更好的逻辑复用更灵活的代码组织Option ApiOption Api的缺陷Composition Api更好的类型推导更小的生产包体积与选项式 API 的关系取舍组合式 API 是否覆盖了所有场景?可以同时使…...
Maven高级-私服
Maven高级-私服6,私服6.1 私服简介6.2 私服安装步骤1:下载解压步骤2:启动Nexus步骤3:浏览器访问步骤4:首次登录重置密码6.3 私服仓库分类6.4 本地仓库访问私服配置步骤1:私服上配置仓库步骤2:配置本地Maven对私服的访问权限步骤3:配置私服的访问路径6.5 私服资源上传…...
网络优化小结
网络基础知识 OSI七层网络架构 OSI简称Open System Intercnnect,开放式系统互联,是一个国际互联网标准制定的一个组织 应用层 实际应用场景,比如 浏览器、文件传输、电子邮件、文件服务、虚拟终端等; http、FTP、ssh等 表示层…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
