scheduled_v2.go 10.3 KB
package service

import (
	"fmt"
	"strconv"
	"time"

	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/infrastructure/dao"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/log"
)

// 定时下发周期评估任务
func TaskSendSummaryEvaluationV2() error {
	nowTime := time.Now()
	defer func() {
		str := fmt.Sprintf("下发周期评估耗时%.2f s", time.Since(nowTime).Seconds())
		log.Logger.Info(str)
	}()
	var newPublisher summaryEvaluationPublisher
	for {
		projectList, err := getPrepareSummaryEvaluation()
		if err != nil {
			return err
		}
		if len(projectList) == 0 {
			break
		}
		newPublisher = summaryEvaluationPublisher{}
		for _, val := range projectList {
			err = newPublisher.sendSummaryEvaluationV2(val)
			return err
		}
	}
	return nil
}

func getPrepareEvaluationCycle() {}
func getPrepareSummaryEvaluation() ([]*domain.EvaluationProject, error) {
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, err
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, err
	}
	defer func() {
		_ = transactionContext.RollbackTransaction()
	}()
	projectRepo := factory.CreateEvaluationProjectRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	})
	// 获取项目数据总数
	_, projectList, err := projectRepo.Find(map[string]interface{}{
		"endTime":      time.Now(),
		"summaryState": domain.ProjectSummaryStateNo,
		"state":        domain.ProjectStateEnable,
		"limit":        200,
	}, "template")
	if err != nil {
		return nil, fmt.Errorf("获取可用的项目数据,%s", err)
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, err
	}
	return projectList, nil
}

// 下发周期综合评估
type summaryEvaluationPublisher struct {
	userCache   map[int64]*domain.User
	departCache map[int]*domain.Department
	cycleCache  map[int64]*domain.EvaluationCycle
}

func (se *summaryEvaluationPublisher) sendSummaryEvaluationV2(projectParam *domain.EvaluationProject) error {
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return err
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return err
	}
	defer func() {
		_ = transactionContext.RollbackTransaction()
	}()
	userRepo := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
	departmentRepo := factory.CreateDepartmentRepository(map[string]interface{}{"transactionContext": transactionContext})
	cycleRepo := factory.CreateEvaluationCycleRepository(map[string]interface{}{"transactionContext": transactionContext})
	evaluationItemRepo := factory.CreateEvaluationItemUsedRepository(map[string]interface{}{"transactionContext": transactionContext})
	_, evaluationItemList, err := evaluationItemRepo.Find(map[string]interface{}{
		"evaluationProjectId": projectParam.Id,
		"nodeType":            int(domain.LinkNodeSelfAssessment),
	})
	if err != nil {
		return err
	}
	if len(evaluationItemList) == 0 {
		return nil
	}
	nodeId := evaluationItemList[0].NodeId
	executor360Map := map[int64]*domain.User{}
	hrbpExist := false
	for _, v := range evaluationItemList {
		nodeId = v.NodeId
		if v.EvaluatorId < 0 {
			hrbpExist = true
		}
		if v.EvaluatorId <= 0 {
			continue
		}
		user360, err := se.getUserData(userRepo, int64(v.EvaluatorId))
		if err != nil {
			return fmt.Errorf("获取360用户%s", err)
		}
		executor360Map[user360.Id] = user360
	}
	//获取周期
	cycleData, err := se.getCycleData(cycleRepo, projectParam.CycleId)
	if err != nil {
		return err
	}
	if cycleData == nil {
		return nil
	}
	if cycleData.TimeEnd == nil {
		return fmt.Errorf("周期%d:%s 结束时间错误", cycleData.Id, cycleData.Name)
	}
	//自评的时间范围
	beginTimeSelf := *cycleData.TimeEnd
	endTimeSelf := dayZeroTime(beginTimeSelf).Add(3*24*time.Hour - time.Second)
	//人资、360评估的时间范围
	beginTime360 := endTimeSelf
	endTime360 := endTimeSelf.Add(2 * 24 * time.Hour)
	//上级评估的是时间范围
	beginTimeSuper := endTime360
	endTimeSuper := endTime360.Add(2 * 24 * time.Hour)
	// 创建周期评估任务
	var newEvaluationList []domain.SummaryEvaluation
	evaluationTemp := domain.SummaryEvaluation{
		Id:                    0,
		CompanyId:             int(projectParam.CompanyId),
		EvaluationProjectId:   int(projectParam.Id),
		EvaluationProjectName: projectParam.Name,
		CycleId:               cycleData.Id,
		CycleName:             cycleData.Name,
		NodeId:                nodeId,
		TargetUser:            domain.StaffDesc{},         //待填充
		TargetDepartment:      []domain.StaffDepartment{}, //待填充
		Executor:              domain.StaffDesc{},
		Types:                 0, //待填充
		Status:                domain.EvaluationUncompleted,
		CheckResult:           domain.EvaluationCheckUncompleted,
		BeginTime:             time.Time{}, //待填充
		EndTime:               time.Time{}, //待填充
		TotalScore:            "",
		CreatedAt:             time.Now(),
		UpdatedAt:             time.Now(),
		DeletedAt:             nil,
	}

	for _, val := range projectParam.Recipients {
		targetUserId, _ := strconv.ParseInt(val, 10, 64)
		if targetUserId == 0 {
			continue
		}
		targetUser, err := se.getUserData(userRepo, targetUserId)
		if err != nil {
			return fmt.Errorf("获取员工数据%s", err)
		}
		if targetUser == nil {
			continue
		}
		targetUserDepartment, err := se.getDepartmentData(departmentRepo, targetUser.DepartmentId)
		if err != nil {
			return fmt.Errorf("获取员工的部门数据%s", err)
		}
		evaluationTemp.TargetDepartment = []domain.StaffDepartment{}
		evaluationTemp.Types = domain.EvaluationSelf
		for _, d := range targetUserDepartment {
			evaluationTemp.TargetDepartment = append(evaluationTemp.TargetDepartment, domain.StaffDepartment{
				DepartmentId:   int(d.Id),
				DepartmentName: d.Name,
			})
		}
		evaluationTemp.TargetUser = domain.StaffDesc{
			UserId:   int(targetUser.Id),
			Account:  targetUser.Account,
			UserName: targetUser.Name,
		}
		//处理自评
		{
			evaluationTemp.Executor = domain.StaffDesc{
				UserId:   int(targetUser.Id),
				Account:  targetUser.Account,
				UserName: targetUser.Name,
			}
			evaluationTemp.BeginTime = beginTimeSelf
			evaluationTemp.EndTime = endTimeSelf
			newEvaluationList = append(newEvaluationList, evaluationTemp)
		}
		//处理360评估
		{
			for _, val2 := range executor360Map {
				evaluationTemp.BeginTime = beginTime360
				evaluationTemp.EndTime = endTime360
				evaluationTemp.Executor = domain.StaffDesc{
					UserId:   int(val2.Id),
					Account:  val2.Account,
					UserName: val2.Name,
				}
				evaluationTemp.Types = domain.Evaluation360
				//确定人资评估
				newEvaluationList = append(newEvaluationList, evaluationTemp)
			}
		}
		//处理人资评估
		{
			if hrbpExist {
				//处理人资评估
				evaluationTemp.BeginTime = beginTime360
				evaluationTemp.EndTime = endTime360
				evaluationTemp.Executor = domain.StaffDesc{}
				evaluationTemp.Types = domain.EvaluationHrbp
				newEvaluationList = append(newEvaluationList, evaluationTemp)
			}
		}
		//处理上级评估
		{
			superUser, _ := se.getUserData(userRepo, targetUser.ParentId)
			if superUser != nil {
				evaluationTemp.Types = domain.EvaluationSuper
				evaluationTemp.Executor = domain.StaffDesc{
					UserId:   int(superUser.Id),
					Account:  superUser.Account,
					UserName: superUser.Name,
				}
				evaluationTemp.BeginTime = beginTimeSuper
				evaluationTemp.EndTime = endTimeSuper
				//确定上级评估
				newEvaluationList = append(newEvaluationList, evaluationTemp)
			}
		}
		//综合考评结果
		{
			evaluationTemp.Types = domain.EvaluationFinish
			evaluationTemp.Executor = domain.StaffDesc{}
			evaluationTemp.BeginTime = endTimeSuper
			evaluationTemp.EndTime = endTimeSuper.Add(2 * 24 * time.Hour)
			newEvaluationList = append(newEvaluationList, evaluationTemp)
		}
	}
	summaryEvaluationRepo := factory.CreateSummaryEvaluationRepository(map[string]interface{}{"transactionContext": transactionContext})
	for i := range newEvaluationList {
		err = summaryEvaluationRepo.Save(&newEvaluationList[i])
		if err != nil {
			return fmt.Errorf("保存周期综合评估%s", err)
		}
	}
	//回填项目的状态
	projectDao := dao.NewEvaluationProjectDao(map[string]interface{}{"transactionContext": transactionContext})
	err = projectDao.UpdateSummaryState(projectParam.Id, domain.ProjectSummaryStateYes)
	if err != nil {
		return fmt.Errorf("保存项目状态%s", err)
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return err
	}
	err = sendSmsEvalation(newEvaluationList)
	return fmt.Errorf("设置短信发送%s", err)
}

// 获取周期设置数据
func (se *summaryEvaluationPublisher) getCycleData(cycleRepo domain.EvaluationCycleRepository, cycleId int64) (*domain.EvaluationCycle, error) {
	var cycleData *domain.EvaluationCycle
	if val, ok := se.cycleCache[cycleId]; ok {
		cycleData = val
	} else {
		_, cycleList, err := cycleRepo.Find(map[string]interface{}{"id": cycleId})
		if err != nil {
			return nil, err
		}
		if len(cycleList) == 0 {
			return nil, nil
		}
		cycleData = cycleList[0]
	}
	return cycleData, nil
}

// 获取用户数据
func (se *summaryEvaluationPublisher) getUserData(userRepo domain.UserRepository, userId int64) (*domain.User, error) {
	if userId == 0 {
		return nil, nil
	}
	var userData *domain.User
	if val, ok := se.userCache[userId]; ok {
		userData = val
	} else {
		_, userList, err := userRepo.Find(map[string]interface{}{"id": userId})
		if err != nil {
			return nil, err
		}
		if len(userList) == 0 {
			return nil, nil
		}
		userData = userList[0]
	}
	return userData, nil
}

// 获取部门数据
func (se *summaryEvaluationPublisher) getDepartmentData(departmentRepo domain.DepartmentRepository, departmentIds []int) ([]*domain.Department, error) {
	departmentList := []*domain.Department{}
	for _, departmentId := range departmentIds {
		if val, ok := se.departCache[departmentId]; ok {
			departmentList = append(departmentList, val)
		} else {
			_, departments, err := departmentRepo.Find(map[string]interface{}{"id": departmentId})
			if err != nil {
				return nil, err
			}
			if len(departmentList) == 0 {
				continue
			}
			departmentList = append(departmentList, departments[0])
		}
	}
	return departmentList, nil
}