正在显示
23 个修改的文件
包含
465 行增加
和
34 行删除
| @@ -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,6 +173,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | @@ -173,6 +173,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | ||
| 173 | ) | 173 | ) |
| 174 | 174 | ||
| 175 | server.AddRoutes( | 175 | server.AddRoutes( |
| 176 | + rest.WithMiddlewares( | ||
| 177 | + []rest.Middleware{serverCtx.LoginStatusCheck}, | ||
| 176 | []rest.Route{ | 178 | []rest.Route{ |
| 177 | { | 179 | { |
| 178 | Method: http.MethodPost, | 180 | Method: http.MethodPost, |
| @@ -224,7 +226,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | @@ -224,7 +226,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | ||
| 224 | Path: "/system/account/search", | 226 | Path: "/system/account/search", |
| 225 | Handler: user.SystemUserAccountSearchHandler(serverCtx), | 227 | Handler: user.SystemUserAccountSearchHandler(serverCtx), |
| 226 | }, | 228 | }, |
| 227 | - }, | 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,6 +357,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | @@ -354,6 +357,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | ||
| 354 | ) | 357 | ) |
| 355 | 358 | ||
| 356 | server.AddRoutes( | 359 | server.AddRoutes( |
| 360 | + rest.WithMiddlewares( | ||
| 361 | + []rest.Middleware{serverCtx.LoginStatusCheck}, | ||
| 357 | []rest.Route{ | 362 | []rest.Route{ |
| 358 | { | 363 | { |
| 359 | Method: http.MethodGet, | 364 | Method: http.MethodGet, |
| @@ -380,12 +385,15 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | @@ -380,12 +385,15 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | ||
| 380 | Path: "/system/role/search", | 385 | Path: "/system/role/search", |
| 381 | Handler: role.SystemSearchRoleHandler(serverCtx), | 386 | Handler: role.SystemSearchRoleHandler(serverCtx), |
| 382 | }, | 387 | }, |
| 383 | - }, | 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( |
| 395 | + rest.WithMiddlewares( | ||
| 396 | + []rest.Middleware{serverCtx.LoginStatusCheck}, | ||
| 389 | []rest.Route{ | 397 | []rest.Route{ |
| 390 | { | 398 | { |
| 391 | Method: http.MethodPost, | 399 | Method: http.MethodPost, |
| @@ -407,7 +415,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | @@ -407,7 +415,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | ||
| 407 | Path: "/system/department/:id", | 415 | Path: "/system/department/:id", |
| 408 | Handler: department.SystemUpdateHandler(serverCtx), | 416 | Handler: department.SystemUpdateHandler(serverCtx), |
| 409 | }, | 417 | }, |
| 410 | - }, | 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, | 56 | Config: c, |
| 47 | DB: db, | 57 | DB: db, |
| 48 | Redis: redis, | 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 | +) |
cmd/discuss/interanl/pkg/gateway/base.go
0 → 100644
| 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 { |
-
请 注册 或 登录 后发表评论