技能学习:学习使用golang(gin框架) + vue.js,开发前端全栈网站-7.GO语言做通用CRUD接口-2 - Go语言中文社区

技能学习:学习使用golang(gin框架) + vue.js,开发前端全栈网站-7.GO语言做通用CRUD接口-2


技能学习:学习使用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
技能学习:学习使用golang(gin框架) + vue.js,开发前端全栈网站-8.模型的关联——无限层级分类
技能学习:学习使用golang(gin框架) + vue.js,开发前端全栈网站-9.管理员及登录注册功能的实现
技能学习:学习使用golang(gin框架) + vue.js,开发前端全栈网站-10.生产环境编译

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 () => {
                // 要想使用await,函数必须使用async
                // await异步执行,待调用接口获取数据完成后再将值传给res,进行下一步操作
                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">
            <!-- submit事件中使用提交方法save,native是找到js原生表单,prevent是指阻止提交时默认跳转页面 -->
            <el-form-item label="分类名">
                <el-input v-model="model.name"></el-input>
                <!-- 双向绑定model -->
            </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..await异步请求方法
        async save(){
            let res
            // 这里放axios方法,用来提交数据
            if(this.id){
                // 传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')
            // 提示信息,使用vue中自带的$message实例
            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"
	// "fmt"
	
	// 引入模型
	"server/models"
)

// 插入数据
func insert(ctx *gin.Context){

	// 解析api参数
	resource := ctx.Param("resource")

	// 连接mongodb服务
	url := "mongodb://127.0.0.1"
	// 设置数据库一致性模式
	// 连接数据库操作,该操作赋值给session
	// err值必写,用于错误处理
	session, err := mgo.Dial(url)
	// 后边程序执行的err与go程序比对,若有错误则返回错误内容
	if err != nil { 
		panic(err) 
	}else{
		// 若没有错误,则在页面返回字符串,显示插入成功
		ctx.String(http.StatusOK, "插入成功")
	}
	// defer用法大家自行百度,我解释不清
	defer session.Close()

	// 设置数据库一致性模式,就当作打开数据库
	session.SetMode(mgo.Monotonic, true)
	// 找到某数据库下的某数据表
	c := session.DB("db_go").C(resource)
	// 以上为连接数据库
	
	if resource == "user" {
		type modelName models.User
		// 使用user数据模型
		var form modelName
	
		// 如果传值格式不符合上方定义的结构,则返回错误信息
		if err := ctx.Bind(&form); err != nil {
			ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}
		// 此时&form就继承了上方定义的结构格式
		// 插入数据,并将insert状态传值给err
		err = c.Insert(&form)
	} else if resource == "category" {
		type modelName models.Category
		// 使用user数据模型
		var form modelName
	
		// 如果传值格式不符合上方定义的结构,则返回错误信息
		if err := ctx.Bind(&form); err != nil {
			ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}
		// 此时&form就继承了上方定义的结构格式
		// 插入数据,并将insert状态传值给err
		err = c.Insert(&form)
	}
	// ctx.String(http.StatusOK, fmt.Sprintf(resource))
}

// 查询数据
func find(ctx *gin.Context){

	// 解析api参数
	resource := ctx.Param("resource")
	id := ctx.Param("id")
	// 传来的id值为"/id",我们要把"/"截去
	id = strings.Trim(id, "/")
	// 将id转化为bson.ObjectId格式
	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){

	// 解析api参数
	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" {
		// 使用user数据模型
		type modelName models.User
		// 查找10条数据
		modelNames := make([]modelName, 10)
	
		// 查找全部
		err = c.Find(nil).All(&modelNames)

		// 返回数据
		ctx.JSON(http.StatusOK, modelNames)
	} else if resource == "category" {
		// 使用user数据模型
		type modelName models.Category
		// 查找10条数据
		modelNames := make([]modelName, 10)
	
		// 查找全部
		err = c.Find
                            
                            版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/m0_51592186/article/details/119103103
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢