first commit
This commit is contained in:
294
services/user_service.go
Normal file
294
services/user_service.go
Normal file
@@ -0,0 +1,294 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user