WIP: Full restruct, seprate service and api

Signed-off-by: Asai Neko <sugar@sne.moe>
This commit is contained in:
2026-01-24 11:42:35 +08:00
parent dfd5532b20
commit 8e11ba4631
31 changed files with 830 additions and 248 deletions

8
api/auth/handler.go Normal file
View File

@@ -0,0 +1,8 @@
package auth
import (
"github.com/gin-gonic/gin"
)
func ApiHandler(r *gin.RouterGroup) {
}

11
api/event/handler.go Normal file
View File

@@ -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))
}

17
api/handler.go Normal file
View File

@@ -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"))
}

11
api/kyc/handler.go Normal file
View File

@@ -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))
}

6
api/user/create.go Normal file
View File

@@ -0,0 +1,6 @@
package user
import "github.com/gin-gonic/gin"
func (self *UserHandler) Create(c *gin.Context) {
}

View File

@@ -2,6 +2,6 @@ package user
import "github.com/gin-gonic/gin" import "github.com/gin-gonic/gin"
func Create(c *gin.Context) { func (self *UserHandler) Full(c *gin.Context) {
} }

24
api/user/handler.go Normal file
View File

@@ -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)
}

6
api/user/info.go Normal file
View File

@@ -0,0 +1,6 @@
package user
import "github.com/gin-gonic/gin"
func (self *UserHandler) Info(c *gin.Context) {
}

7
api/user/list.go Normal file
View File

@@ -0,0 +1,7 @@
package user
import "github.com/gin-gonic/gin"
func (self *UserHandler) List(c *gin.Context) {
}

7
api/user/update.go Normal file
View File

@@ -0,0 +1,7 @@
package user
import "github.com/gin-gonic/gin"
func (self *UserHandler) Update(c *gin.Context) {
}

View File

@@ -33,10 +33,50 @@ type UserSearchDoc struct {
Avatar string `json:"avatar"` 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 var user User
err := Database.WithContext(ctx). err := Database.WithContext(*ctx).
Where("email = ?", email). Where("email = ?", email).
First(&user).Error First(&user).Error
@@ -50,10 +90,10 @@ func (self *User) GetByEmail(ctx context.Context, email string) (*User, error) {
return &user, nil 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 var user User
err := Database.WithContext(ctx). err := Database.WithContext(*ctx).
Where("user_id = ?", userId). Where("user_id = ?", userId).
First(&user).Error First(&user).Error
@@ -67,12 +107,12 @@ func (self *User) GetByUserId(ctx context.Context, userId uuid.UUID) (*User, err
return &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.UUID = uuid.New()
self.UserId = uuid.New() self.UserId = uuid.New()
// DB transaction only // 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 { if err := tx.Create(self).Error; err != nil {
return err return err
} }
@@ -90,8 +130,8 @@ func (self *User) Create(ctx context.Context) error {
return nil return nil
} }
func (self *User) UpdateByUserID(ctx context.Context, userId uuid.UUID) error { func (self *User) UpdateByUserID(ctx *context.Context, userId *uuid.UUID) error {
return Database.WithContext(ctx).Transaction(func(tx *gorm.DB) 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 { if err := tx.Model(&User{}).Where("user_id = ?", userId).Updates(&self).Error; err != nil {
return err 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 var users []User
err := Database.WithContext(ctx).Find(&users).Error err := Database.WithContext(*ctx).Find(&users).Error
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &users, nil 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") index := MeiliSearch.Index("user")
// Fast read from MeiliSearch, no DB involved // Fast read from MeiliSearch, no DB involved
result, err := index.SearchWithContext(ctx, "", &meilisearch.SearchRequest{ result, err := index.SearchWithContext(*ctx, "", &meilisearch.SearchRequest{
Limit: limit, Limit: *limit,
Offset: offset, Offset: *offset,
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@@ -128,7 +168,7 @@ func (self *User) FastListUsers(ctx context.Context, limit, offset int64) (*[]Us
return &list, nil return &list, nil
} }
func (self *User) UpdateSearchIndex(ctx context.Context) error { func (self *User) UpdateSearchIndex(ctx *context.Context) error {
doc := UserSearchDoc{ doc := UserSearchDoc{
UserId: self.UserId.String(), UserId: self.UserId.String(),
Email: self.Email, Email: self.Email,
@@ -145,7 +185,7 @@ func (self *User) UpdateSearchIndex(ctx context.Context) error {
} }
if _, err := index.UpdateDocumentsWithContext( if _, err := index.UpdateDocumentsWithContext(
ctx, *ctx,
[]UserSearchDoc{doc}, []UserSearchDoc{doc},
opts, opts,
); err != nil { ); err != nil {
@@ -155,8 +195,8 @@ func (self *User) UpdateSearchIndex(ctx context.Context) error {
return nil return nil
} }
func (self *User) DeleteSearchIndex(ctx context.Context) error { func (self *User) DeleteSearchIndex(ctx *context.Context) error {
index := MeiliSearch.Index("user") index := MeiliSearch.Index("user")
_, err := index.DeleteDocumentWithContext(ctx, self.UserId.String(), nil) _, err := index.DeleteDocumentWithContext(*ctx, self.UserId.String(), nil)
return err return err
} }

View File

@@ -0,0 +1,7 @@
package kyc
type KycAli struct {
ParamType string `json:"param_type"`
IdentifyNum string `json:"identify_num"`
UserName string `json:"user_name"`
}

View File

@@ -13,12 +13,13 @@ import (
// :5=original // :5=original
type Builder struct { type Builder struct {
Status string Status string
Service string Service string
Endpoint string Endpoint string
Type string Type string
Original string Original string
Error error Error error
ErrorCode string
} }
func (self *Builder) SetStatus(s string) *Builder { func (self *Builder) SetStatus(s string) *Builder {
@@ -51,16 +52,25 @@ func (self *Builder) SetError(e error) *Builder {
return self return self
} }
func (self *Builder) Build(ctx context.Context) string { func (self *Builder) build() {
errorCode := fmt.Sprintf("%s%s%s%s%s", self.ErrorCode = fmt.Sprintf("%s%s%s%s%s",
self.Status, self.Status,
self.Service, self.Service,
self.Endpoint, self.Endpoint,
self.Type, self.Type,
self.Original, self.Original,
) )
if self.Error != nil { }
ErrorHandler(ctx, self.Status, errorCode, self.Error)
} func (self *Builder) Throw(ctx *context.Context) *Builder {
return errorCode 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
} }

View File

@@ -5,15 +5,15 @@ import (
"log/slog" "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 { switch status {
case StatusSuccess: 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: 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: 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: case StatusClient:
slog.ErrorContext(ctx, "Service exception! ErrId: "+errorCode, "id", errorCode, "err", err) slog.ErrorContext(*ctx, "Service exception! ErrId: "+errorCode, "id", errorCode, "err", err)
} }
} }

17
internal/kyc/types.go Normal file
View File

@@ -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"`
}

View File

@@ -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"`
}

View File

@@ -1,8 +1,8 @@
package middleware package middleware
import ( import (
"nixcn-cms/internal/authtoken"
"nixcn-cms/internal/exception" "nixcn-cms/internal/exception"
"nixcn-cms/pkgs/authtoken"
"nixcn-cms/utils" "nixcn-cms/utils"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"

View File

@@ -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"`
}

View File

@@ -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()))
}

View File

@@ -5,6 +5,7 @@ import (
"log/slog" "log/slog"
"net" "net"
"net/http" "net/http"
"nixcn-cms/api"
"nixcn-cms/middleware" "nixcn-cms/middleware"
"time" "time"
@@ -24,7 +25,7 @@ func Start(ctx context.Context) {
r.Use(middleware.GinLogger()) r.Use(middleware.GinLogger())
r.Use(gin.Recovery()) r.Use(gin.Recovery())
Router(r) api.Handler(r.Group("/api/v1"))
// Start http server // Start http server
server := &http.Server{ server := &http.Server{

8
service/common.go Normal file
View File

@@ -0,0 +1,8 @@
package service
import "nixcn-cms/internal/exception"
type CommonResult struct {
HttpCode int
Exception *exception.Builder
}

465
service/user.go Normal file
View File

@@ -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() {}

View File

@@ -1,15 +1,18 @@
package user package user
import ( import (
"context"
"nixcn-cms/data" "nixcn-cms/data"
"nixcn-cms/internal/exception" "nixcn-cms/internal/exception"
"nixcn-cms/utils" "nixcn-cms/utils"
"github.com/gin-gonic/gin"
"github.com/google/uuid" "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") userIdOrig, ok := c.Get("user_id")
if !ok { if !ok {
errorCode := new(exception.Builder). errorCode := new(exception.Builder).

View File

@@ -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)
}

View File

@@ -1,74 +1,51 @@
package user package user
import ( import (
"nixcn-cms/data"
"nixcn-cms/internal/exception" "nixcn-cms/internal/exception"
"nixcn-cms/utils" "nixcn-cms/utils"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/google/uuid"
) )
func Info(c *gin.Context) { func Info(c *gin.Context) {
userData := new(data.User) // userData := new(data.User)
userIdOrig, ok := c.Get("user_id") // userIdOrig, ok := c.Get("user_id")
if !ok { // if !ok {
errorCode := new(exception.Builder). // errorCode := new(exception.Builder).
SetStatus(exception.StatusUser). // SetStatus(exception.StatusUser).
SetService(exception.ServiceUser). // SetService(exception.ServiceUser).
SetEndpoint(exception.EndpointUserServiceInfo). // SetEndpoint(exception.EndpointUserServiceInfo).
SetType(exception.TypeCommon). // SetType(exception.TypeCommon).
SetOriginal(exception.CommonErrorMissingUserId). // SetOriginal(exception.CommonErrorMissingUserId).
Build(c) // Build(c)
utils.HttpResponse(c, 403, errorCode) // utils.HttpResponse(c, 403, errorCode)
return // return
} // }
userId, err := uuid.Parse(userIdOrig.(string)) // userId, err := uuid.Parse(userIdOrig.(string))
if err != nil { // if err != nil {
errorCode := new(exception.Builder). // errorCode := new(exception.Builder).
SetStatus(exception.StatusServer). // SetStatus(exception.StatusServer).
SetService(exception.ServiceUser). // SetService(exception.ServiceUser).
SetEndpoint(exception.EndpointUserServiceInfo). // SetEndpoint(exception.EndpointUserServiceInfo).
SetType(exception.TypeCommon). // SetType(exception.TypeCommon).
SetOriginal(exception.CommonErrorUuidParseFailed). // SetOriginal(exception.CommonErrorUuidParseFailed).
SetError(err). // SetError(err).
Build(c) // Build(c)
utils.HttpResponse(c, 500, errorCode) // utils.HttpResponse(c, 500, errorCode)
return // return
} // }
// Get user from database // Get user from database
user, err := userData.GetByUserId(c, userId) // user, err := userData.GetByUserId(c, userId)
if err != nil { // if err != nil {
errorCode := new(exception.Builder). // utils.HttpResponse(c, 404, errorCode)
SetStatus(exception.StatusUser). // return
SetService(exception.ServiceUser). // }
SetEndpoint(exception.EndpointUserServiceInfo).
SetType(exception.TypeCommon).
SetOriginal(exception.CommonErrorUserNotFound).
SetError(err).
Build(c)
utils.HttpResponse(c, 404, errorCode)
return
}
userInfoResp := struct { 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} }{user.UserId, user.Email, user.Username, user.Nickname, user.Subtitle, user.Avatar, user.Bio, user.PermissionLevel}
errorCode := new(exception.Builder). errorCode := new(exception.Builder).
SetStatus(exception.StatusUser).
SetService(exception.ServiceUser).
SetEndpoint(exception.EndpointUserServiceInfo).
SetType(exception.TypeCommon).
SetOriginal(exception.CommonSuccess).
Build(c) Build(c)
utils.HttpResponse(c, 200, errorCode, userInfoResp) utils.HttpResponse(c, 200, errorCode, userInfoResp)
} }

View File

@@ -1,44 +1,40 @@
package user package user
import ( import (
"net/url"
"nixcn-cms/data" "nixcn-cms/data"
"nixcn-cms/internal/cryptography"
"nixcn-cms/internal/exception" "nixcn-cms/internal/exception"
"nixcn-cms/utils" "nixcn-cms/utils"
"unicode/utf8"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/google/uuid"
) )
func Update(c *gin.Context) { func Update(c *gin.Context) {
// New user model // New user model
userIdOrig, ok := c.Get("user_id") // userIdOrig, ok := c.Get("user_id")
if !ok { // if !ok {
errorCode := new(exception.Builder). // errorCode := new(exception.Builder).
SetStatus(exception.StatusUser). // SetStatus(exception.StatusUser).
SetService(exception.ServiceUser). // SetService(exception.ServiceUser).
SetEndpoint(exception.EndpointUserServiceUpdate). // SetEndpoint(exception.EndpointUserServiceUpdate).
SetType(exception.TypeCommon). // SetType(exception.TypeCommon).
SetOriginal(exception.CommonErrorMissingUserId). // SetOriginal(exception.CommonErrorMissingUserId).
Build(c) // Build(c)
utils.HttpResponse(c, 403, errorCode) // utils.HttpResponse(c, 403, errorCode)
return // return
} // }
userId, err := uuid.Parse(userIdOrig.(string)) // userId, err := uuid.Parse(userIdOrig.(string))
if err != nil { // if err != nil {
errorCode := new(exception.Builder). // errorCode := new(exception.Builder).
SetStatus(exception.StatusServer). // SetStatus(exception.StatusServer).
SetService(exception.ServiceUser). // SetService(exception.ServiceUser).
SetEndpoint(exception.EndpointUserServiceUpdate). // SetEndpoint(exception.EndpointUserServiceUpdate).
SetType(exception.TypeCommon). // SetType(exception.TypeCommon).
SetOriginal(exception.CommonErrorUuidParseFailed). // SetOriginal(exception.CommonErrorUuidParseFailed).
SetError(err). // SetError(err).
Build(c) // Build(c)
utils.HttpResponse(c, 500, errorCode) // utils.HttpResponse(c, 500, errorCode)
return // return
} // }
var ReqInfo data.User var ReqInfo data.User
err = c.ShouldBindJSON(&ReqInfo) err = c.ShouldBindJSON(&ReqInfo)
@@ -79,92 +75,87 @@ func Update(c *gin.Context) {
// utils.HttpResponse(c, 400, "", "invilad user name") // utils.HttpResponse(c, 400, "", "invilad user name")
// return // return
if ReqInfo.Username != "" { // if ReqInfo.Username != "" {
if len(ReqInfo.Username) < 5 || len(ReqInfo.Username) >= 255 { // if len(ReqInfo.Username) < 5 || len(ReqInfo.Username) >= 255 {
errorCode := new(exception.Builder). // errorCode := new(exception.Builder).
SetStatus(exception.StatusUser). // SetStatus(exception.StatusUser).
SetService(exception.ServiceUser). // SetService(exception.ServiceUser).
SetEndpoint(exception.EndpointUserServiceUpdate). // SetEndpoint(exception.EndpointUserServiceUpdate).
SetType(exception.TypeCommon). // SetType(exception.TypeCommon).
SetOriginal(exception.CommonErrorInvalidInput). // SetOriginal(exception.CommonErrorInvalidInput).
Build(c) // Build(c)
utils.HttpResponse(c, 400, errorCode) // utils.HttpResponse(c, 400, errorCode)
return // return
} // }
userData.Username = ReqInfo.Username // userData.Username = ReqInfo.Username
} // }
if ReqInfo.Nickname != "" { // if ReqInfo.Nickname != "" {
if utf8.RuneCountInString(ReqInfo.Nickname) > 24 { // if utf8.RuneCountInString(ReqInfo.Nickname) > 24 {
errorCode := new(exception.Builder). // errorCode := new(exception.Builder).
SetStatus(exception.StatusUser). // SetStatus(exception.StatusUser).
SetService(exception.ServiceUser). // SetService(exception.ServiceUser).
SetEndpoint(exception.EndpointUserServiceUpdate). // SetEndpoint(exception.EndpointUserServiceUpdate).
SetType(exception.TypeCommon). // SetType(exception.TypeCommon).
SetOriginal(exception.CommonErrorInvalidInput). // SetOriginal(exception.CommonErrorInvalidInput).
Build(c) // Build(c)
utils.HttpResponse(c, 400, errorCode) // utils.HttpResponse(c, 400, errorCode)
return // return
} // }
userData.Nickname = ReqInfo.Nickname // userData.Nickname = ReqInfo.Nickname
} // }
if ReqInfo.Subtitle != "" { // if ReqInfo.Subtitle != "" {
if utf8.RuneCountInString(ReqInfo.Subtitle) > 32 { // if utf8.RuneCountInString(ReqInfo.Subtitle) > 32 {
errorCode := new(exception.Builder). // errorCode := new(exception.Builder).
SetStatus(exception.StatusUser). // SetStatus(exception.StatusUser).
SetService(exception.ServiceUser). // SetService(exception.ServiceUser).
SetEndpoint(exception.EndpointUserServiceUpdate). // SetEndpoint(exception.EndpointUserServiceUpdate).
SetType(exception.TypeCommon). // SetType(exception.TypeCommon).
SetOriginal(exception.CommonErrorInvalidInput). // SetOriginal(exception.CommonErrorInvalidInput).
Build(c) // Build(c)
utils.HttpResponse(c, 400, errorCode) // utils.HttpResponse(c, 400, errorCode)
return // return
} // }
userData.Subtitle = ReqInfo.Subtitle // userData.Subtitle = ReqInfo.Subtitle
} // }
if ReqInfo.Avatar != "" { // if ReqInfo.Avatar != "" {
_, err := url.ParseRequestURI(ReqInfo.Avatar) // _, err := url.ParseRequestURI(ReqInfo.Avatar)
if err != nil { // if err != nil {
errorCode := new(exception.Builder). // errorCode := new(exception.Builder).
SetStatus(exception.StatusUser). // SetStatus(exception.StatusUser).
SetService(exception.ServiceUser). // SetService(exception.ServiceUser).
SetEndpoint(exception.EndpointUserServiceUpdate). // SetEndpoint(exception.EndpointUserServiceUpdate).
SetType(exception.TypeCommon). // SetType(exception.TypeCommon).
SetOriginal(exception.CommonErrorInvalidInput). // SetOriginal(exception.CommonErrorInvalidInput).
SetError(err). // SetError(err).
Build(c) // Build(c)
utils.HttpResponse(c, 400, errorCode) // utils.HttpResponse(c, 400, errorCode)
return // return
} // }
userData.Avatar = ReqInfo.Avatar // userData.Avatar = ReqInfo.Avatar
} // }
if ReqInfo.Bio != "" { // if ReqInfo.Bio != "" {
if !cryptography.IsBase64Std(ReqInfo.Bio) { // if !cryptography.IsBase64Std(ReqInfo.Bio) {
errorCode := new(exception.Builder). // errorCode := new(exception.Builder).
SetStatus(exception.StatusUser). // SetStatus(exception.StatusUser).
SetService(exception.ServiceUser). // SetService(exception.ServiceUser).
SetEndpoint(exception.EndpointUserServiceUpdate). // SetEndpoint(exception.EndpointUserServiceUpdate).
SetType(exception.TypeCommon). // SetType(exception.TypeCommon).
SetOriginal(exception.CommonErrorInvalidInput). // SetOriginal(exception.CommonErrorInvalidInput).
Build(c) // Build(c)
utils.HttpResponse(c, 400, errorCode) // utils.HttpResponse(c, 400, errorCode)
return // return
} // }
userData.Bio = ReqInfo.Bio // userData.Bio = ReqInfo.Bio
} // }
// Update user info // Update user info
userData.UpdateByUserID(c, userId) userData.UpdateByUserID(c, userId)
errorCode := new(exception.Builder). errorCode :=
SetStatus(exception.StatusUser).
SetService(exception.ServiceUser).
SetEndpoint(exception.EndpointUserServiceUpdate).
SetType(exception.TypeCommon).
SetOriginal(exception.CommonSuccess).
Build(c) Build(c)
utils.HttpResponse(c, 200, errorCode) utils.HttpResponse(c, 200, errorCode)
} }