作者 yangfu

权限认证

@@ -11,6 +11,7 @@ info( @@ -11,6 +11,7 @@ info(
11 @server( 11 @server(
12 prefix: v1 12 prefix: v1
13 group: department 13 group: department
  14 + middleware: LoginStatusCheck
14 jwt: SystemAuth 15 jwt: SystemAuth
15 ) 16 )
16 service Core { 17 service Core {
@@ -11,6 +11,7 @@ info( @@ -11,6 +11,7 @@ info(
11 @server( 11 @server(
12 prefix: v1 12 prefix: v1
13 group: role 13 group: role
  14 + middleware: LoginStatusCheck
14 jwt: SystemAuth 15 jwt: SystemAuth
15 ) 16 )
16 service Core { 17 service Core {
@@ -209,6 +209,7 @@ type ( @@ -209,6 +209,7 @@ type (
209 @server( 209 @server(
210 prefix: v1 210 prefix: v1
211 group: user 211 group: user
  212 + middleware: LoginStatusCheck
212 jwt: SystemAuth 213 jwt: SystemAuth
213 ) 214 )
214 service Core { 215 service Core {
@@ -249,7 +250,7 @@ service Core { @@ -249,7 +250,7 @@ service Core {
249 250
250 type( 251 type(
251 SystemUserInfoRequest{ 252 SystemUserInfoRequest{
252 - 253 + Token string `header:"x-mmm-accesstoken"`
253 } 254 }
254 SystemUserInfoResponse{ 255 SystemUserInfoResponse{
255 UserId int64 `json:"userId"` 256 UserId int64 `json:"userId"`
@@ -257,6 +258,7 @@ type( @@ -257,6 +258,7 @@ type(
257 Avatar string `json:"avatar"` 258 Avatar string `json:"avatar"`
258 CompanyId int64 `json:"companyId"` 259 CompanyId int64 `json:"companyId"`
259 CompanyName string `json:"companyName"` 260 CompanyName string `json:"companyName"`
  261 + Code string `json:"code"`
260 } 262 }
261 UserStatisticsRequest{ 263 UserStatisticsRequest{
262 UserId int64 `json:"userId"` 264 UserId int64 `json:"userId"`
1 Name: discuss 1 Name: discuss
2 Host: 0.0.0.0 2 Host: 0.0.0.0
3 Port: 8081 3 Port: 8081
4 -Verbose: true 4 +Verbose: false
5 Migrate: false 5 Migrate: false
6 Timeout: 30000 6 Timeout: 30000
7 Log: 7 Log:
@@ -12,7 +12,7 @@ Log: @@ -12,7 +12,7 @@ Log:
12 TimeFormat: 2006-01-02 15:04:05.000 12 TimeFormat: 2006-01-02 15:04:05.000
13 13
14 SystemAuth: 14 SystemAuth:
15 - AccessSecret: discuss-secret 15 + AccessSecret: digital-platform
16 AccessExpire: 360000 16 AccessExpire: 360000
17 17
18 MiniAuth: 18 MiniAuth:
@@ -25,3 +25,8 @@ Redis: @@ -25,3 +25,8 @@ Redis:
25 Pass: 25 Pass:
26 DB: 26 DB:
27 DataSource: host=114.55.200.59 user=postgres password=eagle1010 dbname=sumifcc-discuss-dev port=31543 sslmode=disable TimeZone=Asia/Shanghai 27 DataSource: host=114.55.200.59 user=postgres password=eagle1010 dbname=sumifcc-discuss-dev port=31543 sslmode=disable TimeZone=Asia/Shanghai
  28 +
  29 +ApiAuth:
  30 + Name: ApiAuth
  31 + Host: http://digital-platform-dev.fjmaimaimai.com
  32 + Timeout: 0s
@@ -4,6 +4,7 @@ import ( @@ -4,6 +4,7 @@ import (
4 "github.com/zeromicro/go-zero/core/stores/redis" 4 "github.com/zeromicro/go-zero/core/stores/redis"
5 "github.com/zeromicro/go-zero/rest" 5 "github.com/zeromicro/go-zero/rest"
6 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/config" 6 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/config"
  7 + "time"
7 ) 8 )
8 9
9 type Config struct { 10 type Config struct {
@@ -13,4 +14,11 @@ type Config struct { @@ -13,4 +14,11 @@ type Config struct {
13 SystemAuth config.Auth 14 SystemAuth config.Auth
14 MiniAuth config.Auth 15 MiniAuth config.Auth
15 Migrate bool `json:",optional,default=true"` 16 Migrate bool `json:",optional,default=true"`
  17 + ApiAuth ApiService
  18 +}
  19 +
  20 +type ApiService struct {
  21 + Name string
  22 + Host string
  23 + Timeout time.Duration
16 } 24 }
@@ -173,58 +173,61 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { @@ -173,58 +173,61 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
173 ) 173 )
174 174
175 server.AddRoutes( 175 server.AddRoutes(
176 - []rest.Route{  
177 - {  
178 - Method: http.MethodPost,  
179 - Path: "/system/user/info",  
180 - Handler: user.SystemUserInfoHandler(serverCtx),  
181 - },  
182 - {  
183 - Method: http.MethodPost,  
184 - Path: "/system/user/statistics",  
185 - Handler: user.SystemUserStatisticsHandler(serverCtx),  
186 - },  
187 - {  
188 - Method: http.MethodGet,  
189 - Path: "/system/user/:id",  
190 - Handler: user.SystemUserGetHandler(serverCtx),  
191 - },  
192 - {  
193 - Method: http.MethodPut,  
194 - Path: "/system/user/:id",  
195 - Handler: user.SystemUserUpdateHandler(serverCtx),  
196 - },  
197 - {  
198 - Method: http.MethodPost,  
199 - Path: "/system/user/search",  
200 - Handler: user.SystemUserSearchHandler(serverCtx),  
201 - },  
202 - {  
203 - Method: http.MethodGet,  
204 - Path: "/system/account/:id",  
205 - Handler: user.SystemUserAccountGetHandler(serverCtx),  
206 - },  
207 - {  
208 - Method: http.MethodPost,  
209 - Path: "/system/account",  
210 - Handler: user.SystemUserAccountSaveHandler(serverCtx),  
211 - },  
212 - {  
213 - Method: http.MethodPost,  
214 - Path: "/system/account/enable",  
215 - Handler: user.SystemUserAccountEnableHandler(serverCtx),  
216 - },  
217 - {  
218 - Method: http.MethodPut,  
219 - Path: "/system/account/:id",  
220 - Handler: user.SystemUserAccountUpdateHandler(serverCtx),  
221 - },  
222 - {  
223 - Method: http.MethodPost,  
224 - Path: "/system/account/search",  
225 - Handler: user.SystemUserAccountSearchHandler(serverCtx),  
226 - },  
227 - }, 176 + rest.WithMiddlewares(
  177 + []rest.Middleware{serverCtx.LoginStatusCheck},
  178 + []rest.Route{
  179 + {
  180 + Method: http.MethodPost,
  181 + Path: "/system/user/info",
  182 + Handler: user.SystemUserInfoHandler(serverCtx),
  183 + },
  184 + {
  185 + Method: http.MethodPost,
  186 + Path: "/system/user/statistics",
  187 + Handler: user.SystemUserStatisticsHandler(serverCtx),
  188 + },
  189 + {
  190 + Method: http.MethodGet,
  191 + Path: "/system/user/:id",
  192 + Handler: user.SystemUserGetHandler(serverCtx),
  193 + },
  194 + {
  195 + Method: http.MethodPut,
  196 + Path: "/system/user/:id",
  197 + Handler: user.SystemUserUpdateHandler(serverCtx),
  198 + },
  199 + {
  200 + Method: http.MethodPost,
  201 + Path: "/system/user/search",
  202 + Handler: user.SystemUserSearchHandler(serverCtx),
  203 + },
  204 + {
  205 + Method: http.MethodGet,
  206 + Path: "/system/account/:id",
  207 + Handler: user.SystemUserAccountGetHandler(serverCtx),
  208 + },
  209 + {
  210 + Method: http.MethodPost,
  211 + Path: "/system/account",
  212 + Handler: user.SystemUserAccountSaveHandler(serverCtx),
  213 + },
  214 + {
  215 + Method: http.MethodPost,
  216 + Path: "/system/account/enable",
  217 + Handler: user.SystemUserAccountEnableHandler(serverCtx),
  218 + },
  219 + {
  220 + Method: http.MethodPut,
  221 + Path: "/system/account/:id",
  222 + Handler: user.SystemUserAccountUpdateHandler(serverCtx),
  223 + },
  224 + {
  225 + Method: http.MethodPost,
  226 + Path: "/system/account/search",
  227 + Handler: user.SystemUserAccountSearchHandler(serverCtx),
  228 + },
  229 + }...,
  230 + ),
228 rest.WithJwt(serverCtx.Config.SystemAuth.AccessSecret), 231 rest.WithJwt(serverCtx.Config.SystemAuth.AccessSecret),
229 rest.WithPrefix("/v1"), 232 rest.WithPrefix("/v1"),
230 ) 233 )
@@ -354,60 +357,66 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { @@ -354,60 +357,66 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
354 ) 357 )
355 358
356 server.AddRoutes( 359 server.AddRoutes(
357 - []rest.Route{  
358 - {  
359 - Method: http.MethodGet,  
360 - Path: "/system/role/:id",  
361 - Handler: role.SystemGetRoleHandler(serverCtx),  
362 - },  
363 - {  
364 - Method: http.MethodPost,  
365 - Path: "/system/role",  
366 - Handler: role.SystemSaveRoleHandler(serverCtx),  
367 - },  
368 - {  
369 - Method: http.MethodDelete,  
370 - Path: "/system/role/:id",  
371 - Handler: role.SystemDeleteRoleHandler(serverCtx),  
372 - },  
373 - {  
374 - Method: http.MethodPut,  
375 - Path: "/system/role/:id",  
376 - Handler: role.SystemUpdateRoleHandler(serverCtx),  
377 - },  
378 - {  
379 - Method: http.MethodPost,  
380 - Path: "/system/role/search",  
381 - Handler: role.SystemSearchRoleHandler(serverCtx),  
382 - },  
383 - }, 360 + rest.WithMiddlewares(
  361 + []rest.Middleware{serverCtx.LoginStatusCheck},
  362 + []rest.Route{
  363 + {
  364 + Method: http.MethodGet,
  365 + Path: "/system/role/:id",
  366 + Handler: role.SystemGetRoleHandler(serverCtx),
  367 + },
  368 + {
  369 + Method: http.MethodPost,
  370 + Path: "/system/role",
  371 + Handler: role.SystemSaveRoleHandler(serverCtx),
  372 + },
  373 + {
  374 + Method: http.MethodDelete,
  375 + Path: "/system/role/:id",
  376 + Handler: role.SystemDeleteRoleHandler(serverCtx),
  377 + },
  378 + {
  379 + Method: http.MethodPut,
  380 + Path: "/system/role/:id",
  381 + Handler: role.SystemUpdateRoleHandler(serverCtx),
  382 + },
  383 + {
  384 + Method: http.MethodPost,
  385 + Path: "/system/role/search",
  386 + Handler: role.SystemSearchRoleHandler(serverCtx),
  387 + },
  388 + }...,
  389 + ),
384 rest.WithJwt(serverCtx.Config.SystemAuth.AccessSecret), 390 rest.WithJwt(serverCtx.Config.SystemAuth.AccessSecret),
385 rest.WithPrefix("/v1"), 391 rest.WithPrefix("/v1"),
386 ) 392 )
387 393
388 server.AddRoutes( 394 server.AddRoutes(
389 - []rest.Route{  
390 - {  
391 - Method: http.MethodPost,  
392 - Path: "/system/department/list",  
393 - Handler: department.SystemListHandler(serverCtx),  
394 - },  
395 - {  
396 - Method: http.MethodPost,  
397 - Path: "/system/department/add",  
398 - Handler: department.SystemAddHandler(serverCtx),  
399 - },  
400 - {  
401 - Method: http.MethodGet,  
402 - Path: "/system/department/:id",  
403 - Handler: department.SystemGetHandler(serverCtx),  
404 - },  
405 - {  
406 - Method: http.MethodPut,  
407 - Path: "/system/department/:id",  
408 - Handler: department.SystemUpdateHandler(serverCtx),  
409 - },  
410 - }, 395 + rest.WithMiddlewares(
  396 + []rest.Middleware{serverCtx.LoginStatusCheck},
  397 + []rest.Route{
  398 + {
  399 + Method: http.MethodPost,
  400 + Path: "/system/department/list",
  401 + Handler: department.SystemListHandler(serverCtx),
  402 + },
  403 + {
  404 + Method: http.MethodPost,
  405 + Path: "/system/department/add",
  406 + Handler: department.SystemAddHandler(serverCtx),
  407 + },
  408 + {
  409 + Method: http.MethodGet,
  410 + Path: "/system/department/:id",
  411 + Handler: department.SystemGetHandler(serverCtx),
  412 + },
  413 + {
  414 + Method: http.MethodPut,
  415 + Path: "/system/department/:id",
  416 + Handler: department.SystemUpdateHandler(serverCtx),
  417 + },
  418 + }...,
  419 + ),
411 rest.WithJwt(serverCtx.Config.SystemAuth.AccessSecret), 420 rest.WithJwt(serverCtx.Config.SystemAuth.AccessSecret),
412 rest.WithPrefix("/v1"), 421 rest.WithPrefix("/v1"),
413 ) 422 )
@@ -2,8 +2,15 @@ package user @@ -2,8 +2,15 @@ package user
2 2
3 import ( 3 import (
4 "context" 4 "context"
  5 + "fmt"
5 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" 6 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
6 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" 7 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
  9 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway/authlib"
  10 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
  11 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/tool"
  12 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
  13 + "strconv"
7 14
8 "github.com/zeromicro/go-zero/core/logx" 15 "github.com/zeromicro/go-zero/core/logx"
9 ) 16 )
@@ -23,6 +30,67 @@ func NewSystemUserInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Sy @@ -23,6 +30,67 @@ func NewSystemUserInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Sy
23 } 30 }
24 31
25 func (l *SystemUserInfoLogic) SystemUserInfo(req *types.SystemUserInfoRequest) (resp *types.SystemUserInfoResponse, err error) { 32 func (l *SystemUserInfoLogic) SystemUserInfo(req *types.SystemUserInfoRequest) (resp *types.SystemUserInfoResponse, err error) {
  33 + var (
  34 + conn = l.svcCtx.DefaultDBConn()
  35 + userToken = contextdata.GetUserTokenFromCtx(l.ctx)
  36 + response *authlib.DataUserMe
  37 + company *domain.Company
  38 + companyId int64
  39 + code = tool.Krand(6, tool.KC_RAND_KIND_ALL)
  40 + )
  41 + if response, err = l.svcCtx.ApiAuthService.MeInfo(l.ctx, authlib.RequestUserMeQuery{
  42 + Token: req.Token,
  43 + }); err != nil {
  44 + return nil, xerr.NewErrMsgErr("获取用户资料失败", err)
  45 + }
  46 +
  47 + companyId, _ = strconv.ParseInt(response.CurrentCompany.ID, 10, 64)
  48 + resp = &types.SystemUserInfoResponse{}
  49 + resp.UserName = response.User.NickName
  50 + resp.UserId, _ = strconv.ParseInt(response.User.ID, 10, 64)
  51 + resp.Avatar = response.User.Avatar
  52 + resp.CompanyName = response.CurrentCompany.Name
  53 + resp.CompanyId = companyId
  54 + resp.Code = code
26 55
  56 + if companyId != userToken.CompanyId {
  57 + return nil, xerr.NewErrMsgErr("获取用户资料失败", fmt.Errorf("当前登录公司信息不匹配"))
  58 + }
  59 + company, err = l.svcCtx.CompanyRepository.FindOne(l.ctx, conn, userToken.CompanyId)
  60 + // 新建公司
  61 + if err == domain.ErrNotFound {
  62 + company = &domain.Company{
  63 + Id: companyId,
  64 + Name: response.CurrentCompany.Name,
  65 + Logo: response.CurrentCompany.Logo,
  66 + Code: code,
  67 + }
  68 + if company, err = l.svcCtx.CompanyRepository.Insert(l.ctx, conn, company); err != nil {
  69 + return nil, xerr.NewErrMsgErr("获取用户资料失败", err)
  70 + }
  71 + err = nil
  72 + return
  73 + }
  74 + if err != nil {
  75 + return nil, xerr.NewErrMsgErr("获取用户资料失败", err)
  76 + }
  77 + resp.Code = company.Code
  78 + // 更新公司
  79 + if response.CurrentCompany != nil {
  80 + var changed bool
  81 + if response.CurrentCompany.Name != "" && response.CurrentCompany.Name != company.Name {
  82 + company.Name = response.CurrentCompany.Name
  83 + changed = true
  84 + }
  85 + if response.CurrentCompany.Logo != "" && response.CurrentCompany.Logo != company.Logo {
  86 + company.Logo = response.CurrentCompany.Logo
  87 + changed = true
  88 + }
  89 + if changed {
  90 + if company, err = l.svcCtx.CompanyRepository.UpdateWithVersion(l.ctx, conn, company); err != nil {
  91 + return nil, xerr.NewErrMsgErr("获取用户资料失败", err)
  92 + }
  93 + }
  94 + }
27 return 95 return
28 } 96 }
  1 +package middleware
  2 +
  3 +import (
  4 + "github.com/zeromicro/go-zero/rest/httpx"
  5 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway"
  6 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway/authlib"
  7 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
  9 + "net/http"
  10 +)
  11 +
  12 +type LoginStatusCheckMiddleware struct {
  13 + apiAuth authlib.ApiAuthService
  14 +}
  15 +
  16 +func NewLoginStatusCheckMiddleware(apiAuth authlib.ApiAuthService) *LoginStatusCheckMiddleware {
  17 + return &LoginStatusCheckMiddleware{
  18 + apiAuth: apiAuth,
  19 + }
  20 +}
  21 +
  22 +func (m *LoginStatusCheckMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
  23 + return func(w http.ResponseWriter, r *http.Request) {
  24 + token := r.Header.Get("x-mmm-accesstoken")
  25 + if len(token) > 0 {
  26 + _, err := m.apiAuth.LoginCheck(r.Context(), authlib.RequestLoginCheck{
  27 + Token: token,
  28 + })
  29 + if err != nil {
  30 + gatewayError, ok := err.(gateway.HttpError)
  31 + if ok {
  32 + unAuthResponse(w, gatewayError.Base.Code, gatewayError.Base.Msg)
  33 + return
  34 + }
  35 + result.HttpResult(r, w, struct{}{}, xerr.NewErr(err))
  36 + return
  37 + }
  38 + }
  39 + next(w, r)
  40 + }
  41 +}
  42 +
  43 +func unAuthResponse(w http.ResponseWriter, code int, msg string) {
  44 + data := map[string]interface{}{
  45 + "msg": msg,
  46 + "code": code,
  47 + "data": struct{}{},
  48 + }
  49 + httpx.WriteJson(w, http.StatusUnauthorized, data)
  50 +}
@@ -2,10 +2,14 @@ package svc @@ -2,10 +2,14 @@ package svc
2 2
3 import ( 3 import (
4 "github.com/zeromicro/go-zero/core/stores/redis" 4 "github.com/zeromicro/go-zero/core/stores/redis"
  5 + "github.com/zeromicro/go-zero/rest"
5 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/config" 6 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/config"
  7 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/middleware"
6 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/repository" 8 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/repository"
7 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction" 9 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
8 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" 10 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
  11 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway"
  12 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway/authlib"
9 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/cache" 13 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/cache"
10 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/database" 14 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/database"
11 "gorm.io/gorm" 15 "gorm.io/gorm"
@@ -33,6 +37,10 @@ type ServiceContext struct { @@ -33,6 +37,10 @@ type ServiceContext struct {
33 UserLoveFlagRepository domain.UserLoveFlagRepository 37 UserLoveFlagRepository domain.UserLoveFlagRepository
34 UserReadArticleRepository domain.UserReadArticleRepository 38 UserReadArticleRepository domain.UserReadArticleRepository
35 UserRepository domain.UserRepository 39 UserRepository domain.UserRepository
  40 +
  41 + ApiAuthService authlib.ApiAuthService
  42 +
  43 + LoginStatusCheck rest.Middleware
36 } 44 }
37 45
38 func NewServiceContext(c config.Config) *ServiceContext { 46 func NewServiceContext(c config.Config) *ServiceContext {
@@ -41,11 +49,16 @@ func NewServiceContext(c config.Config) *ServiceContext { @@ -41,11 +49,16 @@ func NewServiceContext(c config.Config) *ServiceContext {
41 49
42 mlCache := cache.NewMultiLevelCache([]string{c.Redis.Host}, c.Redis.Pass) 50 mlCache := cache.NewMultiLevelCache([]string{c.Redis.Host}, c.Redis.Pass)
43 redis, _ := redis.NewRedis(redis.RedisConf{Host: c.Redis.Host, Pass: c.Redis.Pass, Type: "node"}) 51 redis, _ := redis.NewRedis(redis.RedisConf{Host: c.Redis.Host, Pass: c.Redis.Pass, Type: "node"})
44 - 52 + apiAuth := authlib.ApiAuthService{
  53 + Service: gateway.NewService(c.ApiAuth.Name, c.ApiAuth.Host, c.ApiAuth.Timeout),
  54 + }
45 return &ServiceContext{ 55 return &ServiceContext{
46 - Config: c,  
47 - DB: db,  
48 - Redis: redis, 56 + Config: c,
  57 + DB: db,
  58 + Redis: redis,
  59 + ApiAuthService: apiAuth,
  60 + LoginStatusCheck: middleware.NewLoginStatusCheckMiddleware(apiAuth).Handle,
  61 +
49 CommentRepository: repository.NewCommentRepository(cache.NewCachedRepository(mlCache)), 62 CommentRepository: repository.NewCommentRepository(cache.NewCachedRepository(mlCache)),
50 ArticleBackupRepository: repository.NewArticleBackupRepository(cache.NewCachedRepository(mlCache)), 63 ArticleBackupRepository: repository.NewArticleBackupRepository(cache.NewCachedRepository(mlCache)),
51 ArticleCommentRepository: repository.NewArticleCommentRepository(cache.NewCachedRepository(mlCache)), 64 ArticleCommentRepository: repository.NewArticleCommentRepository(cache.NewCachedRepository(mlCache)),
@@ -392,6 +392,7 @@ type SimpleComment struct { @@ -392,6 +392,7 @@ type SimpleComment struct {
392 } 392 }
393 393
394 type SystemUserInfoRequest struct { 394 type SystemUserInfoRequest struct {
  395 + Token string `header:"x-mmm-accesstoken"`
395 } 396 }
396 397
397 type SystemUserInfoResponse struct { 398 type SystemUserInfoResponse struct {
@@ -400,6 +401,7 @@ type SystemUserInfoResponse struct { @@ -400,6 +401,7 @@ type SystemUserInfoResponse struct {
400 Avatar string `json:"avatar"` 401 Avatar string `json:"avatar"`
401 CompanyId int64 `json:"companyId"` 402 CompanyId int64 `json:"companyId"`
402 CompanyName string `json:"companyName"` 403 CompanyName string `json:"companyName"`
  404 + Code string `json:"code"`
403 } 405 }
404 406
405 type UserStatisticsRequest struct { 407 type UserStatisticsRequest struct {
@@ -10,7 +10,7 @@ import ( @@ -10,7 +10,7 @@ import (
10 type Company struct { 10 type Company struct {
11 Id int64 // 唯一标识 11 Id int64 // 唯一标识
12 Name string // 名称 12 Name string // 名称
13 - Code string // 编码(搜索使用,4位字母数字) 13 + Code string `gorm:"uniqueIndex:idx_company_code"` // 编码(搜索使用,4位字母数字)
14 Logo string // 公司LOGO 14 Logo string // 公司LOGO
15 15
16 CreatedAt int64 16 CreatedAt int64
  1 +package authlib
  2 +
  3 +import (
  4 + "context"
  5 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway"
  6 + "net/http"
  7 +)
  8 +
  9 +type ApiAuthService struct {
  10 + gateway.Service
  11 +}
  12 +
  13 +func (svc *ApiAuthService) MeInfo(ctx context.Context, request RequestUserMeQuery) (*DataUserMe, error) {
  14 + var result DataUserMe
  15 + if err := svc.Do(ctx, "/v1/user/me", http.MethodGet, request, &result); err != nil {
  16 + return nil, err
  17 + }
  18 + return &result, nil
  19 +}
  20 +
  21 +func (svc *ApiAuthService) MeAppInfo(ctx context.Context, request RequestUserMeQuery) (*DataUserAppInfo, error) {
  22 + var result DataUserAppInfo
  23 + if err := svc.Do(ctx, "/v1/user/me-app-info", http.MethodGet, request, &result); err != nil {
  24 + return nil, err
  25 + }
  26 + return &result, nil
  27 +}
  28 +
  29 +func (svc *ApiAuthService) LoginCheck(ctx context.Context, request RequestLoginCheck) (*DataLoginCheck, error) {
  30 + var (
  31 + result DataLoginCheck
  32 + err error
  33 + )
  34 + if err = svc.Do(ctx, "/v1/login/check?token="+request.Token, http.MethodGet, request, &result); err != nil {
  35 + return nil, err
  36 + }
  37 + if errCodeMsg, ok := err.(gateway.HttpError); ok {
  38 + return &DataLoginCheck{
  39 + Code: errCodeMsg.Base.Code,
  40 + Msg: errCodeMsg.Base.Msg,
  41 + }, nil
  42 + }
  43 + return &result, nil
  44 +}
  45 +
  46 +func (svc *ApiAuthService) AppLogin(ctx context.Context, request RequestAppLogin) (*DataAppLogin, error) {
  47 + var result DataAppLogin
  48 + if err := svc.Do(ctx, "/v1/login/check?token="+request.Token, http.MethodGet, request, &result); err != nil {
  49 + return nil, err
  50 + }
  51 + return &result, nil
  52 +}
  1 +package authlib
  2 +
  3 +type RequestUserMeQuery struct {
  4 + Token string `header:"x-mmm-accesstoken"`
  5 + //UserId int
  6 + //CompanyId int
  7 +}
  8 +
  9 +type DataUserMe struct {
  10 + User *struct {
  11 + ID string `json:"id"`
  12 + Phone string `json:"phone"`
  13 + NickName string `json:"nickName"`
  14 + Avatar string `json:"avatar"`
  15 + } `json:"user,optional"`
  16 + CompanyList []*struct {
  17 + ID string `json:"id"`
  18 + Name string `json:"name"`
  19 + Logo string `json:"logo"`
  20 + DefaultLogin int `json:"defaultLogin"`
  21 + Types int `json:"types"`
  22 + } `json:"companyList,optional"`
  23 + CurrentCompany *struct {
  24 + ID string `json:"id"`
  25 + Name string `json:"name"`
  26 + Logo string `json:"logo"`
  27 + DefaultLogin int `json:"defaultLogin"`
  28 + Types int `json:"types"`
  29 + } `json:"currentCompany,optional"`
  30 + Workbench []*struct {
  31 + ID int `json:"id"`
  32 + Name string `json:"name"`
  33 + Code string `json:"code"`
  34 + CoverImage string `json:"coverImage"`
  35 + URL string `json:"url"`
  36 + } `json:"workbench,optional"`
  37 + Menus []*struct {
  38 + MenuID int `json:"menuId"`
  39 + ParentID int `json:"parentId"`
  40 + MenuName string `json:"menuName"`
  41 + Code string `json:"code"`
  42 + Types string `json:"types"`
  43 + } `json:"menus,optional"`
  44 +}
  45 +
  46 +type RequestLoginCheck struct {
  47 + Token string
  48 +}
  49 +type DataLoginCheck struct {
  50 + Code int `json:"code,optional"`
  51 + Msg string `json:"msg,optional"`
  52 +}
  53 +
  54 +type (
  55 + RequestAppLogin struct {
  56 + AppKey string `json:"appKey" valid:"Required"` // 应用键值
  57 + Token string `json:"token" valid:"Required"` // 凭证
  58 + }
  59 + DataAppLogin struct {
  60 + AppEnabled bool `json:"appEnabled"`
  61 + }
  62 +)
  63 +
  64 +type (
  65 + DataUserAppInfo struct {
  66 + Apps []AppItem `json:"apps"`
  67 + }
  68 + AppItem struct {
  69 + AppId int64
  70 + AppKey string
  71 + AppName string
  72 + }
  73 +)
  1 +package gateway
  2 +
  3 +import (
  4 + "encoding/json"
  5 + "fmt"
  6 +)
  7 +
  8 +// Response 统一消息返回格式
  9 +type Response struct {
  10 + Code int `json:"code,optional"`
  11 + Msg string `json:"msg,optional"`
  12 + Data json.RawMessage `json:"data,optional"`
  13 +}
  14 +
  15 +//
  16 +//type Request struct {
  17 +// Url string
  18 +// Method string
  19 +// Param interface{}
  20 +//}
  21 +
  22 +type HttpError struct {
  23 + Base Response
  24 +}
  25 +
  26 +func (e HttpError) Error() string {
  27 + return fmt.Sprintf("HttpError code:%d msg:%s", e.Base.Code, e.Base.Msg)
  28 +}
  1 +package gateway
  2 +
  3 +import (
  4 + "context"
  5 + "encoding/json"
  6 + "fmt"
  7 + "github.com/zeromicro/go-zero/core/mapping"
  8 + "github.com/zeromicro/go-zero/rest/httpc"
  9 + "io/ioutil"
  10 + "net/http"
  11 + "strings"
  12 + "time"
  13 +)
  14 +
  15 +type Service struct {
  16 + Timeout time.Duration
  17 + host string
  18 + Interceptor func(msg string)
  19 + ServiceName string
  20 + service httpc.Service
  21 +}
  22 +
  23 +func NewService(name string, host string, timeout time.Duration, opts ...httpc.Option) Service {
  24 + client := &http.Client{}
  25 + //client.Timeout = timeout
  26 +
  27 + service := Service{
  28 + host: host,
  29 + service: httpc.NewServiceWithClient(name, client, opts...),
  30 + }
  31 + return service
  32 +}
  33 +
  34 +func (gateway Service) Do(ctx context.Context, url string, method string, val interface{}, result interface{}) error {
  35 + var (
  36 + baseResponse = Response{}
  37 + begin = time.Now()
  38 + body []byte
  39 + )
  40 + response, err := gateway.service.Do(ctx, method, gateway.host+url, val)
  41 + defer func() {
  42 + jsonParam, _ := json.Marshal(val)
  43 + jsonData, _ := json.Marshal(result)
  44 + if err != nil {
  45 + result = err.Error()
  46 + }
  47 + if gateway.Interceptor != nil {
  48 + gateway.Interceptor(fmt.Sprintf("【网关】%v | %v%v | %v : %v \n-->> %v \n<<-- %v", time.Since(begin), gateway.host, url, strings.ToUpper(method),
  49 + result,
  50 + string(jsonParam),
  51 + string(jsonData),
  52 + ))
  53 + }
  54 + }()
  55 + if err != nil {
  56 + return err
  57 + }
  58 + if response.StatusCode != http.StatusOK {
  59 + return HttpError{
  60 + Base: Response{
  61 + Code: response.StatusCode,
  62 + Msg: response.Status,
  63 + },
  64 + }
  65 + }
  66 + body, err = Bytes(response)
  67 + if err != nil {
  68 + return err
  69 + }
  70 + if err = json.Unmarshal(body, &baseResponse); err != nil {
  71 + return err
  72 + }
  73 + if baseResponse.Code != 0 {
  74 + return HttpError{
  75 + Base: Response{
  76 + Code: baseResponse.Code,
  77 + Msg: baseResponse.Msg,
  78 + },
  79 + }
  80 + }
  81 + if err = mapping.UnmarshalJsonBytes(baseResponse.Data, result); err != nil {
  82 + return err
  83 + }
  84 + return nil
  85 +}
  86 +
  87 +func Bytes(resp *http.Response) ([]byte, error) {
  88 + var body []byte
  89 + if resp.Body == nil {
  90 + return nil, nil
  91 + }
  92 + defer resp.Body.Close()
  93 +
  94 + body, err := ioutil.ReadAll(resp.Body)
  95 + return body, err
  96 +}
  1 +package gateway
  2 +
  3 +import "net/http"
  4 +
  5 +type RequestOptions struct {
  6 + Header http.Header
  7 + // key:form key value:path
  8 + FileMap map[string]string
  9 +}
  10 +
  11 +type Option func(o *RequestOptions)
  12 +
  13 +func WithHeader(header http.Header) Option {
  14 + return func(o *RequestOptions) {
  15 + o.Header = header
  16 + }
  17 +}
  18 +
  19 +func WithFileMap(v map[string]string) Option {
  20 + return func(o *RequestOptions) {
  21 + o.FileMap = v
  22 + }
  23 +}
@@ -9,8 +9,8 @@ import ( @@ -9,8 +9,8 @@ import (
9 ) 9 )
10 10
11 var ( 11 var (
12 - CtxKeyJwtUserId = "UserId"  
13 - CtxKeyJwtCompanyId = "CompanyId" 12 + CtxKeyJwtUserId = "userId"
  13 + CtxKeyJwtCompanyId = "companyId"
14 ) 14 )
15 15
16 func GetInt64FromCtx(ctx context.Context, key string) int64 { 16 func GetInt64FromCtx(ctx context.Context, key string) int64 {
@@ -37,7 +37,7 @@ func HttpResult(r *http.Request, w http.ResponseWriter, resp interface{}, err er @@ -37,7 +37,7 @@ func HttpResult(r *http.Request, w http.ResponseWriter, resp interface{}, err er
37 } 37 }
38 } else { 38 } else {
39 if grpcStatus, ok := status.FromError(causeErr); ok { // grpc err错误 39 if grpcStatus, ok := status.FromError(causeErr); ok { // grpc err错误
40 - grpcCode := uint32(grpcStatus.Code()) 40 + grpcCode := int(grpcStatus.Code())
41 if xerr.IsCodeErr(grpcCode) { 41 if xerr.IsCodeErr(grpcCode) {
42 errCode = grpcCode 42 errCode = grpcCode
43 errMsg = grpcStatus.Message() 43 errMsg = grpcStatus.Message()
@@ -12,11 +12,11 @@ func Success(data interface{}) *ResponseSuccessBean { @@ -12,11 +12,11 @@ func Success(data interface{}) *ResponseSuccessBean {
12 } 12 }
13 13
14 type ResponseErrorBean struct { 14 type ResponseErrorBean struct {
15 - Code uint32 `json:"code"` 15 + Code int `json:"code"`
16 Msg string `json:"msg"` 16 Msg string `json:"msg"`
17 Error string `json:"err"` 17 Error string `json:"err"`
18 } 18 }
19 19
20 -func Error(errCode uint32, errMsg string) *ResponseErrorBean { 20 +func Error(errCode int, errMsg string) *ResponseErrorBean {
21 return &ResponseErrorBean{Code: errCode, Msg: errMsg} 21 return &ResponseErrorBean{Code: errCode, Msg: errMsg}
22 } 22 }
@@ -16,10 +16,10 @@ func (tk UserToken) GenerateToken(secret string, expire int64) (string, error) { @@ -16,10 +16,10 @@ func (tk UserToken) GenerateToken(secret string, expire int64) (string, error) {
16 claims := make(jwt.MapClaims) 16 claims := make(jwt.MapClaims)
17 claims["exp"] = time.Now().Unix() + expire 17 claims["exp"] = time.Now().Unix() + expire
18 claims["iat"] = time.Now().Unix() 18 claims["iat"] = time.Now().Unix()
19 - claims["UserId"] = tk.UserId  
20 - claims["AdminId"] = tk.AdminId  
21 - claims["CompanyId"] = tk.CompanyId  
22 - claims["ClientType"] = tk.ClientType 19 + claims["userId"] = tk.UserId
  20 + claims["adminId"] = tk.AdminId
  21 + claims["companyId"] = tk.CompanyId
  22 + claims["clientType"] = tk.ClientType
23 token := jwt.New(jwt.SigningMethodHS256) 23 token := jwt.New(jwt.SigningMethodHS256)
24 token.Claims = claims 24 token.Claims = claims
25 25
@@ -16,10 +16,10 @@ func NewErrMsgErr(errMsg string, internalError error) *CodeError { @@ -16,10 +16,10 @@ func NewErrMsgErr(errMsg string, internalError error) *CodeError {
16 16
17 /**指定错误码的错误**/ 17 /**指定错误码的错误**/
18 18
19 -func NewCodeErr(errCode uint32, err error) *CodeError { 19 +func NewCodeErr(errCode int, err error) *CodeError {
20 return &CodeError{errCode: errCode, errMsg: MapErrMsg(errCode), InternalError: err} 20 return &CodeError{errCode: errCode, errMsg: MapErrMsg(errCode), InternalError: err}
21 } 21 }
22 22
23 -func NewCodeErrMsg(errCode uint32, err error, msg string) *CodeError { 23 +func NewCodeErrMsg(errCode int, err error, msg string) *CodeError {
24 return &CodeError{errCode: errCode, errMsg: msg, InternalError: err} 24 return &CodeError{errCode: errCode, errMsg: msg, InternalError: err}
25 } 25 }
@@ -4,34 +4,34 @@ import "fmt" @@ -4,34 +4,34 @@ import "fmt"
4 4
5 const ( 5 const (
6 // OK 成功返回 6 // OK 成功返回
7 - OK uint32 = 200 7 + OK int = 200
8 ) 8 )
9 9
10 // 全局错误码 10 // 全局错误码
11 // 系统错误前3位代表业务,后三位代表具体功能 11 // 系统错误前3位代表业务,后三位代表具体功能
12 const ( 12 const (
13 - ServerCommonError uint32 = 100001 // 系统错误  
14 - RequestParamError uint32 = 100002 // 参数请求错误  
15 - TokenExpireError uint32 = 100003 // token失效  
16 - TokenGenerateError uint32 = 100004 // 生成token失败  
17 - DbError uint32 = 100005 // 数据库错误  
18 - DbUpdateAffectedZeroError uint32 = 100006 // 数据库更新错误 13 + ServerCommonError int = 100001 // 系统错误
  14 + RequestParamError int = 100002 // 参数请求错误
  15 + TokenExpireError int = 100003 // token失效
  16 + TokenGenerateError int = 100004 // 生成token失败
  17 + DbError int = 100005 // 数据库错误
  18 + DbUpdateAffectedZeroError int = 100006 // 数据库更新错误
19 ) 19 )
20 20
21 /**微信模块**/ 21 /**微信模块**/
22 const ( 22 const (
23 - ErrWxMiniAuthFailError uint32 = 500001  
24 - ErrUserNoAuth uint32 = 500002 23 + ErrWxMiniAuthFailError int = 500001
  24 + ErrUserNoAuth int = 500002
25 ) 25 )
26 26
27 type CodeError struct { 27 type CodeError struct {
28 - errCode uint32 28 + errCode int
29 errMsg string 29 errMsg string
30 InternalError error 30 InternalError error
31 } 31 }
32 32
33 // GetErrCode 返回给前端的错误码 33 // GetErrCode 返回给前端的错误码
34 -func (e *CodeError) GetErrCode() uint32 { 34 +func (e *CodeError) GetErrCode() int {
35 return e.errCode 35 return e.errCode
36 } 36 }
37 37
1 package xerr 1 package xerr
2 2
3 -var message map[uint32]string 3 +var message map[int]string
4 4
5 func init() { 5 func init() {
6 - message = make(map[uint32]string) 6 + message = make(map[int]string)
7 message[OK] = "SUCCESS" 7 message[OK] = "SUCCESS"
8 message[ServerCommonError] = "服务器开小差啦,稍后再来试一试" 8 message[ServerCommonError] = "服务器开小差啦,稍后再来试一试"
9 message[RequestParamError] = "参数错误" 9 message[RequestParamError] = "参数错误"
@@ -15,7 +15,7 @@ func init() { @@ -15,7 +15,7 @@ func init() {
15 message[ErrWxMiniAuthFailError] = "微信授权失败" 15 message[ErrWxMiniAuthFailError] = "微信授权失败"
16 } 16 }
17 17
18 -func MapErrMsg(errCode uint32) string { 18 +func MapErrMsg(errCode int) string {
19 if msg, ok := message[errCode]; ok { 19 if msg, ok := message[errCode]; ok {
20 return msg 20 return msg
21 } else { 21 } else {
@@ -23,7 +23,7 @@ func MapErrMsg(errCode uint32) string { @@ -23,7 +23,7 @@ func MapErrMsg(errCode uint32) string {
23 } 23 }
24 } 24 }
25 25
26 -func IsCodeErr(errCode uint32) bool { 26 +func IsCodeErr(errCode int) bool {
27 if _, ok := message[errCode]; ok { 27 if _, ok := message[errCode]; ok {
28 return true 28 return true
29 } else { 29 } else {