第一版完成
This commit is contained in:
311
internal/service/user.go
Normal file
311
internal/service/user.go
Normal file
@@ -0,0 +1,311 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"cms-api/internal/dao"
|
||||
"cms-api/internal/model"
|
||||
|
||||
"github.com/gogf/gf/v2/crypto/gmd5"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
type sUser struct{}
|
||||
|
||||
func User() *sUser {
|
||||
return &sUser{}
|
||||
}
|
||||
|
||||
// Login 用户登录
|
||||
func (s *sUser) Login(ctx context.Context, req *model.UserLoginRequest) (*model.UserLoginResponse, error) {
|
||||
// 查询用户
|
||||
user, err := dao.User.GetByAccount(ctx, req.Account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if user == nil {
|
||||
return nil, gerror.New("用户名或密码错误")
|
||||
}
|
||||
|
||||
// 验证密码
|
||||
if !s.VerifyPassword(req.Password, user.Password) {
|
||||
return nil, gerror.New("用户名或密码错误")
|
||||
}
|
||||
|
||||
// 检查状态
|
||||
if user.Status != 0 {
|
||||
statusText := map[int]string{
|
||||
1: "账号已被冻结",
|
||||
2: "账号已被封号",
|
||||
3: "账号已注销",
|
||||
}
|
||||
return nil, gerror.New(statusText[user.Status])
|
||||
}
|
||||
|
||||
// 更新登录信息
|
||||
err = dao.User.Update(ctx, user.Id, g.Map{
|
||||
"ip": g.RequestFromCtx(ctx).GetClientIp(),
|
||||
"updated_at": gtime.Now(),
|
||||
})
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, "更新用户登录信息失败:", err)
|
||||
}
|
||||
|
||||
// 生成token (暂时使用简单的token生成)
|
||||
token := gmd5.MustEncrypt(gconv.String(user.Id) + "_" + gconv.String(gtime.Now().Unix()))
|
||||
|
||||
// 清除密码字段
|
||||
user.Password = ""
|
||||
|
||||
return &model.UserLoginResponse{
|
||||
Token: token,
|
||||
ExpiresIn: 7200, // 2小时
|
||||
User: user,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetById 根据ID获取用户信息
|
||||
func (s *sUser) GetById(ctx context.Context, id int) (*model.User, error) {
|
||||
user, err := dao.User.GetById(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if user == nil {
|
||||
return nil, nil
|
||||
}
|
||||
// 清除密码字段
|
||||
user.Password = ""
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// List 获取用户列表
|
||||
func (s *sUser) List(ctx context.Context, req *model.UserListRequest) (*model.PageResponse, error) {
|
||||
var (
|
||||
page = req.Page
|
||||
pageSize = req.PageSize
|
||||
)
|
||||
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
if pageSize <= 0 {
|
||||
pageSize = 10
|
||||
}
|
||||
|
||||
// 设置分页参数
|
||||
req.Page = page
|
||||
req.PageSize = pageSize
|
||||
|
||||
// 获取列表
|
||||
users, total, err := dao.User.List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 清除密码字段
|
||||
for _, user := range users {
|
||||
user.Password = ""
|
||||
}
|
||||
|
||||
return &model.PageResponse{
|
||||
List: users,
|
||||
Total: total,
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
TotalPages: (total + pageSize - 1) / pageSize,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Create 创建用户
|
||||
func (s *sUser) Create(ctx context.Context, req *model.CreateUserRequest) error {
|
||||
// 检查账号是否存在
|
||||
existUser, err := dao.User.GetByAccount(ctx, req.Account)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if existUser != nil {
|
||||
return gerror.New("账号已存在")
|
||||
}
|
||||
|
||||
// 检查邮箱是否存在
|
||||
existUser, err = dao.User.GetByEmail(ctx, req.Email)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if existUser != nil {
|
||||
return gerror.New("邮箱已存在")
|
||||
}
|
||||
|
||||
// 加密密码
|
||||
hashedPassword := s.HashPassword(req.Password)
|
||||
|
||||
// 创建用户
|
||||
user := &model.User{
|
||||
Account: req.Account,
|
||||
NickName: req.NickName,
|
||||
Avatar: req.Avatar,
|
||||
Email: req.Email,
|
||||
Password: hashedPassword,
|
||||
Balance: req.Balance,
|
||||
RoleId: req.RoleId,
|
||||
IsSysNotifications: req.IsSysNotifications,
|
||||
IsCollectionNotifications: req.IsCollectionNotifications,
|
||||
IsMarketingNotifications: req.IsMarketingNotifications,
|
||||
Status: 0, // 默认正常状态
|
||||
CreatedAt: gtime.Now(),
|
||||
UpdatedAt: gtime.Now(),
|
||||
}
|
||||
|
||||
_, err = dao.User.Create(ctx, user)
|
||||
return err
|
||||
}
|
||||
|
||||
// Update 更新用户
|
||||
func (s *sUser) Update(ctx context.Context, id int, req *model.UpdateUserRequest) error {
|
||||
// 检查用户是否存在
|
||||
user, err := s.GetById(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if user == nil {
|
||||
return gerror.New("用户不存在")
|
||||
}
|
||||
|
||||
// 检查邮箱是否被其他用户使用
|
||||
existUser, err := dao.User.GetByEmail(ctx, req.Email)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if existUser != nil && existUser.Id != id {
|
||||
return gerror.New("邮箱已被使用")
|
||||
}
|
||||
|
||||
// 更新用户
|
||||
updateData := g.Map{
|
||||
"nick_name": req.NickName,
|
||||
"email": req.Email,
|
||||
"avatar": req.Avatar,
|
||||
"balance": req.Balance,
|
||||
"role_id": req.RoleId,
|
||||
"status": req.Status,
|
||||
"is_sys_notifications": req.IsSysNotifications,
|
||||
"is_collection_notifications": req.IsCollectionNotifications,
|
||||
"is_marketing_notifications": req.IsMarketingNotifications,
|
||||
"updated_at": gtime.Now(),
|
||||
}
|
||||
|
||||
return dao.User.Update(ctx, id, updateData)
|
||||
}
|
||||
|
||||
// Delete 删除用户
|
||||
func (s *sUser) Delete(ctx context.Context, id int) error {
|
||||
// 检查用户是否存在
|
||||
user, err := s.GetById(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if user == nil {
|
||||
return gerror.New("用户不存在")
|
||||
}
|
||||
|
||||
return dao.User.Delete(ctx, id)
|
||||
}
|
||||
|
||||
// ChangePassword 修改密码
|
||||
func (s *sUser) ChangePassword(ctx context.Context, id int, req *model.ChangePasswordRequest) error {
|
||||
// 获取用户信息
|
||||
user, err := dao.User.GetById(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if user == nil {
|
||||
return gerror.New("用户不存在")
|
||||
}
|
||||
|
||||
// 验证原密码
|
||||
if !s.VerifyPassword(req.OldPassword, user.Password) {
|
||||
return gerror.New("原密码错误")
|
||||
}
|
||||
|
||||
// 加密新密码
|
||||
hashedPassword := s.HashPassword(req.NewPassword)
|
||||
|
||||
// 更新密码
|
||||
updateData := g.Map{
|
||||
"password": hashedPassword,
|
||||
"last_reset_password_at": gtime.Now().Unix(),
|
||||
"updated_at": gtime.Now(),
|
||||
}
|
||||
|
||||
return dao.User.Update(ctx, id, updateData)
|
||||
}
|
||||
|
||||
// UpdateStatus 更新用户状态
|
||||
func (s *sUser) UpdateStatus(ctx context.Context, id int, status int) error {
|
||||
// 检查用户是否存在
|
||||
user, err := s.GetById(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if user == nil {
|
||||
return gerror.New("用户不存在")
|
||||
}
|
||||
|
||||
return dao.User.UpdateStatus(ctx, id, status)
|
||||
}
|
||||
|
||||
// HashPassword 加密密码
|
||||
func (s *sUser) HashPassword(password string) string {
|
||||
return gmd5.MustEncrypt(password + "cms_user_salt_2024")
|
||||
}
|
||||
|
||||
// VerifyPassword 验证密码
|
||||
func (s *sUser) VerifyPassword(password, hashedPassword string) bool {
|
||||
return gmd5.MustEncrypt(password+"cms_user_salt_2024") == hashedPassword
|
||||
}
|
||||
|
||||
// Profile 获取当前用户信息
|
||||
func (s *sUser) Profile(ctx context.Context) (*model.User, error) {
|
||||
userId := gconv.Int(g.RequestFromCtx(ctx).GetCtxVar("user_id"))
|
||||
return s.GetById(ctx, userId)
|
||||
}
|
||||
|
||||
// UpdateProfile 更新当前用户信息
|
||||
func (s *sUser) UpdateProfile(ctx context.Context, req *model.UpdateUserRequest) error {
|
||||
userId := gconv.Int(g.RequestFromCtx(ctx).GetCtxVar("user_id"))
|
||||
return s.Update(ctx, userId, req)
|
||||
}
|
||||
|
||||
// GetStats 获取用户统计信息
|
||||
func (s *sUser) GetStats(ctx context.Context) (map[string]interface{}, error) {
|
||||
// 获取总用户数
|
||||
totalCount, err := dao.User.GetCount(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 获取各状态用户数
|
||||
normalCount, err := dao.User.GetCountByStatus(ctx, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
frozenCount, err := dao.User.GetCountByStatus(ctx, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bannedCount, err := dao.User.GetCountByStatus(ctx, 2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"total_count": totalCount,
|
||||
"normal_count": normalCount,
|
||||
"frozen_count": frozenCount,
|
||||
"banned_count": bannedCount,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user