Go实战项目-给项目添加一个邀请码的功能【开源十年项目第9次更新】

kaiyuan10nian · · 1832 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

一个深漂近10年的程序员立志用未来10年时间去维护一个项目,这个项目的功能未定,用到什么就做什么,遇到什么就写什么。其主要目的有二,一为加深自己的技术深度,二为其他学习者提供参考。 感兴趣的可以跟着我一起做这个项目,不收费、不套路、人间自有真情在。 备注:前面项目中用到的代码已经分享到GitHub中去了,并且以后所有项目中会出现的代码都会提交上去,欢迎查阅。 地址:https://github.com/kaiyuan10nian/kaiyuan10nian 感兴趣的可以点个star哦~开源十年项目的更新首发于公众号:计算机自学平台,有兴趣的小伙伴可以持续关注,并欢迎各位加我的微信(kaiyuan10nian)跟我一起完成并推动项目的发展。 --- ## Go实战项目-给项目添加一个邀请码的功能 前面总结里面说过,我要给我们的blog项目添加一个邀请码的功能,因为这个项目做完之后我要部署出去的,虽说不靠这个东西去盈利,但是实战要有实战的样子至少把一个项目从0做到1的过程还是要有的。这里就涉及到一个很严重的问题:怎么控制内容?(在国内不可能不控制内容的) - 人工去审核(我没那么多时间) - 接入第三方内容审核(要花钱的) - 智能审核(没这个技术~后面也许可以考虑在开源十年中去实现它) 所以没有办法了,既然我控制不了内容,那我就从源头控制:直接控制输出内容的人。 所以我想到的办法就是在注册的时候做一个限制,不能让每个人都可以注册成功,只能让那些得到我们这个圈子成员信任的人才可以注册体验。那么实现的逻辑要提前去思考了: - 邀请码怎么来的? ​ 邀请码是系统生成的,由已注册会员手动生成,没给会员允许生成5个邀请码,每个邀请码只能使用1次。 - 邀请码在哪使用? ​ 邀请码在新会员注册的时候使用(为必填项) - 邀请码怎么追溯? ​ 因为邀请码的生成是已注册会员手动生成的,所以我会在库里面去拉一张表单独去记录,如果有新会员使用了邀请码那么我也会记录下来,后面若想去追溯就很简单了 根据上面的思路,我们一步一步来实现其功能: 1、先写接口路由: ```go r.GET("/v1/account/invite", common.AuthMiddleware(),controller.Invite) ``` 因为邀请码只能是已注册会员去生成,所以必须加上common.AuthMiddleware()权限限制。 2、实现邀请码的生成: ```go func RandomString(n int) string { var letters = []byte("23456789qwertyupkjhgfdsazxcvbnmMNBVCXZASDFGHJKPOUYTREWQ") result := make([]byte,n) rand.Seed(time.Now().Unix()) for i := range result { result[i] = letters[rand.Intn(len(letters))] } return string(result) } ``` 这个其实就是一个生成随机值的函数,其中我把'0'、'1'、'i'、'l'、'I'、'L'等不容易辨认的字符都去掉了。 3、实现邀请码接口功能: ```go //创建用户邀请码 func Invite(ctx *gin.Context){ udata ,_:= ctx.Get("user")//首先通过token去获取用户信息 dto := dto.ToUserDto(udata.(model.User)) DB := common.GetDB() var inviteCodes []model.InviteCode DB.Where("userid = ?",dto.ID).Find(&inviteCodes)//根据用户信息去查询这个用户有多少个邀请码 fmt.Println(len(inviteCodes)) if len(inviteCodes) < 5{//如果不够5个则允许他继续生成邀请码 code := RandomString(5) newCode := model.InviteCode{ Userid: dto.ID, Code: code, Status: 0, } //生成成功后把它记录进库表里面 if err := DB.Create(&newCode).Error;err != nil{ response.Response(ctx,http.StatusInternalServerError,500,nil,err.Error()) return } response.Response(ctx,http.StatusOK,6000,gin.H{"inviteCode":code},"邀请码生成成功") }else{ response.Response(ctx,http.StatusOK,60001,nil,"每个人只可以拥有5个邀请码") return } } ``` 上述提到了邀请码的创建,我们创建了一个表invitecode专门用来存储(下文有model代码) 4、去修改注册功能 原本我们的注册只需要手机号并设置密码即可,但是我们要控制注册了,那么要加几个验证条件: 1)推荐人是否存在? 2)邀请码是否存在? 3)邀请码是否和推荐人匹配? 4)邀请码是否被人使用过了? 这几个条件判断之后,如果都通过那么给予放行,放行后还要做一个操作: 1)标记该邀请码已被使用 2)把该邀请码跟注册账号进行关联 针对上述逻辑,首先针对库表进行设计和改造 直接在用户表新增了一个字段invitecode,目的就是把邀请码和注册者进行关联。 ```go type User struct { gorm.Model Name string `gorm:"type:varchar(20);not null"` Mobile string `gorm:"varchar(11);not null;unique"` Password string `gorm:"size:255;not null"` InviteCode string `json:"invitecode" gorm:"not null"` } ``` 然后,新建了一个表,专门用来存我们生成的邀请码,以及记录邀请码和生成邀请码的用户进行关联 ```go type InviteCode struct { gorm.Model Userid uint `json:"user_id" gorm:"not null"` Code string `json:"code" gorm:"not null"` Status uint `json:"status" gorm:"not null"` } ``` 库表建好了,下面就是在注册时,我们针对以上逻辑的代码实现:(全部代码请查看github) ```go if isTelephoneExist(DB,recommender){//查询这个推荐者存不存在 id := getRecommenderId(DB,recommender)//先获取推荐者的ID //判断其邀请码的准确性 var inviteCodes []model.InviteCode DB.Where("userid = ?",id).Find(&inviteCodes)//根据id去查这个推荐者有多少邀请码 isValid := false for _,inviteCode := range inviteCodes{//轮寻他所有邀请码 isValid = strings.EqualFold(code,inviteCode.Code)//一一对比,查看注册者输入的是否和库里的一致 if isValid { if inviteCode.Status == 0 {//如果一致,则再验证这个是否已经被用了 DB.Model(&inviteCode).Update("status",1) break }else{ response.Response(ctx,http.StatusOK,60002,nil,"邀请码已使用") return } } } if !isValid { response.Response(ctx,http.StatusOK,60002,nil,"邀请码不存在") return } }else { //最后这个提示,我是想避免被人拿这个接口测试用户存在与否 response.Response(ctx,http.StatusOK,60002,nil,"邀请码不存在") return } ``` 好了,到这里我们基本就完成这个简单的小功能了,直接go run main.go 去亲自体验一下吧。 ok just this.see you next...

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

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

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