package models import ( "crypto/rand" "encoding/base64" "errors" "fmt" "time" "github.com/beego/beego/v2/client/orm" "golang.org/x/crypto/scrypt" ) // Employee 员工模型 type Employee struct { Id int `orm:"auto" json:"id"` TenantId int `orm:"column(tenant_id);default(0)" json:"tenant_id"` EmployeeNo string `orm:"column(employee_no);size(50)" json:"employee_no"` Name string `orm:"size(50)" json:"name"` Phone string `orm:"size(20);null" json:"phone"` Email string `orm:"size(100);null" json:"email"` DepartmentId int `orm:"column(department_id);null;default(0)" json:"department_id"` PositionId int `orm:"column(position_id);null;default(0)" json:"position_id"` BankName string `orm:"column(bank_name);size(100);null" json:"bank_name"` BankAccount string `orm:"column(bank_account);size(50);null" json:"bank_account"` Password string `orm:"size(255);null" json:"-"` // 不返回给前端 Salt string `orm:"size(100);null" json:"-"` // 不返回给前端 LastLoginTime *time.Time `orm:"column(last_login_time);null;type(datetime)" json:"last_login_time,omitempty"` LastLoginIp string `orm:"column(last_login_ip);null;size(50)" json:"last_login_ip,omitempty"` Status int8 `orm:"column(status);default(1)" json:"status"` // 1-在职,0-离职 CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"` UpdateTime time.Time `orm:"column(update_time);type(datetime);auto_now" json:"update_time"` DeleteTime *time.Time `orm:"column(delete_time);null;type(datetime)" json:"delete_time,omitempty"` } // TableName 设置表名 func (e *Employee) TableName() string { return "yz_tenant_employees" } func init() { orm.RegisterModel(new(Employee)) } // GetTenantEmployees 获取租户下的所有员工 func GetTenantEmployees(tenantId int) ([]*Employee, error) { o := orm.NewOrm() var employees []*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) (*Employee, error) { o := orm.NewOrm() employee := &Employee{Id: id} err := o.Read(employee) if err != nil { return nil, err } // 检查是否已删除 if employee.DeleteTime != nil { return nil, orm.ErrNoRows } return employee, nil } // generateSalt 生成随机盐值 func generateEmployeeSalt() (string, error) { salt := make([]byte, 16) _, err := rand.Read(salt) if err != nil { return "", err } return base64.URLEncoding.EncodeToString(salt), nil } // hashEmployeePassword 使用scrypt算法对密码进行加密 func hashEmployeePassword(password, salt string) (string, error) { saltBytes, err := base64.URLEncoding.DecodeString(salt) if err != nil { return "", err } const ( N = 16384 r = 8 p = 1 ) hashBytes, err := scrypt.Key([]byte(password), saltBytes, N, r, p, 32) if err != nil { return "", err } return base64.URLEncoding.EncodeToString(hashBytes), nil } // AddEmployee 添加员工(自动设置默认密码) func AddEmployee(employee *Employee, defaultPassword string) (int64, error) { // 生成盐值 salt, err := generateEmployeeSalt() if err != nil { return 0, fmt.Errorf("生成盐值失败: %v", err) } employee.Salt = salt // 加密默认密码 hashedPassword, err := hashEmployeePassword(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 *Employee) error { o := orm.NewOrm() _, err := o.Update(employee, "employee_no", "name", "phone", "email", "department_id", "position_id", "bank_name", "bank_account", "status", "update_time") return err } // ResetEmployeePassword 重置员工密码为默认密码 func ResetEmployeePassword(employeeId int, defaultPassword string) error { o := orm.NewOrm() employee := &Employee{Id: employeeId} if err := o.Read(employee); err != nil { return fmt.Errorf("员工不存在: %v", err) } // 生成新盐值 salt, err := generateEmployeeSalt() if err != nil { return fmt.Errorf("生成盐值失败: %v", err) } employee.Salt = salt // 加密默认密码 hashedPassword, err := hashEmployeePassword(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 := &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 := hashEmployeePassword(newPassword, employee.Salt) if err != nil { return fmt.Errorf("密码加密失败: %v", err) } employee.Password = hashedPassword _, err = o.Update(employee, "Password") return err } // verifyEmployeePassword 验证密码是否正确 func verifyEmployeePassword(password, salt, storedHash string) bool { hash, err := hashEmployeePassword(password, salt) if err != nil { return false } return hash == storedHash } // ValidateEmployee 验证员工登录信息(使用工号作为登录账号) func ValidateEmployee(employeeNo, password string, tenantId int) (*Employee, error) { o := orm.NewOrm() // 1. 根据工号和租户ID查询员工(排除已删除的) var employee 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 := &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 } // GetAllEmployees 获取所有员工(排除已删除的) func GetAllEmployees() ([]*Employee, error) { o := orm.NewOrm() var employees []*Employee _, err := o.QueryTable("yz_tenant_employees"). Filter("delete_time__isnull", true). OrderBy("-create_time"). All(&employees) return employees, err }