diff --git a/internal/db/models/user_dao.go b/internal/db/models/user_dao.go index 774d1b8b..618dfec6 100644 --- a/internal/db/models/user_dao.go +++ b/internal/db/models/user_dao.go @@ -1,9 +1,12 @@ package models import ( + "github.com/TeaOSLab/EdgeAPI/internal/errors" _ "github.com/go-sql-driver/mysql" "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/dbs" + "github.com/iwind/TeaGo/types" + stringutil "github.com/iwind/TeaGo/utils/string" ) const ( @@ -33,7 +36,7 @@ func init() { } // 启用条目 -func (this *UserDAO) EnableUser(id uint32) (rowsAffected int64, err error) { +func (this *UserDAO) EnableUser(id int64) (rowsAffected int64, err error) { return this.Query(). Pk(id). Set("state", UserStateEnabled). @@ -41,7 +44,7 @@ func (this *UserDAO) EnableUser(id uint32) (rowsAffected int64, err error) { } // 禁用条目 -func (this *UserDAO) DisableUser(id uint32) (rowsAffected int64, err error) { +func (this *UserDAO) DisableUser(id int64) (rowsAffected int64, err error) { return this.Query(). Pk(id). Set("state", UserStateDisabled). @@ -49,7 +52,7 @@ func (this *UserDAO) DisableUser(id uint32) (rowsAffected int64, err error) { } // 查找启用中的条目 -func (this *UserDAO) FindEnabledUser(id uint32) (*User, error) { +func (this *UserDAO) FindEnabledUser(id int64) (*User, error) { result, err := this.Query(). Pk(id). Attr("state", UserStateEnabled). @@ -67,3 +70,80 @@ func (this *UserDAO) FindUserFullname(userId int64) (string, error) { Result("fullname"). FindStringCol("") } + +// 创建用户 +func (this *UserDAO) CreateUser(username string, password string, fullname string, mobile string, tel string, email string, remark string, source string) (int64, error) { + op := NewUserOperator() + op.Username = username + op.Password = stringutil.Md5(password) + op.Fullname = fullname + op.Mobile = mobile + op.Tel = tel + op.Email = email + op.Remark = remark + op.Source = source + + op.IsOn = true + op.State = UserStateEnabled + _, err := this.Save(op) + if err != nil { + return 0, err + } + return types.Int64(op.Id), nil +} + +// 修改用户 +func (this *UserDAO) UpdateUser(userId int64, username string, password string, fullname string, mobile string, tel string, email string, remark string, isOn bool) error { + if userId <= 0 { + return errors.New("invalid userId") + } + op := NewUserOperator() + op.Id = userId + op.Username = username + if len(password) > 0 { + op.Password = stringutil.Md5(password) + } + op.Fullname = fullname + op.Mobile = mobile + op.Tel = tel + op.Email = email + op.Remark = remark + op.IsOn = isOn + _, err := this.Save(op) + return err +} + +// 计算用户数量 +func (this *UserDAO) CountAllEnabledUsers(keyword string) (int64, error) { + query := this.Query() + query.State(UserStateEnabled) + if len(keyword) > 0 { + query.Where("(username LIKE :keyword OR fullname LIKE :keyword OR mobile LIKE :keyword OR email LIKE :keyword OR tel LIKE :keyword OR remark LIKE :keyword)"). + Param("keyword", "%"+keyword+"%") + } + return query.Count() +} + +// 列出单页用户 +func (this *UserDAO) ListEnabledUsers(keyword string) (result []*User, err error) { + query := this.Query() + query.State(UserStateEnabled) + if len(keyword) > 0 { + query.Where("(username LIKE :keyword OR fullname LIKE :keyword OR mobile LIKE :keyword OR email LIKE :keyword OR tel LIKE :keyword OR remark LIKE :keyword)"). + Param("keyword", "%"+keyword+"%") + } + _, err = query. + DescPk(). + Slice(&result). + FindAll() + return +} + +// 检查用户名是否存在 +func (this *UserDAO) ExistUser(userId int64, username string) (bool, error) { + return this.Query(). + State(UserStateEnabled). + Attr("username", username). + Neq("id", userId). + Exist() +} diff --git a/internal/db/models/user_model.go b/internal/db/models/user_model.go index bab4a9be..4ed9c188 100644 --- a/internal/db/models/user_model.go +++ b/internal/db/models/user_model.go @@ -15,6 +15,7 @@ type User struct { CreatedAt uint64 `field:"createdAt"` // 创建时间 UpdatedAt uint64 `field:"updatedAt"` // 修改时间 State uint8 `field:"state"` // 状态 + Source string `field:"source"` // 来源 } type UserOperator struct { @@ -31,6 +32,7 @@ type UserOperator struct { CreatedAt interface{} // 创建时间 UpdatedAt interface{} // 修改时间 State interface{} // 状态 + Source interface{} // 来源 } func NewUserOperator() *UserOperator { diff --git a/internal/nodes/api_node.go b/internal/nodes/api_node.go index 0e67adc8..79af7dc9 100644 --- a/internal/nodes/api_node.go +++ b/internal/nodes/api_node.go @@ -200,6 +200,7 @@ func (this *APINode) listenRPC(listener net.Listener, tlsConfig *tls.Config) err pb.RegisterACMEUserServiceServer(rpcServer, &services.ACMEUserService{}) pb.RegisterACMETaskServiceServer(rpcServer, &services.ACMETaskService{}) pb.RegisterACMEAuthenticationServiceServer(rpcServer, &services.ACMEAuthenticationService{}) + pb.RegisterUserServiceServer(rpcServer, &services.UserService{}) err := rpcServer.Serve(listener) if err != nil { return errors.New("[API_NODE]start rpc failed: " + err.Error()) diff --git a/internal/rpc/services/service_user.go b/internal/rpc/services/service_user.go new file mode 100644 index 00000000..dd899b50 --- /dev/null +++ b/internal/rpc/services/service_user.go @@ -0,0 +1,139 @@ +package services + +import ( + "context" + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" +) + +// 用户相关服务 +type UserService struct { + BaseService +} + +// 创建用户 +func (this *UserService) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserResponse, error) { + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + userId, err := models.SharedUserDAO.CreateUser(req.Username, req.Password, req.Fullname, req.Mobile, req.Tel, req.Email, req.Remark, req.Source) + if err != nil { + return nil, err + } + return &pb.CreateUserResponse{UserId: userId}, nil +} + +// 修改用户 +func (this *UserService) UpdateUser(ctx context.Context, req *pb.UpdateUserRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + err = models.SharedUserDAO.UpdateUser(req.UserId, req.Username, req.Password, req.Fullname, req.Mobile, req.Tel, req.Email, req.Remark, req.IsOn) + if err != nil { + return nil, err + } + return this.Success() +} + +// 删除用户 +func (this *UserService) DeleteUser(ctx context.Context, req *pb.DeleteUserRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + _, err = models.SharedUserDAO.DisableUser(req.UserId) + if err != nil { + return nil, err + } + return this.Success() +} + +// 计算用户数量 +func (this *UserService) CountAllEnabledUsers(ctx context.Context, req *pb.CountAllEnabledUsersRequest) (*pb.RPCCountResponse, error) { + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + count, err := models.SharedUserDAO.CountAllEnabledUsers(req.Keyword) + if err != nil { + return nil, err + } + return this.SuccessCount(count) +} + +// 列出单页用户 +func (this *UserService) ListEnabledUsers(ctx context.Context, req *pb.ListEnabledUsersRequest) (*pb.ListEnabledUsersResponse, error) { + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + users, err := models.SharedUserDAO.ListEnabledUsers(req.Keyword) + if err != nil { + return nil, err + } + + result := []*pb.User{} + for _, user := range users { + result = append(result, &pb.User{ + Id: int64(user.Id), + Username: user.Username, + Fullname: user.Fullname, + Mobile: user.Mobile, + Tel: user.Tel, + Email: user.Email, + Remark: user.Remark, + IsOn: user.IsOn == 1, + CreatedAt: int64(user.CreatedAt), + }) + } + + return &pb.ListEnabledUsersResponse{Users: result}, nil +} + +// 查询单个用户信息 +func (this *UserService) FindEnabledUser(ctx context.Context, req *pb.FindEnabledUserRequest) (*pb.FindEnabledUserResponse, error) { + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + user, err := models.SharedUserDAO.FindEnabledUser(req.UserId) + if err != nil { + return nil, err + } + if user == nil { + return &pb.FindEnabledUserResponse{User: nil}, nil + } + return &pb.FindEnabledUserResponse{User: &pb.User{ + Id: int64(user.Id), + Username: user.Username, + Fullname: user.Fullname, + Mobile: user.Mobile, + Tel: user.Tel, + Email: user.Email, + Remark: user.Remark, + IsOn: user.IsOn == 1, + CreatedAt: int64(user.CreatedAt), + }}, nil +} + +// 检查用户名是否存在 +func (this *UserService) CheckUsername(ctx context.Context, req *pb.CheckUsernameRequest) (*pb.CheckUsernameResponse, error) { + _, err := this.ValidateAdmin(ctx, 0) + if err != nil { + return nil, err + } + + b, err := models.SharedUserDAO.ExistUser(req.UserId, req.Username) + if err != nil { + return nil, err + } + return &pb.CheckUsernameResponse{Exists: b}, nil +}