285 lines
7.3 KiB
Go
285 lines
7.3 KiB
Go
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
|
||
}
|
||
|