自己的客服系统做好了,官网页面也有了,但是没有介绍性的内容文章。网站被收录的太少,这样会导致网站的权重不高,搜索排名比较低。
因此要简单的加上一个小型的内容管理功能。
设计数据库
很简单的两张表,分类表和内容表
DROP TABLE IF EXISTS `cms_cate`; CREATE TABLE `cms_cate` ( `id` int(11) NOT NULL AUTO_INCREMENT, `cat_name` varchar(50) NOT NULL DEFAULT \'\' COMMENT \'分类名称\', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT \'创建时间\', PRIMARY KEY (`id`) COMMENT \'自增主键索引\' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT \'CMS分类表\'; DROP TABLE IF EXISTS `cms_news`; CREATE TABLE `cms_news` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(500) COLLATE utf8mb4_general_ci NOT NULL DEFAULT \'\' COMMENT \'标题\', `content` text COLLATE utf8mb4_general_ci COMMENT \'内容\', `cat_id` int(11) NOT NULL DEFAULT \'0\' COMMENT \'分类ID\', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT \'创建时间\', PRIMARY KEY (`id`) COMMENT \'自增主键索引\' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT \'CMS内容表\';
编写数据库操作gorm Model部分
设计两个结构体
type CmsCate struct { Id uint `json:\"id\"` CatName string `json:\"cat_name\"` CreatedAt types.Time `json:\"created_at\"` } type CmsNews struct { Id uint `json:\"id\"` Title string `json:\"title\"` Content string `json:\"content\"` CreatedAt types.Time `json:\"created_at\"` }
types.Time类型是我对time.Time类型的包装,用于在序列化为json的时候,可以格式化时间
package types import ( \"database/sql/driver\" \"fmt\" \"time\" ) type Time struct { time.Time } func (t Time) MarshalJSON() ([]byte, error) { localTime := t.Format(\"2006-01-02 15:04:05\") return []byte(fmt.Sprintf(`\"%s\"`, localTime)), nil } func (t Time) Value() (driver.Value, error) { var zeroTime time.Time if t.Time.UnixNano() == zeroTime.UnixNano() { return nil, nil } return t.Time, nil } func (t *Time) Scan(v interface{}) error { value, ok := v.(time.Time) if ok { *t = Time{Time: value} return nil } return fmt.Errorf(\"can not convert %v to timestamp\", v) }
分类表和内容表的增删查改
DB就是*gorm.DB类型,这是在链接数据库的时候,已经赋值好的全局变量
/*内容表*/ //根据条件查询条数 func CountCmsNews(query interface{}, args ...interface{}) uint { var v uint DB.Table(\"cms_news\").Where(query, args...).Count(&v) return v } //根据条件更新 func (this *CmsNews) SaveCmsNews(query interface{}, args ...interface{}) error { db := DB.Table(\"cms_news\").Where(query, args...).Update(this) return db.Error } //增加数据 func (this *CmsNews) AddCmsNews() error { return DB.Create(this).Error } //根据条件查询分页列表 func FindCmsNews(page, pagesize int, query interface{}, args ...interface{}) []CmsNews { offset := (page - 1) * pagesize var res []CmsNews DB.Table(\"cms_news\").Where(query, args...).Order(\"id desc\").Offset(offset).Limit(pagesize).Find(&res) return res } //根据条件删除 func DelCmsNews(query interface{}, args ...interface{}) error { return DB.Where(query, args...).Delete(&CmsNews{}).Error } /*分类表*/ //根据条件分类 func (this *CmsCate) SaveCmsCate(query interface{}, args ...interface{}) error { db := DB.Table(\"cms_cate\").Where(query, args...).Update(this) return db.Error } //增加分类 func (this *CmsCate) AddCmsCate() error { return DB.Create(this).Error } //根据条件查询分类列表 func FindCmsCate(page, pagesize int, query interface{}, args ...interface{}) []CmsCate { offset := (page - 1) * pagesize var res []CmsCate DB.Table(\"cms_cate\").Where(query, args...).Order(\"id desc\").Offset(offset).Limit(pagesize).Find(&res) return res } //根据条件删除分类 func DelCmsCate(query interface{}, args ...interface{}) error { return DB.Where(query, args...).Delete(&CmsCate{}).Error }
编写gin路由处理部分
gin路由入口
//系统相关 systemGroup := engine.Group(\"/system\") systemGroup.Use() { //分类列表 systemGroup.GET(\"/cmsCate\", controller.GetCmsCate) //删除分类 systemGroup.GET(\"/delCmsCate\", controller.DelCmsCate) //增加或编辑分类 systemGroup.POST(\"/cmsCate\", controller.PostCmsCate) //CMS内容列表 systemGroup.GET(\"/cmsNews\", controller.GetCmsNews) //增加或编辑内容 systemGroup.POST(\"/cmsNews\", controller.PostCmsNews) //删除内容 systemGroup.GET(\"/delCmsNews\", controller.DelCmsNews) }
gin框架路由处理逻辑
返回参数部分,我进行了小的封装,可以参考去掉。
只看调用model部分的处理逻辑
package controller import ( \"github.com/gin-gonic/gin\" \"kefu/models\" \"kefu/types\" \"strconv\" ) type CmsCateForm struct { Id uint `form:\"id\" json:\"id\" uri:\"id\" xml:\"id\"` CateName string `form:\"cate_name\" json:\"cate_name\" uri:\"cate_name\" xml:\"cate_name\" binding:\"required\"` } //分类列表(暂不分页) func GetCmsCate(c *gin.Context) { list := models.FindCmsCate(1, 1000, \"\") c.JSON(200, gin.H{ \"code\": types.ApiCode.SUCCESS, \"msg\": types.ApiCode.GetMessage(types.ApiCode.SUCCESS), \"result\": list, }) } //编辑CMS分类 func PostCmsCate(c *gin.Context) { var form CmsCateForm err := c.Bind(&form) if err != nil { c.JSON(200, gin.H{ \"code\": types.ApiCode.FAILED, \"msg\": types.ApiCode.GetMessage(types.ApiCode.INVALID), \"result\": err.Error(), }) return } modelCms := &models.CmsCate{ Id: form.Id, CatName: form.CateName, } //添加分类 if form.Id == 0 { err := modelCms.AddCmsCate() if err != nil { c.JSON(200, gin.H{ \"code\": types.ApiCode.FAILED, \"msg\": err.Error(), }) return } } else { //修改分类 err := modelCms.SaveCmsCate(\"id = ?\", form.Id) if err != nil { c.JSON(200, gin.H{ \"code\": types.ApiCode.FAILED, \"msg\": err.Error(), }) return } } c.JSON(200, gin.H{ \"code\": types.ApiCode.SUCCESS, \"msg\": types.ApiCode.GetMessage(types.ApiCode.SUCCESS), }) } type CmsNewsForm struct { Id uint `form:\"id\" json:\"id\" uri:\"id\" xml:\"id\"` CateId string `form:\"cate_id\" json:\"cate_id\" uri:\"cate_id\" xml:\"cate_id\" binding:\"required\"` Content string `form:\"content\" json:\"content\" uri:\"content\" xml:\"content\" binding:\"required\"` Title string `form:\"title\" json:\"title\" uri:\"title\" xml:\"title\" binding:\"required\"` } //CMS内容列表 func GetCmsNews(c *gin.Context) { //分页处理 page, _ := strconv.Atoi(c.Query(\"page\")) if page <= 0 { page = 1 } pagesize, _ := strconv.Atoi(c.Query(\"pagesize\")) if pagesize <= 0 || pagesize > 50 { pagesize = 10 } //判断分类ID条件 catId := c.Query(\"cat_id\") query := \"1=1 \" args := make([]interface{}, 0) if catId != \"\" { query += \"and cat_id = ? \" args = append(args, catId) } //分页查询 count := models.CountCmsNews(query, args...) list := models.FindCmsNews(page, pagesize, query, args...) c.JSON(200, gin.H{ \"code\": types.ApiCode.SUCCESS, \"msg\": types.ApiCode.GetMessage(types.ApiCode.SUCCESS), \"result\": gin.H{ \"list\": list, \"count\": count, \"pagesize\": pagesize, \"page\": page, }, }) } //编辑CMS内容 func PostCmsNews(c *gin.Context) { var form CmsNewsForm err := c.Bind(&form) if err != nil { c.JSON(200, gin.H{ \"code\": types.ApiCode.FAILED, \"msg\": types.ApiCode.GetMessage(types.ApiCode.INVALID), \"result\": err.Error(), }) return } modelCms := &models.CmsNews{ Id: form.Id, CatId: form.CateId, Title: form.Title, } //添加 if form.Id == 0 { err := modelCms.AddCmsNews() if err != nil { c.JSON(200, gin.H{ \"code\": types.ApiCode.FAILED, \"msg\": err.Error(), }) return } } else { //修改 err := modelCms.SaveCmsNews(\"id = ?\", form.Id) if err != nil { c.JSON(200, gin.H{ \"code\": types.ApiCode.FAILED, \"msg\": err.Error(), }) return } } c.JSON(200, gin.H{ \"code\": types.ApiCode.SUCCESS, \"msg\": types.ApiCode.GetMessage(types.ApiCode.SUCCESS), }) } //删除分类 func DelCmsCate(c *gin.Context) { id := c.Query(\"id\") err := models.DelCmsCate(\"id = ?\", id) if err != nil { c.JSON(200, gin.H{ \"code\": types.ApiCode.FAILED, \"msg\": err.Error(), }) return } c.JSON(200, gin.H{ \"code\": types.ApiCode.SUCCESS, \"msg\": types.ApiCode.GetMessage(types.ApiCode.SUCCESS), }) } //删除内容 func DelCmsNews(c *gin.Context) { id := c.Query(\"id\") err := models.DelCmsNews(\"id = ?\", id) if err != nil { c.JSON(200, gin.H{ \"code\": types.ApiCode.FAILED, \"msg\": err.Error(), }) return } c.JSON(200, gin.H{ \"code\": types.ApiCode.SUCCESS, \"msg\": types.ApiCode.GetMessage(types.ApiCode.SUCCESS), }) }
可以使用接口测试工具,对接口进行测试
十年开发经验程序员,离职全心创业中,历时三年开发出的产品《唯一客服系统》
一款基于Golang+Vue开发的在线客服系统,软件著作权编号:2021SR1462600。一套可私有化部署的网站在线客服系统,编译后的二进制文件可直接使用无需搭开发环境,下载zip解压即可,仅依赖MySQL数据库,是一个开箱即用的全渠道在线客服系统,致力于帮助广大开发者/公司快速部署整合私有化客服功能。
开源地址:唯一客服(开源学习版)
官网地址:唯一客服官网
来源:https://www.cnblogs.com/taoshihan/p/16901834.html
本站部分图文来源于网络,如有侵权请联系删除。