Merge pull request #4 from Selly-Modules/feature/AllMethod
Feature/all method
This commit is contained in:
		
						commit
						23df1ec737
					
				| 
						 | 
				
			
			@ -48,6 +48,7 @@ func (payload CreateOptions) newUser() (result User, err error) {
 | 
			
		|||
	return User{
 | 
			
		||||
		ID:             mongodb.NewObjectID(),
 | 
			
		||||
		Name:           payload.Name,
 | 
			
		||||
		SearchString:   getSearchString(payload.Name, payload.Phone, payload.Email),
 | 
			
		||||
		Phone:          payload.Phone,
 | 
			
		||||
		Email:          payload.Email,
 | 
			
		||||
		HashedPassword: hashPassword(payload.Password),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,82 @@
 | 
			
		|||
package usermngmt
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"go.mongodb.org/mongo-driver/bson"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// AllQuery ...
 | 
			
		||||
type AllQuery struct {
 | 
			
		||||
	Page    int64
 | 
			
		||||
	Limit   int64
 | 
			
		||||
	Keyword string
 | 
			
		||||
	RoleID  string
 | 
			
		||||
	Status  string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// All ...
 | 
			
		||||
func (s Service) All(queryParams AllQuery) (r ResponseUserAll) {
 | 
			
		||||
	var (
 | 
			
		||||
		ctx  = context.Background()
 | 
			
		||||
		wg   sync.WaitGroup
 | 
			
		||||
		cond = bson.M{}
 | 
			
		||||
	)
 | 
			
		||||
	query := commonQuery{
 | 
			
		||||
		Page:    queryParams.Page,
 | 
			
		||||
		Limit:   queryParams.Limit,
 | 
			
		||||
		Keyword: queryParams.Keyword,
 | 
			
		||||
		RoleID:  queryParams.RoleID,
 | 
			
		||||
		Status:  queryParams.Status,
 | 
			
		||||
		Sort:    bson.M{"createdAt": -1},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Assign condition
 | 
			
		||||
	query.SetDefaultLimit()
 | 
			
		||||
	query.AssignKeyword(cond)
 | 
			
		||||
	query.AssignRoleID(cond)
 | 
			
		||||
	query.AssignStatus(cond)
 | 
			
		||||
 | 
			
		||||
	wg.Add(1)
 | 
			
		||||
	go func() {
 | 
			
		||||
		defer wg.Done()
 | 
			
		||||
		docs := s.userFindByCondition(ctx, cond, query.GetFindOptionsUsingPage())
 | 
			
		||||
		r.List = getResponseList(ctx, docs)
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	wg.Add(1)
 | 
			
		||||
	go func() {
 | 
			
		||||
		defer wg.Done()
 | 
			
		||||
		r.Total = s.userCountByCondition(ctx, cond)
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	wg.Wait()
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getResponseList(ctx context.Context, users []User) []ResponseUser {
 | 
			
		||||
	res := make([]ResponseUser, 0)
 | 
			
		||||
 | 
			
		||||
	for _, user := range users {
 | 
			
		||||
		role, _ := s.roleFindByID(ctx, user.RoleID)
 | 
			
		||||
		res = append(res, ResponseUser{
 | 
			
		||||
			ID:     user.ID.Hex(),
 | 
			
		||||
			Name:   user.Name,
 | 
			
		||||
			Phone:  user.Phone,
 | 
			
		||||
			Email:  user.Email,
 | 
			
		||||
			Status: user.Status,
 | 
			
		||||
			Role: RoleShort{
 | 
			
		||||
				ID:      role.ID.Hex(),
 | 
			
		||||
				Name:    role.Name,
 | 
			
		||||
				IsAdmin: role.IsAdmin,
 | 
			
		||||
			},
 | 
			
		||||
			Other:     user.Other,
 | 
			
		||||
			CreatedAt: user.CreatedAt,
 | 
			
		||||
			UpdatedAt: user.UpdatedAt,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return res
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -44,12 +44,13 @@ func (s Service) UpdateByUserID(userID string, payload UpdateOptions) error {
 | 
			
		|||
	roleID, _ := mongodb.NewIDFromString(payload.RoleID)
 | 
			
		||||
	updateData := bson.M{
 | 
			
		||||
		"$set": bson.M{
 | 
			
		||||
			"name":      payload.Name,
 | 
			
		||||
			"phone":     payload.Phone,
 | 
			
		||||
			"email":     payload.Email,
 | 
			
		||||
			"roleId":    roleID,
 | 
			
		||||
			"other":     payload.Other,
 | 
			
		||||
			"updatedAt": now(),
 | 
			
		||||
			"name":         payload.Name,
 | 
			
		||||
			"searchString": getSearchString(payload.Name, payload.Phone, payload.Email),
 | 
			
		||||
			"phone":        payload.Phone,
 | 
			
		||||
			"email":        payload.Email,
 | 
			
		||||
			"roleId":       roleID,
 | 
			
		||||
			"other":        payload.Other,
 | 
			
		||||
			"updatedAt":    now(),
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										57
									
								
								db.go
								
								
								
								
							
							
						
						
									
										57
									
								
								db.go
								
								
								
								
							| 
						 | 
				
			
			@ -8,6 +8,7 @@ import (
 | 
			
		|||
	"go.mongodb.org/mongo-driver/bson"
 | 
			
		||||
	"go.mongodb.org/mongo-driver/bson/primitive"
 | 
			
		||||
	"go.mongodb.org/mongo-driver/mongo"
 | 
			
		||||
	"go.mongodb.org/mongo-driver/mongo/options"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//  getUserCollection ...
 | 
			
		||||
| 
						 | 
				
			
			@ -92,9 +93,9 @@ func (s Service) userUpdateOneByCondition(ctx context.Context, cond interface{},
 | 
			
		|||
	_, err := col.UpdateOne(ctx, cond, payload)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Error("usermngmt - Update", logger.LogData{
 | 
			
		||||
			"cond": cond,
 | 
			
		||||
			"cond":    cond,
 | 
			
		||||
			"payload": payload,
 | 
			
		||||
			"err": err.Error(),
 | 
			
		||||
			"err":     err.Error(),
 | 
			
		||||
		})
 | 
			
		||||
		return fmt.Errorf("error when update user: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -109,4 +110,56 @@ func (s Service) userFindByID(ctx context.Context, id primitive.ObjectID) (User,
 | 
			
		|||
	)
 | 
			
		||||
	err := col.FindOne(ctx, bson.M{"_id": id}).Decode(&doc)
 | 
			
		||||
	return doc, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s Service) userFindByCondition(ctx context.Context, cond interface{}, opts ...*options.FindOptions) (docs []User) {
 | 
			
		||||
	var (
 | 
			
		||||
		col = s.getUserCollection()
 | 
			
		||||
	)
 | 
			
		||||
	docs = make([]User, 0)
 | 
			
		||||
 | 
			
		||||
	cursor, err := col.Find(ctx, cond, opts...)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Error("usermngmt - All", 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 - All - decode", logger.LogData{
 | 
			
		||||
			"cond": cond,
 | 
			
		||||
			"opts": opts,
 | 
			
		||||
			"err":  err.Error(),
 | 
			
		||||
		})
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// userCountByCondition ...
 | 
			
		||||
func (s Service) userCountByCondition(ctx context.Context, cond interface{}) int64 {
 | 
			
		||||
	var (
 | 
			
		||||
		col = s.getUserCollection()
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	total, err := col.CountDocuments(ctx, cond)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Error("usermngmt - Count", logger.LogData{
 | 
			
		||||
			"err":  err.Error(),
 | 
			
		||||
			"cond": cond,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	return total
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s Service) roleFindByID(ctx context.Context, id primitive.ObjectID) (Role, error) {
 | 
			
		||||
	var (
 | 
			
		||||
		col = s.getRoleCollection()
 | 
			
		||||
		doc Role
 | 
			
		||||
	)
 | 
			
		||||
	err := col.FindOne(ctx, bson.M{"_id": id}).Decode(&doc)
 | 
			
		||||
	return doc, err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								helper.go
								
								
								
								
							
							
						
						
									
										24
									
								
								helper.go
								
								
								
								
							| 
						 | 
				
			
			@ -1,6 +1,11 @@
 | 
			
		|||
package usermngmt
 | 
			
		||||
 | 
			
		||||
import "golang.org/x/crypto/bcrypt"
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"github.com/Selly-Modules/mongodb"
 | 
			
		||||
	"golang.org/x/crypto/bcrypt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func hashPassword(password string) string {
 | 
			
		||||
	bytes, _ := bcrypt.GenerateFromPassword([]byte(password), passwordHashingCost)
 | 
			
		||||
| 
						 | 
				
			
			@ -11,3 +16,20 @@ func checkPasswordHash(password, hash string) bool {
 | 
			
		|||
	err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
 | 
			
		||||
	return err == nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getSearchString(fieldList ...string) string {
 | 
			
		||||
	var (
 | 
			
		||||
		searchList = make([]interface{}, 0)
 | 
			
		||||
		format     = ""
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	for i, value := range fieldList {
 | 
			
		||||
		searchList = append(searchList, mongodb.NonAccentVietnamese(value))
 | 
			
		||||
		if i == 0 {
 | 
			
		||||
			format += "%s"
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		format += " %s"
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf(format, searchList...)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										28
									
								
								model.go
								
								
								
								
							
							
						
						
									
										28
									
								
								model.go
								
								
								
								
							| 
						 | 
				
			
			@ -10,6 +10,7 @@ import (
 | 
			
		|||
type User struct {
 | 
			
		||||
	ID             primitive.ObjectID `bson:"_id" json:"_id"`
 | 
			
		||||
	Name           string             `bson:"name" json:"name"`
 | 
			
		||||
	SearchString   string             `bson:"searchString" json:"-"`
 | 
			
		||||
	Phone          string             `bson:"phone" json:"phone"` // unique
 | 
			
		||||
	Email          string             `bson:"email" json:"email"` // unique
 | 
			
		||||
	HashedPassword string             `bson:"hashedPassword" json:"-"`
 | 
			
		||||
| 
						 | 
				
			
			@ -20,6 +21,19 @@ type User struct {
 | 
			
		|||
	UpdatedAt      time.Time          `bson:"updatedAt" json:"updatedAt"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ResponseUser ...
 | 
			
		||||
type ResponseUser struct {
 | 
			
		||||
	ID        string    `json:"_id"`
 | 
			
		||||
	Name      string    `json:"name"`
 | 
			
		||||
	Phone     string    `json:"phone"`
 | 
			
		||||
	Email     string    `json:"email"`
 | 
			
		||||
	Status    string    `json:"status"`
 | 
			
		||||
	Role      RoleShort `json:"role"`
 | 
			
		||||
	Other     string    `json:"other"`
 | 
			
		||||
	CreatedAt time.Time `json:"createdAt"`
 | 
			
		||||
	UpdatedAt time.Time `json:"updatedAt"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Role ...
 | 
			
		||||
type Role struct {
 | 
			
		||||
	ID        primitive.ObjectID `bson:"_id" json:"_id"`
 | 
			
		||||
| 
						 | 
				
			
			@ -29,3 +43,17 @@ type Role struct {
 | 
			
		|||
	CreatedAt time.Time          `bson:"createdAt" json:"createdAt"`
 | 
			
		||||
	UpdatedAt time.Time          `bson:"updatedAt" json:"updatedAt"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type RoleShort struct {
 | 
			
		||||
	ID      string `json:"_id"`
 | 
			
		||||
	Name    string `json:"name"`
 | 
			
		||||
	IsAdmin bool   `json:"isAdmin"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	// ResponseUserAll ...
 | 
			
		||||
	ResponseUserAll struct {
 | 
			
		||||
		List  []ResponseUser `json:"list"`
 | 
			
		||||
		Total int64          `json:"total"`
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,58 @@
 | 
			
		|||
package usermngmt
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/Selly-Modules/mongodb"
 | 
			
		||||
	"go.mongodb.org/mongo-driver/bson"
 | 
			
		||||
	"go.mongodb.org/mongo-driver/mongo/options"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type commonQuery struct {
 | 
			
		||||
	Page    int64
 | 
			
		||||
	Limit   int64
 | 
			
		||||
	Keyword string
 | 
			
		||||
	RoleID  string
 | 
			
		||||
	Status  string
 | 
			
		||||
	Sort    interface{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AssignKeyword ...
 | 
			
		||||
func (q *commonQuery) AssignKeyword(cond bson.M) {
 | 
			
		||||
	if q.Keyword != "" {
 | 
			
		||||
		cond["searchString"] = mongodb.GenerateQuerySearchString(q.Keyword)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AssignRoleID ...
 | 
			
		||||
func (q *commonQuery) AssignRoleID(cond bson.M) {
 | 
			
		||||
	if q.RoleID != "" {
 | 
			
		||||
		if id, isValid := mongodb.NewIDFromString(q.RoleID); isValid {
 | 
			
		||||
			cond["roleId"] = id
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AssignStatus ...
 | 
			
		||||
func (q *commonQuery) AssignStatus(cond bson.M) {
 | 
			
		||||
	if q.Status != "" {
 | 
			
		||||
		cond["status"] = q.Status
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetFindOptionsUsingPage ...
 | 
			
		||||
func (q *commonQuery) GetFindOptionsUsingPage() *options.FindOptions {
 | 
			
		||||
	opts := options.Find()
 | 
			
		||||
	if q.Limit > 0 {
 | 
			
		||||
		opts.SetLimit(q.Limit).SetSkip(q.Limit * q.Page)
 | 
			
		||||
	}
 | 
			
		||||
	if q.Sort != nil {
 | 
			
		||||
		opts.SetSort(q.Sort)
 | 
			
		||||
	}
 | 
			
		||||
	return opts
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetDefaultLimit ...
 | 
			
		||||
func (q *commonQuery) SetDefaultLimit() {
 | 
			
		||||
	if q.Limit <= 0 || q.Limit > 20 {
 | 
			
		||||
		q.Limit = 20
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue