diff --git a/api/auth/handler.go b/api/auth/handler.go new file mode 100644 index 0000000..ad630b1 --- /dev/null +++ b/api/auth/handler.go @@ -0,0 +1,8 @@ +package auth + +import ( + "github.com/gin-gonic/gin" +) + +func ApiHandler(r *gin.RouterGroup) { +} diff --git a/api/event/handler.go b/api/event/handler.go new file mode 100644 index 0000000..8e182c5 --- /dev/null +++ b/api/event/handler.go @@ -0,0 +1,11 @@ +package event + +import ( + "nixcn-cms/middleware" + + "github.com/gin-gonic/gin" +) + +func ApiHandler(r *gin.RouterGroup) { + r.Use(middleware.ApiVersionCheck(), middleware.JWTAuth(), middleware.Permission(10)) +} diff --git a/api/handler.go b/api/handler.go new file mode 100644 index 0000000..883fca7 --- /dev/null +++ b/api/handler.go @@ -0,0 +1,17 @@ +package api + +import ( + "nixcn-cms/api/auth" + "nixcn-cms/api/event" + "nixcn-cms/api/kyc" + "nixcn-cms/api/user" + + "github.com/gin-gonic/gin" +) + +func Handler(r *gin.RouterGroup) { + auth.ApiHandler(r.Group("/auth")) + user.ApiHandler(r.Group("/user")) + event.ApiHandler(r.Group("/event")) + kyc.ApiHandler(r.Group("/kyc")) +} diff --git a/api/kyc/handler.go b/api/kyc/handler.go new file mode 100644 index 0000000..452c43d --- /dev/null +++ b/api/kyc/handler.go @@ -0,0 +1,11 @@ +package kyc + +import ( + "nixcn-cms/middleware" + + "github.com/gin-gonic/gin" +) + +func ApiHandler(r *gin.RouterGroup) { + r.Use(middleware.ApiVersionCheck(), middleware.JWTAuth(), middleware.Permission(10)) +} diff --git a/api/user/create.go b/api/user/create.go new file mode 100644 index 0000000..dafe823 --- /dev/null +++ b/api/user/create.go @@ -0,0 +1,6 @@ +package user + +import "github.com/gin-gonic/gin" + +func (self *UserHandler) Create(c *gin.Context) { +} diff --git a/service/user/create.go b/api/user/full.go similarity index 52% rename from service/user/create.go rename to api/user/full.go index 4fe088e..2a84bde 100644 --- a/service/user/create.go +++ b/api/user/full.go @@ -2,6 +2,6 @@ package user import "github.com/gin-gonic/gin" -func Create(c *gin.Context) { +func (self *UserHandler) Full(c *gin.Context) { } diff --git a/api/user/handler.go b/api/user/handler.go new file mode 100644 index 0000000..1d2ac0f --- /dev/null +++ b/api/user/handler.go @@ -0,0 +1,24 @@ +package user + +import ( + "nixcn-cms/middleware" + "nixcn-cms/service" + + "github.com/gin-gonic/gin" +) + +type UserHandler struct { + svc service.UserService +} + +func ApiHandler(r *gin.RouterGroup) { + userSvc := service.NewUserService() + userHandler := &UserHandler{userSvc} + + r.Use(middleware.ApiVersionCheck(), middleware.JWTAuth(), middleware.Permission(5)) + r.GET("/info", userHandler.Info) + r.PATCH("/update", userHandler.Update) + r.GET("/list", middleware.Permission(20), userHandler.List) + r.POST("/full", middleware.Permission(40), userHandler.Full) + r.POST("/create", middleware.Permission(50), userHandler.Create) +} diff --git a/api/user/info.go b/api/user/info.go new file mode 100644 index 0000000..b1b816e --- /dev/null +++ b/api/user/info.go @@ -0,0 +1,6 @@ +package user + +import "github.com/gin-gonic/gin" + +func (self *UserHandler) Info(c *gin.Context) { +} diff --git a/api/user/list.go b/api/user/list.go new file mode 100644 index 0000000..92521be --- /dev/null +++ b/api/user/list.go @@ -0,0 +1,7 @@ +package user + +import "github.com/gin-gonic/gin" + +func (self *UserHandler) List(c *gin.Context) { + +} diff --git a/api/user/update.go b/api/user/update.go new file mode 100644 index 0000000..56a3bf3 --- /dev/null +++ b/api/user/update.go @@ -0,0 +1,7 @@ +package user + +import "github.com/gin-gonic/gin" + +func (self *UserHandler) Update(c *gin.Context) { + +} diff --git a/data/user.go b/data/user.go index 7124b18..ce49e1e 100644 --- a/data/user.go +++ b/data/user.go @@ -33,10 +33,50 @@ type UserSearchDoc struct { Avatar string `json:"avatar"` } -func (self *User) GetByEmail(ctx context.Context, email string) (*User, error) { +func (self *User) SetEmail(s string) *User { + self.Email = s + return self +} + +func (self *User) SetUsername(s string) *User { + self.Username = s + return self +} + +func (self *User) SetNickname(s string) *User { + self.Nickname = s + return self +} + +func (self *User) SetSubtitle(s string) *User { + self.Subtitle = s + return self +} + +func (self *User) SetAvatar(s string) *User { + self.Avatar = s + return self +} + +func (self *User) SetBio(s string) *User { + self.Bio = s + return self +} + +func (self *User) SetPermissionLevel(s uint) *User { + self.PermissionLevel = s + return self +} + +func (self *User) SetAllowPublic(s bool) *User { + self.AllowPublic = s + return self +} + +func (self *User) GetByEmail(ctx *context.Context, email *string) (*User, error) { var user User - err := Database.WithContext(ctx). + err := Database.WithContext(*ctx). Where("email = ?", email). First(&user).Error @@ -50,10 +90,10 @@ func (self *User) GetByEmail(ctx context.Context, email string) (*User, error) { return &user, nil } -func (self *User) GetByUserId(ctx context.Context, userId uuid.UUID) (*User, error) { +func (self *User) GetByUserId(ctx *context.Context, userId *uuid.UUID) (*User, error) { var user User - err := Database.WithContext(ctx). + err := Database.WithContext(*ctx). Where("user_id = ?", userId). First(&user).Error @@ -67,12 +107,12 @@ func (self *User) GetByUserId(ctx context.Context, userId uuid.UUID) (*User, err return &user, err } -func (self *User) Create(ctx context.Context) error { +func (self *User) Create(ctx *context.Context) error { self.UUID = uuid.New() self.UserId = uuid.New() // DB transaction only - if err := Database.WithContext(ctx).Transaction(func(tx *gorm.DB) error { + if err := Database.WithContext(*ctx).Transaction(func(tx *gorm.DB) error { if err := tx.Create(self).Error; err != nil { return err } @@ -90,8 +130,8 @@ func (self *User) Create(ctx context.Context) error { return nil } -func (self *User) UpdateByUserID(ctx context.Context, userId uuid.UUID) error { - return Database.WithContext(ctx).Transaction(func(tx *gorm.DB) error { +func (self *User) UpdateByUserID(ctx *context.Context, userId *uuid.UUID) error { + return Database.WithContext(*ctx).Transaction(func(tx *gorm.DB) error { if err := tx.Model(&User{}).Where("user_id = ?", userId).Updates(&self).Error; err != nil { return err } @@ -99,22 +139,22 @@ func (self *User) UpdateByUserID(ctx context.Context, userId uuid.UUID) error { }) } -func (self *User) GetFullTable(ctx context.Context) (*[]User, error) { +func (self *User) GetFullTable(ctx *context.Context) (*[]User, error) { var users []User - err := Database.WithContext(ctx).Find(&users).Error + err := Database.WithContext(*ctx).Find(&users).Error if err != nil { return nil, err } return &users, nil } -func (self *User) FastListUsers(ctx context.Context, limit, offset int64) (*[]UserSearchDoc, error) { +func (self *User) FastListUsers(ctx *context.Context, limit, offset *int64) (*[]UserSearchDoc, error) { index := MeiliSearch.Index("user") // Fast read from MeiliSearch, no DB involved - result, err := index.SearchWithContext(ctx, "", &meilisearch.SearchRequest{ - Limit: limit, - Offset: offset, + result, err := index.SearchWithContext(*ctx, "", &meilisearch.SearchRequest{ + Limit: *limit, + Offset: *offset, }) if err != nil { return nil, err @@ -128,7 +168,7 @@ func (self *User) FastListUsers(ctx context.Context, limit, offset int64) (*[]Us return &list, nil } -func (self *User) UpdateSearchIndex(ctx context.Context) error { +func (self *User) UpdateSearchIndex(ctx *context.Context) error { doc := UserSearchDoc{ UserId: self.UserId.String(), Email: self.Email, @@ -145,7 +185,7 @@ func (self *User) UpdateSearchIndex(ctx context.Context) error { } if _, err := index.UpdateDocumentsWithContext( - ctx, + *ctx, []UserSearchDoc{doc}, opts, ); err != nil { @@ -155,8 +195,8 @@ func (self *User) UpdateSearchIndex(ctx context.Context) error { return nil } -func (self *User) DeleteSearchIndex(ctx context.Context) error { +func (self *User) DeleteSearchIndex(ctx *context.Context) error { index := MeiliSearch.Index("user") - _, err := index.DeleteDocumentWithContext(ctx, self.UserId.String(), nil) + _, err := index.DeleteDocumentWithContext(*ctx, self.UserId.String(), nil) return err } diff --git a/pkgs/kyc/kyc.go b/internal/ali_cnrid/kyc.go similarity index 100% rename from pkgs/kyc/kyc.go rename to internal/ali_cnrid/kyc.go diff --git a/internal/ali_cnrid/types.go b/internal/ali_cnrid/types.go new file mode 100644 index 0000000..9aa6f39 --- /dev/null +++ b/internal/ali_cnrid/types.go @@ -0,0 +1,7 @@ +package kyc + +type KycAli struct { + ParamType string `json:"param_type"` + IdentifyNum string `json:"identify_num"` + UserName string `json:"user_name"` +} diff --git a/pkgs/authcode/authcode.go b/internal/authcode/authcode.go similarity index 100% rename from pkgs/authcode/authcode.go rename to internal/authcode/authcode.go diff --git a/pkgs/authtoken/authtoken.go b/internal/authtoken/authtoken.go similarity index 100% rename from pkgs/authtoken/authtoken.go rename to internal/authtoken/authtoken.go diff --git a/pkgs/email/email.go b/internal/email/email.go similarity index 100% rename from pkgs/email/email.go rename to internal/email/email.go diff --git a/internal/exception/builder.go b/internal/exception/builder.go index ec71051..0494961 100644 --- a/internal/exception/builder.go +++ b/internal/exception/builder.go @@ -13,12 +13,13 @@ import ( // :5=original type Builder struct { - Status string - Service string - Endpoint string - Type string - Original string - Error error + Status string + Service string + Endpoint string + Type string + Original string + Error error + ErrorCode string } func (self *Builder) SetStatus(s string) *Builder { @@ -51,16 +52,25 @@ func (self *Builder) SetError(e error) *Builder { return self } -func (self *Builder) Build(ctx context.Context) string { - errorCode := fmt.Sprintf("%s%s%s%s%s", +func (self *Builder) build() { + self.ErrorCode = fmt.Sprintf("%s%s%s%s%s", self.Status, self.Service, self.Endpoint, self.Type, self.Original, ) - if self.Error != nil { - ErrorHandler(ctx, self.Status, errorCode, self.Error) - } - return errorCode +} + +func (self *Builder) Throw(ctx *context.Context) *Builder { + self.build() + if self.Error != nil { + ErrorHandler(ctx, self.Status, self.ErrorCode, self.Error) + } + return self +} + +func (self *Builder) String() string { + self.build() + return self.ErrorCode } diff --git a/internal/exception/error.go b/internal/exception/error.go index c7ab181..bc38a17 100644 --- a/internal/exception/error.go +++ b/internal/exception/error.go @@ -5,15 +5,15 @@ import ( "log/slog" ) -func ErrorHandler(ctx context.Context, status string, errorCode string, err error) { +func ErrorHandler(ctx *context.Context, status string, errorCode string, err error) { switch status { case StatusSuccess: - slog.InfoContext(ctx, "Service exception! ErrId: "+errorCode, "id", errorCode, "err", err) + slog.InfoContext(*ctx, "Service exception! ErrId: "+errorCode, "id", errorCode, "err", err) case StatusUser: - slog.WarnContext(ctx, "Service exception! ErrId: "+errorCode, "id", errorCode, "err", err) + slog.WarnContext(*ctx, "Service exception! ErrId: "+errorCode, "id", errorCode, "err", err) case StatusServer: - slog.ErrorContext(ctx, "Service exception! ErrId: "+errorCode, "id", errorCode, "err", err) + slog.ErrorContext(*ctx, "Service exception! ErrId: "+errorCode, "id", errorCode, "err", err) case StatusClient: - slog.ErrorContext(ctx, "Service exception! ErrId: "+errorCode, "id", errorCode, "err", err) + slog.ErrorContext(*ctx, "Service exception! ErrId: "+errorCode, "id", errorCode, "err", err) } } diff --git a/internal/kyc/types.go b/internal/kyc/types.go new file mode 100644 index 0000000..9bdbece --- /dev/null +++ b/internal/kyc/types.go @@ -0,0 +1,17 @@ +package kyc + +type KycInfo struct { + Type string `json:"type"` // cnrid/passport + LegalName string `json:"legal_name"` + ResidentId string `json:"rsident_id"` + PassportInfo PassportInfo `json:"passport_info"` +} + +type PassportInfo struct { + FirstName string `json:"first_name"` + LastName string `json:"last_name"` + DateOfExpire string `json:"date_of_expire"` + Nationality string `json:"nationality"` + DocumentType string `json:"document_type"` + DocumentNumber string `json:"document_number"` +} diff --git a/internal/sc_realid/types.go b/internal/sc_realid/types.go new file mode 100644 index 0000000..2f98ca4 --- /dev/null +++ b/internal/sc_realid/types.go @@ -0,0 +1,13 @@ +package screalid + +type KycPassportResponse struct { + Status string `json:"status"` + FinalResult struct { + FirstName string `json:"firstName"` + LastName string `json:"lastName"` + DateOfExpire string `json:"dateOfExpire"` + Nationality string `json:"nationality"` + DocumentType string `json:"documentType"` + DocumentNumber string `json:"documentNumber"` + } `json:"finalResult"` +} diff --git a/pkgs/turnstile/turnstile.go b/internal/turnstile/turnstile.go similarity index 100% rename from pkgs/turnstile/turnstile.go rename to internal/turnstile/turnstile.go diff --git a/middleware/jwt.go b/middleware/jwt.go index 33d22fe..f83df73 100644 --- a/middleware/jwt.go +++ b/middleware/jwt.go @@ -1,8 +1,8 @@ package middleware import ( + "nixcn-cms/internal/authtoken" "nixcn-cms/internal/exception" - "nixcn-cms/pkgs/authtoken" "nixcn-cms/utils" "github.com/gin-gonic/gin" diff --git a/pkgs/kyc/types.go b/pkgs/kyc/types.go deleted file mode 100644 index b11d1af..0000000 --- a/pkgs/kyc/types.go +++ /dev/null @@ -1,13 +0,0 @@ -package kyc - -type KycInfo struct { - Type string `json:"type"` // Chinese / Foreigner - LegalName string `json:"legal_name"` - ResidentId string `json:"rsident_id"` -} - -type KycAli struct { - ParamType string `json:"param_type"` - IdentifyNum string `json:"identify_num"` - UserName string `json:"user_name"` -} diff --git a/server/router.go b/server/router.go deleted file mode 100644 index 3c4d238..0000000 --- a/server/router.go +++ /dev/null @@ -1,18 +0,0 @@ -package server - -import ( - "nixcn-cms/middleware" - "nixcn-cms/service/auth" - "nixcn-cms/service/event" - "nixcn-cms/service/user" - - "github.com/gin-gonic/gin" -) - -func Router(e *gin.Engine) { - // API Services - api := e.Group("/api/v1") - auth.Handler(api.Group("/auth")) - user.Handler(api.Group("/user", middleware.ApiVersionCheck())) - event.Handler(api.Group("/event", middleware.ApiVersionCheck())) -} diff --git a/server/server.go b/server/server.go index 7171c81..9bbff23 100644 --- a/server/server.go +++ b/server/server.go @@ -5,6 +5,7 @@ import ( "log/slog" "net" "net/http" + "nixcn-cms/api" "nixcn-cms/middleware" "time" @@ -24,7 +25,7 @@ func Start(ctx context.Context) { r.Use(middleware.GinLogger()) r.Use(gin.Recovery()) - Router(r) + api.Handler(r.Group("/api/v1")) // Start http server server := &http.Server{ diff --git a/service/common.go b/service/common.go new file mode 100644 index 0000000..cb41d95 --- /dev/null +++ b/service/common.go @@ -0,0 +1,8 @@ +package service + +import "nixcn-cms/internal/exception" + +type CommonResult struct { + HttpCode int + Exception *exception.Builder +} diff --git a/service/user.go b/service/user.go new file mode 100644 index 0000000..4efd86f --- /dev/null +++ b/service/user.go @@ -0,0 +1,465 @@ +package service + +import ( + "context" + "net/url" + "nixcn-cms/data" + "nixcn-cms/internal/cryptography" + "nixcn-cms/internal/exception" + "strconv" + "unicode/utf8" + + "github.com/google/uuid" +) + +type UserService interface { + GetUserInfo(*UserInfoPayload) *UserInfoResult + UpdateUserInfo(*UserInfoPayload) *UserInfoResult + ListUsers(*UserListPayload) *UserListResult + GetUserFullTable(*UserTablePayload) *UserTableResult + CreateUser() +} + +type UserServiceImpl struct{} + +func NewUserService() UserService { + return &UserServiceImpl{} +} + +type UserInfoData struct { + UserId uuid.UUID `json:"user_id"` + Email string `json:"email"` + Username string `json:"username"` + Nickname string `json:"nickname"` + Subtitle string `json:"subtitle"` + Avatar string `json:"avatar"` + Bio string `json:"bio"` + PermissionLevel uint `json:"permission_level"` + AllowPublic bool `json:"allow_public"` +} + +type UserInfoPayload struct { + Context *context.Context + UserId *uuid.UUID + Data *UserInfoData +} + +type UserInfoResult struct { + *CommonResult + Data *UserInfoData +} + +// GetUserInfo +func (self *UserServiceImpl) GetUserInfo(payload *UserInfoPayload) (result *UserInfoResult) { + var err error + + userData, err := new(data.User). + GetByUserId( + payload.Context, + payload.UserId, + ) + + if err != nil { + exception := new(exception.Builder). + SetStatus(exception.StatusUser). + SetService(exception.ServiceUser). + SetEndpoint(exception.EndpointUserServiceInfo). + SetType(exception.TypeCommon). + SetOriginal(exception.CommonErrorUserNotFound). + SetError(err). + Throw(payload.Context) + + result = &UserInfoResult{ + CommonResult: &CommonResult{ + HttpCode: 404, + Exception: exception, + }, + Data: nil, + } + + return + } + + exception := new(exception.Builder). + SetStatus(exception.StatusUser). + SetService(exception.ServiceUser). + SetEndpoint(exception.EndpointUserServiceInfo). + SetType(exception.TypeCommon). + SetOriginal(exception.CommonSuccess). + SetError(nil). + Throw(payload.Context) + + result = &UserInfoResult{ + CommonResult: &CommonResult{ + HttpCode: 200, + Exception: exception, + }, + Data: &UserInfoData{ + UserId: userData.UserId, + Email: userData.Email, + Username: userData.Username, + Nickname: userData.Nickname, + Subtitle: userData.Subtitle, + Avatar: userData.Avatar, + Bio: userData.Bio, + PermissionLevel: userData.PermissionLevel, + AllowPublic: userData.AllowPublic, + }, + } + + return +} + +// UpdateUserInfo +func (self *UserServiceImpl) UpdateUserInfo(payload *UserInfoPayload) (result *UserInfoResult) { + var err error + + userData := new(data.User). + SetNickname(payload.Data.Nickname). + SetSubtitle(payload.Data.Subtitle). + SetAvatar(payload.Data.Avatar). + SetBio(payload.Data.Bio). + SetAllowPublic(payload.Data.AllowPublic) + + if payload.Data.Username != "" { + if len(payload.Data.Username) < 5 || len(payload.Data.Username) >= 255 { + execption := new(exception.Builder). + SetStatus(exception.StatusUser). + SetService(exception.ServiceUser). + SetType(exception.TypeCommon). + SetOriginal(exception.CommonErrorInvalidInput) + + result = &UserInfoResult{ + CommonResult: &CommonResult{ + HttpCode: 400, + Exception: execption, + }, + } + + return + } + userData.SetUsername(payload.Data.Username) + } + + if payload.Data.Nickname != "" { + if utf8.RuneCountInString(payload.Data.Nickname) > 24 { + execption := new(exception.Builder). + SetStatus(exception.StatusUser). + SetService(exception.ServiceUser). + SetType(exception.TypeCommon). + SetOriginal(exception.CommonErrorInvalidInput) + + result = &UserInfoResult{ + CommonResult: &CommonResult{ + HttpCode: 400, + Exception: execption, + }, + } + + return + } + userData.SetNickname(payload.Data.Nickname) + } + + if payload.Data.Subtitle != "" { + if utf8.RuneCountInString(payload.Data.Subtitle) > 32 { + execption := new(exception.Builder). + SetStatus(exception.StatusUser). + SetService(exception.ServiceUser). + SetEndpoint(exception.EndpointUserServiceUpdate). + SetType(exception.TypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + SetError(nil). + Throw(payload.Context) + + result = &UserInfoResult{ + CommonResult: &CommonResult{ + HttpCode: 400, + Exception: execption, + }, + } + + return + } + userData.SetSubtitle(payload.Data.Subtitle) + } + + if payload.Data.Avatar != "" { + _, err := url.ParseRequestURI(payload.Data.Avatar) + if err != nil { + execption := new(exception.Builder). + SetStatus(exception.StatusUser). + SetService(exception.ServiceUser). + SetEndpoint(exception.EndpointUserServiceUpdate). + SetType(exception.TypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + SetError(err). + Throw(payload.Context) + + result = &UserInfoResult{ + CommonResult: &CommonResult{ + HttpCode: 400, + Exception: execption, + }, + } + + return + } + userData.SetAvatar(payload.Data.Avatar) + } + + if payload.Data.Bio != "" { + if !cryptography.IsBase64Std(payload.Data.Bio) { + execption := new(exception.Builder). + SetStatus(exception.StatusUser). + SetService(exception.ServiceUser). + SetEndpoint(exception.EndpointUserServiceUpdate). + SetType(exception.TypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + SetError(nil). + Throw(payload.Context) + + result = &UserInfoResult{ + CommonResult: &CommonResult{ + HttpCode: 400, + Exception: execption, + }, + } + + return + } + userData.Bio = payload.Data.Bio + } + + err = userData.UpdateByUserID(payload.Context, payload.UserId) + if err != nil { + exception := new(exception.Builder). + SetStatus(exception.StatusServer). + SetService(exception.ServiceUser). + SetEndpoint(exception.EndpointUserServiceUpdate). + SetType(exception.TypeCommon). + SetOriginal(exception.CommonErrorDatabase). + SetError(err). + Throw(payload.Context) + + result = &UserInfoResult{ + CommonResult: &CommonResult{ + HttpCode: 500, + Exception: exception, + }, + } + + return + } + + exception := new(exception.Builder). + SetStatus(exception.StatusUser). + SetService(exception.ServiceUser). + SetEndpoint(exception.EndpointUserServiceUpdate). + SetType(exception.TypeCommon). + SetOriginal(exception.CommonSuccess). + SetError(nil). + Throw(payload.Context) + + result = &UserInfoResult{ + CommonResult: &CommonResult{ + HttpCode: 200, + Exception: exception, + }, + Data: nil, + } + + return +} + +type UserListPayload struct { + Context *context.Context + Limit *string + LimitStatus *bool + Offset *string + OffsetStatus *bool +} + +type UserListResult struct { + *CommonResult + UserList *[]data.UserSearchDoc `json:"user_list"` +} + +// ListUsers +func (self *UserServiceImpl) ListUsers(payload *UserListPayload) (result *UserListResult) { + var limit string + if !*payload.LimitStatus || *payload.Limit == "" { + limit = "0" + } + + var offset string + if !*payload.OffsetStatus || *payload.Offset == "" { + exception := new(exception.Builder). + SetStatus(exception.StatusUser). + SetService(exception.ServiceUser). + SetEndpoint(exception.EndpointUserServiceList). + SetType(exception.TypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + SetError(nil). + Throw(payload.Context) + + result = &UserListResult{ + CommonResult: &CommonResult{ + HttpCode: 500, + Exception: exception, + }, + UserList: nil, + } + + return + } else { + offset = *payload.Offset + } + + // Parse string to int64 + limitNum, err := strconv.ParseInt(limit, 10, 64) + if err != nil { + exception := new(exception.Builder). + SetStatus(exception.StatusUser). + SetService(exception.ServiceUser). + SetEndpoint(exception.EndpointUserServiceList). + SetType(exception.TypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + SetError(err). + Throw(payload.Context) + + result = &UserListResult{ + CommonResult: &CommonResult{ + HttpCode: 400, + Exception: exception, + }, + UserList: nil, + } + + return + } + + offsetNum, err := strconv.ParseInt(offset, 10, 64) + if err != nil { + exception := new(exception.Builder). + SetStatus(exception.StatusUser). + SetService(exception.ServiceUser). + SetEndpoint(exception.EndpointUserServiceList). + SetType(exception.TypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + SetError(err). + Throw(payload.Context) + + result = &UserListResult{ + CommonResult: &CommonResult{ + HttpCode: 400, + Exception: exception, + }, + UserList: nil, + } + + return + } + + // Get user list from search engine + userList, err := new(data.User). + FastListUsers(payload.Context, &limitNum, &offsetNum) + if err != nil { + exception := new(exception.Builder). + SetStatus(exception.StatusServer). + SetService(exception.ServiceUser). + SetEndpoint(exception.EndpointUserServiceList). + SetType(exception.TypeSpecific). + SetOriginal(exception.UserListMeilisearchFailed). + SetError(err). + Throw(payload.Context) + + result = &UserListResult{ + CommonResult: &CommonResult{ + HttpCode: 500, + Exception: exception, + }, + UserList: nil, + } + } + + exception := new(exception.Builder). + SetStatus(exception.StatusServer). + SetService(exception.ServiceUser). + SetEndpoint(exception.EndpointUserServiceList). + SetType(exception.TypeCommon). + SetOriginal(exception.CommonSuccess). + SetError(nil). + Throw(payload.Context) + + result = &UserListResult{ + CommonResult: &CommonResult{ + HttpCode: 200, + Exception: exception, + }, + UserList: userList, + } + + return + +} + +type UserTablePayload struct { + Context *context.Context +} + +type UserTableResult struct { + *CommonResult + UserTable *[]data.User `json:"user_table"` +} + +// ListUserFullTable +func (self *UserServiceImpl) GetUserFullTable(payload *UserTablePayload) (result *UserTableResult) { + var err error + + userFullTable, err := new(data.User). + GetFullTable(payload.Context) + + if err != nil { + exception := new(exception.Builder). + SetStatus(exception.StatusServer). + SetService(exception.ServiceUser). + SetEndpoint(exception.EndpointUserServiceFull). + SetType(exception.TypeCommon). + SetOriginal(exception.CommonErrorDatabase). + SetError(err). + Throw(payload.Context) + + result = &UserTableResult{ + CommonResult: &CommonResult{ + HttpCode: 500, + Exception: exception, + }, + UserTable: nil, + } + + return + } + + exception := new(exception.Builder). + SetStatus(exception.StatusServer). + SetService(exception.ServiceUser). + SetEndpoint(exception.EndpointUserServiceFull). + SetType(exception.TypeCommon). + SetOriginal(exception.CommonSuccess). + SetError(nil). + Throw(payload.Context) + + result = &UserTableResult{ + CommonResult: &CommonResult{ + HttpCode: 200, + Exception: exception, + }, + UserTable: userFullTable, + } + + return +} + +// CreateUser +func (self *UserServiceImpl) CreateUser() {} diff --git a/service/user/full.go b/service/user/full.go index 8b7f0fa..d4019a4 100644 --- a/service/user/full.go +++ b/service/user/full.go @@ -1,15 +1,18 @@ package user import ( + "context" "nixcn-cms/data" "nixcn-cms/internal/exception" "nixcn-cms/utils" - "github.com/gin-gonic/gin" "github.com/google/uuid" ) -func Full(c *gin.Context) { +type ServiceFullResponse struct { +} + +func ServiceFull(ctx context.Context, userId uuid.UUID) (data *[]data.User, httpCode int, errorCode string) { userIdOrig, ok := c.Get("user_id") if !ok { errorCode := new(exception.Builder). diff --git a/service/user/handler.go b/service/user/handler.go deleted file mode 100644 index 350c297..0000000 --- a/service/user/handler.go +++ /dev/null @@ -1,16 +0,0 @@ -package user - -import ( - "nixcn-cms/middleware" - - "github.com/gin-gonic/gin" -) - -func Handler(r *gin.RouterGroup) { - r.Use(middleware.JWTAuth(), middleware.Permission(5)) - r.GET("/info", Info) - r.PATCH("/update", Update) - r.GET("/list", middleware.Permission(20), List) - r.POST("/full", middleware.Permission(40), Full) - r.POST("/create", middleware.Permission(50), Create) -} diff --git a/service/user/info.go b/service/user/info.go index eea97ae..1af3e49 100644 --- a/service/user/info.go +++ b/service/user/info.go @@ -1,74 +1,51 @@ package user import ( - "nixcn-cms/data" "nixcn-cms/internal/exception" "nixcn-cms/utils" "github.com/gin-gonic/gin" - "github.com/google/uuid" ) func Info(c *gin.Context) { - userData := new(data.User) - userIdOrig, ok := c.Get("user_id") - if !ok { - errorCode := new(exception.Builder). - SetStatus(exception.StatusUser). - SetService(exception.ServiceUser). - SetEndpoint(exception.EndpointUserServiceInfo). - SetType(exception.TypeCommon). - SetOriginal(exception.CommonErrorMissingUserId). - Build(c) - utils.HttpResponse(c, 403, errorCode) - return - } - userId, err := uuid.Parse(userIdOrig.(string)) - if err != nil { - errorCode := new(exception.Builder). - SetStatus(exception.StatusServer). - SetService(exception.ServiceUser). - SetEndpoint(exception.EndpointUserServiceInfo). - SetType(exception.TypeCommon). - SetOriginal(exception.CommonErrorUuidParseFailed). - SetError(err). - Build(c) - utils.HttpResponse(c, 500, errorCode) - return - } + // userData := new(data.User) + // userIdOrig, ok := c.Get("user_id") + // if !ok { + // errorCode := new(exception.Builder). + // SetStatus(exception.StatusUser). + // SetService(exception.ServiceUser). + // SetEndpoint(exception.EndpointUserServiceInfo). + // SetType(exception.TypeCommon). + // SetOriginal(exception.CommonErrorMissingUserId). + // Build(c) + // utils.HttpResponse(c, 403, errorCode) + // return + // } + // userId, err := uuid.Parse(userIdOrig.(string)) + // if err != nil { + // errorCode := new(exception.Builder). + // SetStatus(exception.StatusServer). + // SetService(exception.ServiceUser). + // SetEndpoint(exception.EndpointUserServiceInfo). + // SetType(exception.TypeCommon). + // SetOriginal(exception.CommonErrorUuidParseFailed). + // SetError(err). + // Build(c) + // utils.HttpResponse(c, 500, errorCode) + // return + // } // Get user from database - user, err := userData.GetByUserId(c, userId) - if err != nil { - errorCode := new(exception.Builder). - SetStatus(exception.StatusUser). - SetService(exception.ServiceUser). - SetEndpoint(exception.EndpointUserServiceInfo). - SetType(exception.TypeCommon). - SetOriginal(exception.CommonErrorUserNotFound). - SetError(err). - Build(c) - utils.HttpResponse(c, 404, errorCode) - return - } + // user, err := userData.GetByUserId(c, userId) + // if err != nil { + // utils.HttpResponse(c, 404, errorCode) + // return + // } userInfoResp := struct { - UserId uuid.UUID `json:"user_id"` - Email string `json:"email"` - Username string `json:"username"` - Nickname string `json:"nickname"` - Subtitle string `json:"subtitle"` - Avatar string `json:"avatar"` - Bio string `json:"bio"` - PermissionLevel uint `json:"permission_level"` }{user.UserId, user.Email, user.Username, user.Nickname, user.Subtitle, user.Avatar, user.Bio, user.PermissionLevel} errorCode := new(exception.Builder). - SetStatus(exception.StatusUser). - SetService(exception.ServiceUser). - SetEndpoint(exception.EndpointUserServiceInfo). - SetType(exception.TypeCommon). - SetOriginal(exception.CommonSuccess). Build(c) utils.HttpResponse(c, 200, errorCode, userInfoResp) } diff --git a/service/user/update.go b/service/user/update.go index d400e02..e292a3a 100644 --- a/service/user/update.go +++ b/service/user/update.go @@ -1,44 +1,40 @@ package user import ( - "net/url" "nixcn-cms/data" - "nixcn-cms/internal/cryptography" "nixcn-cms/internal/exception" "nixcn-cms/utils" - "unicode/utf8" "github.com/gin-gonic/gin" - "github.com/google/uuid" ) func Update(c *gin.Context) { // New user model - userIdOrig, ok := c.Get("user_id") - if !ok { - errorCode := new(exception.Builder). - SetStatus(exception.StatusUser). - SetService(exception.ServiceUser). - SetEndpoint(exception.EndpointUserServiceUpdate). - SetType(exception.TypeCommon). - SetOriginal(exception.CommonErrorMissingUserId). - Build(c) - utils.HttpResponse(c, 403, errorCode) - return - } - userId, err := uuid.Parse(userIdOrig.(string)) - if err != nil { - errorCode := new(exception.Builder). - SetStatus(exception.StatusServer). - SetService(exception.ServiceUser). - SetEndpoint(exception.EndpointUserServiceUpdate). - SetType(exception.TypeCommon). - SetOriginal(exception.CommonErrorUuidParseFailed). - SetError(err). - Build(c) - utils.HttpResponse(c, 500, errorCode) - return - } + // userIdOrig, ok := c.Get("user_id") + // if !ok { + // errorCode := new(exception.Builder). + // SetStatus(exception.StatusUser). + // SetService(exception.ServiceUser). + // SetEndpoint(exception.EndpointUserServiceUpdate). + // SetType(exception.TypeCommon). + // SetOriginal(exception.CommonErrorMissingUserId). + // Build(c) + // utils.HttpResponse(c, 403, errorCode) + // return + // } + // userId, err := uuid.Parse(userIdOrig.(string)) + // if err != nil { + // errorCode := new(exception.Builder). + // SetStatus(exception.StatusServer). + // SetService(exception.ServiceUser). + // SetEndpoint(exception.EndpointUserServiceUpdate). + // SetType(exception.TypeCommon). + // SetOriginal(exception.CommonErrorUuidParseFailed). + // SetError(err). + // Build(c) + // utils.HttpResponse(c, 500, errorCode) + // return + // } var ReqInfo data.User err = c.ShouldBindJSON(&ReqInfo) @@ -79,92 +75,87 @@ func Update(c *gin.Context) { // utils.HttpResponse(c, 400, "", "invilad user name") // return - if ReqInfo.Username != "" { - if len(ReqInfo.Username) < 5 || len(ReqInfo.Username) >= 255 { - errorCode := new(exception.Builder). - SetStatus(exception.StatusUser). - SetService(exception.ServiceUser). - SetEndpoint(exception.EndpointUserServiceUpdate). - SetType(exception.TypeCommon). - SetOriginal(exception.CommonErrorInvalidInput). - Build(c) - utils.HttpResponse(c, 400, errorCode) - return - } - userData.Username = ReqInfo.Username - } + // if ReqInfo.Username != "" { + // if len(ReqInfo.Username) < 5 || len(ReqInfo.Username) >= 255 { + // errorCode := new(exception.Builder). + // SetStatus(exception.StatusUser). + // SetService(exception.ServiceUser). + // SetEndpoint(exception.EndpointUserServiceUpdate). + // SetType(exception.TypeCommon). + // SetOriginal(exception.CommonErrorInvalidInput). + // Build(c) + // utils.HttpResponse(c, 400, errorCode) + // return + // } + // userData.Username = ReqInfo.Username + // } - if ReqInfo.Nickname != "" { - if utf8.RuneCountInString(ReqInfo.Nickname) > 24 { - errorCode := new(exception.Builder). - SetStatus(exception.StatusUser). - SetService(exception.ServiceUser). - SetEndpoint(exception.EndpointUserServiceUpdate). - SetType(exception.TypeCommon). - SetOriginal(exception.CommonErrorInvalidInput). - Build(c) - utils.HttpResponse(c, 400, errorCode) - return - } - userData.Nickname = ReqInfo.Nickname - } + // if ReqInfo.Nickname != "" { + // if utf8.RuneCountInString(ReqInfo.Nickname) > 24 { + // errorCode := new(exception.Builder). + // SetStatus(exception.StatusUser). + // SetService(exception.ServiceUser). + // SetEndpoint(exception.EndpointUserServiceUpdate). + // SetType(exception.TypeCommon). + // SetOriginal(exception.CommonErrorInvalidInput). + // Build(c) + // utils.HttpResponse(c, 400, errorCode) + // return + // } + // userData.Nickname = ReqInfo.Nickname + // } - if ReqInfo.Subtitle != "" { - if utf8.RuneCountInString(ReqInfo.Subtitle) > 32 { - errorCode := new(exception.Builder). - SetStatus(exception.StatusUser). - SetService(exception.ServiceUser). - SetEndpoint(exception.EndpointUserServiceUpdate). - SetType(exception.TypeCommon). - SetOriginal(exception.CommonErrorInvalidInput). - Build(c) - utils.HttpResponse(c, 400, errorCode) - return - } - userData.Subtitle = ReqInfo.Subtitle - } + // if ReqInfo.Subtitle != "" { + // if utf8.RuneCountInString(ReqInfo.Subtitle) > 32 { + // errorCode := new(exception.Builder). + // SetStatus(exception.StatusUser). + // SetService(exception.ServiceUser). + // SetEndpoint(exception.EndpointUserServiceUpdate). + // SetType(exception.TypeCommon). + // SetOriginal(exception.CommonErrorInvalidInput). + // Build(c) + // utils.HttpResponse(c, 400, errorCode) + // return + // } + // userData.Subtitle = ReqInfo.Subtitle + // } - if ReqInfo.Avatar != "" { - _, err := url.ParseRequestURI(ReqInfo.Avatar) - if err != nil { - errorCode := new(exception.Builder). - SetStatus(exception.StatusUser). - SetService(exception.ServiceUser). - SetEndpoint(exception.EndpointUserServiceUpdate). - SetType(exception.TypeCommon). - SetOriginal(exception.CommonErrorInvalidInput). - SetError(err). - Build(c) - utils.HttpResponse(c, 400, errorCode) - return - } - userData.Avatar = ReqInfo.Avatar - } + // if ReqInfo.Avatar != "" { + // _, err := url.ParseRequestURI(ReqInfo.Avatar) + // if err != nil { + // errorCode := new(exception.Builder). + // SetStatus(exception.StatusUser). + // SetService(exception.ServiceUser). + // SetEndpoint(exception.EndpointUserServiceUpdate). + // SetType(exception.TypeCommon). + // SetOriginal(exception.CommonErrorInvalidInput). + // SetError(err). + // Build(c) + // utils.HttpResponse(c, 400, errorCode) + // return + // } + // userData.Avatar = ReqInfo.Avatar + // } - if ReqInfo.Bio != "" { - if !cryptography.IsBase64Std(ReqInfo.Bio) { - errorCode := new(exception.Builder). - SetStatus(exception.StatusUser). - SetService(exception.ServiceUser). - SetEndpoint(exception.EndpointUserServiceUpdate). - SetType(exception.TypeCommon). - SetOriginal(exception.CommonErrorInvalidInput). - Build(c) - utils.HttpResponse(c, 400, errorCode) - return - } - userData.Bio = ReqInfo.Bio - } + // if ReqInfo.Bio != "" { + // if !cryptography.IsBase64Std(ReqInfo.Bio) { + // errorCode := new(exception.Builder). + // SetStatus(exception.StatusUser). + // SetService(exception.ServiceUser). + // SetEndpoint(exception.EndpointUserServiceUpdate). + // SetType(exception.TypeCommon). + // SetOriginal(exception.CommonErrorInvalidInput). + // Build(c) + // utils.HttpResponse(c, 400, errorCode) + // return + // } + // userData.Bio = ReqInfo.Bio + // } // Update user info userData.UpdateByUserID(c, userId) - errorCode := new(exception.Builder). - SetStatus(exception.StatusUser). - SetService(exception.ServiceUser). - SetEndpoint(exception.EndpointUserServiceUpdate). - SetType(exception.TypeCommon). - SetOriginal(exception.CommonSuccess). + errorCode := Build(c) utils.HttpResponse(c, 200, errorCode) }