快速入门GoFly框架新增接口/上手写代码

huanglishi · · 446 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

拿到一个新框架大家可能无从下手,因为你对框架设计思路、结构不了解,从而产生恐惧,所以我们框架是通过简单可视化界面安装,安装后即可看到效果,然后点击先点点看各个功能,看现有的功能是怎么写的,这个现成功能作为参考,最好再自己写新的功能,下面我们就带大家如何写新的功能。 通过以上文档,我猜您已经在您电脑成功安装并成功运行项目了,通过“开发必看”文档,您已经对哦框架有所了解,现在我们教你如何开发新的功能,对应我们前后端分离框架来说,后端写的功能都是提供给各个前端调用的api接口,所以我们往后开发功能都称为新增“接口”。 # 新增一个模块 我们在app目录下新加一个模块,当你下载新的代码安装后,app目录下只有admin、business、common三个文件夹和controller.go一个文件,其中controller.go是主控制器可以引入app下模块和设置全局路由拦截及请求前处理。我们用增加wxapp(微信应用模块)举例子,开发步骤如下: ### 第1.新增一个目录 在app下新建一个名称为 wxapp 的目录,这名称就是这个模块的名称,接口请求就是从wxapp开始也就是域名+wxapp/,例如:https://goflys.cn/wxapp ### 第2.在目录下添加控制器 在wxapp 的目录中新建controller.go一个文件,这个就是整个wxapp 模块的控制器,代码如下: ```golang package wxapp /** * 引入控制器 * 请把您使用包用 _ "gofly/app/wxapp/XX"导入您编写的包 自动生成路由 * 不是使用则注释掉 */ import ( "gofly/utils/gf" ) // 路由中间件/路由钩子 func RouterHandler(c *gf.GinCtx, IsCtr bool) { if IsCtr { //在这里面处理拦截操作 c.Next() } } ``` 新建好的控制器文件后,要不这个模块添加到app下的controller.go主控制中并且引入模块路由中间件(如果模块不需拦截则可以不引入),代码如下: ```golang package controller /** * app路由引入口《引入模块控制器》 * * 请把您使用包用 _ "gofly/app/xx"导入您编写的包 自动生成路由 * 不需要使用的模块则注释掉 例如home模块暂时用不到就注释掉,这样不占用资源,使用是取消注释即可。 * 路由规则:包路径“business/article” + 包中结构体“Cate”转小写+方法名(首字母转小写_ "gofly/app/business" * 有控制的模块请在RouterHandler添加模块的路由钩子 */ import ( "gofly/app/admin" "gofly/app/business" _ "gofly/app/common" "gofly/app/wxapp" //新增的wxapp模块 "gofly/utils/gf" ) // 路由中间件/路由钩子 func RouterHandler(c *gf.GinCtx) { business.RouterHandler(c, gf.IsModelPath(c.FullPath(), "business")) admin.RouterHandler(c, gf.IsModelPath(c.FullPath(), "admin")) wxapp.RouterHandler(c, gf.IsModelPath(c.FullPath(), "wxapp"))//新增的wxapp模块 } ``` ### 第3.在wxapp目录下创建接口文件夹 我们在wxapp模块创建名称user的用户相关接口类,和用户相关的接口将在user目录下添加,比如user中常见的用户基本操作(登录,获取用户信息)、用户订单等,我们下面从用户操作和用户订单给大家举例。这个类名user也会生成路由路径,到这里路由为:/wxapp/user,加上域名则为:https://goflys.cn/wxapp/user。我们框架会自动根据目录层级生成接口请求路径,这样路由就不用你手动编写,且不会出现路由重复、命名更规则、可以根据请求的接口路径快速定位代码位置方便更新代码。 ### 第4.在user目录下创建接口文件 我们创建index.go来写用户常见操作,创建order.go来写用户订单相关功能,我们通过index.go和order.go两个给大家讲解接口,index,go中比较特殊框架为了减少路由层级框架对index命名的文件,在生成路由是会忽略index这一级生成路由为:/wxapp/user/+接口名称。其他命名路由会添加文件名,例如order.go生成路由为:/wxapp/user/order/+接口名称。index常用在与类名意义相同的功能上,类型本例user类的用户登录、获取用户信息等是和User类名称对应的功能,所以我们把用户登录、获取用户信息等用户操作功能放到index.go中,这样生成路由基于没有index这一层。 创建接口文件后我们在把user类在wxapp模块控制器引入,就是在app/wxapp/controller.go中import一下user,引入类的代码如下: ```golang package wxapp /** * 引入控制器 * 请把您使用包用 _ "gofly/app/wxapp/XX"导入您编写的包 自动生成路由 * 不是使用则注释掉 */ import ( _ "gofly/app/wxapp/user" //这个就是新引入的 user类 "gofly/utils/gf" ) // 路由中间件/路由钩子 func RouterHandler(c *gf.GinCtx, IsCtr bool) { if IsCtr { //在这里面处理拦截操作 c.Next() } } ``` ##### 4.1 新增index.go文件: 示例我只写接口方法,接口业务这里就不详细展开,您自己根据业务编写,index.go示例代码如下: ```golang package user import "gofly/utils/gf" // 用户 type Index struct{} func init() { fpath := Index{} gf.Register(&fpath, fpath) } // 获取用户信息 func (api *Index) GetInfo(c *gf.GinCtx) { user_id, _ := c.Get("userID") //当前用户ID userdata, err := gf.Model("business_user").Fields("id,businessID,name,nickname,mobile,email,avatar,status,createtime").Where("id", user_id).Find() if err != nil { gf.Failed().SetMsg("查找用户数据!").Regin(c) } else { gf.Success().SetMsg("获取用户信息").SetData(userdata).Regin(c) } } // 用户登录 func (api *Index) Login(c *gf.GinCtx) { //更具登录业务写登录功能 gf.Success().SetMsg("用户登录").Regin(c) } ``` 到这里我们就看到终端看到GetInfo和Login两个接口注册到路由中了,您可以通过:域名(服务端地址)+/wxapp/user/getInfo请求接口了。例如下图,大家可能疑问为什么GetInfo会生成为GET请求、Login又会是POST请已经为何首字母变小写,这问题请去:接口开发规范 这一节了解。 ![微信截图_20240529173454.png](https://static.golangjob.cn/240529/037d834061dda83db332b81af1ad1f50.png) ##### 4.2 新增order.go文件: 在user目录下创建order.go文件,package包名是类目录名user个必须规范,order.go基本代码如下: ```golang package user import "gofly/utils/gf" // 用户订单 type Order struct{} func init() { fpath := Order{} gf.Register(&fpath, fpath) } ``` 其中代码的结构体type Order struct{} 的Order名称要和order.go文件名一致,并且把首字母变大写。init函数中fpath := Order{} 的Order就是是=结构体名称,每个文件要写成和文件名称一样。 下面在order中添加功能接口,我们就添加一个获取订单列表GetList、获取订单详情GetDetail和修改订单状态UpStatus(取消订单、确认订单)3个接口做演示。代码如下: ```golang package user import ( "gofly/utils/gf" "gofly/utils/tools/gmap" ) // 用户订单 type Order struct{} func init() { fpath := Order{} gf.Register(&fpath, fpath) } // 获取订单列表 func (Order) GetList(c *gf.GinCtx) { pageNo := gf.Int(c.DefaultQuery("page", "1")) pageSize := gf.Int(c.DefaultQuery("pageSize", "10")) //搜索添条件 param, _ := gf.RequestParam(c) whereMap := gmap.New() if gf.DbHaseField("business_ordermanage", "businessID") { whereMap.Set("businessID", c.GetHeader("Businessid")) } user, err := gf.ParseTokenGetInfo(c) if err != nil { gf.Failed().SetMsg("登录失效请重新登录!").SetCode(401).SetData(err).Regin(c) } whereMap.Set("uid", user.ID) if title, ok := param["title"]; ok && title != "" { whereMap.Set("title like ?", "%"+gf.String(title)+"%") } MDB := gf.Model("business_order").Where(whereMap) totalCount, _ := MDB.Clone().Count() list, err := MDB.Fields("id,uid,title,status,createtime,updatetime").Page(pageNo, pageSize).Order("id desc").Select() if err != nil { gf.Failed().SetMsg(err.Error()).Regin(c) } else { gf.Success().SetMsg("获取全部列表").SetData(gf.Map{ "page": pageNo, "pageSize": pageSize, "total": totalCount, "items": list}).Regin(c) } } // 获取订单详情 func (Order) GetDetail(c *gf.GinCtx) { id := c.DefaultQuery("id", "") if id == "" { gf.Failed().SetMsg("请传参数订单id").Regin(c) } else { data, err := gf.Model("business_order").Where("id", id).Fields("id,uid,title,status,createtime,updatetime").Find() if err != nil { gf.Failed().SetMsg("获取内容失败").SetData(err).Regin(c) } else { gf.Success().SetMsg("获取订单详情").SetData(data).Regin(c) } } } // 更新订单状态 func (Order) UpStatus(c *gf.GinCtx) { param, _ := gf.RequestParam(c) res, err := gf.Model("business_order").Where("id", param["id"]).Data(gf.Map{"status": param["status"]}).Update() if err != nil { gf.Failed().SetMsg("更新失败!").SetData(err).Regin(c) } else { msg := "更新成功!" if res == nil { msg = "暂无数据更新" } gf.Success().SetMsg(msg).SetData(res).Regin(c) } } ``` 我们会在终端看到GetList、GetDetail、UpStatus生成请求路由了,也就是可以调用这些接口,如下图: ![微信截图_20240529175528.png](https://static.golangjob.cn/240529/47bdecc5de64ba23be1512d4c6f193f1.png) 我们细心的朋友可能发现,func 的函数前有个括号index和order两个写法不一样,这样我们和大家说明一下,func (Order) GetList(c *gf.GinCtx) {}中(Order)可以写成func (api *Order) GetList(c *gf.GinCtx) {}这种。func (Order)和func (api *Order)两种在我们示例都可以正常运行,写成func (Order)可以减少点代码,如果您写的业务有连锁操作需求再func (api *Order)这样通api去操作结构体内的变量值等操作。所以用不到api是可以省略,当然你留着也没有影响。 到此您就学会了使用框架新增功能了,同样的需要再现有的admin和business模块新增类或者一个接口也是同样操作,您就自己举一反三自己动手试试,反复写几次让自己对框架有深入了解,千万别急躁慢慢来,要自己多去探索,形成自学习惯。

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

446 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传