Giter Club home page Giter Club logo

go-server's Introduction

ci Coverage Status Go Report Card License Repo Size

Golang 实现的基础服务

这是我在闲暇时间写的一些基础服务, 基本上大多数后端服务都需要用到的。

它用来帮助我快速开始一个项目,而不是重头开始写,浪费大量时间和精力。

想到哪里写哪里, 我会不断的完善它。

为什么不写成微服务形式,模块分离? 项目体量没有达到。

技术栈

  • Web 框架 iris
  • 数据库 Postgres
  • 缓存 Redis
  • 身份认证机制 Session/JWT/oAuth2
  • 数据库操作 GORM
  • 消息队列 nsq
  • RBAC 的鉴权模型
  • Docker 一键启动应用

包含哪些模块?

模块 说明
验证模块 包含注册/登陆/账号激活/忘记密码/双重身份认证
用户模块 包含用户信息的模块, 用户资料/登陆密码/扫码登录/交易密码/用户邀请
授权模块 oAuth 授权登陆, 目前支持 微信小程序/Google/Github/Gitlab/Twitter/Facebook
钱包模块 包含钱包的相关操作,钱包转账/结算
财务模块 所有涉及到钱的的操作都会被记录在此, 例如转账记录/消费记录
横幅模块 对于网站相关 Banner 的操作,可根据不同的平台设置不同的横幅,例如 PC 端大屏的与 APP 不相同
新闻模块 新闻公告类的相关操作, CMS 内容
系统通知 系统通知的相关模块,主要用于管理员发送给全员的通知
消息模块 用户的个人消息模块, 主要用于管理员发送给某个用户的通知
推送模块 APP 的推送通知模块,接入第三方 onesignal
地区模块 包含全国各地区的行政码划分等
地址模块 用户设置相关的地址模块,例如收货地址
上传模块 包含用户上传文件/图片的相关操作, 包含 hash 去重/图片压缩/图片缩放/图片裁剪
下载模块 包含用户下载文件/图片的相关操作
邮件模块 关于邮件的相关操作,例如发送邮件, 用于发送验证码之类
短信模块 用于发送短信验证码,接入第三方服务阿里云/腾讯云
静态文件模块 用户访问服务器的静态文件, 放置与 /public 目录下的文件
反馈模块 用户反馈模块,用户建议反馈/BUG反馈
页面菜单模块 定义后台页面菜单/页面权限
日志模块 系统日志/登陆日志/操作日志/异常日志
帮助中心 可嵌套的帮助中心模块
配置中心 由后台接口控制的配置中心,配置例如 SMTP/短信/小程序 等信息
定时任务模块 进行一系列的定时任务,例如切割表,迁移冷数据等
客服系统 基于 Websocket 的客服系统,实时消息推送,一对多服务关系

如何使用?

首先搭建项目需要的依赖数据库/服务, 这里推荐使用 Docker

docker 目录中提供了 docker-compose 配置文件,方便一键搭建。

然后获取构建好的可执行文件, 找到对应的平台,并且下载。或者自行构建。

你需要使用 5 个文件

  1. message_queue_server

启用消息队列消费服务器,用于消费在队列里面的事物。

  1. resource_server

静态文件服务器。用于静态文件的上传/下载/缩略图等

  1. user_server

监听用户相关的接口服务

  1. admin_server

监听管理员相关的接口服务

5。scheduled_server

定时任务

  1. customer_service

客服系统

然后复制 .env 到可执行文件目录下,运行可执行文件即可。例如 ./user_server start

快速下载可执行文件

curl -fsSL https://raw.githubusercontent.com/axetroy/go-server/master/install.sh | bash -s v0.5.2

如何进行本地开发?

首选确保你安装有:

再根据以下命令运行

# 克隆项目
$ go get -v github.com/axetroy/go-server # 拉取项目

# 启用项目依赖(数据库,消息队列等)
$ cd $GOPATH/github/axetroy/go-server # 切换到项目目录
$ cd docker
$ ./start.sh

# 启动接口服务
$ cd $GOPATH/github/axetroy/go-server # 切换到项目目录
$ go run ./cmd/admin/main.go migrate # 同步数据库表
$ go run ./cmd/message_queue/main.go # 启动消息队列
$ go run ./cmd/user/main.go # 运行用户端的接口服务
$ go run ./cmd/admin/main.go # 运行管理员端的接口服务
$ go run ./cmd/resource/main.go # 运行资源类的接口服务
$ go run ./cmd/scheduled/main.go # 运行定时任务
$ go run ./cmd/customer_service/main.go # 运行客服系统

可以通过 .env 文件进行配置

如何构建?

$ make build

在生成的 bin 目录下查找对应平台的可执行文件运行即可

如何测试?

make test

鸣谢

特别感谢 JetBrains 为本开源项目提供免费的 IntelliJ GoLand 授权

License

The MIT License

go-server's People

Contributors

axetroy avatar renovate-bot avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-server's Issues

具体化错误码

具体化错误状态码

  • 具体化每个错误的状态码
  • 添加错误状态码对应的接口

独立出第三方登陆

第三方登陆

  • 微信登陆
  • Google 登陆
  • Github 登陆

每个第三方登陆,都有一个关联的帐号 ID,这个 ID 不应该写进 User 表

而是独立出一个 关联表

方便为了后续的 绑定/解除绑定 作铺垫

ref: #19

一起同芒

  • product
    • name, desc, price
    • thumb, images
    • sku
    • content(html/md)

手机注册的参数

现在手机注册时不需要填密码,注册成功后,就没法用密码登录.

  1. 保持现在的注册逻辑,修改密码可使用code && new_password,接口判断code || old_password
  2. 改注册的参数为code&phone&password&invite_code

可能用1比较好,吧?

ShouldBindJSON修改为ShouldBind兼容json和form表单

func SignInRouter(c *gin.Context) {
var (
input SignInParams
err error
res = schema.Response{}
)

defer func() {
	if err != nil {
		res.Data = nil
		res.Message = err.Error()
	}
	c.JSON(http.StatusOK, res)
}()
**if err = c.ShouldBindJSON(&input);** err != nil {
	err = exception.InvalidParams
	return
}

res = SignIn(controller.NewContext(c), input)

}
在学习您的代码,ShouldBindJSON改为ShouldBind可以兼容前端json和form,会不会好一些

用户反馈的变动更改

当用户反馈变更时,比如管理员锁定/关闭,那么就通知用户

  • 手机消息推送
  • 发送一条个人消息

收货地址服务

接口列表

  • 添加收货地址
  • 修改收货地址
  • 获取收货地址列表
  • 获取收货地址详情
  • 获取我的默认收货地址
  • 获取 **省份/城市/地区 代码列表
  • 验证各地区的 地区码 是否正确

抽象 httpserver,剥离对 gin 的依赖

目前有好多地方用到 gin 的依赖

接下来就是剥离对 gin 的依赖,抽象化 http 服务

这样使得我在切换 http 框架的时候,可以做到很低的成本切换。

gin 框架确实向换了

TODO: CMS 社区

  • 主题 topic
  • 发帖 post
  • 评论 comment
  • 点赞 like
  • 收藏 favorites
  • 置顶 top

用户端接口

		{
			cmsRouter := v1.Party("/cms")
			cmsRouter.Get("/topic", area.GetProvinces)                                      // TODO: 获取话题/主题
			cmsRouter.Post("/post/topic/{topic_id}", area.GetProvinces)                     // TODO: 在 xx 话题下发帖
			cmsRouter.Delete("/post/{post_id}", area.GetProvinces)                          // TODO: 删除帖子
			cmsRouter.Post("/post/{post_id}/comment", area.GetProvinces)                    // TODO: 创建评论
			cmsRouter.Delete("/post/{post_id}/comment", area.GetProvinces)                  // TODO: 创建评论
			cmsRouter.Put("/post/{post_id}/like", area.GetProvinces)                        // TODO: 顶帖子
			cmsRouter.Put("/post/{post_id}/unlike", area.GetProvinces)                      // TODO: 踩帖子 👎
			cmsRouter.Put("/post/{post_id}/comment/{comment_id}/like", area.GetProvinces)   // TODO: 顶评论
			cmsRouter.Put("/post/{post_id}/comment/{comment_id}/unlike", area.GetProvinces) // TODO: 踩评论 👎
			cmsRouter.Get("/favourite", area.GetProvinces)                                  // TODO: 获取收藏夹列表
			cmsRouter.Post("/favourite", area.GetProvinces)                                 // TODO: 创建收藏夹
			cmsRouter.Get("/favourite/{id}", area.GetProvinces)                             // TODO: 获取收藏夹详情
			cmsRouter.Delete("/favourite/{id}", area.GetProvinces)                          // TODO: 删除收藏夹
			cmsRouter.Put("/favourite/{id}", area.GetProvinces)                             // TODO: 更新收藏夹
			cmsRouter.Post("/favourite/{id}/post", area.GetProvinces)                       // TODO: 把帖子加入收藏夹
			cmsRouter.Delete("/favourite/{id}/post", area.GetProvinces)                     // TODO: 把帖子从收藏夹中删除
		}

数据签名

在一些敏感接口进行数据签名,加强数据传输安全, 保证数据不会被篡改。

例如转账/登陆接口等

接入微信小程序登陆

这在某些场景下,使用微信小程序登陆。

授权成功后,返回 code,后端根据 code 获取用户对应的 open_id

根据 open_id 可以关联到平台的帐号

重写文件上传下载模块

如果部署多个节点,显然目前这样是不行的。

得独立出一个单独的进程。

目前没有上传到 OSS/CDN 的打算。

本地存储完全够用各种小项目

完善按 sort 排序

目前按照 sort 字段进行的排序没有与预期的一致

需要传值 sort=created_at DESC

真实的设计应该是

  • 支持多个条件进行排序
  • 简化排序字段

最终目标设计 sort=+created_at,-balance

+表示正序排序
-表示反向排序
以,分割支持多个字段

配置抽离到数据库可配置

例如 邮件服务/短信服务 这类跟业务相关的配置.

抽离到 数据库 中可配置

然后, 可能为了适配以后可能出现的集群,要加上 etcd

平滑停止/重启应用

为了避免强行 kill 掉程序产生的莫名其妙的问题。搞个平滑停止和重启。

具体怎么做呢,就是给进程发送信号,进程接收放信号之后,不再接收新的 http 请求。

然后预留10秒钟时间处理剩下的任务,之后退出进程。

重构注册流程

注册接口现在是大一统,统一一个接口。

但是现在有必要把他分开来

1. 用户名注册

通过用户名 + 密码注册

2. 邮箱注册

通过邮箱,发送注册链接到目标邮箱,类似 https://domain.com/register?code=xxxxx&email=xxxx

然后链接跳转到注册页面,填写 用户名+密码。点击注册后生成帐号

3. 手机注册

通过手机号 + 短信验证码注册

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.

开发客服系统

接入客服系统.

  • 自动问答系统
    • 机器学习分类
    • 关键字捕捉
  • 人工客服系统
    • socket 连接
    • 客服分配机制

UpdateProfileParams.Status

type UpdateProfileParams struct {
Username *string `json:"username" validate:"omitempty,min=1,max=36" comment:"用户名"` // 用户名,部分用户有机会修改自己的用户名,比如微信注册的帐号
Nickname *string `json:"nickname" validate:"omitempty,min=1,max=36" comment:"昵称"`
Gender *model.Gender `json:"gender" validate:"omitempty,oneof=0 1 2" comment:"性别"`
Avatar *string `json:"avatar" validate:"omitempty,url" comment:"头像"`
Wechat *UpdateWechatProfileParams `json:"wechat" validate:"omitempty" comment:"微信信息"` // 更新微信绑定的帐号相关
}

管理员应该能修改用户状态

根据自定义的 error 返回状态码

列出一个状态码表

这属于前期工作没有做好,会有很大的工作量

目前正在探索一个一劳永逸的方法,在最外层捕捉错误,然后赋值错误码

允许重命名 username

username 可以作为登陆凭证

而一些第三方登陆之后,会自动生成一个 username。

添加一个字段 rename_remaind 标记用户还有几次重命名的机会,默认 0

TODO: banner

管理员

  • 新增 Banner
  • 删除 Banner
  • 修改 Banner
  • 获取 banner 列表

公有

  • 获取 Banner 列表

Dependency Dashboard

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.