package services import ( "errors" "fmt" "server/models" "time" "github.com/beego/beego/v2/client/orm" ) // verifyEmployeePassword 验证员工密码是否正确 func verifyEmployeePassword(password, salt, storedHash string) bool { hash, err := hashPassword(password, salt) if err != nil { return false } return hash == storedHash } // GetTenantEmployees 获取租户下的所有员工 func GetTenantEmployees(tenantId int) ([]*models.Employee, error) { o := orm.NewOrm() var employees []*models.Employee _, err := o.QueryTable("yz_tenant_employees"). Filter("tenant_id", tenantId). Filter("delete_time__isnull", true). OrderBy("-create_time"). All(&employees) return employees, err } // GetEmployeeById 根据ID获取员工信息 func GetEmployeeById(id int) (*models.Employee, error) { o := orm.NewOrm() employee := &models.Employee{Id: id} err := o.Read(employee) if err != nil { return nil, err } // 检查是否已删除 if employee.DeleteTime != nil { return nil, orm.ErrNoRows } return employee, nil } // EmployeeDetail 员工详细信息(包含关联的部门、职位、角色信息) type EmployeeDetail struct { Employee *models.Employee `json:"employee"` Department *models.Department `json:"department,omitempty"` Position *models.Position `json:"position,omitempty"` Role *models.Role `json:"role,omitempty"` } // GetEmployeeDetailWithRelations 根据ID获取员工详细信息(包含关联的部门、职位、角色) // 使用并行查询优化性能 func GetEmployeeDetailWithRelations(id int) (*EmployeeDetail, error) { // 先获取员工基本信息 employee, err := GetEmployeeById(id) if err != nil { return nil, err } detail := &EmployeeDetail{ Employee: employee, } // 使用 goroutine 并行查询关联数据,提高性能 type deptResult struct { department *models.Department err error } type posResult struct { position *models.Position err error } type roleResult struct { role *models.Role err error } deptChan := make(chan deptResult, 1) posChan := make(chan posResult, 1) roleChan := make(chan roleResult, 1) // 并行查询部门信息 if employee.DepartmentId > 0 { go func() { dept, err := models.GetDepartmentById(employee.DepartmentId) deptChan <- deptResult{department: dept, err: err} }() } else { deptChan <- deptResult{department: nil, err: nil} } // 并行查询职位信息 if employee.PositionId > 0 { go func() { pos, err := models.GetPositionById(employee.PositionId) posChan <- posResult{position: pos, err: err} }() } else { posChan <- posResult{position: nil, err: nil} } // 并行查询角色信息 if employee.Role > 0 { go func() { role, err := models.GetRoleById(employee.Role) roleChan <- roleResult{role: role, err: err} }() } else { roleChan <- roleResult{role: nil, err: nil} } // 接收所有结果 deptRes := <-deptChan posRes := <-posChan roleRes := <-roleChan // 设置关联数据(忽略错误,如果不存在就不设置) if deptRes.department != nil && deptRes.err == nil { detail.Department = deptRes.department } if posRes.position != nil && posRes.err == nil { detail.Position = posRes.position } if roleRes.role != nil && roleRes.err == nil { detail.Role = roleRes.role } return detail, nil } // GetAllEmployees 获取所有员工(排除已删除的) func GetAllEmployees() ([]*models.Employee, error) { o := orm.NewOrm() var employees []*models.Employee _, err := o.QueryTable("yz_tenant_employees"). Filter("delete_time__isnull", true). OrderBy("-create_time"). All(&employees) return employees, err } // AddEmployee 添加员工(自动设置默认密码) func AddEmployee(employee *models.Employee, defaultPassword string) (int64, error) { // 生成盐值 salt, err := generateUserSalt() if err != nil { return 0, fmt.Errorf("生成盐值失败: %v", err) } employee.Salt = salt // 加密默认密码 hashedPassword, err := hashPassword(defaultPassword, salt) if err != nil { return 0, fmt.Errorf("密码加密失败: %v", err) } employee.Password = hashedPassword o := orm.NewOrm() id, err := o.Insert(employee) return id, err } // UpdateEmployee 更新员工信息 func UpdateEmployee(employee *models.Employee) error { o := orm.NewOrm() _, err := o.Update(employee, "employee_no", "name", "phone", "email", "department_id", "position_id", "role", "bank_name", "bank_account", "status", "update_time") return err } // ResetEmployeePassword 重置员工密码为默认密码 func ResetEmployeePassword(employeeId int, defaultPassword string) error { o := orm.NewOrm() employee := &models.Employee{Id: employeeId} if err := o.Read(employee); err != nil { return fmt.Errorf("员工不存在: %v", err) } // 生成新盐值 salt, err := generateUserSalt() if err != nil { return fmt.Errorf("生成盐值失败: %v", err) } employee.Salt = salt // 加密默认密码 hashedPassword, err := hashPassword(defaultPassword, salt) if err != nil { return fmt.Errorf("密码加密失败: %v", err) } employee.Password = hashedPassword _, err = o.Update(employee, "Password", "Salt") return err } // ChangeEmployeePassword 修改员工密码 func ChangeEmployeePassword(employeeId int, oldPassword, newPassword string) error { o := orm.NewOrm() employee := &models.Employee{Id: employeeId} if err := o.Read(employee); err != nil { return fmt.Errorf("员工不存在: %v", err) } // 验证旧密码 if !verifyEmployeePassword(oldPassword, employee.Salt, employee.Password) { return errors.New("旧密码不正确") } // 加密新密码 hashedPassword, err := hashPassword(newPassword, employee.Salt) if err != nil { return fmt.Errorf("密码加密失败: %v", err) } employee.Password = hashedPassword _, err = o.Update(employee, "Password") return err } // ValidateEmployee 验证员工登录信息(使用工号作为登录账号) func ValidateEmployee(employeeNo, password string, tenantId int) (*models.Employee, error) { o := orm.NewOrm() // 1. 根据工号和租户ID查询员工(排除已删除的) var employee models.Employee err := o.QueryTable("yz_tenant_employees"). Filter("employee_no", employeeNo). Filter("tenant_id", tenantId). Filter("delete_time__isnull", true). Filter("status", 1). // 只允许在职员工登录 One(&employee) if err == orm.ErrNoRows { return nil, errors.New("员工不存在或已离职") } if err != nil { return nil, fmt.Errorf("查询员工失败: %v", err) } // 2. 检查密码和盐是否存在 if employee.Password == "" || employee.Salt == "" { return nil, errors.New("员工密码未设置,请联系管理员") } // 3. 验证密码 if verifyEmployeePassword(password, employee.Salt, employee.Password) { return &employee, nil } return nil, errors.New("密码不正确") } // DeleteEmployee 软删除员工 func DeleteEmployee(id int) error { o := orm.NewOrm() employee := &models.Employee{Id: id} if err := o.Read(employee); err != nil { return err } now := time.Now() employee.DeleteTime = &now _, err := o.Update(employee, "delete_time") return err } // IsEmployee 检查指定的ID是否是员工(用于判断登录类型) func IsEmployee(id int) bool { o := orm.NewOrm() employee := &models.Employee{Id: id} err := o.Read(employee) if err != nil { return false } // 检查是否已删除 if employee.DeleteTime != nil { return false } return true }