package services import ( "Quincy_admin/repositories" "Quincy_admin/schemas" "Quincy_admin/utils" "fmt" "net" "time" "golang.org/x/crypto/bcrypt" ) type UserService struct { repo *repositories.UserRepository } func NewUserService(repo *repositories.UserRepository) (*UserService, error) { service := &UserService{repo: repo} return service, nil } // CreateUser 创建用户 func (s *UserService) CreateUser(userReq *schemas.CreateUser) error { // 只有当密码不为空时才进行加密处理 if userReq.Password != "" { hashedPassword, err := s.HashPassword(userReq.Password) if err != nil { return fmt.Errorf("密码加密失败: %v", err) } userReq.Password = hashedPassword } else { return fmt.Errorf("密码不能为空") } //添加默认值 userReq.RoleCode = 0 userReq.Status = schemas.UserStatusDisabled // 如果 UserCode 为空,生成一个唯一的 UserCode,确保与数据库中已有的不重复 foundUniqueCode := false for i := 0; i < 5; i++ { // 最多尝试5次 userReq.SessionCode = utils.GenerateUserCode("S10", 7) // 检查数据库是否已存在该 sessioncode count, err := s.repo.IsUserCodeExists(userReq.SessionCode) if err != nil { return err } if count == 0 { foundUniqueCode = true break } } // 如果5次尝试后仍未找到唯一code,返回错误 if !foundUniqueCode { return fmt.Errorf("无法生成唯一的用户编码,已尝试5次") } // 生成唯一的 Username,确保与数据库中已有的不重复 foundUniqueName := false for i := 0; i < 5; i++ { userReq.Username, _ = utils.GenerateUsername(8) // 检查数据库是否已存在该 Username count, err := s.repo.IsUsernameExists(userReq.Username) if err != nil { return err } if count == 0 { foundUniqueName = true break } } // 如果5次尝试后仍未找到唯一username,返回错误 if !foundUniqueName { return fmt.Errorf("无法生成唯一的用户名,已尝试5次") } return s.repo.Create(userReq) } // IsEmailExists 检查邮箱是否已存在 func (s *UserService) IsEmailExists(email string) (int, error) { return s.repo.IsEmailExists(email) } // GetUserByID 通过用户ID查找用户 func (s *UserService) GetUserByID(scode string) (*schemas.UserInfo, error) { return s.repo.FindByID(scode) } // GetUserByUsername 通过用户名查找用户 func (s *UserService) GetUserByUsername(username string) (*schemas.UserInfo, error) { return s.repo.FindByUsername(username) } // GetUserLocation 获取用户地理位置信息 func (s *UserService) GetUserLocation(ipAddress string) (map[string]string, error) { geoDB := utils.GetGeoIP() if geoDB == nil { return nil, fmt.Errorf("GeoIP database not initialized") } // 解析 IP 地址 ip := net.ParseIP(ipAddress) if ip == nil { return nil, fmt.Errorf("invalid IP address: %s", ipAddress) } // 查询地理位置 record, err := geoDB.City(ip) if err != nil { return nil, fmt.Errorf("failed to query GeoIP database: %v", err) } // 构造返回结果 location := map[string]string{ "ip": ipAddress, "country": record.Country.Names["zh-CN"], "country_code": record.Country.IsoCode, "province": "", "city": "", "latitude": fmt.Sprintf("%f", record.Location.Latitude), "longitude": fmt.Sprintf("%f", record.Location.Longitude), } // 获取省份/州信息 if len(record.Subdivisions) > 0 { location["province"] = record.Subdivisions[0].Names["zh-CN"] } // 获取城市信息 if record.City.Names["zh-CN"] != "" { location["city"] = record.City.Names["zh-CN"] } //fmt.Println("location:", location) return location, nil } // StoreLoginSession 存储登录会话 //func (s *UserService) StoreLoginSession(sessionKey string, userInfo *schemas.UserInfo, expireTime time.Duration) error { // InitRedis := utils.GetRedis() // ctx := utils.GetContext() // // // 将用户信息序列化后存储到Redis // userInfoBytes, err := json.Marshal(userInfo) // if err != nil { // return err // } // // err = InitRedis.Set(ctx, sessionKey, userInfoBytes, expireTime).Err() // if err != nil { // return err // } // // return nil //} // RecordLoginLog 记录登录日志 func (s *UserService) RecordLoginLog(userID int, username string, ipAddress string, userAgent string, status int, failureReason string) error { // 获取地理位置信息 locationInfo, err := s.GetUserLocation("60.255.157.229") var locationStr string if err == nil { locationStr = fmt.Sprintf("%s%s%s", locationInfo["country"], locationInfo["province"], locationInfo["city"]) } else { locationStr = "未知位置" } // 创建登录日志记录 now := time.Now() loginLog := &schemas.LoginLog{ UserID: userID, Username: username, IPAddress: ipAddress, Location: locationStr, UserAgent: userAgent, LoginTime: schemas.NewCustomTime(&now), Status: status, FailureReason: failureReason, CreateTime: schemas.NewCustomTime(&now), } // 插入数据库 return s.repo.RecordLoginLog(loginLog) } // UpdateUser 更新用户信息 func (s *UserService) UpdateUser(user *schemas.UpdateUser) (int, error) { // 检查是否尝试修改超级管理员账户(ID=1) if user.ID == 1 { return 0, fmt.Errorf("无法修改超级管理员账户信息") } // 只有当密码不为空时才进行加密处理 if user.Password != "" { hashedPassword, err := s.HashPassword(user.Password) if err != nil { return 0, fmt.Errorf("密码加密失败: %v", err) } user.Password = hashedPassword } else { // 如果密码为空,则不更新密码字段 user.Password = "" } return s.repo.Update(user) } // UpdateLastLoginTime 更新用户最后登录时间 func (s *UserService) UpdateLastLoginTime(scode string) error { return s.repo.UpdateLastLoginTime(scode, time.Now()) } // UpdateStatus 删除用户 func (s *UserService) UpdateStatus(id int, enable int) error { // 防止修改超级管理员账户(ID=1) if id == 1 { return fmt.Errorf("无权限修改超级管理员账户") } return s.repo.UpdateStatus(id, enable) } // HashPassword 对密码进行加密 func (s *UserService) HashPassword(password string) (string, error) { hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { return "", err } return string(hashedPassword), nil } // VerifyPassword 验证密码 func (s *UserService) VerifyPassword(plainPassword, hashedPassword string) bool { err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(plainPassword)) return err == nil } // GetUserList 获取用户列表 func (s *UserService) GetUserList(req *schemas.UserListRequest) ([]*schemas.UserInfo, int64, error) { return s.repo.GetUserList(req) } // GetRoleList 获取角色列表 func (s *UserService) GetRoleList(req *schemas.RoleListRequest) ([]*schemas.RoleResponseList, int64, error) { return s.repo.GetRoleList(req) } // GetLoginLogList 获取登录日志列表 func (s *UserService) GetLoginLogList(req *schemas.LoginLogListRequest) ([]*schemas.LoginLog, int64, error) { return s.repo.GetLoginLogList(req) } // AssignRole 分配角色 func (s *UserService) AssignRole(userIdValue, roleIdValue int) error { // 检查用户是否已分配角色 exists, err := s.repo.AssignRoleExists(userIdValue) if err != nil { return err } if !exists { // 用户未分配角色,执行插入操作 return s.repo.AssignRole(userIdValue, roleIdValue) } else { // 用户已分配角色,执行更新操作 return s.repo.UpdateAssignRole(userIdValue, roleIdValue) } } // UpdateRoleStatus 删除用户 func (s *UserService) UpdateRoleStatus(id int, enable int) error { // 防止修改超级管理员账户(ID=1) if id == 1 { return fmt.Errorf("无权限修改超级管理员账户") } return s.repo.UpdateRoleStatus(id, enable) } // CreateRole 创建角色 func (s *UserService) CreateRole(req *schemas.CreateRole) error { return s.repo.CreateRole(req) } // UpdateRole 更新角色 func (s *UserService) UpdateRole(req *schemas.CreateRole) error { return s.repo.UpdateRole(req) }