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{
|
return User{
|
||||||
ID: mongodb.NewObjectID(),
|
ID: mongodb.NewObjectID(),
|
||||||
Name: payload.Name,
|
Name: payload.Name,
|
||||||
|
SearchString: getSearchString(payload.Name, payload.Phone, payload.Email),
|
||||||
Phone: payload.Phone,
|
Phone: payload.Phone,
|
||||||
Email: payload.Email,
|
Email: payload.Email,
|
||||||
HashedPassword: hashPassword(payload.Password),
|
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
|
||||||
|
}
|
|
@ -45,6 +45,7 @@ func (s Service) UpdateByUserID(userID string, payload UpdateOptions) error {
|
||||||
updateData := bson.M{
|
updateData := bson.M{
|
||||||
"$set": bson.M{
|
"$set": bson.M{
|
||||||
"name": payload.Name,
|
"name": payload.Name,
|
||||||
|
"searchString": getSearchString(payload.Name, payload.Phone, payload.Email),
|
||||||
"phone": payload.Phone,
|
"phone": payload.Phone,
|
||||||
"email": payload.Email,
|
"email": payload.Email,
|
||||||
"roleId": roleID,
|
"roleId": roleID,
|
||||||
|
|
53
db.go
53
db.go
|
@ -8,6 +8,7 @@ import (
|
||||||
"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"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
)
|
)
|
||||||
|
|
||||||
// getUserCollection ...
|
// getUserCollection ...
|
||||||
|
@ -110,3 +111,55 @@ func (s Service) userFindByID(ctx context.Context, id primitive.ObjectID) (User,
|
||||||
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 (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
|
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 {
|
func hashPassword(password string) string {
|
||||||
bytes, _ := bcrypt.GenerateFromPassword([]byte(password), passwordHashingCost)
|
bytes, _ := bcrypt.GenerateFromPassword([]byte(password), passwordHashingCost)
|
||||||
|
@ -11,3 +16,20 @@ func checkPasswordHash(password, hash string) bool {
|
||||||
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
||||||
return err == nil
|
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 {
|
type User struct {
|
||||||
ID primitive.ObjectID `bson:"_id" json:"_id"`
|
ID primitive.ObjectID `bson:"_id" json:"_id"`
|
||||||
Name string `bson:"name" json:"name"`
|
Name string `bson:"name" json:"name"`
|
||||||
|
SearchString string `bson:"searchString" json:"-"`
|
||||||
Phone string `bson:"phone" json:"phone"` // unique
|
Phone string `bson:"phone" json:"phone"` // unique
|
||||||
Email string `bson:"email" json:"email"` // unique
|
Email string `bson:"email" json:"email"` // unique
|
||||||
HashedPassword string `bson:"hashedPassword" json:"-"`
|
HashedPassword string `bson:"hashedPassword" json:"-"`
|
||||||
|
@ -20,6 +21,19 @@ type User struct {
|
||||||
UpdatedAt time.Time `bson:"updatedAt" json:"updatedAt"`
|
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 ...
|
// Role ...
|
||||||
type Role struct {
|
type Role struct {
|
||||||
ID primitive.ObjectID `bson:"_id" json:"_id"`
|
ID primitive.ObjectID `bson:"_id" json:"_id"`
|
||||||
|
@ -29,3 +43,17 @@ type Role struct {
|
||||||
CreatedAt time.Time `bson:"createdAt" json:"createdAt"`
|
CreatedAt time.Time `bson:"createdAt" json:"createdAt"`
|
||||||
UpdatedAt time.Time `bson:"updatedAt" json:"updatedAt"`
|
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