yunzer_go/server/services/employee.go
2025-11-06 15:56:29 +08:00

285 lines
7.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}