golang入门项目——打卡抽奖系统

功能介绍

用户加入群组之后,会在签到群组所设的签到地点进行签到和签退,并限制同一个设备只能签到一个用户,签到成功之后。会获取一定的限制在该群组使用的积分。该群组可以设置一些抽奖活动,用户可使用该群组内的积分来进行该群组的抽奖活动。

项目功能

前台的主要功能

功能项功能说明
基本的用户操作用户邮箱注册、登陆、修改头像、修改用户地址、修改用户密码
群组操作创建群组、用户加入群组、改变群组头像、获取群组成员、群组的解散
群组打卡用户签到、签退,获取用户和群组成员的打卡记录,打卡记录的生成,请假
打卡配置群组打卡地点的增加、删除,获取群组打卡位置,打卡ip限制
群组抽奖活动抽奖活动的增加、删除、更新,获取群组的抽奖活动。用户抽奖
群组抽奖奖品抽奖活动奖品的增加、删除、更新,获取活动的奖品列表
用户的抽奖记录用户抽奖记录的生成、获取

后台的主要功能

管理员操作管理员的登陆
用户管理用户列表的获取,用户的删除
群组管理群组的删除
活动管理活动列表的获取,活动的删除
用户订单管理用户订单的获取、删除
打卡管理获取群组和用户的打卡记录

项目实现

技术选型

技术选型
语言Go1.20
存储Redis、Mysql
rpc框架Kitex
http框架Hertz
orm框架Gorm、Gen
消息队列Rabbitmq
日志框架Logrus、File-rotatelogs
容器技术Docker
服务注册与发现Etcd

开发设计

1.JWT鉴权:

基于golang-jwt包实现了token的颁发与解析
token的自动续期

2.密码安全:

长度限制:为了保证密码的可记忆性以及安全性,限制密码长度为6~30
加密:使用md5加盐进行加密。

3.接口防刷:

基于Redis构建了一个通过检测用户IP地址限制统一IP多次刷赞的中间件,服务器可配置每分钟用户访问
点赞接口的上限量,当用户访问接口次数超过此上限时,将返回“操作频繁,请稍后重试”信息提醒。

4.Redis缓存:

对近期访问的信息进行缓存,对访问的不存在的数据也在redis当中缓存空值来防止缓存穿透。
对于数据更新操作,为了保证数据库与缓存的数据一致性,采用先更新数据库再更新缓存,然后延时双
删的策略

5.消息队列:

引入了消息队列来应对一些高并发场景下的并发安全问题
对服务之间进行解耦
对一些重要的存储失败的信息进行暂存再次尝试存储来避免重要数据的丢失

6.高并发设计

对于抽奖场景的高并发,先通过查缓存判断当前时间是否在活动时间内,活动奖品是否有剩余,用户的
积分是否够用。满足所有条件才会把这次抽奖请求放入到rabbitmq中。lottery服务处理完这次请求之后,	
通过redis异步返回抽奖的结果。
高并发下如果生成用户抽奖记录失败,会把这次订单存到rabbitmq中,再次尝试生成订单,这样保证了	
重要信息的不丢失。
对于发送邮件验证码,用户签到记录的生成这种可能需要高并发的场景,也采用了rabbitmq做中间缓存

7.Docker部署:

使用dokcer-compose整合项目依赖,快速部署所需要的依赖并根据init.sql文件建表。

8.OSS存储:

使用七牛云服务器进行OSS存储,来减少本地磁盘IO

架构设计

微服务设计

在这里插入图片描述

数据库设计

在这里插入图片描述
1.活动的奖品总数、群组的人数、奖品的数量、用户在群组的签到天数
2.每张表添加了deleted_at作软删除,并记录更新创建时间
3.索引:

1.查询时deleted_at常做条件使用,所有的deleted_at建立索引
2.对user表的email和deleted_at作联合唯一索引
3.对user_group表,对gid建立索引,对uid,gid,deleted_at建立联合唯一索引
4.对sign_month表,对gid建立索引,对uid,month,gid建立联合唯一索引
5.对sign_record表,对gid建立索引,对uid,gid,deleted_at建立联合唯一索引
6.对sign_group_pos表,对gid,name,longtitude,latitude,deleted_at建立联合唯一索引
7.对ask_leave表,对gid,uid,time,deleted_at建立联合唯一索引
8.对admin表,对name,password,deleted_at建立联合唯一索引
9.对activity表,对uid建立索引,对gid建立索引
10.对prize表,对aid建立索引
11.对user_order表,对uid,pid建立联合唯一索引

缓存设计

keyvalue相关操作
user:{uid}hash类型存储用户的基本信息
{email}:{code}string类型存储用户注册时的验证码
group:{gid}hash类型存储群组的基本信息
sign:user:start:{gid}set类型存储群组中签到的用户的id
sign:user:end:{gid}set类型存储群组中签退的用户的id
sign:month:{gid}:{uid}setbit类型存储群组用户的月签到信息
sign:ip:{ip}string类型存储操作请求的ip地址和用户的的映射
sign:location:{gid}geo类型存储群组签到的地理位置
record:{uid}hash类型存储用户的签到记录
activity:{aid}hash类型存储活动的信息
prize:{pid}hash类型存储奖品的信息
prize:aid:{aid}set类型存储活动的所有奖品id
order:user:{uid}:{offset}:{limit}set类型存储用户奖品单页的订单id列表
order:{oid}hash类型存储用户奖品单的信息
email:return:{email}string类型从rabbitmq读取email并发送邮寄后的异步返回处理结果的code
sign:return:{uid}:{gid}string类型从rabbitmq读取签到请求信息后异步返回处理结果的code
choose:return:{uid}:{gid}string类型从rabbitmq读取抽奖请求信息后异步返回处理结果的code
ip:count:{ip}string类型用于存储ip地址在2分钟内的请求次数
token:{token}string类型存储初始token指向的真实token

消息队列设计

在这里插入图片描述

代码目录

├── cmd
│   ├── api
│   │   └── biz
│   │       ├── handler
│   │       │   ├── api
│   │       │   │   ├── base
│   │       │   │   │   ├── admin.go
│   │       │   │   │   ├── group.go
│   │       │   │   │   └── user.go
│   │       │   │   ├── lottery
│   │       │   │   │   ├── activity.go
│   │       │   │   │   ├── choose.go
│   │       │   │   │   ├── prize.go
│   │       │   │   │   └── record.go
│   │       │   │   └── sign
│   │       │   │       ├── record.go
│   │       │   │       ├── sign.go
│   │       │   │       └── signPos.go
│   │       │   ├── common
│   │       │   │   └── handle_biz.go
│   │       │   └── ping.go
│   │       ├── middleware
│   │       │   ├── auth.go
│   │       │   └── ipLimit.go
│   │       ├── model
│   │       │   ├── api
│   │       │   │   └── api.go
│   │       │   ├── lottery
│   │       │   │   └── lottery.go
│   │       │   ├── sign
│   │       │   │   └── sign.go
│   │       │   └── user
│   │       │       └── base.go
│   │       └── router
│   │           ├── api
│   │           │   ├── api.go
│   │           │   └── middleware.go
│   │           └── register.go
│   ├── generate
│   │   └── main.go
│   ├── main
│   │   └── main.go
│   └── rpc
│       ├── base
│       │   └── base.go
│       ├── lottery
│       │   └── lottery.go
│       └── sign
│           └── sign.go
├── dao
│   ├── cache
│   │   ├── activity.go
│   │   ├── group.go
│   │   ├── handlerErr.go
│   │   ├── init.go
│   │   ├── ip.go
│   │   ├── order.go
│   │   ├── prize.go
│   │   ├── sign.go
│   │   └── user.go
│   └── db
│       ├── activity.go
│       ├── admin.go
│       ├── group.go
│       ├── init.go
│       ├── model
│       │   ├── activity.gen.go
│       │   ├── admin.gen.go
│       │   ├── ask_leave.gen.go
│       │   ├── prize.gen.go
│       │   ├── sign_group.gen.go
│       │   ├── sign_group_pos.gen.go
│       │   ├── sign_list.gen.go
│       │   ├── sign_month.gen.go
│       │   ├── sign_record.gen.go
│       │   ├── user.gen.go
│       │   ├── user_group.gen.go
│       │   └── user_order.gen.go
│       ├── order.go
│       ├── prize.go
│       ├── record.go
│       ├── sign.go
│       └── user.go
├── docker-compose.yml
├── go.mod
├── go.sum
├── idl
│   ├── api.thrift
│   ├── base.thrift
│   ├── lottery.thrift
│   └── sign.thrift
├── kitex_gen
│   ├── lottery
│   │   ├── k-consts.go
│   │   ├── k-lottery.go
│   │   ├── lottery.go
│   │   └── lotteryservice
│   │       ├── client.go
│   │       ├── invoker.go
│   │       ├── lotteryservice.go
│   │       └── server.go
│   ├── sign
│   │   ├── k-consts.go
│   │   ├── k-sign.go
│   │   ├── sign.go
│   │   └── signservice
│   │       ├── client.go
│   │       ├── invoker.go
│   │       ├── server.go
│   │       └── signservice.go
│   └── user
│       ├── base.go
│       ├── baseservice
│       │   ├── baseservice.go
│       │   ├── client.go
│       │   ├── invoker.go
│       │   └── server.go
│       ├── k-base.go
│       └── k-consts.go
├── pkg
│   ├── config
│   │   └── mysql
│   │       └── init.sql
│   ├── constants
│   │   └── const.go
│   ├── errmsg
│   │   └── error.go
│   ├── jwt
│   │   └── jwt.go
│   └── log
│       ├── log.go
│       └── logs
├── rabbitmq
│   ├── comm
│   │   └── comm.go
│   ├── consumer
│   │   ├── chooseConsumer.go
│   │   ├── emailConsumer.go
│   │   ├── init.go
│   │   ├── orderConsumer.go
│   │   ├── recordConsumer.go
│   │   ├── regularConsumer.go
│   │   └── signConsumer.go
│   ├── model
│   │   ├── choose.go
│   │   ├── order.go
│   │   ├── record.go
│   │   └── sign.go
│   └── producer
│       ├── chooseProducer.go
│       ├── emailProducer.go
│       ├── init.go
│       ├── orderProducer.go
│       ├── recordProducer.go
│       ├── regularProducer.go
│       └── signProducer.go
├── script
│   └── bootstrap.sh
├── service
│   ├── base
│       ├── pos.go
│       ├── record.go
│       └── sign.go
└── utils
    ├── email.go
    └── rand.go

源码地址

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值