add RoleMethods #6

Merged
lqhoang99 merged 2 commits from feature/Role into master 2021-11-10 08:05:20 +00:00
10 changed files with 363 additions and 31 deletions

View File

@ -37,6 +37,11 @@ func (s Service) GetAllUser(query model.UserAllQuery) model.UserAll {
return user.All(query) return user.All(query)
} }
// ChangeAllUsersStatus ...
func (s Service) ChangeAllUsersStatus(roleID, status string) error {
return user.ChangeAllUsersStatus(roleID, status)
}
// //
// Role // Role
// //
@ -47,3 +52,13 @@ func (s Service) GetAllUser(query model.UserAllQuery) model.UserAll {
func (s Service) CreateRole(payload model.RoleCreateOptions) error { func (s Service) CreateRole(payload model.RoleCreateOptions) error {
return role.Create(payload) return role.Create(payload)
} }
// UpdateRole ...
func (s Service) UpdateRole(roleID string, payload model.RoleUpdateOptions) error {
return role.Update(roleID, payload)
}
// GetAllRoles ...
func (s Service) GetAllRoles(query model.RoleAllQuery) model.RoleAll {
return role.All(query)
}

View File

@ -2,6 +2,7 @@ package internal
import ( import (
"fmt" "fmt"
"strings"
"github.com/Selly-Modules/mongodb" "github.com/Selly-Modules/mongodb"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
@ -36,3 +37,12 @@ func GetSearchString(fieldList ...string) string {
} }
return fmt.Sprintf(format, searchList...) return fmt.Sprintf(format, searchList...)
} }
// GenerateCode ...
func GenerateCode(s string) string {
var (
underscore = "_"
emptySpace = " "
)
return strings.ReplaceAll(mongodb.NonAccentVietnamese(s), emptySpace, underscore)
}

View File

@ -8,12 +8,12 @@ import (
// DBRole ... // DBRole ...
type DBRole struct { type DBRole struct {
ID primitive.ObjectID `bson:"_id" json:"_id"` ID primitive.ObjectID `bson:"_id"`
Name string `bson:"name" json:"name"` Name string `bson:"name"`
Code string `bson:"code" json:"code"` Code string `bson:"code"`
IsAdmin bool `bson:"isAdmin" json:"isAdmin"` IsAdmin bool `bson:"isAdmin"`
CreatedAt time.Time `bson:"createdAt" json:"createdAt"` CreatedAt time.Time `bson:"createdAt"`
UpdatedAt time.Time `bson:"updatedAt" json:"updatedAt"` UpdatedAt time.Time `bson:"updatedAt"`
} }
// DBUser ... // DBUser ...

View File

@ -1,6 +1,49 @@
package model package model
import (
"errors"
"github.com/Selly-Modules/logger"
)
// RoleCreateOptions ... // RoleCreateOptions ...
type RoleCreateOptions struct { type RoleCreateOptions struct {
Name string Name string
} }
// RoleUpdateOptions ...
type RoleUpdateOptions struct {
Name string
}
// RoleAllQuery ...
type RoleAllQuery struct {
Page int64
Limit int64
}
// Validate ...
func (co RoleCreateOptions) Validate() error {
// Name
if co.Name == "" {
logger.Error("usermngmt - Role - Create: no name data", logger.LogData{
"payload": co,
})
return errors.New("no name data")
}
return nil
}
// Validate ...
func (co RoleUpdateOptions) Validate() error {
// Name
if co.Name == "" {
logger.Error("usermngmt - Role - Update: no name data", logger.LogData{
"payload": co,
})
return errors.New("no name data")
}
return nil
}

View File

@ -1,8 +1,30 @@
package model package model
import (
"time"
)
// RoleShort ... // RoleShort ...
type RoleShort struct { type RoleShort struct {
ID string `json:"_id"` ID string `json:"_id"`
Name string `json:"name"` Name string `json:"name"`
IsAdmin bool `json:"isAdmin"` IsAdmin bool `json:"isAdmin"`
} }
// Role ...
type Role struct {
ID string `json:"_id"`
Name string `json:"name"`
Code string `json:"code"`
IsAdmin bool `json:"isAdmin"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
type (
// RoleAll ...
RoleAll struct {
List []Role `json:"list"`
Total int64 `json:"total"`
}
)

View File

@ -45,7 +45,7 @@ type UserAllQuery struct {
func (co UserCreateOptions) Validate() error { func (co UserCreateOptions) Validate() error {
// Name // Name
if co.Name == "" { if co.Name == "" {
logger.Error("usermngmt - Create: no Name data", logger.LogData{ logger.Error("usermngmt - User - Create: no name data", logger.LogData{
"payload": co, "payload": co,
}) })
return errors.New("no name data") return errors.New("no name data")
@ -53,7 +53,7 @@ func (co UserCreateOptions) Validate() error {
// Phone // Phone
if co.Phone == "" { if co.Phone == "" {
logger.Error("usermngmt - Create: no phone data", logger.LogData{ logger.Error("usermngmt - User - Create: no phone data", logger.LogData{
"payload": co, "payload": co,
}) })
return errors.New("no phone data") return errors.New("no phone data")
@ -61,7 +61,7 @@ func (co UserCreateOptions) Validate() error {
// Email // Email
if co.Email == "" { if co.Email == "" {
logger.Error("usermngmt - Create: no email data", logger.LogData{ logger.Error("usermngmt - User - Create: no email data", logger.LogData{
"payload": co, "payload": co,
}) })
return errors.New("no email data") return errors.New("no email data")
@ -69,7 +69,7 @@ func (co UserCreateOptions) Validate() error {
// Password // Password
if co.Password == "" { if co.Password == "" {
logger.Error("usermngmt - Create: no password data", logger.LogData{ logger.Error("usermngmt - User - Create: no password data", logger.LogData{
"payload": co, "payload": co,
}) })
return errors.New("no password data") return errors.New("no password data")
@ -77,7 +77,7 @@ func (co UserCreateOptions) Validate() error {
// Status // Status
if co.Status == "" { if co.Status == "" {
logger.Error("usermngmt - Create: no status data", logger.LogData{ logger.Error("usermngmt - User - Create: no status data", logger.LogData{
"payload": co, "payload": co,
}) })
return errors.New("no status data") return errors.New("no status data")
@ -85,7 +85,7 @@ func (co UserCreateOptions) Validate() error {
// RoleID // RoleID
if co.RoleID == "" { if co.RoleID == "" {
logger.Error("usermngmt - Create: no roleID data", logger.LogData{ logger.Error("usermngmt - User - Create: no roleID data", logger.LogData{
"payload": co, "payload": co,
}) })
return errors.New("no role id data") return errors.New("no role id data")
@ -98,7 +98,7 @@ func (co UserCreateOptions) Validate() error {
func (uo UserUpdateOptions) Validate() error { func (uo UserUpdateOptions) Validate() error {
// Name // Name
if uo.Name == "" { if uo.Name == "" {
logger.Error("usermngmt - Update: no name data", logger.LogData{ logger.Error("usermngmt - User - Update: no name data", logger.LogData{
"payload": uo, "payload": uo,
}) })
return errors.New("no name data") return errors.New("no name data")
@ -106,7 +106,7 @@ func (uo UserUpdateOptions) Validate() error {
// Phone // Phone
if uo.Phone == "" { if uo.Phone == "" {
logger.Error("usermngmt - Update: no phone data", logger.LogData{ logger.Error("usermngmt - User - Update: no phone data", logger.LogData{
"payload": uo, "payload": uo,
}) })
return errors.New("no phone data") return errors.New("no phone data")
@ -114,7 +114,7 @@ func (uo UserUpdateOptions) Validate() error {
// Email // Email
if uo.Email == "" { if uo.Email == "" {
logger.Error("usermngmt - Update: no email data", logger.LogData{ logger.Error("usermngmt - User - Update: no email data", logger.LogData{
"payload": uo, "payload": uo,
}) })
return errors.New("no email data") return errors.New("no email data")
@ -122,7 +122,7 @@ func (uo UserUpdateOptions) Validate() error {
// RoleID // RoleID
if uo.RoleID == "" { if uo.RoleID == "" {
logger.Error("usermngmt - Update: no roleID data", logger.LogData{ logger.Error("usermngmt - User - Update: no roleID data", logger.LogData{
"payload": uo, "payload": uo,
}) })
return errors.New("no role id data") return errors.New("no role id data")
@ -135,7 +135,7 @@ func (uo UserUpdateOptions) Validate() error {
func (co ChangePasswordOptions) Validate() error { func (co ChangePasswordOptions) Validate() error {
// OldPassword, NewPassword // OldPassword, NewPassword
if co.OldPassword == "" || co.NewPassword == "" { if co.OldPassword == "" || co.NewPassword == "" {
logger.Error("usermngmt - ChangePassword: old or new password cannot be empty", logger.LogData{ logger.Error("usermngmt - User - ChangePassword: old or new password cannot be empty", logger.LogData{
"payload": co, "payload": co,
}) })
return errors.New("old or new password cannot be empty") return errors.New("old or new password cannot be empty")

View File

@ -2,11 +2,14 @@ package role
import ( import (
"context" "context"
"fmt"
"github.com/Selly-Modules/logger"
"github.com/Selly-Modules/usermngmt/database" "github.com/Selly-Modules/usermngmt/database"
"github.com/Selly-Modules/usermngmt/model" "github.com/Selly-Modules/usermngmt/model"
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
) )
func findByID(ctx context.Context, id primitive.ObjectID) (model.DBRole, error) { func findByID(ctx context.Context, id primitive.ObjectID) (model.DBRole, error) {
@ -17,3 +20,78 @@ func findByID(ctx context.Context, id primitive.ObjectID) (model.DBRole, error)
err := col.FindOne(ctx, bson.M{"_id": id}).Decode(&doc) err := col.FindOne(ctx, bson.M{"_id": id}).Decode(&doc)
return doc, err return doc, err
} }
func create(ctx context.Context, doc model.DBRole) error {
var (
col = database.GetRoleCol()
)
_, err := col.InsertOne(ctx, doc)
if err != nil {
logger.Error("usermngmt - Role - InsertOne", logger.LogData{
"doc": doc,
"err": err.Error(),
})
return fmt.Errorf("error when create role: %s", err.Error())
}
return nil
}
func updateOneByCondition(ctx context.Context, cond interface{}, payload interface{}) error {
var (
col = database.GetRoleCol()
)
_, err := col.UpdateOne(ctx, cond, payload)
if err != nil {
logger.Error("usermngmt - Role - UpdateOne", logger.LogData{
"cond": cond,
"payload": payload,
"err": err.Error(),
})
return fmt.Errorf("error when update role: %s", err.Error())
}
return err
}
func findByCondition(ctx context.Context, cond interface{}, opts ...*options.FindOptions) (docs []model.DBRole) {
var (
col = database.GetRoleCol()
)
docs = make([]model.DBRole, 0)
cursor, err := col.Find(ctx, cond, opts...)
if err != nil {
logger.Error("usermngmt - Role - Find", logger.LogData{
"cond": cond,
"opts": opts,
"err": err.Error(),
})
return
}
defer cursor.Close(ctx)
if err = cursor.All(ctx, &docs); err != nil {
logger.Error("usermngmt - Role - Decode", logger.LogData{
"cond": cond,
"opts": opts,
"err": err.Error(),
})
return
}
return
}
// countByCondition ...
func countByCondition(ctx context.Context, cond interface{}) int64 {
var (
col = database.GetRoleCol()
)
total, err := col.CountDocuments(ctx, cond)
if err != nil {
logger.Error("usermngmt - Role - CountDocuments", logger.LogData{
"err": err.Error(),
"cond": cond,
})
}
return total
}

View File

@ -2,19 +2,133 @@ package role
import ( import (
"context" "context"
"errors"
"sync"
"github.com/Selly-Modules/mongodb"
"github.com/Selly-Modules/usermngmt/internal"
"github.com/Selly-Modules/usermngmt/model" "github.com/Selly-Modules/usermngmt/model"
"go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/bson"
) )
// FindByID ...
func FindByID(ctx context.Context, id primitive.ObjectID) (model.DBRole, error) {
role, err := findByID(ctx, id)
return role, err
}
// Create ... // Create ...
func Create(payload model.RoleCreateOptions) error { func Create(payload model.RoleCreateOptions) error {
// TODO later var (
ctx = context.Background()
)
// Validate payload
if err := payload.Validate(); err != nil {
return err
}
// New role data from payload
doc := newRole(payload)
// Create role
if err := create(ctx, doc); err != nil {
return err
}
return nil return nil
} }
// newRole ...
func newRole(payload model.RoleCreateOptions) model.DBRole {
timeNow := internal.Now()
return model.DBRole{
ID: mongodb.NewObjectID(),
Name: payload.Name,
Code: internal.GenerateCode(payload.Name),
CreatedAt: timeNow,
UpdatedAt: timeNow,
}
}
// Update ...
func Update(roleID string, payload model.RoleUpdateOptions) error {
var (
ctx = context.Background()
)
// Validate payload
if err := payload.Validate(); err != nil {
return err
}
// Validate roleID
id, isValid := mongodb.NewIDFromString(roleID)
if !isValid {
return errors.New("invalid role id data")
}
// Setup condition
cond := bson.M{
"_id": id,
}
// Setup update data
updateData := bson.M{
"$set": bson.M{
"name": payload.Name,
"code": internal.GenerateCode(payload.Name),
"updatedAt": internal.Now(),
},
}
// Update
if err := updateOneByCondition(ctx, cond, updateData); err != nil {
return err
}
return nil
}
// All ...
func All(queryParams model.RoleAllQuery) (r model.RoleAll) {
var (
ctx = context.Background()
wg sync.WaitGroup
cond = bson.M{}
)
query := model.CommonQuery{
Page: queryParams.Page,
Limit: queryParams.Limit,
Sort: bson.M{"createdAt": -1},
}
// Assign condition
query.SetDefaultLimit()
wg.Add(1)
go func() {
defer wg.Done()
docs := findByCondition(ctx, cond, query.GetFindOptionsUsingPage())
r.List = getResponseList(docs)
}()
wg.Add(1)
go func() {
defer wg.Done()
r.Total = countByCondition(ctx, cond)
}()
wg.Wait()
return
}
func getResponseList(roles []model.DBRole) []model.Role {
res := make([]model.Role, 0)
for _, role := range roles {
res = append(res, model.Role{
ID: role.ID.Hex(),
Name: role.Name,
Code: role.Code,
CreatedAt: role.CreatedAt,
UpdatedAt: role.UpdatedAt,
})
}
return res
}

View File

@ -29,7 +29,7 @@ func isPhoneNumberOrEmailExisted(ctx context.Context, phone, email string) bool
} }
total, err := col.CountDocuments(ctx, cond) total, err := col.CountDocuments(ctx, cond)
if err != nil { if err != nil {
logger.Error("usermngmt - countUserByCondition", logger.LogData{ logger.Error("usermngmt - User - CountDocuments", logger.LogData{
"condition": cond, "condition": cond,
"err": err.Error(), "err": err.Error(),
}) })
@ -48,7 +48,7 @@ func isRoleIDExisted(ctx context.Context, roleID primitive.ObjectID) bool {
} }
total, err := col.CountDocuments(ctx, cond) total, err := col.CountDocuments(ctx, cond)
if err != nil { if err != nil {
logger.Error("usermngmt - countRoleByCondition", logger.LogData{ logger.Error("usermngmt - Role - CountDocuments", logger.LogData{
"condition": cond, "condition": cond,
"err": err.Error(), "err": err.Error(),
}) })
@ -72,7 +72,7 @@ func create(ctx context.Context, doc model.DBUser) error {
) )
_, err := col.InsertOne(ctx, doc) _, err := col.InsertOne(ctx, doc)
if err != nil { if err != nil {
logger.Error("usermngmt - Create", logger.LogData{ logger.Error("usermngmt - User - InsertOne", logger.LogData{
"doc": doc, "doc": doc,
"err": err.Error(), "err": err.Error(),
}) })
@ -88,7 +88,24 @@ func updateOneByCondition(ctx context.Context, cond interface{}, payload interfa
) )
_, err := col.UpdateOne(ctx, cond, payload) _, err := col.UpdateOne(ctx, cond, payload)
if err != nil { if err != nil {
logger.Error("usermngmt - Update", logger.LogData{ logger.Error("usermngmt - User - UpdateOne", logger.LogData{
"cond": cond,
"payload": payload,
"err": err.Error(),
})
return fmt.Errorf("error when update user: %s", err.Error())
}
return err
}
func updateManyByCondition(ctx context.Context, cond interface{}, payload interface{}) error {
var (
col = database.GetUserCol()
)
_, err := col.UpdateMany(ctx, cond, payload)
if err != nil {
logger.Error("usermngmt - User - UpdateMany", logger.LogData{
"cond": cond, "cond": cond,
"payload": payload, "payload": payload,
"err": err.Error(), "err": err.Error(),
@ -116,7 +133,7 @@ func findByCondition(ctx context.Context, cond interface{}, opts ...*options.Fin
cursor, err := col.Find(ctx, cond, opts...) cursor, err := col.Find(ctx, cond, opts...)
if err != nil { if err != nil {
logger.Error("usermngmt - All", logger.LogData{ logger.Error("usermngmt - User - Find", logger.LogData{
"cond": cond, "cond": cond,
"opts": opts, "opts": opts,
"err": err.Error(), "err": err.Error(),
@ -125,7 +142,7 @@ func findByCondition(ctx context.Context, cond interface{}, opts ...*options.Fin
} }
defer cursor.Close(ctx) defer cursor.Close(ctx)
if err = cursor.All(ctx, &docs); err != nil { if err = cursor.All(ctx, &docs); err != nil {
logger.Error("usermngmt - All - decode", logger.LogData{ logger.Error("usermngmt - User - Decode", logger.LogData{
"cond": cond, "cond": cond,
"opts": opts, "opts": opts,
"err": err.Error(), "err": err.Error(),

View File

@ -257,3 +257,36 @@ func ChangeUserStatus(userID, newStatus string) error {
return nil return nil
} }
// ChangeAllUsersStatus ...
func ChangeAllUsersStatus(roleID, status string) error {
var (
ctx = context.Background()
)
// Validate roleID
id, isValid := mongodb.NewIDFromString(roleID)
if !isValid {
return errors.New("invalid role id data")
}
// Setup condition
cond := bson.M{
"roleId": id,
}
// Setup update data
updateData := bson.M{
"$set": bson.M{
"status": status,
"updatedAt": internal.Now(),
},
}
// Update
if err := updateManyByCondition(ctx, cond, updateData); err != nil {
return err
}
return nil
}