pg_employee_repository.go 8.5 KB
package repository

import (
	"fmt"
	"github.com/go-pg/pg"
	pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
	"github.com/linmadan/egglib-go/utils/snowflake"
	"gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain"
	"gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/pg/models"
)

type EmployeeRepository struct {
	transactionContext *pgTransaction.TransactionContext
}

func (repository *EmployeeRepository) nextIdentify() (int64, error) {
	IdWorker, err := snowflake.NewIdWorker(2)
	if err != nil {
		return 0, err
	}
	id, err := IdWorker.NextId()
	return id, err
}

func (repository *EmployeeRepository) Save(employee *domain.Employee) (*domain.Employee, error) {
	tx := repository.transactionContext.PgTx
	if employee.Identify() == nil {
		employeeId, err := repository.nextIdentify()
		if err != nil {
			return employee, err
		}
		if _, err := tx.QueryOne(
			pg.Scan(&employee.EmployeeId, &employee.CompanyId, &employee.EmployeeInfo.Uid, &employee.EmployeeInfo.EmployeeName, &employee.EmployeeInfo.EmployeeAccount, &employee.EmployeeInfo.EmployeeAvatarUrl, &employee.EmployeeInfo.IsPrincipal, &employee.SuMoney, &employee.Status, pg.Array(&employee.Permissions)),
			"INSERT INTO employees (id, company_id, uid, employee_name, employee_account, employee_avatar_url, is_principal, su_money, status, permissions) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING id, company_id, uid, employee_name, employee_account, employee_avatar_url, is_principal, su_money, status, permissions",
			employeeId, employee.CompanyId, employee.EmployeeInfo.Uid, employee.EmployeeInfo.EmployeeName, employee.EmployeeInfo.EmployeeAccount, employee.EmployeeInfo.EmployeeAvatarUrl, employee.EmployeeInfo.IsPrincipal, employee.SuMoney, employee.Status, pg.Array(employee.Permissions)); err != nil {
			return employee, err
		}
	} else {
		if _, err := tx.QueryOne(
			pg.Scan(&employee.EmployeeId, &employee.CompanyId, &employee.EmployeeInfo.Uid, &employee.EmployeeInfo.EmployeeName, &employee.EmployeeInfo.EmployeeAccount, &employee.EmployeeInfo.EmployeeAvatarUrl, &employee.EmployeeInfo.IsPrincipal, &employee.SuMoney, &employee.Status, pg.Array(&employee.Permissions)),
			"UPDATE employees SET employee_name=?, employee_account=?, employee_avatar_url=?, is_principal=?, su_money=?, status=?, permissions=? WHERE uid=? RETURNING id, company_id, uid, employee_name, employee_account, employee_avatar_url, is_principal, su_money, status, permissions",
			employee.EmployeeInfo.EmployeeName, employee.EmployeeInfo.EmployeeAccount, &employee.EmployeeInfo.EmployeeAvatarUrl, employee.EmployeeInfo.IsPrincipal, employee.SuMoney, employee.Status, pg.Array(employee.Permissions), employee.EmployeeInfo.Uid); err != nil {
			return employee, err
		}
	}
	return employee, nil
}

func (repository *EmployeeRepository) Remove(employee *domain.Employee) (*domain.Employee, error) {
	tx := repository.transactionContext.PgTx
	employeeModel := new(models.Employee)
	employeeModel.Id = employee.Identify().(int64)
	if _, err := tx.Model(employeeModel).Where("uid = ?", employee.EmployeeInfo.Uid).Delete(); err != nil {
		return employee, err
	}
	return employee, nil
}

func (repository *EmployeeRepository) FindOne(queryOptions map[string]interface{}) (*domain.Employee, error) {
	tx := repository.transactionContext.PgTx
	employeeModel := new(models.Employee)
	query := tx.Model(employeeModel)
	if uid, ok := queryOptions["uid"]; ok {
		query = query.Where("employee.uid = ?", uid)
	}
	if account, ok := queryOptions["account"]; ok {
		query = query.Where("employee.employee_account = ?", account)
	}
	if companyId, ok := queryOptions["companyId"]; ok {
		query = query.Where("employee.company_id = ?", companyId)
	}
	if status, ok := queryOptions["status"]; ok && status.(int) != 0 {
		query = query.Where(`employee.status = ?`, status)   // 筛除已离职员工
	}
	if err := query.First(); err != nil {
		if err.Error() == "pg: no rows in result set" {
			return nil, fmt.Errorf("无效的员工")
		} else {
			return nil, err
		}
	}
	if employeeModel.Id == 0 {
		return nil, nil
	} else {
		return repository.transformPgModelToDomainModel(employeeModel)
	}
}

func (repository *EmployeeRepository) FindByIds(queryOptions map[string]interface{}) (int64, []*domain.Employee, error) {
	tx := repository.transactionContext.PgTx
	var employeeModels []*models.Employee
	employees := make([]*domain.Employee, 0)
	query := tx.Model(&employeeModels)
	if ids, ok := queryOptions["ids"]; ok && len(ids.([]int)) != 0 {
		query = query.Where("employee.uid IN (?)", pg.In(ids.([]int)) )
	}
	if where, ok := queryOptions["where"]; ok && where.(map[string]interface{}) != nil {
		if personNameMatch, ok := where.(map[string]interface{})["personNameMatch"]; ok && (personNameMatch != "") {
			query = query.Where("employee.employee_name LIKE ?", fmt.Sprintf("%%%s%%", personNameMatch.(string)))
		}
		if companyId, ok := where.(map[string]interface{})["companyId"]; ok && companyId.(float64) != 0 {
			query = query.Where("employee.company_id = ?", companyId)
		}
	}
	if status, ok := queryOptions["status"]; ok && status.(int) != 0 {
		query = query.Where(`employee.status = ?`, status)
	}
	if count, err := query.Order("uid DESC").SelectAndCount(); err != nil {
		return 0, employees, err
	} else {
		for _, employeeModel := range employeeModels {
			if employee, err := repository.transformPgModelToDomainModel(employeeModel); err != nil {
				return 0, employees, err
			} else {
				employees = append(employees, employee)
			}
		}
		return int64(count), employees, nil
	}
}

func (repository *EmployeeRepository) Find(queryOptions map[string]interface{}) (int64, []*domain.Employee, error) {
	tx := repository.transactionContext.PgTx
	var employeeModels []*models.Employee
	employees := make([]*domain.Employee, 0)
	query := tx.Model(&employeeModels)
	if companyId, ok := queryOptions["companyId"]; ok {
		query = query.Where("employee.company_id = ?", companyId)
	}
	if employeeNameMatch, ok := queryOptions["employeeNameMatch"]; ok && (employeeNameMatch != "") {
		query = query.Where("employee.employee_name LIKE ?", fmt.Sprintf("%%%s%%", employeeNameMatch.(string)))
	}
	if ids, ok := queryOptions["ids"]; ok && len(ids.([]int)) != 0 {
		query = query.Where("employee.uid IN (?)", pg.In(ids.([]int)) )
	}
	if where, ok := queryOptions["where"]; ok && where.(map[string]interface{}) != nil {
		if personNameMatch, ok := where.(map[string]interface{})["personNameMatch"]; ok && (personNameMatch != "") {
			query = query.Where("employee.employee_name LIKE ?", fmt.Sprintf("%%%s%%", personNameMatch.(string)))
		}
		if companyId, ok := where.(map[string]interface{})["companyId"]; ok && companyId.(float64) != 0 {
			query = query.Where("employee.company_id = ?", companyId)
		}
	}
	if status, ok := queryOptions["status"]; ok && status.(int) != 0 {
		query = query.Where(`employee.status = ?`, status)
	}
	if isPrincipal, ok := queryOptions["isPrincipal"]; ok && isPrincipal.(bool) != false {
		query = query.Where("employee.is_principal = ? ", isPrincipal)
	}
	if offset, ok := queryOptions["offset"]; ok {
		offset := offset.(int)
		if offset > -1 {
			query = query.Offset(offset)
		}
	} else {
		query = query.Offset(0)
	}
	if limit, ok := queryOptions["limit"]; ok {
		limit := limit.(int)
		if limit > -1 {
			query = query.Limit(limit)
		}
	} else {
		query = query.Limit(20)
	}
	if count, err := query.Order("uid DESC").SelectAndCount(); err != nil {
		return 0, employees, err
	} else {
		for _, employeeModel := range employeeModels {
			if employee, err := repository.transformPgModelToDomainModel(employeeModel); err != nil {
				return 0, employees, err
			} else {
				employees = append(employees, employee)
			}
		}
		return int64(count), employees, nil
	}
}

func (repository *EmployeeRepository) transformPgModelToDomainModel(employeeModel *models.Employee) (*domain.Employee, error) {
	return &domain.Employee{
		EmployeeId: employeeModel.Id,
		CompanyId:  employeeModel.CompanyId,
		EmployeeInfo: &domain.EmployeeInfo{
			Uid:               employeeModel.Uid,
			EmployeeName:      employeeModel.EmployeeName,
			EmployeeAccount:   employeeModel.EmployeeAccount,
			EmployeeAvatarUrl: employeeModel.EmployeeAvatarUrl,
			IsPrincipal:       employeeModel.IsPrincipal,
		},
		SuMoney:     employeeModel.SuMoney,
		Status:      employeeModel.Status,
		Permissions: employeeModel.Permissions,
	}, nil
}

func NewEmployeeRepository(transactionContext *pgTransaction.TransactionContext) (*EmployeeRepository, error) {
	if transactionContext == nil {
		return nil, fmt.Errorf("transactionContext参数不能为nil")
	} else {
		return &EmployeeRepository{
			transactionContext: transactionContext,
		}, nil
	}
}