scheduled_send_evaluation.go 12.3 KB
package service

import (
	"fmt"
	"strconv"
	"time"

	"github.com/linmadan/egglib-go/core/application"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/notify"
	"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)
	}()
	for {
		cycleList, err := getPrepareEvaluationCycle()
		if err != nil {
			return err
		}
		if len(cycleList) == 0 {
			break
		}
		err = sendSummaryEvaluationByCycle(cycleList[0])
		if err != nil {
			return err
		}
	}
	return nil
}

func dayEndTime(t time.Time) time.Time {
	y, m, d := t.Local().Date()
	t2 := time.Date(y, m, d, 23, 59, 59, 0, time.Local)
	return t2
}

// 获取周期
func getPrepareEvaluationCycle() ([]*domain.EvaluationCycle, 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()
	}()
	cycleRepo := factory.CreateEvaluationCycleRepository(map[string]interface{}{"transactionContext": transactionContext})
	cycleList, err := cycleRepo.FindCycleEnd(1)
	if err != nil {
		return nil, fmt.Errorf("获取可用的周期数据,%s", err)
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, err
	}
	return cycleList, nil
}

// 按周期下发 综合评估任务
func sendSummaryEvaluationByCycle(cycleParam *domain.EvaluationCycle) error {
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return err
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return err
	}
	defer func() {
		_ = transactionContext.RollbackTransaction()
	}()

	projectRepo := factory.CreateEvaluationProjectRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	})
	// 获取项目数据总数
	_, projectList, err := projectRepo.Find(map[string]interface{}{
		"cycleId":      cycleParam.Id,
		"summaryState": domain.ProjectSummaryStateNo,
		"state":        domain.ProjectStateEnable,
		"limit":        500,
	}, "template")
	if err != nil {
		return fmt.Errorf("获取可用的项目数据,%s", err)
	}
	permissionData, err := getPermission(cycleParam.CompanyId)
	if err != nil {
		return fmt.Errorf("获取公司的周期评估设置项,%s", err)
	}
	var newEvaluationList []domain.SummaryEvaluation
	newPublisher := summaryEvaluationPublisher{}
	for _, val := range projectList {
		evaluationList, err := newPublisher.sendSummaryEvaluationV2(transactionContext, val, cycleParam, *permissionData)
		if err != nil {
			return fmt.Errorf("按项目下发综合评估任务数据,%s", err)
		}
		newEvaluationList = append(newEvaluationList, evaluationList...)
	}
	// 回填周期的状态
	cycleDao := dao.NewEvaluationCycleDao(map[string]interface{}{"transactionContext": transactionContext})
	err = cycleDao.UpdateSummaryState(cycleParam.Id, domain.ProjectSummaryStateYes)
	if err != nil {
		return fmt.Errorf("保存项目周期状态%s", err)
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return err
	}
	err = sendSmsEvalation(newEvaluationList)
	if err != nil {
		return fmt.Errorf("设置短信消息%s", err)
	}
	return nil
}

// // 添加待发送的短信通知
func sendSmsEvalation(param []domain.SummaryEvaluation) error {
	for i := range param {
		if param[i].Types == domain.EvaluationSelf {
			notify.AddNotifySummaryEvaluation(&param[i])
		}
	}
	return nil
}

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

func (se *summaryEvaluationPublisher) sendSummaryEvaluationV2(
	transactionContext application.TransactionContext,
	projectParam *domain.EvaluationProject,
	cycleData *domain.EvaluationCycle,
	permissioData domain.Permission,
) ([]domain.SummaryEvaluation, error) {
	userRepo := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
	departmentRepo := factory.CreateDepartmentRepository(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 nil, err
	}
	if len(evaluationItemList) == 0 {
		return nil, 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 nil, fmt.Errorf("获取360用户%s", err)
		}
		executor360Map[user360.Id] = user360
	}
	if cycleData.TimeEnd == nil {
		return nil, fmt.Errorf("周期%d:%s 结束时间错误", cycleData.Id, cycleData.Name)
	}

	//自评的时间范围
	beginTimeSelf := *cycleData.TimeEnd //
	beginDay := dayEndTime(beginTimeSelf)
	//修改 周期结束时间那天的第二天开始计算
	endTimeSelf := beginDay.Add(time.Duration(permissioData.CycleDeadline.AssessmentSelf.Hour) * time.Hour).
		Add(time.Duration(permissioData.CycleDeadline.AssessmentSelf.Minute) * time.Minute)
	//人资、360评估的时间范围
	beginTime360 := endTimeSelf
	endTime360 := beginDay.Add(time.Duration(permissioData.CycleDeadline.AssessmentAll.Hour) * time.Hour).
		Add(time.Duration(permissioData.CycleDeadline.AssessmentAll.Minute) * time.Minute)
	//人资评估的时间范围
	beginTimeHr := endTimeSelf
	endTimeHr := beginDay.Add(time.Duration(permissioData.CycleDeadline.AssessmentHr.Hour) * time.Hour).
		Add(time.Duration(permissioData.CycleDeadline.AssessmentHr.Minute) * time.Minute)

	//上级评估的是时间范围
	beginTimeSuper := endTimeHr
	endTimeSuper := beginDay.Add(time.Duration(permissioData.CycleDeadline.AssessmentSuperior.Hour) * time.Hour).
		Add(time.Duration(permissioData.CycleDeadline.AssessmentSuperior.Minute) * time.Minute)

	//考核结果的时间范围
	beginTimeFinish := endTimeSuper
	endTimeFinish := beginDay.Add(time.Duration(permissioData.CycleDeadline.ViewMyPerf.Hour) * time.Hour).
		Add(time.Duration(permissioData.CycleDeadline.ViewMyPerf.Minute) * time.Minute)
	// 创建周期评估任务
	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,
		Version:               domain.EvaluationV2,
	}

	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 nil, fmt.Errorf("获取员工数据%s", err)
		}
		if targetUser == nil {
			continue
		}
		targetUserDepartment, err := se.getDepartmentData(departmentRepo, targetUser.DepartmentId)
		if err != nil {
			return nil, fmt.Errorf("获取员工的部门数据%s", err)
		}
		evaluationTemp.TargetDepartment = []domain.StaffDepartment{}

		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.Types = domain.EvaluationSelf
			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 = beginTimeHr
				evaluationTemp.EndTime = endTimeHr
				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 = beginTimeFinish
			evaluationTemp.EndTime = endTimeFinish
			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 nil, fmt.Errorf("保存周期综合评估%s", err)
		}
	}
	//回填项目的状态
	projectDao := dao.NewEvaluationProjectDao(map[string]interface{}{"transactionContext": transactionContext})
	err = projectDao.UpdateSummaryState(projectParam.Id, domain.ProjectSummaryStateYes)
	if err != nil {
		return nil, fmt.Errorf("保存项目状态%s", err)
	}
	return newEvaluationList, 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
}