技能学习:学习使用golang(gin框架) + vue.js,开发前端全栈网站-7.GO语言做通用CRUD接口-2
相关文章: 技能学习:学习使用golang(gin框架) + vue.js,开发前端全栈网站-1.工具和本地环境 技能学习:学习使用golang(gin框架) + vue.js,开发前端全栈网站-2.启动项目 技能学习:学习使用golang(gin框架) + vue.js,开发前端全栈网站-3.接收json数据 技能学习:学习使用golang(gin框架) + vue.js,开发前端全栈网站-4.连接mongodb数据库 技能学习:学习使用golang(gin框架) + vue.js,开发前端全栈网站-5.跨域并跨域传输数据 技能学习:学习使用golang(gin框架) + vue.js,开发前端全栈网站-6.GO语言做通用CRUD接口-1 技能学习:学习使用golang(gin框架) + vue.js,开发前端全栈网站-7.GO语言做通用CRUD接口-2
1.制作分类功能的列表页
CategoryList.vue:
<template>
<div>
<h1>分类列表</h1>
<el-table :data="items">
<el-table-column prop="_id" label="ID" width="220">
</el-table-column>
<el-table-column prop="parent.name" label="上级分类">
</el-table-column>
<el-table-column prop="name" label="分类名称">
</el-table-column>
<el-table-column
fixed="right"
label="操作"
width="100">
<template slot-scope="scope">
<el-button type="text" size="small" @click="$router.push('/categories/edit/' + scope.row._id)">编辑</el-button>
<el-button @click="remove(scope.row)" type="text" size="small">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
items: []
}
},
methods: {
async fetch(){
const res = await this.$http.get('rest/categories')
this.items = res.data
},
remove(row){
this.$confirm('是否确定要删除分类"' + row.name + '"?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
const res = await this.$http.delete('rest/categories/' + row._id)
this.$message({
type: 'success',
message: '删除成功!'
});
if(res.status == 200){
this.fetch()
}
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
}
},
created() {
this.fetch()
}
}
</script>
解释:  在首页导航中引入该页面:  在路由页面引入组件和路由:  保存进入admin端页面查看效果: 
2.CRUD接口中的查找数据
可以看到上方页面已经显示成功,但是里边的数据并没有呈现出来,是因为查询数据接口还没有完善,下面针对查找信息接口进行完善: (1)接口地址:  接口地址正确,没问题。 (2)接口函数:  目前接口函数还是最开始我们学习接口路由时,测试使用user表的数据模型,与现在接口不匹配,所以我们要整改一下:  此时,编译测试,没问题。  在admin端页面进入分类列表页面:  接口调用成功,但没有成功后的数据。检查原因:  我们的接口传值为categories,但是表名和参数判断为category,所以把接口传递的参数改为category即可:  保存刷新admin端,测试还是不行,原来是因为没有将获取的数据以json格式返回:  重新编译进行测试:  查询所有数据成功,没问题。
3.CRUD接口中的删除数据
检查接口:  优化删除接口:  由于删除字段的命令相同,不需要用到模型,所以免去了if-else判断模型字段的过程。 编译运行,测试:    此时可以看到过程都没问题,但是我们想删除的字段并没有删除成功,查看运行结果:  原因是web端中id值没有传成功,也就是没有找到该条信息中的id。 同时我也意识到之前的查询接口中,也没有成功查询到id字段:  经短时间查找原因,发现一个大BUG,虽然我们插入字段的过程中mongodb会自动生成_id,所以不需要在模型中定义id字段,但我们查询数据是需要通过模型进行查询的:  于是我们需要在模型中添加一个id字段:  保存编译,刷新页面测试:  _id字段就查询出来了,同时上方ID也显示。 此时再测试删除字段:  旭,居然还在:  检查问题!查看手册!!百度!!!! 原因是数据库中的id是个bson格式,而我们传来的id是string字符串格式,所以使用id字段需要把它变成bson格式:  我就不信,这次一定可以! 编译执行测试: 还!是!不!可!以!!! 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊,接着查:  hehe,居然又是传参错误,改成category。  测试:  成功了,可以,研究一下午终于成了。
4.CRUD接口中的单条查询和修改数据
我们修改分类功能复用添加分类功能的组件categorySet.vue组件:  修改组件:
<template>
<div>
<h1>创建分类</h1>
<el-form label-width="80px" style="margin-top:20px;" @submit.native.prevent="save">
<el-form-item label="分类名">
<el-input v-model="model.name"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" native-type="submit">保存</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data(){
return {
model: {}
}
},
methods: {
async save(){
let res
if(this.id){
res = await this.$http.put('rest/categories/' + this.id, this.model)
}else{
res = await this.$http.post('rest/categories', this.model)
}
this.$router.push('/categories/list')
this.$message({
type: 'success',
message: '保存成功'
})
},
async fetch(){
const res = await this.$http.get('rest/categories/' + this.id)
this.model = res.data
},
},
created(){
this.id && this.fetch()
}
}
</script>
 修改完成,测试:  说res没有被使用,小bug不足为虑,在下边console一个即可:  再测试,新建分类:  列表页面点击编辑,暂时没有页面生成:  应该是无法获取id,继续修改,给CategorySet.vue中添加props:  同时在admin/index.js路由文件中添加修改数据路由:  最后,在编辑按钮路由地址处将create改成edit:  保存,重新点击编辑:   页面出现,说明组件复用成功,但是数据没有查询成功。  (1)CRUD根据id查询数据接口: 第一步,还是改前端接口调用处的categories:  第二步,修改根据id查询数据接口:  编译启动,测试:  成功,没问题。 (2)CRUD修改数据 接口:  调用接口地址没问题,调整修改数据接口:  编译启动,测试,将123改为“node.js”:  接口调用成功,但数据没有成功修改:  经过二次测试,发现form没有值:  进一步搞懂,根据模型为form赋值的方法需要有.bind()方法进行数据的合并,同时&form已经是json格式,不需要使用bson.M方法,修改如下:  此时,重新编译启动,修改测试:  成功。 到此restful风格的CRUD接口全部完成,下面将全部后端接口贴给大家:
package db
import(
"github.com/gin-gonic/gin"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"net/http"
"strings"
"server/models"
)
func insert(ctx *gin.Context){
resource := ctx.Param("resource")
url := "mongodb://127.0.0.1"
session, err := mgo.Dial(url)
if err != nil {
panic(err)
}else{
ctx.String(http.StatusOK, "插入成功")
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
c := session.DB("db_go").C(resource)
if resource == "user" {
type modelName models.User
var form modelName
if err := ctx.Bind(&form); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
err = c.Insert(&form)
} else if resource == "category" {
type modelName models.Category
var form modelName
if err := ctx.Bind(&form); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
err = c.Insert(&form)
}
}
func find(ctx *gin.Context){
resource := ctx.Param("resource")
id := ctx.Param("id")
id = strings.Trim(id, "/")
var _id bson.ObjectId
_id = bson.ObjectIdHex(id)
url := "mongodb://127.0.0.1"
session, err := mgo.Dial(url)
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
c := session.DB("db_go").C(resource)
if resource == "user" {
type modelName models.User
modelNamer := modelName{}
err = c.Find(bson.M{"_id": _id}).One(&modelNamer)
ctx.JSON(http.StatusOK, modelNamer)
} else if resource == "category" {
type modelName models.Category
modelNamer := modelName{}
err = c.Find(bson.M{"_id": _id}).One(&modelNamer)
ctx.JSON(http.StatusOK, modelNamer)
}
}
func findAll(ctx *gin.Context){
resource := ctx.Param("resource")
url := "mongodb://127.0.0.1"
session, err := mgo.Dial(url)
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
c := session.DB("db_go").C(resource)
if resource == "user" {
type modelName models.User
modelNames := make([]modelName, 10)
err = c.Find(nil).All(&modelNames)
ctx.JSON(http.StatusOK, modelNames)
} else if resource == "category" {
type modelName models.Category
modelNames := make([]modelName, 10)
err = c.Find(nil).All(&modelNames)
ctx.JSON(http.StatusOK, modelNames)
}
}
func delete(ctx *gin.Context){
resource := ctx.Param("resource")
id := ctx.Param("id")
id = strings.Trim(id, "/")
var _id bson.ObjectId
_id = bson.ObjectIdHex(id)
url := "mongodb://127.0.0.1"
session, err := mgo.Dial(url)
if err != nil {
panic(err)
}else{
ctx.String(http.StatusOK, id)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
c := session.DB("db_go").C(resource)
err = c.Remove(bson.M{"_id": _id})
}
func update(ctx *gin.Context){
resource := ctx.Param("resource")
id := ctx.Param("id")
id = strings.Trim(id, "/")
var _id bson.ObjectId
_id = bson.ObjectIdHex(id)
url := "mongodb://127.0.0.1"
session, err := mgo.Dial(url)
if err != nil {
panic(err)
}else{
ctx.String(http.StatusOK, "修改成功")
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
c := session.DB("db_go").C(resource)
if resource == "user" {
type modelName models.User
var form modelName
if err := ctx.Bind(&form); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
err = c.Update(bson.M{"_id": _id}, &form)
ctx.JSON(http.StatusOK, &form)
} else if resource == "category" {
type modelName models.Category
var form modelName
if err := ctx.Bind(&form); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
err = c.Update(bson.M{"_id": _id}, &form)
ctx.JSON(http.StatusOK, &form)
}
}
func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token")
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
c.Header("Access-Control-Allow-Credentials", "true")
if method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
}
c.Next()
}
}
func Main(e *gin.Engine) {
e.Use(Cors())
e.POST("/admin/api/rest/:resource", insert)
e.DELETE("/admin/api/rest/:resource/*id", delete)
e.PUT("/admin/api/rest/:resource/*id", update)
e.GET("/admin/api/rest/:resource", findAll)
// 根据id查某数据
e.GET("/admin/api/rest/:resource/*id", find)
}
大家学习过程有任何疑问可以留言,我研究好后进行回复。 下篇文章我们开始研究mongodb数据库特有的关联方法(无限级分类)。
更多设计、功能的学习经验,大家也可以去我的公众号查看!
———— 
|