yunzer_go/server/models/employee.go

243 lines
7.1 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 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
}