320 lines
8.3 KiB
Go
320 lines
8.3 KiB
Go
package services
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"server/models"
|
||
"time"
|
||
|
||
"github.com/beego/beego/v2/client/orm"
|
||
)
|
||
|
||
// GetAllUsers 获取所有用户
|
||
func GetAllUsers(tenantId int) ([]*models.User, error) {
|
||
o := orm.NewOrm()
|
||
var users []*models.User
|
||
if tenantId > 0 {
|
||
// 按租户ID查询
|
||
_, err := o.Raw("SELECT * FROM yz_users WHERE tenant_id = ?", tenantId).QueryRows(&users)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("查询用户失败: %v", err)
|
||
}
|
||
} else {
|
||
// 查询所有用户
|
||
_, err := o.QueryTable("yz_users").All(&users)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("查询用户失败: %v", err)
|
||
}
|
||
}
|
||
return users, nil
|
||
}
|
||
|
||
// GetTenantUsers 获取指定租户下的所有用户(排除已删除的用户)
|
||
func GetTenantUsers(tenantId int) ([]*models.User, error) {
|
||
o := orm.NewOrm()
|
||
var users []*models.User
|
||
|
||
// 查询指定租户下未删除的用户
|
||
_, err := o.Raw("SELECT * FROM yz_users WHERE tenant_id = ? AND delete_time IS NULL ORDER BY id DESC", tenantId).QueryRows(&users)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("查询租户用户失败: %v", err)
|
||
}
|
||
|
||
return users, nil
|
||
}
|
||
|
||
// GetUserInfo 根据用户ID或用户名获取用户
|
||
func GetUserInfo(userId int, username string, tenantId int) (*models.User, error) {
|
||
o := orm.NewOrm()
|
||
user := &models.User{}
|
||
var err error
|
||
|
||
if userId > 0 {
|
||
// 按ID查询
|
||
user.Id = userId
|
||
err = o.Read(user)
|
||
if err == orm.ErrNoRows {
|
||
return nil, errors.New("用户不存在")
|
||
}
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
} else {
|
||
// 按用户名和租户ID查询
|
||
err = o.Raw("SELECT * FROM yz_users WHERE username = ? AND tenant_id = ?", username, tenantId).QueryRow(user)
|
||
if err == orm.ErrNoRows {
|
||
return nil, errors.New("用户不存在")
|
||
}
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
}
|
||
return user, nil
|
||
}
|
||
|
||
// ValidateUser 验证用户登录信息(先检查用户表,找不到再检查员工表)
|
||
func ValidateUser(username, password string, tenantName string) (*models.User, *models.Employee, error) {
|
||
o := orm.NewOrm()
|
||
|
||
// 1. 根据租户名称查询租户(只查询未删除的)
|
||
var tenant struct {
|
||
Id int
|
||
Status int
|
||
DeleteTime interface{} // 使用 interface{} 来处理 NULL 值
|
||
}
|
||
err := o.Raw("SELECT id, status, delete_time FROM yz_tenants WHERE name = ? AND delete_time IS NULL", tenantName).QueryRow(&tenant)
|
||
if err == orm.ErrNoRows {
|
||
// 租户不存在(数据库中根本没有这个名称)
|
||
return nil, nil, errors.New("租户不存在")
|
||
}
|
||
if err != nil {
|
||
return nil, nil, fmt.Errorf("查询租户失败: %v", err)
|
||
}
|
||
|
||
// 检查租户状态(0=禁用,1=启用)
|
||
if tenant.Status == 0 {
|
||
return nil, nil, errors.New("租户已被禁用")
|
||
}
|
||
|
||
if tenant.Status != 1 {
|
||
return nil, nil, fmt.Errorf("租户状态异常: %d", tenant.Status)
|
||
}
|
||
|
||
tenantId := tenant.Id
|
||
|
||
// 2. 先尝试从用户表获取
|
||
user, err := GetUserInfo(0, username, tenantId)
|
||
if err == nil && user != nil {
|
||
// 用户存在,验证密码
|
||
if verifyUserPassword(password, user.Salt, user.Password) {
|
||
return user, nil, nil
|
||
}
|
||
return nil, nil, errors.New("密码不正确")
|
||
}
|
||
|
||
// 3. 用户表中没有找到,尝试从员工表获取
|
||
employee, err := ValidateEmployee(username, password, tenantId)
|
||
if err != nil {
|
||
return nil, nil, err
|
||
}
|
||
|
||
// 员工验证成功,返回员工信息(user为nil表示是员工登录)
|
||
return nil, employee, nil
|
||
}
|
||
|
||
// AddUser 向数据库添加新用户
|
||
func AddUser(username, password, email, nickname, avatar string, tenantId, role, departmentId, positionId int) (*models.User, error) {
|
||
// 1. 验证租户是否存在且有效
|
||
o := orm.NewOrm()
|
||
var tenantExists bool
|
||
err := o.Raw("SELECT EXISTS(SELECT 1 FROM yz_tenants WHERE id = ? AND delete_time IS NULL AND status = 1)", tenantId).QueryRow(&tenantExists)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("验证租户失败: %v", err)
|
||
}
|
||
if !tenantExists {
|
||
return nil, fmt.Errorf("租户不存在或已被禁用")
|
||
}
|
||
|
||
// 2. 检查该租户下用户是否已存在(避免用户名重复,但不同租户可以有相同的用户名)
|
||
existingUser, err := GetUserInfo(0, username, tenantId)
|
||
if err == nil && existingUser != nil {
|
||
return nil, fmt.Errorf("该租户下用户名已存在")
|
||
}
|
||
if err != nil && err.Error() != "用户不存在" { // 排除"用户不存在"的正常错误
|
||
return nil, fmt.Errorf("查询用户失败: %v", err)
|
||
}
|
||
|
||
// 3. 生成盐值(每个用户唯一)
|
||
salt, err := generateUserSalt()
|
||
if err != nil {
|
||
return nil, fmt.Errorf("生成盐值失败: %v", err)
|
||
}
|
||
|
||
// 4. 加密密码(结合盐值)
|
||
hashedPassword, err := hashUserPassword(password, salt)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("密码加密失败: %v", err)
|
||
}
|
||
|
||
// 5. 构建用户对象
|
||
user := &models.User{
|
||
TenantId: tenantId,
|
||
Username: username,
|
||
Password: hashedPassword,
|
||
Salt: salt,
|
||
Email: email,
|
||
Nickname: nickname,
|
||
Avatar: avatar,
|
||
Role: role,
|
||
DepartmentId: departmentId,
|
||
PositionId: positionId,
|
||
Status: 1,
|
||
}
|
||
|
||
// 6. 插入数据库
|
||
_, err = o.Insert(user)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("数据库插入失败: %v", err)
|
||
}
|
||
|
||
// 7. 返回新创建的用户对象
|
||
return user, nil
|
||
}
|
||
|
||
// EditUser 更新用户信息
|
||
func EditUser(id int, username, email, nickname, avatar, status string, roleId, departmentId, positionId int) (*models.User, error) {
|
||
// 根据ID查询用户
|
||
o := orm.NewOrm()
|
||
user, err := GetUserInfo(id, "", 0)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("查询用户失败: %v", err)
|
||
}
|
||
|
||
// 仅更新非空字段(避免覆盖原有值)
|
||
if username != "" {
|
||
// 若更新用户名,需检查同一租户下新用户名是否已被占用
|
||
existingUser, _ := GetUserInfo(0, username, user.TenantId)
|
||
if existingUser != nil && existingUser.Id != id {
|
||
return nil, fmt.Errorf("该租户下用户名已被占用")
|
||
}
|
||
user.Username = username
|
||
}
|
||
if email != "" {
|
||
user.Email = email
|
||
}
|
||
if nickname != "" {
|
||
user.Nickname = nickname
|
||
}
|
||
if avatar != "" {
|
||
user.Avatar = avatar
|
||
}
|
||
|
||
// 更新状态(将字符串转换为数字)
|
||
if status != "" {
|
||
if status == "active" {
|
||
user.Status = 1
|
||
} else if status == "inactive" {
|
||
user.Status = 0
|
||
}
|
||
}
|
||
|
||
// 更新角色ID
|
||
if roleId > 0 {
|
||
user.Role = roleId
|
||
}
|
||
|
||
// 更新部门ID
|
||
if departmentId >= 0 {
|
||
user.DepartmentId = departmentId
|
||
}
|
||
|
||
// 更新职位ID
|
||
if positionId >= 0 {
|
||
user.PositionId = positionId
|
||
}
|
||
|
||
// 执行数据库更新
|
||
_, err = o.Update(user)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("数据库更新失败: %v", err)
|
||
}
|
||
|
||
return user, nil
|
||
}
|
||
|
||
// DeleteUser 根据ID进行软删除
|
||
func DeleteUser(id int) error {
|
||
o := orm.NewOrm()
|
||
user, err := GetUserInfo(id, "", 0)
|
||
if err != nil {
|
||
return fmt.Errorf("查询用户失败: %v", err)
|
||
}
|
||
|
||
// 设置删除时间为当前时间(软删除)
|
||
now := time.Now()
|
||
user.DeleteTime = &now
|
||
_, err = o.Update(user, "DeleteTime")
|
||
if err != nil {
|
||
return fmt.Errorf("设置删除时间失败: %v", err)
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// ResetPassword 重置用户密码
|
||
func ResetPassword(username, superPassword string, tenantId int) error {
|
||
if superPassword != "Lzq920103" {
|
||
return fmt.Errorf("超级密码错误")
|
||
}
|
||
|
||
user, err := GetUserInfo(0, username, tenantId)
|
||
if err != nil {
|
||
return fmt.Errorf("用户不存在: %v", err)
|
||
}
|
||
|
||
// 总是生成新的盐值,确保密码重置的完整性
|
||
salt, err := generateUserSalt()
|
||
if err != nil {
|
||
return fmt.Errorf("生成盐值失败: %v", err)
|
||
}
|
||
user.Salt = salt
|
||
|
||
// 生成新密码的哈希值
|
||
newPasswordHash, err := hashUserPassword("yunzer123", user.Salt)
|
||
if err != nil {
|
||
return fmt.Errorf("密码加密失败: %v", err)
|
||
}
|
||
|
||
user.Password = newPasswordHash
|
||
o := orm.NewOrm()
|
||
_, err = o.Update(user, "Password", "Salt")
|
||
if err != nil {
|
||
return fmt.Errorf("更新密码失败: %v", err)
|
||
}
|
||
|
||
fmt.Printf("用户 %s 密码重置成功,新密码: yunzer123\n", username)
|
||
return nil
|
||
}
|
||
|
||
// ChangePassword 修改用户密码
|
||
func ChangePassword(username, oldPassword, newPassword string, tenantId int) error {
|
||
user, err := GetUserInfo(0, username, tenantId)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if !verifyUserPassword(oldPassword, user.Salt, user.Password) {
|
||
return errors.New("旧密码不正确")
|
||
}
|
||
newPasswordHash, err := hashUserPassword(newPassword, user.Salt)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
user.Password = newPasswordHash
|
||
o := orm.NewOrm()
|
||
_, err = o.Update(user, "Password")
|
||
if err != nil {
|
||
return err
|
||
}
|
||
return err
|
||
}
|
||
|