mirror of
https://github.com/xinliangnote/go-gin-api.git
synced 2024-04-21 12:31:46 +00:00
upgrade
This commit is contained in:
@@ -35,13 +35,15 @@
|
||||
```cassandraql
|
||||
├── main.go # 项目入口文件
|
||||
├── configs # 配置文件统一存放目录
|
||||
├── docs # Swagger 文档,执行 swag init 生成的
|
||||
├── init # 项目初始脚本,比如初始化 SQL 语句
|
||||
├── docs # Swagger 文档
|
||||
├── init # 项目初始配置,比如初始化 SQL 语句
|
||||
├── internal # 业务目录
|
||||
│ ├── api # 业务代码
|
||||
│ ├── graph # GraphQL 代码
|
||||
│ ├── pkg # 内部使用的 package
|
||||
├── logs # 存放日志的目录
|
||||
└── pkg # 一些封装好的 package
|
||||
├── logs # 日志目录
|
||||
├── pkg # 外部使用的 package
|
||||
└── scripts # 操作脚本
|
||||
```
|
||||
## Features
|
||||
|
||||
|
||||
@@ -68,7 +68,6 @@ func init() {
|
||||
viper.SetConfigName(env.Active().Value() + "_configs")
|
||||
viper.SetConfigType("toml")
|
||||
viper.AddConfigPath("./configs")
|
||||
viper.AddConfigPath("../../configs") // 兼容 cmd/cron/main.go 引用配置文件
|
||||
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
panic(err)
|
||||
|
||||
+2
-2
@@ -351,11 +351,11 @@ type swaggerInfo struct {
|
||||
|
||||
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||
var SwaggerInfo = swaggerInfo{
|
||||
Version: "",
|
||||
Version: "2.0",
|
||||
Host: "127.0.0.1:9999",
|
||||
BasePath: "",
|
||||
Schemes: []string{},
|
||||
Title: "go-gin-api docs api",
|
||||
Title: "swagger 接口文档",
|
||||
Description: "",
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -1,12 +1,13 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"title": "go-gin-api docs api",
|
||||
"title": "swagger 接口文档",
|
||||
"contact": {},
|
||||
"license": {
|
||||
"name": "MIT",
|
||||
"url": "https://github.com/xinliangnote/go-gin-api/blob/master/LICENSE"
|
||||
}
|
||||
},
|
||||
"version": "2.0"
|
||||
},
|
||||
"host": "127.0.0.1:9999",
|
||||
"paths": {
|
||||
|
||||
+2
-1
@@ -62,7 +62,8 @@ info:
|
||||
license:
|
||||
name: MIT
|
||||
url: https://github.com/xinliangnote/go-gin-api/blob/master/LICENSE
|
||||
title: go-gin-api docs api
|
||||
title: swagger 接口文档
|
||||
version: "2.0"
|
||||
paths:
|
||||
/auth/get:
|
||||
post:
|
||||
|
||||
@@ -3,6 +3,7 @@ module github.com/xinliangnote/go-gin-api
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/99designs/gqlgen v0.13.0
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/gin-contrib/pprof v1.2.1
|
||||
@@ -19,6 +20,7 @@ require (
|
||||
github.com/spf13/viper v1.7.1
|
||||
github.com/swaggo/gin-swagger v1.3.0
|
||||
github.com/swaggo/swag v1.7.0
|
||||
github.com/vektah/gqlparser/v2 v2.1.0
|
||||
go.uber.org/multierr v1.5.0
|
||||
go.uber.org/zap v1.16.0
|
||||
golang.org/x/mod v0.4.0 // indirect
|
||||
|
||||
@@ -11,6 +11,8 @@ cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqCl
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/99designs/gqlgen v0.13.0 h1:haLTcUp3Vwp80xMVEg5KRNwzfUrgFdRmtBY8fuB8scA=
|
||||
github.com/99designs/gqlgen v0.13.0/go.mod h1:NV130r6f4tpRWuAI+zsrSdooO/eWUv+Gyyoi3rEfXIk=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
@@ -22,10 +24,17 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
||||
github.com/agnivade/levenshtein v1.0.3 h1:M5ZnqLOoZR8ygVq0FfkXsNOKzMCk0xRiow0R5+5VkQ0=
|
||||
github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
@@ -51,11 +60,14 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c h1:TUuUh0Xgj97tLMNtWtNvI9mIV6isjEb9lBMNv+77IGM=
|
||||
github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/gzip v0.0.1 h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc=
|
||||
github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w=
|
||||
@@ -69,6 +81,7 @@ github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6
|
||||
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
||||
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
|
||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||
github.com/go-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
@@ -104,6 +117,7 @@ github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRf
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@@ -140,6 +154,9 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
@@ -158,6 +175,7 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
@@ -194,6 +212,7 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
@@ -201,7 +220,9 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
@@ -217,6 +238,7 @@ github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eI
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -240,6 +262,8 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.10.4 h1:NiTx7EEvBzu9sFOD1zORteLSt3o8gnlvZZwSE9TnY9U=
|
||||
github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
@@ -265,14 +289,19 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
@@ -292,6 +321,7 @@ github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
|
||||
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
@@ -316,8 +346,12 @@ github.com/ugorji/go/codec v1.1.13 h1:013LbFhocBoIqgHeIHKlV4JWYhqogATYWZhIcH0WHn
|
||||
github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU=
|
||||
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U=
|
||||
github.com/vektah/gqlparser/v2 v2.1.0 h1:uiKJ+T5HMGGQM2kRKQ8Pxw8+Zq9qhhZhz/lieYvCMns=
|
||||
github.com/vektah/gqlparser/v2 v2.1.0/go.mod h1:SyUiHgLATUR8BiYURfTirrTcGpcE+4XkV2se04Px1Ms=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
@@ -361,6 +395,7 @@ golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
@@ -440,6 +475,7 @@ golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0/go.mod h1:tRJNPiyCQ0inRvYxb
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
@@ -447,6 +483,7 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
@@ -459,6 +496,7 @@ golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20201120155355-20be4ac4bd6e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201226215659-b1c90890d22a h1:pdfjQ7VswBeGam3EpuEJ4e8EAb7JgaubV570LO/SIQM=
|
||||
golang.org/x/tools v0.0.0-20201226215659-b1c90890d22a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
@@ -540,3 +578,5 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20180110180208-2cc67fd64755/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
||||
sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67/go.mod h1:L5q+DGLGOQFpo1snNEkLOJT2d1YTW66rWNzatr3He1k=
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
# Where are all the schema files located? globs are supported eg src/**/*.graphqls
|
||||
schema:
|
||||
- internal/graph/schemas/*.graphql
|
||||
|
||||
# Where should the generated server code go?
|
||||
exec:
|
||||
filename: internal/graph/generated/generated.go
|
||||
package: generated
|
||||
|
||||
# Uncomment to enable federation
|
||||
# federation:
|
||||
# filename: graph/generated/federation.go
|
||||
# package: generated
|
||||
|
||||
# Where should any generated models go?
|
||||
model:
|
||||
filename: internal/graph/model/generated.go
|
||||
package: model
|
||||
|
||||
# Where should the resolver implementations go?
|
||||
resolver:
|
||||
filename: internal/graph/resolvers/generated/generated.go
|
||||
type: Resolver
|
||||
package: resolvers
|
||||
|
||||
# Optional: turn on use `gqlgen:"fieldName"` tags in your models
|
||||
# struct_tag: json
|
||||
|
||||
# Optional: turn on to use []Thing instead of []*Thing
|
||||
# omit_slice_element_pointers: false
|
||||
|
||||
# Optional: set to speed up generation time by not performing a final validation pass.
|
||||
# skip_validation: true
|
||||
|
||||
# gqlgen will search for any type names in the schema in these go packages
|
||||
# if they match it will use them, otherwise it will generate them.
|
||||
autobind:
|
||||
- "github.com/xinliangnote/go-gin-api/internal/graph/model"
|
||||
|
||||
# This section declares type mapping between the GraphQL and go type systems
|
||||
#
|
||||
# The first line in each type will be used as defaults for resolver arguments and
|
||||
# modelgen, the others will be allowed when binding to fields. Configure them to
|
||||
# your liking
|
||||
models:
|
||||
ID:
|
||||
model:
|
||||
- github.com/99designs/gqlgen/graphql.ID
|
||||
- github.com/99designs/gqlgen/graphql.Int
|
||||
- github.com/99designs/gqlgen/graphql.Int64
|
||||
- github.com/99designs/gqlgen/graphql.Int32
|
||||
Int:
|
||||
model:
|
||||
- github.com/99designs/gqlgen/graphql.Int
|
||||
- github.com/99designs/gqlgen/graphql.Int64
|
||||
- github.com/99designs/gqlgen/graphql.Int32
|
||||
@@ -171,7 +171,10 @@ func (d *Demo) Trace() core.HandlerFunc {
|
||||
}
|
||||
|
||||
// 调试信息
|
||||
p.Println("res2.Data.Name", res2.Data.Name, p.WithTrace(c.Trace()))
|
||||
p.Println("res2.Data.Name",
|
||||
res2.Data.Name,
|
||||
p.WithTrace(c.Trace()),
|
||||
)
|
||||
|
||||
// 执行 SQL 信息
|
||||
d.userService.GetUserByUserName(c, "test_user")
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/xinliangnote/go-gin-api/internal/pkg/db"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var _ UserRepo = (*userRepo)(nil)
|
||||
@@ -42,8 +43,9 @@ func (u *userRepo) Create(ctx core.Context, user user_model.UserDemo) (id uint,
|
||||
|
||||
func (u *userRepo) getUserByID(ctx core.Context, id uint) (*user_model.UserDemo, error) {
|
||||
data := new(user_model.UserDemo)
|
||||
err := u.db.GetDbR().WithContext(ctx.RequestContext()).First(data, id).Where("is_deleted = ?", -1).Error
|
||||
if err != nil {
|
||||
err := u.db.GetDbR().
|
||||
WithContext(ctx.RequestContext()).First(data, id).Where("is_deleted = ?", -1).Error
|
||||
if err != nil && err != gorm.ErrRecordNotFound {
|
||||
return nil, errors.Wrap(err, "[user_demo] get user data err")
|
||||
}
|
||||
return data, nil
|
||||
@@ -52,7 +54,7 @@ func (u *userRepo) getUserByID(ctx core.Context, id uint) (*user_model.UserDemo,
|
||||
func (u *userRepo) UpdateNickNameByID(ctx core.Context, id uint, nickname string) (err error) {
|
||||
user, err := u.getUserByID(ctx, id)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "[user_demo] update user data err")
|
||||
return errors.Wrap(err, "[user_demo] get user data err")
|
||||
}
|
||||
return u.db.GetDbW().WithContext(ctx.RequestContext()).Model(user).Update("nick_name", nickname).Error
|
||||
}
|
||||
@@ -60,7 +62,7 @@ func (u *userRepo) UpdateNickNameByID(ctx core.Context, id uint, nickname string
|
||||
func (u *userRepo) Delete(ctx core.Context, id uint) (err error) {
|
||||
user, err := u.getUserByID(ctx, id)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "[user_demo] update user data err")
|
||||
return errors.Wrap(err, "[user_demo] get user data err")
|
||||
}
|
||||
return u.db.GetDbW().WithContext(ctx.RequestContext()).Model(user).Update("is_deleted", 1).Error
|
||||
}
|
||||
@@ -72,7 +74,7 @@ func (u *userRepo) GetUserByUserName(ctx core.Context, username string) (*user_m
|
||||
Select([]string{"id", "user_name", "nick_name", "mobile"}).
|
||||
Where("user_name = ? and is_deleted = ?", username, -1).
|
||||
First(data).Error
|
||||
if err != nil {
|
||||
if err != nil && err != gorm.ErrRecordNotFound {
|
||||
return nil, errors.Wrap(err, "[user_demo] get user data err")
|
||||
}
|
||||
return data, nil
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"github.com/xinliangnote/go-gin-api/internal/api/controller/demo"
|
||||
"github.com/xinliangnote/go-gin-api/internal/api/controller/user_handler"
|
||||
"github.com/xinliangnote/go-gin-api/internal/api/router/middleware/auth"
|
||||
"github.com/xinliangnote/go-gin-api/internal/graph/handler"
|
||||
"github.com/xinliangnote/go-gin-api/internal/pkg/cache"
|
||||
"github.com/xinliangnote/go-gin-api/internal/pkg/core"
|
||||
"github.com/xinliangnote/go-gin-api/internal/pkg/db"
|
||||
@@ -33,6 +34,13 @@ func NewHTTPMux(logger *zap.Logger, db db.Repo, cache cache.Repo) (core.Mux, err
|
||||
|
||||
demoHandler := demo.NewDemo(logger, db, cache)
|
||||
userHandler := user_handler.NewUserDemo(logger, db, cache)
|
||||
gqlHandler := handler.New(logger, db, cache)
|
||||
|
||||
gql := mux.Group("/graphql")
|
||||
{
|
||||
gql.GET("", gqlHandler.Playground())
|
||||
gql.POST("/query", gqlHandler.Query())
|
||||
}
|
||||
|
||||
// user_demo CURD
|
||||
user := mux.Group("/user", core.WrapAuthHandler(auth.AuthHandler))
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
## example
|
||||
|
||||
```cassandraql
|
||||
1.
|
||||
query {
|
||||
bySex(sex: "男") {
|
||||
id
|
||||
name
|
||||
sex
|
||||
mobile
|
||||
}
|
||||
}
|
||||
|
||||
2.
|
||||
mutation {
|
||||
updateUserMobile(data: {id: "1", mobile: "13299999999"}) {
|
||||
id
|
||||
name
|
||||
sex
|
||||
mobile
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,102 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/xinliangnote/go-gin-api/internal/graph/generated"
|
||||
"github.com/xinliangnote/go-gin-api/internal/graph/resolvers"
|
||||
"github.com/xinliangnote/go-gin-api/internal/pkg/cache"
|
||||
"github.com/xinliangnote/go-gin-api/internal/pkg/core"
|
||||
"github.com/xinliangnote/go-gin-api/internal/pkg/db"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
"github.com/99designs/gqlgen/graphql/handler"
|
||||
"github.com/99designs/gqlgen/graphql/handler/extension"
|
||||
"github.com/99designs/gqlgen/graphql/handler/lru"
|
||||
"github.com/99designs/gqlgen/graphql/handler/transport"
|
||||
"github.com/99designs/gqlgen/graphql/playground"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var _ Gql = (*gql)(nil)
|
||||
|
||||
type Gql interface {
|
||||
i()
|
||||
Playground() core.HandlerFunc
|
||||
Query() core.HandlerFunc
|
||||
}
|
||||
|
||||
type gql struct {
|
||||
logger *zap.Logger
|
||||
db db.Repo
|
||||
cache cache.Repo
|
||||
}
|
||||
|
||||
func New(logger *zap.Logger, db db.Repo, cache cache.Repo) Gql {
|
||||
return &gql{
|
||||
logger: logger,
|
||||
cache: cache,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *gql) i() {}
|
||||
|
||||
func (g *gql) Query() core.HandlerFunc {
|
||||
|
||||
// 定义扩展字段
|
||||
extensions := make(map[string]interface{})
|
||||
|
||||
h := handler.New(generated.NewExecutableSchema(
|
||||
resolvers.NewRootResolvers(g.logger, g.db, g.cache)),
|
||||
)
|
||||
|
||||
h.AddTransport(transport.Websocket{
|
||||
KeepAlivePingInterval: 10 * time.Second,
|
||||
})
|
||||
|
||||
// 设置 transport
|
||||
h.AddTransport(transport.Options{})
|
||||
h.AddTransport(transport.GET{})
|
||||
h.AddTransport(transport.POST{})
|
||||
|
||||
h.SetQueryCache(lru.New(1000))
|
||||
|
||||
// 启用侧边栏文档
|
||||
h.Use(extension.Introspection{})
|
||||
|
||||
h.Use(extension.AutomaticPersistedQuery{
|
||||
Cache: lru.New(100),
|
||||
})
|
||||
|
||||
return func(c core.Context) {
|
||||
var responses interface{}
|
||||
|
||||
defer func() {
|
||||
// 设置 core log
|
||||
c.GraphPayload(responses)
|
||||
}()
|
||||
|
||||
// 设置 core trace_id
|
||||
extensions["trace_id"] = c.Trace().ID()
|
||||
|
||||
h.AroundResponses(func(ctx context.Context, next graphql.ResponseHandler) *graphql.Response {
|
||||
resp := next(ctx)
|
||||
resp.Extensions = extensions
|
||||
responses = resp
|
||||
return resp
|
||||
})
|
||||
|
||||
// 设置 core context
|
||||
coreContext := context.WithValue(c.Request().Context(), resolvers.CoreContextKey, c)
|
||||
h.ServeHTTP(c.ResponseWriter(), c.Request().WithContext(coreContext))
|
||||
}
|
||||
}
|
||||
|
||||
func (g *gql) Playground() core.HandlerFunc {
|
||||
h := playground.Handler("GraphQL", "/graphql/query")
|
||||
return func(c core.Context) {
|
||||
h.ServeHTTP(c.ResponseWriter(), c.Request())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
|
||||
|
||||
package model
|
||||
|
||||
type User struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Sex string `json:"sex"`
|
||||
Mobile string `json:"mobile"`
|
||||
}
|
||||
|
||||
type UpdateUserMobileInput struct {
|
||||
ID string `json:"id"`
|
||||
Mobile string `json:"mobile"`
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package resolvers
|
||||
|
||||
// THIS CODE IS A STARTING POINT ONLY. IT WILL NOT BE UPDATED WITH SCHEMA CHANGES.
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/xinliangnote/go-gin-api/internal/graph/generated"
|
||||
"github.com/xinliangnote/go-gin-api/internal/graph/model"
|
||||
)
|
||||
|
||||
type Resolver struct{}
|
||||
|
||||
func (r *mutationResolver) UpdateUserMobile(ctx context.Context, data model.UpdateUserMobileInput) (*model.User, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (r *queryResolver) BySex(ctx context.Context, sex string) ([]*model.User, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
// Mutation returns generated.MutationResolver implementation.
|
||||
func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResolver{r} }
|
||||
|
||||
// Query returns generated.QueryResolver implementation.
|
||||
func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
|
||||
|
||||
type mutationResolver struct{ *Resolver }
|
||||
type queryResolver struct{ *Resolver }
|
||||
@@ -0,0 +1,51 @@
|
||||
package resolvers
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/xinliangnote/go-gin-api/internal/api/service/user_service"
|
||||
"github.com/xinliangnote/go-gin-api/internal/graph/generated"
|
||||
"github.com/xinliangnote/go-gin-api/internal/pkg/cache"
|
||||
"github.com/xinliangnote/go-gin-api/internal/pkg/core"
|
||||
"github.com/xinliangnote/go-gin-api/internal/pkg/db"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type coreCtxKeyType struct{ name string }
|
||||
|
||||
var CoreContextKey = coreCtxKeyType{"_core_context"}
|
||||
|
||||
type mutationResolver struct{ *Resolver }
|
||||
|
||||
type queryResolver struct{ *Resolver }
|
||||
|
||||
type Resolver struct {
|
||||
logger *zap.Logger
|
||||
cache cache.Repo
|
||||
userService user_service.UserService
|
||||
}
|
||||
|
||||
func NewRootResolvers(logger *zap.Logger, db db.Repo, cache cache.Repo) generated.Config {
|
||||
c := generated.Config{
|
||||
Resolvers: &Resolver{
|
||||
logger: logger,
|
||||
cache: cache,
|
||||
userService: user_service.NewUserService(db, cache),
|
||||
},
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (r *Resolver) Mutation() generated.MutationResolver {
|
||||
return &mutationResolver{r}
|
||||
}
|
||||
|
||||
func (r *Resolver) Query() generated.QueryResolver {
|
||||
return &queryResolver{r}
|
||||
}
|
||||
|
||||
// getCoreContextByCtx 获取 core context
|
||||
func (r *Resolver) getCoreContextByCtx(ctx context.Context) core.Context {
|
||||
return ctx.Value(CoreContextKey).(core.Context)
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package resolvers
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/xinliangnote/go-gin-api/internal/graph/model"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (r *queryResolver) BySex(ctx context.Context, sex string) ([]*model.User, error) {
|
||||
if sex == "" {
|
||||
return nil, errors.New("sex required")
|
||||
}
|
||||
|
||||
//模拟数据
|
||||
var users []*model.User
|
||||
users = append(users, &model.User{ID: "1", Name: "Tom", Sex: sex, Mobile: "13266666666"})
|
||||
users = append(users, &model.User{ID: "1", Name: "Jack", Sex: sex, Mobile: "13288888888"})
|
||||
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func (r *mutationResolver) UpdateUserMobile(ctx context.Context, data model.UpdateUserMobileInput) (*model.User, error) {
|
||||
if data.ID == "" {
|
||||
return nil, errors.New("id required")
|
||||
}
|
||||
|
||||
if data.Mobile == "" {
|
||||
return nil, errors.New("mobile required")
|
||||
}
|
||||
|
||||
//模拟数据
|
||||
user := new(model.User)
|
||||
user.ID = data.ID
|
||||
user.Mobile = data.Mobile
|
||||
user.Sex = "男"
|
||||
user.Name = "Jack"
|
||||
|
||||
//操作数据库
|
||||
//userData, err := r.userService.GetUserByUserName(r.getCoreContextByCtx(ctx), "test_user")
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
type User {
|
||||
id: String!
|
||||
name: String!
|
||||
sex: String!
|
||||
mobile: String!
|
||||
}
|
||||
|
||||
# 查询 集合
|
||||
type Query {
|
||||
bySex(sex: String!): [User!]
|
||||
}
|
||||
|
||||
# 输入类型: 一般用户更改资源中的输入是列表对象,完成复杂任务
|
||||
input updateUserMobileInput {
|
||||
id:ID!
|
||||
mobile: String!
|
||||
}
|
||||
|
||||
# 更改或者创建 集合
|
||||
type Mutation {
|
||||
updateUserMobile(data: updateUserMobileInput!): User
|
||||
}
|
||||
Vendored
+7
-1
@@ -75,6 +75,7 @@ func redisConnect() (*redis.Client, error) {
|
||||
|
||||
// Set set some <key,value> into redis
|
||||
func (c *cacheRepo) Set(key, value string, ttl time.Duration, options ...Option) error {
|
||||
ts := time.Now()
|
||||
opt := newOption()
|
||||
defer func() {
|
||||
if opt.Trace != nil {
|
||||
@@ -82,7 +83,8 @@ func (c *cacheRepo) Set(key, value string, ttl time.Duration, options ...Option)
|
||||
opt.Redis.Handle = "set"
|
||||
opt.Redis.Key = key
|
||||
opt.Redis.Value = value
|
||||
opt.Redis.TTL = ttl
|
||||
opt.Redis.TTL = ttl.Minutes()
|
||||
opt.Redis.CostSeconds = time.Since(ts).Seconds()
|
||||
opt.Trace.AppendRedis(opt.Redis)
|
||||
}
|
||||
}()
|
||||
@@ -100,12 +102,14 @@ func (c *cacheRepo) Set(key, value string, ttl time.Duration, options ...Option)
|
||||
|
||||
// Get get some key from redis
|
||||
func (c *cacheRepo) Get(key string, options ...Option) (string, error) {
|
||||
ts := time.Now()
|
||||
opt := newOption()
|
||||
defer func() {
|
||||
if opt.Trace != nil {
|
||||
opt.Redis.Timestamp = time_parse.CSTLayoutString()
|
||||
opt.Redis.Handle = "get"
|
||||
opt.Redis.Key = key
|
||||
opt.Redis.CostSeconds = time.Since(ts).Seconds()
|
||||
opt.Trace.AppendRedis(opt.Redis)
|
||||
}
|
||||
}()
|
||||
@@ -155,12 +159,14 @@ func (c *cacheRepo) Del(keys ...string) bool {
|
||||
}
|
||||
|
||||
func (c *cacheRepo) Incr(key string, options ...Option) int64 {
|
||||
ts := time.Now()
|
||||
opt := newOption()
|
||||
defer func() {
|
||||
if opt.Trace != nil {
|
||||
opt.Redis.Timestamp = time_parse.CSTLayoutString()
|
||||
opt.Redis.Handle = "incr"
|
||||
opt.Redis.Key = key
|
||||
opt.Redis.CostSeconds = time.Since(ts).Seconds()
|
||||
opt.Trace.AppendRedis(opt.Redis)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -22,14 +22,15 @@ type HandlerFunc func(c Context)
|
||||
type Trace = trace.T
|
||||
|
||||
const (
|
||||
_Alias = "_alias_"
|
||||
_TraceName = "_trace_"
|
||||
_LoggerName = "_logger_"
|
||||
_BodyName = "_body_"
|
||||
_PayloadName = "_payload_"
|
||||
_UserID = "_user_id_"
|
||||
_UserName = "_user_name_"
|
||||
_AbortErrorName = "_abort_error_"
|
||||
_Alias = "_alias_"
|
||||
_TraceName = "_trace_"
|
||||
_LoggerName = "_logger_"
|
||||
_BodyName = "_body_"
|
||||
_PayloadName = "_payload_"
|
||||
_GraphPayloadName = "_graph_payload_"
|
||||
_UserID = "_user_id_"
|
||||
_UserName = "_user_name_"
|
||||
_AbortErrorName = "_abort_error_"
|
||||
)
|
||||
|
||||
var contextPool = &sync.Pool{
|
||||
@@ -92,6 +93,10 @@ type Context interface {
|
||||
Payload(payload errno.Error)
|
||||
getPayload() errno.Error
|
||||
|
||||
// GraphPayload GraphQL返回值 与 api 返回结构不同
|
||||
GraphPayload(payload interface{})
|
||||
getGraphPayload() interface{}
|
||||
|
||||
// AbortWithError 错误返回
|
||||
AbortWithError(err errno.Error)
|
||||
abortError() errno.Error
|
||||
@@ -115,6 +120,8 @@ type Context interface {
|
||||
Alias() string
|
||||
setAlias(path string)
|
||||
|
||||
// Request 获取 Request 对象
|
||||
Request() *http.Request
|
||||
// RawData 获取 Request.Body
|
||||
RawData() []byte
|
||||
// Method 获取 Request.Method
|
||||
@@ -127,6 +134,9 @@ type Context interface {
|
||||
URI() string
|
||||
// RequestContext 获取请求的 context (当 client 关闭后,会自动 canceled)
|
||||
RequestContext() StdContext
|
||||
|
||||
// ResponseWriter 获取 ResponseWriter 对象
|
||||
ResponseWriter() gin.ResponseWriter
|
||||
}
|
||||
|
||||
type context struct {
|
||||
@@ -216,14 +226,27 @@ func (c *context) setLogger(logger *zap.Logger) {
|
||||
}
|
||||
|
||||
func (c *context) getPayload() errno.Error {
|
||||
payload, _ := c.ctx.Get(_PayloadName)
|
||||
return payload.(errno.Error)
|
||||
if payload, ok := c.ctx.Get(_PayloadName); ok != false {
|
||||
return payload.(errno.Error)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *context) Payload(payload errno.Error) {
|
||||
c.ctx.Set(_PayloadName, payload)
|
||||
}
|
||||
|
||||
func (c *context) getGraphPayload() interface{} {
|
||||
if payload, ok := c.ctx.Get(_GraphPayloadName); ok != false {
|
||||
return payload
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *context) GraphPayload(payload interface{}) {
|
||||
c.ctx.Set(_GraphPayloadName, payload)
|
||||
}
|
||||
|
||||
func (c *context) Header() http.Header {
|
||||
header := c.ctx.Request.Header
|
||||
|
||||
@@ -303,6 +326,11 @@ func (c *context) setAlias(path string) {
|
||||
}
|
||||
}
|
||||
|
||||
// Request 获取 Request
|
||||
func (c *context) Request() *http.Request {
|
||||
return c.ctx.Request
|
||||
}
|
||||
|
||||
func (c *context) RawData() []byte {
|
||||
body, ok := c.ctx.Get(_BodyName)
|
||||
if !ok {
|
||||
@@ -341,3 +369,8 @@ func (c *context) RequestContext() StdContext {
|
||||
c.Logger(),
|
||||
}
|
||||
}
|
||||
|
||||
// ResponseWriter 获取 ResponseWriter
|
||||
func (c *context) ResponseWriter() gin.ResponseWriter {
|
||||
return c.ctx.Writer
|
||||
}
|
||||
|
||||
@@ -353,6 +353,7 @@ func New(logger *zap.Logger, options ...Option) (Mux, error) {
|
||||
businessCodeMsg string
|
||||
abortErr error
|
||||
traceId string
|
||||
graphResponse interface{}
|
||||
)
|
||||
|
||||
if ctx.IsAborted() {
|
||||
@@ -382,6 +383,8 @@ func New(logger *zap.Logger, options ...Option) (Mux, error) {
|
||||
ctx.JSON(response.GetHttpCode(), response)
|
||||
}
|
||||
|
||||
graphResponse = context.getGraphPayload()
|
||||
|
||||
if opt.recordMetrics != nil {
|
||||
uri := context.URI()
|
||||
if alias := context.Alias(); alias != "" {
|
||||
@@ -415,24 +418,40 @@ func New(logger *zap.Logger, options ...Option) (Mux, error) {
|
||||
Body: string(context.RawData()),
|
||||
})
|
||||
|
||||
var responseBody interface{}
|
||||
|
||||
if response != nil {
|
||||
responseBody = response
|
||||
}
|
||||
|
||||
if graphResponse != nil {
|
||||
responseBody = graphResponse
|
||||
}
|
||||
|
||||
t.WithResponse(&trace.Response{
|
||||
Header: ctx.Writer.Header(),
|
||||
HttpCode: ctx.Writer.Status(),
|
||||
HttpCodeMsg: http.StatusText(ctx.Writer.Status()),
|
||||
BusinessCode: businessCode,
|
||||
BusinessCodeMsg: businessCodeMsg,
|
||||
Body: response,
|
||||
Body: responseBody,
|
||||
CostSeconds: time.Since(ts).Seconds(),
|
||||
})
|
||||
|
||||
t.Success = !ctx.IsAborted() && ctx.Writer.Status() == http.StatusOK
|
||||
t.CostSeconds = time.Since(ts).Seconds()
|
||||
|
||||
if abortErr == nil {
|
||||
logger.Info("core-interceptor", zap.Any("trace", t))
|
||||
} else {
|
||||
logger.Info("core-interceptor", zap.Any("trace", t), zap.Error(abortErr))
|
||||
}
|
||||
|
||||
logger.Info("core-interceptor",
|
||||
zap.Any("method", ctx.Request.Method),
|
||||
zap.Any("path", decodedURL),
|
||||
zap.Any("http_code", ctx.Writer.Status()),
|
||||
zap.Any("business_code", businessCode),
|
||||
zap.Any("success", t.Success),
|
||||
zap.Any("cost_seconds", t.CostSeconds),
|
||||
zap.Any("trace_id", t.Identifier),
|
||||
zap.Any("trace_info", t),
|
||||
zap.Error(abortErr),
|
||||
)
|
||||
}()
|
||||
|
||||
ctx.Next()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package trace
|
||||
|
||||
type Debug struct {
|
||||
Key string `json:"key"` //标示
|
||||
Value interface{} `json:"value"` //值
|
||||
Key string `json:"key"` // 标示
|
||||
Value interface{} `json:"value"` // 值
|
||||
CostSeconds float64 `json:"cost_seconds"` // 执行时间(单位秒)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package trace
|
||||
|
||||
import "time"
|
||||
|
||||
type Redis struct {
|
||||
Timestamp string `json:"timestamp"` // 时间,格式:2006-01-02 15:04:05
|
||||
Handle string `json:"handle"` // 操作,function
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value,omitempty"`
|
||||
TTL time.Duration `json:"ttl,omitempty"`
|
||||
Timestamp string `json:"timestamp"` // 时间,格式:2006-01-02 15:04:05
|
||||
Handle string `json:"handle"` // 操作,SET/GET 等
|
||||
Key string `json:"key"` // Key
|
||||
Value string `json:"value,omitempty"` // Value
|
||||
TTL float64 `json:"ttl,omitempty"` // 超时时长(单位分)
|
||||
CostSeconds float64 `json:"cost_seconds"` // 执行时间(单位秒)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package trace
|
||||
type SQL struct {
|
||||
Timestamp string `json:"timestamp"` // 时间,格式:2006-01-02 15:04:05
|
||||
Stack string `json:"stack"` // 文件地址和行号
|
||||
CostSeconds float64 `json:"cost_seconds"` // 执行时长(单位秒)
|
||||
SQL string `json:"sql"` // SQL 语句
|
||||
Rows int64 `json:"rows_affected"` // 影响行数
|
||||
CostSeconds float64 `json:"cost_seconds"` // 执行时长(单位秒)
|
||||
}
|
||||
|
||||
@@ -10,14 +10,15 @@ import (
|
||||
"github.com/xinliangnote/go-gin-api/internal/api/router"
|
||||
"github.com/xinliangnote/go-gin-api/internal/pkg/cache"
|
||||
"github.com/xinliangnote/go-gin-api/internal/pkg/db"
|
||||
"github.com/xinliangnote/go-gin-api/pkg/env"
|
||||
"github.com/xinliangnote/go-gin-api/pkg/logger"
|
||||
"github.com/xinliangnote/go-gin-api/pkg/shutdown"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// @title go-gin-api docs api
|
||||
// @version
|
||||
// @title swagger 接口文档
|
||||
// @version 2.0
|
||||
// @description
|
||||
|
||||
// @contact.name
|
||||
@@ -30,9 +31,9 @@ import (
|
||||
// @host 127.0.0.1:9999
|
||||
// @BasePath
|
||||
func main() {
|
||||
// 初始化日志
|
||||
// 初始化 logger
|
||||
loggers, err := logger.NewJSONLogger(
|
||||
logger.WithField("domain", configs.ProjectName()),
|
||||
logger.WithField("domain", fmt.Sprintf("%s[%s]", configs.ProjectName(), env.Active().Value())),
|
||||
logger.WithTimeLayout("2006-01-02 15:04:05"),
|
||||
logger.WithFileP(fmt.Sprintf("./logs/%s-access.log", configs.ProjectName())),
|
||||
)
|
||||
@@ -41,13 +42,13 @@ func main() {
|
||||
}
|
||||
defer loggers.Sync()
|
||||
|
||||
// 初始化数据库
|
||||
// 初始化 DB
|
||||
dbRepo, err := db.New()
|
||||
if err != nil {
|
||||
loggers.Fatal("new db err", zap.Error(err))
|
||||
}
|
||||
|
||||
// 初始化缓存
|
||||
// 初始化 Cache
|
||||
cacheRepo, err := cache.New()
|
||||
if err != nil {
|
||||
loggers.Fatal("new cache err", zap.Error(err))
|
||||
@@ -71,14 +72,33 @@ func main() {
|
||||
}()
|
||||
|
||||
// 优雅关闭
|
||||
shutdown.NewHook().Close(func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||
defer cancel()
|
||||
shutdown.NewHook().Close(
|
||||
// 关闭 http server
|
||||
func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||
defer cancel()
|
||||
|
||||
if err := server.Shutdown(ctx); err != nil {
|
||||
loggers.Fatal("shutdown err", zap.Error(err))
|
||||
} else {
|
||||
loggers.Info("shutdown success")
|
||||
}
|
||||
})
|
||||
if err := server.Shutdown(ctx); err != nil {
|
||||
loggers.Error("server shutdown err", zap.Error(err))
|
||||
} else {
|
||||
loggers.Info("server shutdown success")
|
||||
}
|
||||
},
|
||||
|
||||
// 关闭 db
|
||||
func() {
|
||||
if err := dbRepo.DbWClose(); err != nil {
|
||||
loggers.Error("dbw close err", zap.Error(err))
|
||||
}
|
||||
|
||||
if err := dbRepo.DbRClose(); err != nil {
|
||||
loggers.Error("dbr close err", zap.Error(err))
|
||||
}
|
||||
},
|
||||
|
||||
// 关闭 cache
|
||||
func() {
|
||||
cacheRepo.Close()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
+35
-22
@@ -23,10 +23,11 @@ const (
|
||||
type Option func(*option)
|
||||
|
||||
type option struct {
|
||||
level zapcore.Level
|
||||
fields map[string]string
|
||||
file io.Writer
|
||||
timeLayout string
|
||||
level zapcore.Level
|
||||
fields map[string]string
|
||||
file io.Writer
|
||||
timeLayout string
|
||||
disableConsole bool
|
||||
}
|
||||
|
||||
// WithDebugLevel only greater than 'level' will output
|
||||
@@ -90,11 +91,12 @@ func WithFileRotationP(file string) Option {
|
||||
|
||||
return func(opt *option) {
|
||||
opt.file = &lumberjack.Logger{ // concurrent-safed
|
||||
Filename: file,
|
||||
MaxSize: 10, // megabytes
|
||||
MaxBackups: 100,
|
||||
MaxAge: 30, // days
|
||||
LocalTime: true,
|
||||
Filename: file, // 文件路径
|
||||
MaxSize: 128, // 单个文件最大尺寸,默认单位 M
|
||||
MaxBackups: 300, // 最多保留 300 个备份
|
||||
MaxAge: 30, // 最大时间,默认单位 day
|
||||
LocalTime: true, // 使用本地时间
|
||||
Compress: true, // 是否压缩 disabled by default
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,6 +108,13 @@ func WithTimeLayout(timeLayout string) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithEnableConsole write log to os.Stdout or os.Stderr
|
||||
func WithDisableConsole() Option {
|
||||
return func(opt *option) {
|
||||
opt.disableConsole = true
|
||||
}
|
||||
}
|
||||
|
||||
// NewJSONLogger return a json-encoder zap logger,
|
||||
func NewJSONLogger(opts ...Option) (*zap.Logger, error) {
|
||||
opt := &option{level: DefaultLevel, fields: make(map[string]string)}
|
||||
@@ -120,19 +129,19 @@ func NewJSONLogger(opts ...Option) (*zap.Logger, error) {
|
||||
|
||||
// similar to zap.NewProductionEncoderConfig()
|
||||
encoderConfig := zapcore.EncoderConfig{
|
||||
TimeKey: "timestamp",
|
||||
TimeKey: "time",
|
||||
LevelKey: "level",
|
||||
NameKey: "logger", // used by logger.Named(key); optional; useless
|
||||
CallerKey: "caller",
|
||||
MessageKey: "msg",
|
||||
StacktraceKey: "stacktrace", // use by zap.AddStacktrace; optional; useless
|
||||
LineEnding: zapcore.DefaultLineEnding,
|
||||
EncodeLevel: zapcore.LowercaseLevelEncoder,
|
||||
EncodeLevel: zapcore.LowercaseLevelEncoder, // 小写编码器
|
||||
EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
|
||||
enc.AppendString(t.Format(timeLayout))
|
||||
},
|
||||
EncodeDuration: zapcore.MillisDurationEncoder,
|
||||
EncodeCaller: zapcore.ShortCallerEncoder,
|
||||
EncodeCaller: zapcore.ShortCallerEncoder, // 全路径编码器
|
||||
}
|
||||
|
||||
jsonEncoder := zapcore.NewJSONEncoder(encoderConfig)
|
||||
@@ -150,16 +159,20 @@ func NewJSONLogger(opts ...Option) (*zap.Logger, error) {
|
||||
stdout := zapcore.Lock(os.Stdout) // lock for concurrent safe
|
||||
stderr := zapcore.Lock(os.Stderr) // lock for concurrent safe
|
||||
|
||||
core := zapcore.NewTee(
|
||||
zapcore.NewCore(jsonEncoder,
|
||||
zapcore.NewMultiWriteSyncer(stdout),
|
||||
lowPriority,
|
||||
),
|
||||
zapcore.NewCore(jsonEncoder,
|
||||
zapcore.NewMultiWriteSyncer(stderr),
|
||||
highPriority,
|
||||
),
|
||||
)
|
||||
core := zapcore.NewTee()
|
||||
|
||||
if !opt.disableConsole {
|
||||
core = zapcore.NewTee(
|
||||
zapcore.NewCore(jsonEncoder,
|
||||
zapcore.NewMultiWriteSyncer(stdout),
|
||||
lowPriority,
|
||||
),
|
||||
zapcore.NewCore(jsonEncoder,
|
||||
zapcore.NewMultiWriteSyncer(stderr),
|
||||
highPriority,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
if opt.file != nil {
|
||||
core = zapcore.NewTee(core,
|
||||
|
||||
@@ -2,6 +2,7 @@ package p
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/xinliangnote/go-gin-api/internal/pkg/trace"
|
||||
)
|
||||
@@ -20,11 +21,13 @@ func newOption() *option {
|
||||
}
|
||||
|
||||
func Println(key string, value interface{}, options ...Option) {
|
||||
ts := time.Now()
|
||||
opt := newOption()
|
||||
defer func() {
|
||||
if opt.Trace != nil {
|
||||
opt.Debug.Key = key
|
||||
opt.Debug.Value = value
|
||||
opt.Debug.CostSeconds = time.Since(ts).Seconds()
|
||||
opt.Trace.AppendDebug(opt.Debug)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -27,7 +27,19 @@ func RFC3339ToCSTLayout(value string) (string, error) {
|
||||
return ts.In(cst).Format(CSTLayout), nil
|
||||
}
|
||||
|
||||
// CSTLayoutString 格式化时间
|
||||
// 返回 "2006-01-02 15:04:05" 格式的时间
|
||||
func CSTLayoutString() string {
|
||||
ts := time.Now()
|
||||
return ts.In(cst).Format(CSTLayout)
|
||||
}
|
||||
|
||||
// CSTLayoutStringToUnix 返回 unix 时间戳
|
||||
// 2020-01-24 21:11:11 => 1579871471
|
||||
func CSTLayoutStringToUnix(cstLayoutString string) (int64, error) {
|
||||
stamp, err := time.ParseInLocation(CSTLayout, cstLayoutString, cst)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return stamp.Unix(), nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package time_parse
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestRFC3339ToCSTLayout(t *testing.T) {
|
||||
t.Log(RFC3339ToCSTLayout("2020-11-08T08:18:46+08:00"))
|
||||
}
|
||||
|
||||
func TestCSTLayoutString(t *testing.T) {
|
||||
t.Log(CSTLayoutString())
|
||||
}
|
||||
|
||||
func TestCSTLayoutStringToUnix(t *testing.T) {
|
||||
t.Log(CSTLayoutStringToUnix("2020-01-24 21:11:11"))
|
||||
}
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
printf "\nRegenerating gqlgen files\n"
|
||||
rm -f internal/graph/generated/generated.go \
|
||||
internal/graph/model/generated.go \
|
||||
internal/graph/resolvers/generated/generated.go
|
||||
time go run -v github.com/99designs/gqlgen $1
|
||||
printf "\nDone.\n\n"
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
printf "\nRegenerating swagger doc\n\n"
|
||||
time go run -v github.com/swaggo/swag/cmd/swag init
|
||||
printf "\nDone.\n\n"
|
||||
Reference in New Issue
Block a user