From bf53df1dc30048556cd9da0180d089f63688612b Mon Sep 17 00:00:00 2001 From: lishuang Date: Sat, 13 May 2023 15:45:07 +0800 Subject: [PATCH] feat: finish the space create and page feature. --- code/rest/space_controller.go | 69 +++++++++++++++++++++++++++++++++-- code/rest/space_dao.go | 11 ++---- code/rest/space_model.go | 1 + code/rest/space_service.go | 13 +++++++ code/rest/user_controller.go | 27 +++++--------- code/rest/user_model.go | 2 + code/rest/user_service.go | 34 +++++++++++++---- code/support/tank_context.go | 8 ++-- code/tool/i18n/i18n.go | 3 ++ 9 files changed, 128 insertions(+), 40 deletions(-) diff --git a/code/rest/space_controller.go b/code/rest/space_controller.go index e7bce18..c27690f 100644 --- a/code/rest/space_controller.go +++ b/code/rest/space_controller.go @@ -3,8 +3,10 @@ package rest import ( "github.com/eyebluecn/tank/code/core" "github.com/eyebluecn/tank/code/tool/builder" + "github.com/eyebluecn/tank/code/tool/i18n" "github.com/eyebluecn/tank/code/tool/result" "net/http" + "regexp" "strconv" ) @@ -14,6 +16,7 @@ type SpaceController struct { matterDao *MatterDao matterService *MatterService spaceService *SpaceService + userService *UserService } func (this *SpaceController) Init() { @@ -39,6 +42,11 @@ func (this *SpaceController) Init() { this.spaceService = b } + b = core.CONTEXT.GetBean(this.userService) + if b, ok := b.(*UserService); ok { + this.userService = b + } + } func (this *SpaceController) RegisterRoutes() map[string]func(writer http.ResponseWriter, request *http.Request) { @@ -54,8 +62,50 @@ func (this *SpaceController) RegisterRoutes() map[string]func(writer http.Respon } func (this *SpaceController) Create(writer http.ResponseWriter, request *http.Request) *result.WebResult { - //TODO: - return this.Success("OK") + //space's name + name := request.FormValue("name") + sizeLimitStr := request.FormValue("sizeLimit") + totalSizeLimitStr := request.FormValue("totalSizeLimit") + + //only admin can edit user's sizeLimit + var sizeLimit int64 = 0 + if sizeLimitStr == "" { + panic("space's limit size is required") + } else { + intSizeLimit, err := strconv.Atoi(sizeLimitStr) + if err != nil { + this.PanicError(err) + } + sizeLimit = int64(intSizeLimit) + } + + var totalSizeLimit int64 = 0 + if totalSizeLimitStr == "" { + panic("space's total limit size is required") + } else { + intTotalSizeLimit, err := strconv.Atoi(totalSizeLimitStr) + if err != nil { + this.PanicError(err) + } + totalSizeLimit = int64(intTotalSizeLimit) + } + + //validation work. + if m, _ := regexp.MatchString(USERNAME_PATTERN, name); !m { + panic(result.BadRequestI18n(request, i18n.SpaceNameError)) + } + + if this.userDao.CountByUsername(name) > 0 { + panic(result.BadRequestI18n(request, i18n.SpaceNameExist, name)) + } + + user := this.userService.CreateUser(request, name, "", USER_ROLE_SPACE, sizeLimit, totalSizeLimit) + + //create related space. + space := this.spaceService.CreateSpace(user.Uuid) + space.User = user + + return this.Success(space) } func (this *SpaceController) Delete(writer http.ResponseWriter, request *http.Request) *result.WebResult { @@ -122,7 +172,20 @@ func (this *SpaceController) Page(writer http.ResponseWriter, request *http.Requ }, } - pager := this.spaceDao.Page(page, pageSize, user.Uuid, sortArray) + //TODO: user fetch self's sapces. + var pager *Pager + if user.Role == USER_ROLE_USER { + + } else if user.Role == USER_ROLE_ADMINISTRATOR { + pager = this.spaceDao.Page(page, pageSize, sortArray) + } + + //fill the space's user. + if pager != nil { + for _, space := range pager.Data.([]*Space) { + space.User = this.userDao.FindByUuid(space.UserUuid) + } + } return this.Success(pager) } diff --git a/code/rest/space_dao.go b/code/rest/space_dao.go index d50ec1e..39b9f57 100644 --- a/code/rest/space_dao.go +++ b/code/rest/space_dao.go @@ -37,22 +37,17 @@ func (this *SpaceDao) CheckByUuid(uuid string) *Space { return entity } -func (this *SpaceDao) Page(page int, pageSize int, userUuid string, sortArray []builder.OrderPair) *Pager { - - count, spaces := this.PlainPage(page, pageSize, userUuid, sortArray) +func (this *SpaceDao) Page(page int, pageSize int, sortArray []builder.OrderPair) *Pager { + count, spaces := this.PlainPage(page, pageSize, sortArray) pager := NewPager(page, pageSize, count, spaces) return pager } -func (this *SpaceDao) PlainPage(page int, pageSize int, userUuid string, sortArray []builder.OrderPair) (int, []*Space) { +func (this *SpaceDao) PlainPage(page int, pageSize int, sortArray []builder.OrderPair) (int, []*Space) { var wp = &builder.WherePair{} - if userUuid != "" { - wp = wp.And(&builder.WherePair{Query: "user_uuid = ?", Args: []interface{}{userUuid}}) - } - var conditionDB *gorm.DB conditionDB = core.CONTEXT.GetDB().Model(&Space{}).Where(wp.Query, wp.Args...) diff --git a/code/rest/space_model.go b/code/rest/space_model.go index 3409499..caaabc8 100644 --- a/code/rest/space_model.go +++ b/code/rest/space_model.go @@ -13,4 +13,5 @@ type Space struct { UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"` CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"` UserUuid string `json:"userUuid" gorm:"type:char(36);unique:uk_user_uuid"` + User *User `json:"user" gorm:"-"` } diff --git a/code/rest/space_service.go b/code/rest/space_service.go index 1a4e156..3f94d79 100644 --- a/code/rest/space_service.go +++ b/code/rest/space_service.go @@ -44,3 +44,16 @@ func (this *SpaceService) Detail(uuid string) *Space { return space } + +// create space +func (this *SpaceService) CreateSpace(userUuid string) *Space { + + space := &Space{ + UserUuid: userUuid, + } + + space = this.spaceDao.Create(space) + + return space + +} diff --git a/code/rest/user_controller.go b/code/rest/user_controller.go index 27c4eef..84cfa9b 100644 --- a/code/rest/user_controller.go +++ b/code/rest/user_controller.go @@ -96,7 +96,7 @@ func (this *UserController) innerLogin(writer http.ResponseWriter, request *http this.userDao.Save(user) } -//login by username and password +// login by username and password func (this *UserController) Login(writer http.ResponseWriter, request *http.Request) *result.WebResult { username := request.FormValue("username") @@ -119,7 +119,7 @@ func (this *UserController) Login(writer http.ResponseWriter, request *http.Requ return this.Success(user) } -//login by authentication. +// login by authentication. func (this *UserController) AuthenticationLogin(writer http.ResponseWriter, request *http.Request) *result.WebResult { authentication := request.FormValue("authentication") @@ -140,13 +140,13 @@ func (this *UserController) AuthenticationLogin(writer http.ResponseWriter, requ return this.Success(user) } -//fetch current user's info. +// fetch current user's info. func (this *UserController) Info(writer http.ResponseWriter, request *http.Request) *result.WebResult { user := this.checkUser(request) return this.Success(user) } -//register by username and password. After registering, will auto login. +// register by username and password. After registering, will auto login. func (this *UserController) Register(writer http.ResponseWriter, request *http.Request) *result.WebResult { username := request.FormValue("username") @@ -216,6 +216,7 @@ func (this *UserController) Create(writer http.ResponseWriter, request *http.Req totalSizeLimit = int64(intTotalSizeLimit) } + //validation work. if m, _ := regexp.MatchString(USERNAME_PATTERN, username); !m { panic(result.BadRequestI18n(request, i18n.UsernameError)) } @@ -228,20 +229,12 @@ func (this *UserController) Create(writer http.ResponseWriter, request *http.Req panic(result.BadRequestI18n(request, i18n.UsernameExist, username)) } + //check user role. if role != USER_ROLE_USER && role != USER_ROLE_ADMINISTRATOR { - role = USER_ROLE_USER + panic(result.BadRequestI18n(request, i18n.UserRoleError)) } - user := &User{ - Username: username, - Password: util.GetBcrypt(password), - Role: role, - SizeLimit: sizeLimit, - TotalSizeLimit: totalSizeLimit, - Status: USER_STATUS_OK, - } - - user = this.userDao.Create(user) + user := this.userService.CreateUser(request, username, password, role, sizeLimit, totalSizeLimit) return this.Success(user) } @@ -439,7 +432,7 @@ func (this *UserController) Transfiguration(writer http.ResponseWriter, request return this.Success(session.Uuid) } -//scan user's physics files. create index into EyeblueTank +// scan user's physics files. create index into EyeblueTank func (this *UserController) Scan(writer http.ResponseWriter, request *http.Request) *result.WebResult { uuid := request.FormValue("uuid") @@ -494,7 +487,7 @@ func (this *UserController) ChangePassword(writer http.ResponseWriter, request * return this.Success(user) } -//admin reset password. +// admin reset password. func (this *UserController) ResetPassword(writer http.ResponseWriter, request *http.Request) *result.WebResult { userUuid := request.FormValue("userUuid") diff --git a/code/rest/user_model.go b/code/rest/user_model.go index f2bc0cc..1590f9a 100644 --- a/code/rest/user_model.go +++ b/code/rest/user_model.go @@ -7,6 +7,8 @@ import ( const ( //guest USER_ROLE_GUEST = "GUEST" + //共享空间 + USER_ROLE_SPACE = "SPACE" //normal user USER_ROLE_USER = "USER" //administrator diff --git a/code/rest/user_service.go b/code/rest/user_service.go index 6e05a08..c99b231 100644 --- a/code/rest/user_service.go +++ b/code/rest/user_service.go @@ -11,7 +11,7 @@ import ( "time" ) -//@Service +// @Service type UserService struct { BaseBean userDao *UserDao @@ -82,7 +82,7 @@ func (this *UserService) Init() { this.locker = cache.NewTable() } -//lock a user's operation. If lock, user cannot operate file. +// lock a user's operation. If lock, user cannot operate file. func (this *UserService) MatterLock(userUuid string) { cacheItem, err := this.locker.Value(userUuid) @@ -98,7 +98,7 @@ func (this *UserService) MatterLock(userUuid string) { this.locker.Add(userUuid, duration, true) } -//unlock +// unlock func (this *UserService) MatterUnlock(userUuid string) { exist := this.locker.Exists(userUuid) @@ -110,8 +110,8 @@ func (this *UserService) MatterUnlock(userUuid string) { } } -//load session to SessionCache. This method will be invoked in every request. -//authorize by 1. cookie 2. username and password in request form. 3. Basic Auth +// load session to SessionCache. This method will be invoked in every request. +// authorize by 1. cookie 2. username and password in request form. 3. Basic Auth func (this *UserService) PreHandle(writer http.ResponseWriter, request *http.Request) { sessionId := util.GetSessionUuidFromRequest(request, core.COOKIE_AUTH_KEY) @@ -182,7 +182,7 @@ func (this *UserService) PreHandle(writer http.ResponseWriter, request *http.Req } -//find a cache user by its userUuid +// find a cache user by its userUuid func (this *UserService) FindCacheUsersByUuid(userUuid string) []*User { var users []*User @@ -204,7 +204,7 @@ func (this *UserService) FindCacheUsersByUuid(userUuid string) []*User { return users } -//remove cache user by its userUuid +// remove cache user by its userUuid func (this *UserService) RemoveCacheUserByUuid(userUuid string) { var sessionId interface{} @@ -233,7 +233,25 @@ func (this *UserService) RemoveCacheUserByUuid(userUuid string) { } } -//delete user +// create user +func (this *UserService) CreateUser(request *http.Request, username string, password string, role string, sizeLimit int64, totalSizeLimit int64) *User { + + user := &User{ + Username: username, + Password: util.GetBcrypt(password), + Role: role, + SizeLimit: sizeLimit, + TotalSizeLimit: totalSizeLimit, + Status: USER_STATUS_OK, + } + + user = this.userDao.Create(user) + + return user + +} + +// delete user func (this *UserService) DeleteUser(request *http.Request, currentUser *User) { //delete from cache diff --git a/code/support/tank_context.go b/code/support/tank_context.go index fa94bfa..f4a95f8 100644 --- a/code/support/tank_context.go +++ b/code/support/tank_context.go @@ -80,10 +80,10 @@ func (this *TankContext) OpenDb() { dbLogger := logger.New( log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer logger.Config{ - SlowThreshold: time.Second, // slow SQL 1s - LogLevel: logger.Silent, // log level. open when debug. - IgnoreRecordNotFoundError: true, // ignore ErrRecordNotFound - Colorful: false, // colorful print + SlowThreshold: time.Second, // slow SQL 1s + LogLevel: logger.Info, // log level. open when debug. + IgnoreRecordNotFoundError: true, // ignore ErrRecordNotFound + Colorful: false, // colorful print }, ) diff --git a/code/tool/i18n/i18n.go b/code/tool/i18n/i18n.go index b520b65..ad9c7d2 100644 --- a/code/tool/i18n/i18n.go +++ b/code/tool/i18n/i18n.go @@ -27,6 +27,7 @@ var ( UsernameNotExist = &Item{English: `username "%s" not exists`, Chinese: `用户名"%s"不存在`} UsernameIsNotAdmin = &Item{English: `username "%s" is not admin user`, Chinese: `用户名"%s"不是管理员账号`} UsernameError = &Item{English: `username can only be letters, numbers or _`, Chinese: `用户名必填,且只能包含中文,字母,数字和'_'`} + UserRoleError = &Item{English: `user role is not correct`, Chinese: `用户角色设置错误`} UserRegisterNotAllowd = &Item{English: `admin has banned register`, Chinese: `管理员已禁用自主注册`} UserPasswordLengthError = &Item{English: `password at least 6 chars`, Chinese: `密码长度至少为6位`} UserOldPasswordError = &Item{English: `old password error`, Chinese: `旧密码不正确`} @@ -46,6 +47,8 @@ var ( ShareCodeRequired = &Item{English: `share code required`, Chinese: `提取码必填`} ShareCodeError = &Item{English: `share code error`, Chinese: `提取码错误`} CronValidateError = &Item{English: `cron error. five fields needed. eg: 1 * * * *`, Chinese: `Cron表达式错误,必须为5位。例如:1 * * * *`} + SpaceNameError = &Item{English: `space's name can only be letters, numbers or _`, Chinese: `共享空间名称必填,且只能包含中文,字母,数字和'_'`} + SpaceNameExist = &Item{English: `space's name "%s" exists`, Chinese: `共享空间名称"%s"已存在`} ) func (this *Item) Message(request *http.Request) string {