common

package module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 6, 2022 License: MIT Imports: 21 Imported by: 0

README

common

基于gorm、gin、zap、viper实现的对一些常用库的二次封装以及连接mysql、redis、etcd、日志的公共包,简化开发过程,能快速的搭建一个web后端服务器

1. 技术选型

2.功能特性

  • 支持数据库mysql、redis、etcd连接
  • 提供五种文件上传(存储)的方式,包括本地上传、阿里云存储对象、七牛云存储对象、腾讯云存储对象、华为云存储对象
  • 提供通知功能,提供email和webhook两种方式
  • 提供http请求Get方法和Post方法
  • 提供日志封装
  • 通过viper加载配置文件,支持testing和production两种环境,支持json、yaml、ini三种文件格式
  • 提供一些有用的工具包
    • event.go: 监听程序的退出信号
    • file.go: 一些对文件目录处理的函数
    • ip.go: 获取本机ip
    • map.go: 对map的一些封装,提高安全性
    • md5.go: 对数据的普通加密
    • parse.go: 对cmd命令的解析
    • platform.go: 一些关于各平台的常量
    • scrypt.go: 对数据的高级加密,不可逆
    • strings.go: 字符串转化的一些处理函数
    • system.go: 获取服务器的cpu、硬盘、内存等信息
    • task.go: 对定时任务的简单封装
    • time.go: 对时间的一些处理函数
    • uuid.go: 获取uuid(唯一)
目录 说明
dbclient 基于gorm实现的数据库mysql连接
etcdclient 提供etcd连接
httpclient 提供http(get/post)请求方法
logger 基于zap实现的日志管理,实现日志分类以及分割
notify 提供email和webhook两种通知方式
server 基于gin实现对web服务的启动
utils 一些工具类
config.go 配置信息的结构体并基于viper加载配置文件
upload.go 文件上传功能的方法封装
env.go 一些环境变量
request.go 常见的绑定请求的的结构体
response.go 常见的请求返回的结构体

3. 使用方法

go get -u github.com/tmnhs/common

详细的使用示例可见: common-test

3.1.配置文件

配置文件支持多种环境(testing/prodution)和多种格式(json/yaml/ini)

注意事项:配置文件的目录必须是下面这个样子

├── cmd
├── conf
|     ├── production                #生产环境,支持json、yaml、ini三种配置文件
|     |          └── main.json
|     └── testing
|                └── main.json      #测试环境,支持json、yaml、ini三种配置文件
└── internal

配置文件示例(json格式)

{
  "mysql": {
    "path": "127.0.0.1",
    "port": "3306",
    "config": "charset=utf8mb4&parseTime=True&loc=Local",
    "db-name": "common-test",
    "username": "root",
    "password": "root",
    "max-idle-conns": 100,
    "max-open-conns": 100,
    "log-mode": "info",
    "log-zap": false
  },
  "redis": {
    "addr": "127.0.0.1:6379",
    "password": "",
    "db": 0
  },
  "system": {
    "env": "testing",
    "addr": 8089,
    "version": "v1.0.2"
  },
  "etcd": {
    "endpoints": [
      "http://127.0.0.1:2379"
    ],
    "username": "",
    "password": "",
    "dial-timeout": 2,
    "req-timeout": 5
  },
  "email": {
    "port": 465,
    "from": "test@qq.com",
    "host": "smtp.qq.com",
    "is-ssl": true,
    "secret": "test",
    "nickname": "common-test",
    "to": [
      "test@test.mobi"
    ]
  },
  "webhook": {
    "url": "url",
    "kind": "feishu"
  },
  "log": {
    "level": "debug",
    "format": "console",
    "prefix": "[common]",
    "director": "logs",
    "showLine": false,
    "encode-level": "LowercaseLevelEncoder",
    "stacktrace-key": "stacktrace",
    "log-in-console": true
  }
}
3.2 开启一个web应用
func main() {
  	//参数为需要启动的服务(etcd/mysql/redis)
    //连接成功后可以通过dbclient.GetMysqlDD(),etcdClient.GetEtcd(),redisclient.GetRedis()获取对应的client
    //通过logger.GetLogger()获取日志处理器
    //通过common.GetConfigModels()获取配置文件的信息
	srv, err := server.NewApiServer(server.WithEtcd(),server.WithMysql(),server.WithRedis())
	if err != nil {
		logger.GetLogger().Error(fmt.Sprintf("new api server error:%s", err.Error()))
		os.Exit(1)
	}
	// 注册路由
	srv.RegisterRouters(handler.RegisterRouters)

	// 建表,当然,如果不需要可以直接注释掉
	err = service.RegisterTables(dbclient.GetMysqlDB())
	if err != nil {
		logger.GetLogger().Error(fmt.Sprintf("init db table error:%#v", err))
	}
	err = srv.ListenAndServe()
	if err != nil {
		logger.GetLogger().Error(fmt.Sprintf("startup api server error:%v", err.Error()))
		os.Exit(1)
	}
	os.Exit(0)
}

3.3 注册路由

func RegisterRouters(r *gin.Engine) {

	configRoute(r)

	configNoRoute(r)
}

func configRoute(r *gin.Engine) {

	hello := r.Group("/ping")
	{
		hello.GET("", func(c *gin.Context) {
			c.JSON(200, "pong")
		})
	}

	base := r.Group("")
	{
		base.POST("register", defaultUserRouter.Register)
		base.POST("login", defaultUserRouter.Login)
	}

	user := r.Group("/user")
	user.Use(middlerware.JWTAuth())
	{
		user.POST("del", defaultUserRouter.Delete)
		user.POST("update", defaultUserRouter.Update)
		user.POST("change_pw", defaultUserRouter.ChangePassword)
		user.GET("find", defaultUserRouter.FindById)
		user.POST("search", defaultUserRouter.Search)
	}
}

func configNoRoute(r *gin.Engine) {
	/*	r.LoadHTMLGlob("./dist/*.html") // npm打包成dist的路径
		r.StaticFile("favicon.ico", "./dist/favicon.ico")
		r.Static("/css", "./dist/css")
		r.Static("/fonts", "./dist/fonts")
		r.Static("/js", "./dist/js")
		r.Static("/img", "./dist/img")
		r.StaticFile("/", "./dist/index.html") // 前端网页入口页面*/
}

4. 可能出现的问题

如果引入包并且go mod tidy 出现以下错误时

go: finding module for package google.golang.org/grpc/naming
github.com/tmnhs/common-test/cmd imports
        github.com/tmnhs/common/server imports
        github.com/tmnhs/common/etcdclient imports
        github.com/coreos/etcd/clientv3 tested by
        github.com/coreos/etcd/clientv3.test imports
        github.com/coreos/etcd/integration imports
        github.com/coreos/etcd/proxy/grpcproxy imports
        google.golang.org/grpc/naming: module google.golang.org/grpc@latest found (v1.50.1), but does not contain package google.golang.org/grpc/naming

可以在go.mod中添加以下一行(这个报错和etcd连接的第三方库有版本冲突)

replace google.golang.org/grpc => google.golang.org/grpc v1.26.0

5. 其他功能

如果你需要添加其他的功能,建议将common克隆到你的项目里自行修改,然后

replace github.com/tmnhs/common => ../common

6. 交流讨论

如有问题欢迎加qq:1685290935一起交流讨论

Documentation

Index

Constants

View Source
const (
	EnvTesting    = Environment("testing")
	EnvProduction = Environment("production")
)

use export ENVIRONMENT=testing set global environment

View Source
const (
	SUCCESS = 200
	ERROR   = 1000

	ErrorRequestParameter = 1001
	ErrorTokenGenerate    = 1002
	ErrorUserNameExist    = 1003
)
View Source
const (
	Version   = "v1.1.0"
	ApiModule = "common/api-server"
)

Variables

This section is empty.

Functions

func FailWithCode

func FailWithCode(code int, c *gin.Context)

func FailWithDetailed

func FailWithDetailed(code int, data interface{}, message string, c *gin.Context)

func FailWithMessage

func FailWithMessage(code int, message string, c *gin.Context)

func Ok

func Ok(c *gin.Context)

func OkWithData

func OkWithData(data interface{}, c *gin.Context)

func OkWithDetailed

func OkWithDetailed(data interface{}, message string, c *gin.Context)

func OkWithMessage

func OkWithMessage(message string, c *gin.Context)

func Result

func Result(code int, data interface{}, msg string, c *gin.Context)

Types

type AliyunOSS added in v1.2.0

type AliyunOSS struct {
	Endpoint        string `mapstructure:"endpoint" json:"endpoint" yaml:"endpoint" ini:"endpoint"`
	AccessKeyId     string `mapstructure:"access-key-id" json:"access-key-id" yaml:"access-key-id" ini:"access-key-id"`
	AccessKeySecret string `mapstructure:"access-key-secret" json:"access-key-secret" yaml:"access-key-secret" ini:"access-key-secret"`
	BucketName      string `mapstructure:"bucket-name" json:"bucket-name" yaml:"bucket-name" ini:"bucket-name"`
	BucketUrl       string `mapstructure:"bucket-url" json:"bucket-url" yaml:"bucket-url" ini:"bucket-url"`
	BasePath        string `mapstructure:"base-path" json:"base-path" yaml:"base-path" ini:"base-path"`
}

阿里云存储对象

func (*AliyunOSS) DeleteFile added in v1.2.0

func (a *AliyunOSS) DeleteFile(key string) error

func (*AliyunOSS) NewBucket added in v1.2.0

func (a *AliyunOSS) NewBucket() (*oss.Bucket, error)

func (*AliyunOSS) UploadFile added in v1.2.0

func (a *AliyunOSS) UploadFile(file *multipart.FileHeader) (string, string, error)

阿里云

type ByID

type ByID struct {
	ID int `json:"id" form:"id"`
}

type ByIDS

type ByIDS struct {
	IDS []int `json:"ids" form:"ids"`
}

type Config

type Config struct {
	Log    Log    `mapstructure:"log" json:"log" yaml:"log" ini:"log"`
	System System `mapstructure:"system" json:"system" yaml:"system" ini:"system"`
	Mysql  Mysql  `mapstructure:"mysql" json:"mysql" yaml:"mysql" ini:"mysql"`
	Redis  Redis  `mapstructure:"redis" json:"redis" yaml:"redis" ini:"redis"`
	Etcd   Etcd   `mapstructure:"etcd" json:"etcd" yaml:"etcd" ini:"etcd"`
	Notify Notify `mapstructure:"notify" json:"notify" yaml:"notify" ini:"notify"`
	Upload Upload `mapstructure:"upload" json:"upload" yaml:"upload" ini:"upload"`
}

func GetConfigModels

func GetConfigModels() *Config

func LoadConfig

func LoadConfig(env, configFileName string) (*Config, error)

type Email

type Email struct {
	Port     int      `mapstructure:"port" json:"port" yaml:"port" ini:"port"`                 // 端口
	From     string   `mapstructure:"from" json:"from" yaml:"from" ini:"from"`                 // 收件人
	Host     string   `mapstructure:"host" json:"host" yaml:"host" ini:"host"`                 // 服务器地址
	IsSSL    bool     `mapstructure:"is-ssl" json:"is-ssl" yaml:"is-ssl" ini:"is-ssl"`         // 是否SSL
	Secret   string   `mapstructure:"secret" json:"secret" yaml:"secret" ini:"secret"`         // 密钥
	Nickname string   `mapstructure:"nickname" json:"nickname" yaml:"nickname" ini:"nickname"` // 昵称
	To       []string `mapstructure:"to" json:"to" yaml:"to" ini:"to"`
}

notify

type Environment

type Environment string

func NewGlobalEnvironment

func NewGlobalEnvironment() (Environment, error)

NewGlobalEnvironment 读取系统全局配置的环境变量

func (Environment) Invalid

func (env Environment) Invalid() bool

func (*Environment) Production

func (env *Environment) Production() Environment

func (*Environment) String

func (env *Environment) String() string

func (*Environment) Testing

func (env *Environment) Testing() Environment

type Etcd

type Etcd struct {
	Endpoints   []string `mapstructure:"endpoints" json:"endpoints" yaml:"endpoints" ini:"endpoints"`
	Username    string   `mapstructure:"username" json:"username" yaml:"username" ini:"username"`
	Password    string   `mapstructure:"password" json:"password" yaml:"password" ini:"password"`
	DialTimeout int64    `mapstructure:"dial-timeout" json:"dial-timeout" yaml:"dial-timeout" ini:"dial-timeout"`
	ReqTimeout  int64    `mapstructure:"req-timeout" json:"req-timeout" yaml:"req-timeout" ini:"req-timeout"`
}

type HuaWeiObs added in v1.2.0

type HuaWeiObs struct {
	Path      string `mapstructure:"path" json:"path" yaml:"path" ini:"path"`
	Bucket    string `mapstructure:"bucket" json:"bucket" yaml:"bucket" ini:"bucket"`
	Endpoint  string `mapstructure:"endpoint" json:"endpoint" yaml:"endpoint" ini:"endpoint"`
	AccessKey string `mapstructure:"access-key" json:"access-key" yaml:"access-key" ini:"access-key"`
	SecretKey string `mapstructure:"secret-key" json:"secret-key" yaml:"secret-key" ini:"secret-key"`
}

华为云存储对象

func (*HuaWeiObs) DeleteFile added in v1.2.0

func (h *HuaWeiObs) DeleteFile(key string) error

func (*HuaWeiObs) NewHuaWeiObsClient added in v1.2.0

func (h *HuaWeiObs) NewHuaWeiObsClient() (client *obs.ObsClient, err error)

func (*HuaWeiObs) UploadFile added in v1.2.0

func (h *HuaWeiObs) UploadFile(file *multipart.FileHeader) (filename string, filepath string, err error)

type Local added in v1.2.0

type Local struct {
	Path string `mapstructure:"path" json:"path" yaml:"path" ini:"path"` // 本地文件路径
}

upload

func (*Local) DeleteFile added in v1.2.0

func (l *Local) DeleteFile(key string) error

func (*Local) UploadFile added in v1.2.0

func (l *Local) UploadFile(file *multipart.FileHeader) (string, string, error)

type Log

type Log struct {
	Level         string `mapstructure:"level" json:"level" yaml:"level" ini:"level"`                                    // 级别
	Format        string `mapstructure:"format" json:"format" yaml:"format" ini:"level"`                                 // 输出
	Prefix        string `mapstructure:"prefix" json:"prefix" yaml:"prefix" ini:"level"`                                 // 日志前缀
	Director      string `mapstructure:"director" json:"director"  yaml:"director" ini:"level"`                          // 日志文件夹
	ShowLine      bool   `mapstructure:"show-line" json:"showLine" yaml:"showLine" ini:"showLine"`                       // 显示行
	EncodeLevel   string `mapstructure:"encode-level" json:"encodeLevel" yaml:"encode-level" ini:"encode-level"`         // 编码级
	StacktraceKey string `mapstructure:"stacktrace-key" json:"stacktraceKey" yaml:"stacktrace-key" ini:"stacktrace-key"` // 栈名
	LogInConsole  bool   `mapstructure:"log-in-console" json:"logInConsole" yaml:"log-in-console" ini:"log-in-console"`  // 输出控制台
}

type Mysql

type Mysql struct {
	Path         string `mapstructure:"path" json:"path" yaml:"path" ini:"path"`                                       // 服务器地址
	Port         string `mapstructure:"port" json:"port" yaml:"port" ini:"port"`                                       // 端口
	Config       string `mapstructure:"config" json:"config" yaml:"config" ini:"config"`                               // 高级配置
	Dbname       string `mapstructure:"db-name" json:"dbname" yaml:"db-name" ini:"db-name"`                            // 数据库名
	Username     string `mapstructure:"username" json:"username" yaml:"username" ini:"username"`                       // 数据库用户名
	Password     string `mapstructure:"password" json:"password" yaml:"password" ini:"password"`                       // 数据库密码
	MaxIdleConns int    `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns" ini:"max-idle-conns"` // 空闲中的最大连接数
	MaxOpenConns int    `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns" ini:"max-open-conns"` // 打开到数据库的最大连接数
	LogMode      string `mapstructure:"log-mode" json:"logMode" yaml:"log-mode" ini:"log-mode"`                        // 是否开启Gorm全局日志
	LogZap       bool   `mapstructure:"log-zap" json:"logZap" yaml:"log-zap" ini:"log-zap"`                            // 是否通过zap写入日志文件
}

func (*Mysql) Dsn

func (m *Mysql) Dsn() string

func (*Mysql) EmptyDsn

func (m *Mysql) EmptyDsn() string

type Notify added in v1.2.0

type Notify struct {
	Email   Email   `mapstructure:"email" json:"email" yaml:"email" ini:"email"`
	WebHook WebHook `mapstructure:"webhook" json:"webhook" yaml:"webhook" ini:"webhook"`
}

notify

type PageInfo

type PageInfo struct {
	Page     int `json:"page" form:"page"`           // 页码
	PageSize int `json:"page_size" form:"page_size"` // 每页大小
}

PageInfo Paging common input parameter structure

func (*PageInfo) Check

func (page *PageInfo) Check()

type PageResult

type PageResult struct {
	List     interface{} `json:"list"`
	Total    int64       `json:"total"`
	Page     int         `json:"page"`
	PageSize int         `json:"page_size"`
}

type Qiniu added in v1.2.0

type Qiniu struct {
	Zone          string `mapstructure:"zone" json:"zone" yaml:"zone" ini:"zone"`                                             // 存储区域
	Bucket        string `mapstructure:"bucket" json:"bucket" yaml:"bucket" ini:"bucket"`                                     // 空间名称
	ImgPath       string `mapstructure:"img-path" json:"img-path" yaml:"img-path" ini:"img-path"`                             // CDN加速域名
	UseHTTPS      bool   `mapstructure:"use-https" json:"use-https" yaml:"use-https" ini:"use-https"`                         // 是否使用https
	AccessKey     string `mapstructure:"access-key" json:"access-key" yaml:"access-key" ini:"access-key"`                     // 秘钥AK
	SecretKey     string `mapstructure:"secret-key" json:"secret-key" yaml:"secret-key" ini:"secret-key"`                     // 秘钥SK
	UseCdnDomains bool   `mapstructure:"use-cdn-domains" json:"use-cdn-domains" yaml:"use-cdn-domains" ini:"use-cdn-domains"` // 上传是否使用CDN上传加速
}

七牛云存对象

func (*Qiniu) Config added in v1.2.0

func (q *Qiniu) Config() *storage.Config

func (*Qiniu) DeleteFile added in v1.2.0

func (q *Qiniu) DeleteFile(key string) error

func (*Qiniu) UploadBytes added in v1.2.0

func (q *Qiniu) UploadBytes(data []byte) (string, string, error)

七牛云 上传字节文件

func (*Qiniu) UploadFile added in v1.2.0

func (q *Qiniu) UploadFile(file *multipart.FileHeader) (string, string, error)

上传文件

type Redis

type Redis struct {
	DB       int    `mapstructure:"db" json:"db" yaml:"db" ini:"db"`                         // redis的哪个数据库
	Addr     string `mapstructure:"addr" json:"addr" yaml:"addr" ini:"addr"`                 // 服务器地址:端口
	Password string `mapstructure:"password" json:"password" yaml:"password" ini:"password"` // 密码
}

type Response

type Response struct {
	Code int         `json:"code"`
	Data interface{} `json:"data"`
	Msg  string      `json:"msg"`
}

type System

type System struct {
	Env        string `mapstructure:"env" json:"env" yaml:"env" ini:"env"`
	Addr       int    `mapstructure:"addr" json:"addr" yaml:"addr" ini:"addr"`
	UploadType string `mapstructure:"upload-type" json:"upload-type" yaml:"upload-type" ini:"upload-type"` // Oss类型
	Version    string `mapstructure:"version" json:"version" yaml:"version" ini:"version"`
}

type TencentCOS added in v1.2.0

type TencentCOS struct {
	Bucket     string `mapstructure:"bucket" json:"bucket" yaml:"bucket" ini:"bucket"`
	Region     string `mapstructure:"region" json:"region" yaml:"region" ini:"region"`
	SecretID   string `mapstructure:"secret-id" json:"secret-id" yaml:"secret-id" ini:"secret-id"`
	SecretKey  string `mapstructure:"secret-key" json:"secret-key" yaml:"secret-key" ini:"secret-key"`
	BaseURL    string `mapstructure:"base-url" json:"base-url" yaml:"base-url" ini:"base-url"`
	PathPrefix string `mapstructure:"path-prefix" json:"path-prefix" yaml:"path-prefix" ini:"path-prefix"`
}

腾讯云存储对象

func (*TencentCOS) DeleteFile added in v1.2.0

func (t *TencentCOS) DeleteFile(key string) error

DeleteFile delete file form COS

func (*TencentCOS) NewClient added in v1.2.0

func (t *TencentCOS) NewClient() *cos.Client

NewClient init COS client

func (*TencentCOS) UploadFile added in v1.2.0

func (t *TencentCOS) UploadFile(file *multipart.FileHeader) (string, string, error)

UploadFile upload file to COS

type Upload added in v1.2.0

type Upload struct {
	// oss
	Local      Local      `mapstructure:"local" json:"local" yaml:"local" ini:"local"`
	Qiniu      Qiniu      `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu" ini:"qiniu"`
	AliyunOSS  AliyunOSS  `mapstructure:"aliyun-oss" json:"aliyun-oss" yaml:"aliyun-oss" ini:"aliyun-oss"`
	HuaWeiObs  HuaWeiObs  `mapstructure:"hua-wei-obs" json:"hua-wei-obs" yaml:"hua-wei-obs" ini:"hua-wei-obs"`
	TencentCOS TencentCOS `mapstructure:"tencent-cos" json:"tencent-cos" yaml:"tencent-cos" ini:"tencent-cos"`
}

upload

type WebHook

type WebHook struct {
	Kind string `mapstructure:"kind" json:"kind" yaml:"kind" ini:"kind"`
	Url  string `mapstructure:"url" json:"url" yaml:"url" ini:"kind"`
}

notify

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL