scheduled.go 9.9 KB
package service

import (
	"fmt"
	"strconv"
	"time"

	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/constant"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/infrastructure/serviceGateway"
	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/log"

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

// sendSummaryEvaluafionTask 根据评估项目设置,确认是否下发评估任务
// project 需要处理的项目
// userList 全体的员工数据 map[id]=>domain.User
// departmetList 全部的部门数据 map[id]=>domain.Department
func sendSummaryEvaluation(project *domain.EvaluationProject,
	userMap map[int64]*domain.User, departmentMap map[int64]*domain.Department) ([]domain.SummaryEvaluation, error) {
	//自评的时间范围
	beginTimeSelf := project.EndTime
	endTimeSelf := dayZeroTime(project.EndTime).Add(4*24*time.Hour - time.Second)
	//人资、360评估的时间范围
	beginTime360 := beginTimeSelf
	endTime360 := endTimeSelf.Add(2 * 24 * time.Hour)
	//上级评估的是时间范围
	beginTimeSuper := endTime360
	endTimeSuper := endTime360.Add(2 * 24 * time.Hour)
	//
	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})

	evaluationItemRepo := factory.CreateEvaluationItemUsedRepository(map[string]interface{}{"transactionContext": transactionContext})

	cycleData, err := cycleRepo.FindOne(map[string]interface{}{"id": project.CycleId})
	if err != nil {
		return nil, err
	}
	//确定 被评估的人
	targetUserId := []int64{}
	for _, v := range project.Recipients {
		id, err := strconv.ParseInt(v, 10, 64)
		if err == nil {
			targetUserId = append(targetUserId, id)
		}
	}
	if len(targetUserId) == 0 {
		return nil, nil
	}
	//被评估的员工
	targetUserMap := map[int64]*domain.User{}

	for _, v := range targetUserId {
		u, ok := userMap[v]
		if ok {
			targetUserMap[v] = u
		}
	}
	//确定360评估的执行人
	_, itemList, err := evaluationItemRepo.Find(map[string]interface{}{"evaluationProjectId": project.Id})
	if err != nil {
		return nil, err
	}
	nodeId := 0
	executor360Map := map[int64]*domain.User{}
	for _, v := range itemList {
		nodeId = v.NodeId
		if v.EvaluatorId <= 0 {
			continue
		}
		if u, ok := userMap[int64(v.EvaluatorId)]; ok {
			executor360Map[u.Id] = u
		}
	}
	//创建周期评估任务
	var newEvaluationList []domain.SummaryEvaluation
	evaluationTemp := domain.SummaryEvaluation{
		Id:                    0,
		CompanyId:             int(project.CompanyId),
		EvaluationProjectId:   int(project.Id),
		EvaluationProjectName: project.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 _, v := range targetUserMap {
		//处理自评
		evaluationTemp.TargetUser = domain.StaffDesc{
			UserId:   int(v.Id),
			Account:  v.Account,
			UserName: v.Name,
		}
		evaluationTemp.Executor = domain.StaffDesc{
			UserId:   int(v.Id),
			Account:  v.Account,
			UserName: v.Name,
		}
		evaluationTemp.BeginTime = beginTimeSelf
		evaluationTemp.EndTime = endTimeSelf
		evaluationTemp.TargetDepartment = []domain.StaffDepartment{}
		evaluationTemp.Types = domain.EvaluationSelf
		for _, departId := range v.DepartmentId {
			depart, ok := departmentMap[int64(departId)]
			if !ok {
				continue
			}
			evaluationTemp.TargetDepartment = append(evaluationTemp.TargetDepartment, domain.StaffDepartment{
				DepartmentId:   int(depart.Id),
				DepartmentName: depart.Name,
			})
		}
		//确定自评
		newEvaluationList = append(newEvaluationList, evaluationTemp)
		//处理人资评估
		evaluationTemp.BeginTime = beginTime360
		evaluationTemp.EndTime = endTime360
		evaluationTemp.Executor = domain.StaffDesc{}
		evaluationTemp.Types = domain.EvaluationHrbp
		//确定人资评估
		newEvaluationList = append(newEvaluationList, evaluationTemp)
		//处理360 评估
		for _, v2 := range executor360Map {
			evaluationTemp.BeginTime = beginTime360
			evaluationTemp.EndTime = endTime360
			evaluationTemp.Executor = domain.StaffDesc{
				UserId:   int(v2.Id),
				Account:  v2.Account,
				UserName: v2.Name,
			}
			evaluationTemp.Types = domain.Evaluation360
			//确定人资评估
			newEvaluationList = append(newEvaluationList, evaluationTemp)
		}

		//处理上级评估
		superUser, ok := userMap[v.ParentId]
		if ok {
			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)
		}
	}
	summaryEvaluationRepo := factory.CreateSummaryEvaluationRepository(map[string]interface{}{"transactionContext": transactionContext})
	for i := range newEvaluationList {
		err = summaryEvaluationRepo.Save(&newEvaluationList[i])
		if err != nil {
			return nil, err
		}
	}
	//回填 项目的状态
	evaluationProjectRepo := factory.CreateEvaluationProjectRepository(map[string]interface{}{"transactionContext": transactionContext})
	project.SummaryState = domain.ProjectSummaryStateYes
	_, err = evaluationProjectRepo.Insert(project)
	if err != nil {
		return nil, err
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, err
	}
	return newEvaluationList, nil
}

func dayZeroTime(t time.Time) time.Time {
	y, m, d := t.UTC().Date()
	t2 := time.Date(y, m, d, 0, 0, 0, 0, time.UTC)
	return t2
}

// 下发周期评估
func TaskSendSummaryEvaluation() 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,
	})

	userRepo := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})

	departmentRepo := factory.CreateDepartmentRepository(map[string]interface{}{"transactionContext": transactionContext})

	_, projectList, err := projectRepo.Find(map[string]interface{}{
		"endTime":      time.Now(),
		"summaryState": domain.ProjectSummaryStateNo,
		"state":        domain.ProjectStateEnable,
	}, "template")
	if err != nil {
		return fmt.Errorf("获取可用的项目数据,%s", err)
	}
	companyIdMap := map[int64]struct{}{}
	for _, v := range projectList {
		companyIdMap[v.CompanyId] = struct{}{}
	}

	var createdEvalationList []domain.SummaryEvaluation

	//获取可执行的项目
	for companyId := range companyIdMap {
		//获取员工数据,部门数据
		_, userList, err := userRepo.Find(map[string]interface{}{"companyId": companyId})
		if err != nil {
			log.Logger.Error("TaskSendSummaryEvaluation 获取员工数据:" + err.Error())
			continue
		}
		_, departmentList, err := departmentRepo.Find(map[string]interface{}{"companyId": companyId})
		if err != nil {
			log.Logger.Error("TaskSendSummaryEvaluation 获取部门数据:" + err.Error())
			continue
		}
		//转map
		userMap := map[int64]*domain.User{}
		for _, v := range userList {
			userMap[v.Id] = v
		}
		departmentMap := map[int64]*domain.Department{}
		for _, v := range departmentList {
			departmentMap[v.Id] = v
		}
		for _, v := range projectList {
			if v.CompanyId != companyId {
				continue
			}
			evalationList, err := sendSummaryEvaluation(v, userMap, departmentMap)
			if err != nil {
				log.Logger.Error("TaskSendSummaryEvaluation 下发评估任务:" + err.Error())
				continue
			}
			createdEvalationList = append(createdEvalationList, evalationList...)
		}
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return err
	}
	//发送短信通知
	err = sendSmsEvalation(createdEvalationList)
	return err
}

// 发送短信通知
func sendSmsEvalation(param []domain.SummaryEvaluation) error {
	if constant.Env != "prd" {
		return nil
	}
	//处理短信发送
	//过滤去重 处理需要发送改执行人的消息 执行人id=>domain.LogSms
	noticeMap := map[string]*domain.LogSms{}
	for _, v := range param {
		phone := v.Executor.Account
		name := v.Executor.UserName
		if _, ok := noticeMap[phone]; ok {
			continue
		}
		smsMessage := domain.LogSms{}
		smsMessage.SummaryEvaluationMessage(phone, name)
		noticeMap[phone] = &smsMessage
	}

	sms := serviceGateway.SmsService{}
	for _, v := range noticeMap {
		err := sms.SendNoticeSms(v.Phone, v.TemplateId, v.Value)
		if err != nil {
			v.Result = err.Error()
		}
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return err
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return err
	}
	defer func() {
		_ = transactionContext.RollbackTransaction()
	}()
	logSmsRepo := factory.CreateLogSmsRepository(map[string]interface{}{"transactionContext": transactionContext})
	for _, v := range noticeMap {
		err = logSmsRepo.Insert(v)
		if err != nil {
			log.Logger.Error("TaskSendSummaryEvaluation 发送短信通知:" + err.Error())
		}
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return err
	}
	return nil
}