百木园-与人分享,
就是让自己快乐。

在线客服系统源码开发实战总结:Golang实现CMS内容管理增删查改功能

自己的客服系统做好了,官网页面也有了,但是没有介绍性的内容文章。网站被收录的太少,这样会导致网站的权重不高,搜索排名比较低。

因此要简单的加上一个小型的内容管理功能。

设计数据库

很简单的两张表,分类表和内容表

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
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » 在线客服系统源码开发实战总结:Golang实现CMS内容管理增删查改功能

相关推荐

  • 暂无文章