311 lines
7.4 KiB
Go
311 lines
7.4 KiB
Go
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
|
|
} |