Feature/all method #4

Merged
lqhoang99 merged 3 commits from feature/AllMethod into master 2021-11-09 06:41:46 +00:00
7 changed files with 254 additions and 9 deletions

View File

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

82
action_get_all.go Normal file
View File

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

View File

@ -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
View File

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

View File

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

View File

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

58
query.go Normal file
View File

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