department_service.go 3.8 KB
package department

import (
	"github.com/linmadan/egglib-go/core/application"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/department/adapter"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/department/command"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory"
)

type SDepartmentService struct{}

func NewDepartmentService() *SDepartmentService {
	newService := &SDepartmentService{}
	return newService
}

func (ds *SDepartmentService) ListAndCount(in *command.QueryDepartmentCommand) (interface{}, error) {
	transactionContext, err := factory.ValidateStartTransaction(in)
	if err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	departmentRepository := factory.CreateDepartmentRepository(map[string]interface{}{"transactionContext": transactionContext})
	userRepository := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
	companyRepository := factory.CreateCompanyRepository(map[string]interface{}{"transactionContext": transactionContext})

	departments, err := departmentRepository.FindAll(in.CompanyId)
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}

	adapters := make([]*adapter.DepartmentAdapter, 0)
	mapDep := map[int64]*adapter.DepartmentAdapter{}
	mapDepNum := map[int64]int{}
	// 已经按等级Level升序排序, 1级> 2级> ...
	for i := range departments {

		apt := &adapter.DepartmentAdapter{
			Id:          departments[i].Id,
			Name:        departments[i].Name,
			CompanyId:   departments[i].CompanyId,
			ParentId:    departments[i].ParentId,
			Departments: make([]*adapter.DepartmentAdapter, 0),
		}
		mapDep[apt.Id] = apt

		// 一级节点
		if apt.ParentId == 0 {
			adapters = append(adapters, apt)
		} else {
			// 上级节点若存在,加到上级的子节点
			if parent, ok := mapDep[apt.ParentId]; ok {
				parent.Departments = append(parent.Departments, apt)
			}
		}

		// 所有部门ID
		mapDepNum[apt.Id] = 0
	}

	// 获取公司信息
	company, err := companyRepository.FindOne(map[string]interface{}{"id": in.CompanyId})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}

	// 获取所有用户
	userCount, users, err := userRepository.Find(map[string]interface{}{"companyId": in.CompanyId})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}

	for i := range users {
		v := users[i]
		// 注.如果用户部门下挂到公司下,顶级公司数量暂时使用所有用户数量(userCount)
		for _, depId := range v.DepartmentId {
			if count, ok := mapDepNum[int64(depId)]; ok {
				mapDepNum[int64(depId)] = count + 1 // 部门数量 + 1
			}
		}
	}

	// 计算部门下的用户总数量
	ds.calculateChildTotal(mapDepNum, adapters)

	// 创建顶级部门(公司)
	top := make([]*adapter.DepartmentAdapter, 0)
	top = append(top, &adapter.DepartmentAdapter{
		Id:          0,
		Name:        company.Name,
		CompanyId:   company.Id,
		ParentId:    0,
		Departments: adapters,
		UserTotal:   userCount, // 公司下的所有用户
	})

	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return map[string]interface{}{"list": top}, nil
}

// 计算子部门总量
func (ds *SDepartmentService) calculateChildTotal(mapDepNum map[int64]int, departments []*adapter.DepartmentAdapter) int {
	var total = 0
	for i := range departments {
		// 子部门总数量
		var childTotal = ds.calculateChildTotal(mapDepNum, departments[i].Departments)
		// 当前部门数量
		if count, ok := mapDepNum[departments[i].Id]; ok {
			childTotal += count
		}
		// 更新部门数量
		departments[i].UserTotal = childTotal

		total += childTotal
	}
	return total
}