package service import ( "sort" "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/application/staff_assess/command" "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 (srv StaffAssessServeice) CreateStaffAssessTask(transactionContext application.TransactionContext, param *command.CreateStaffAssessTask) (map[string]interface{}, error) { log.Logger.Debug("CreateStaffAssessTask 获取参数", map[string]interface{}{ "param": param, }) assessTaskRepo := factory.CreateStaffAssessTaskRepository(map[string]interface{}{"transactionContext": transactionContext}) taskBeginTime, err := time.ParseInLocation("2006-01-02 15:04:05", param.BeginTime, time.Local) if err != nil { return nil, application.ThrowError(application.ARG_ERROR, "任务开始时间填写错误,"+param.BeginTime) } taskEndTime, err := time.ParseInLocation("2006-01-02 15:04:05", param.EndTime, time.Local) if err != nil { return nil, application.ThrowError(application.ARG_ERROR, "任务结束时间填写错误,"+param.EndTime) } nowTime := time.Now() assessTaskData := &domain.StaffAssessTask{ Id: 0, CompanyId: param.CompanyId, EvaluationProjectId: param.EvaluationProjectId, EvaluationProjectName: param.EvaluationProjectName, CycleId: param.CycleId, CycleName: param.CycleName, BeginTime: taskBeginTime, EndTime: taskEndTime, StepList: []domain.AssessTaskStep{}, ExecutorId: []int{}, CreatedAt: nowTime, UpdatedAt: nowTime, DeletedAt: nil, BeginDay: taskBeginTime.Local().Format("2006-01-02"), } executorIds := []int{} //提取评估的参与人id executorIdMap := map[int]struct{}{} //过滤重复的用户 //从入参中提取参与人 for _, v := range param.ExecutorId { if _, ok := executorIdMap[v]; ok { continue } executorIdMap[v] = struct{}{} executorIds = append(executorIds, v) } assessTaskData.ExecutorId = executorIds for _, v := range param.StepList { stepBeginTime, err := time.ParseInLocation("2006-01-02 15:04:05", param.BeginTime, time.Local) if err != nil { return nil, application.ThrowError(application.ARG_ERROR, "评估环节开始时间填写错误,"+param.BeginTime) } stepEndTime, err := time.ParseInLocation("2006-01-02 15:04:05", param.EndTime, time.Local) if err != nil { return nil, application.ThrowError(application.ARG_ERROR, "评估环节结束时间填写错误,"+param.EndTime) } step := domain.AssessTaskStep{ SortBy: v.SortBy, LinkNodeId: v.LinkNodeId, LinkNodeName: v.LinkNodeName, LinkNodeType: v.LinkNodeType, BeginTime: stepBeginTime, EndTime: stepEndTime, } assessTaskData.StepList = append(assessTaskData.StepList, step) } //添加员工的节点任务 assessList, err := srv.buildStaffAssess(transactionContext, assessTaskData) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "生成个人评估项"+err.Error()) } //合并项目评估的新旧数据 _, assassessTaskList, err := assessTaskRepo.Find(map[string]interface{}{ "evaluationProjectId": param.EvaluationProjectId, "beginDay": taskBeginTime.Local().Format("2006-01-02"), }) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "查询同日期同项目已存在的评估任务"+err.Error()) } if len(assassessTaskList) > 0 { //旧数据中提取参与人 for _, v := range assassessTaskList[0].ExecutorId { if _, ok := executorIdMap[v]; ok { continue } executorIdMap[v] = struct{}{} executorIds = append(executorIds, v) } assassessTaskList[0].UpdatedAt = time.Now() assassessTaskList[0].ExecutorId = executorIds //更新步骤 assassessTaskList[0].StepList = append(assassessTaskList[0].StepList, assessTaskData.StepList...) for _, val := range assessTaskData.StepList { hasFound := false for _, val2 := range assassessTaskList[0].StepList { if val.LinkNodeType == val2.LinkNodeType { hasFound = true break } } if !hasFound { assassessTaskList[0].StepList = append(assassessTaskList[0].StepList, val) } } assessTaskData = assassessTaskList[0] //排序流程环节 } stepList := domain.SortTaskStep(assessTaskData.StepList) sort.Sort(stepList) //保存 下发的每日评估 _, err = assessTaskRepo.Save(assessTaskData) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "保存评估任务"+err.Error()) } //保存 员工的需要填写的每日评估 assessRepo := factory.CreateStaffAssessRepository(map[string]interface{}{"transactionContext": transactionContext}) //保存 员工的需要填写的每日任务型 指标项 taskRecordRepo := factory.CreateTaskRecordRepository(map[string]interface{}{"transactionContext": transactionContext}) // 保存 员工的需要填写的每日任务型 指标项 taskDao := dao.NewTaskDao(map[string]interface{}{"transactionContext": transactionContext}) for i := range assessList { assessList[i].StaffAssessTaskId = assessTaskData.Id _, err = assessRepo.Save(&assessList[i]) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "保存个人评估项"+err.Error()) } if assessList[i].Types == domain.AssessSelf { //添加待发送的短信通知 notify.AddNotifyStaffAssess(&assessList[i]) } if assessList[i].Types == domain.AssessSelf { //添加 指标任务 taskRecordList, err := srv.buildTaskRecord(&assessList[i]) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "构建个人任务型指标项"+err.Error()) } for _, val2 := range taskRecordList { _, err := taskRecordRepo.Insert(val2) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "保存个人任务型指标项"+err.Error()) } err = taskDao.IncreaseAnomaly([]int{val2.TaskId}, 1) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "保存个人任务型指标项"+err.Error()) } } } } return map[string]interface{}{ "assessTaskId": assessTaskData.Id, }, nil } // 添加节点任务 func (srv StaffAssessServeice) buildStaffAssess(transactionContext application.TransactionContext, param *domain.StaffAssessTask) ([]domain.StaffAssess, error) { selfUserId := []int{} //评估的参与人 userIdMap := map[int]struct{}{} //过滤重复的用户 for _, v := range param.ExecutorId { if _, ok := userIdMap[v]; ok { continue } selfUserId = append(selfUserId, v) } // 获取用户的信息 if len(selfUserId) == 0 { log.Logger.Error("createStaffAssess", map[string]interface{}{ "param": param, }) return nil, application.ThrowError(application.ARG_ERROR, "未填写评估任务的执行人") } userRepo := factory.CreateUserRepository(map[string]interface{}{ "transactionContext": transactionContext, }) //获取员工信息 _, userList, err := userRepo.Find(map[string]interface{}{ "ids": selfUserId, "status": 1, }) if err != nil { return nil, application.ThrowError(application.ARG_ERROR, "获取员工信息"+err.Error()) } departmentRepo := factory.CreateDepartmentRepository(map[string]interface{}{ "transactionContext": transactionContext, }) //获取用户的部门 userDepartmentMap := map[int64][]*domain.Department{} for _, v := range userList { if len(v.DepartmentId) == 0 { continue } _, departmemtList, err := departmentRepo.Find(map[string]interface{}{ "ids": v.DepartmentId, }) if err != nil { return nil, application.ThrowError(application.ARG_ERROR, "获取员工的部门信息"+err.Error()) } userDepartmentMap[v.Id] = departmemtList } assessList := []domain.StaffAssess{} //数据样板 stepSelfTemp := domain.StaffAssess{ Id: 0, CompanyId: param.CompanyId, EvaluationProjectId: param.EvaluationProjectId, EvaluationProjectName: param.EvaluationProjectName, CycleId: param.CycleId, CycleName: param.CycleName, StaffAssessTaskId: param.Id, // TargetUser: domain.StaffDesc{}, // TargetDepartment: nil, // Executor: domain.StaffDesc{}, Types: "", // LinkNodeId: v.LinkNodeId, Status: domain.StaffAssessUncompleted, // BeginTime: time.Time{}, // EndTime: time.Time{}, CreatedAt: param.CreatedAt, UpdatedAt: param.UpdatedAt, DeletedAt: nil, } for _, v := range param.StepList { if v.LinkNodeType == domain.LinkNodeSelfAssessment { //员工自评 stepSelfTemp.BeginTime = v.BeginTime stepSelfTemp.EndTime = v.EndTime stepSelfTemp.LinkNodeId = v.LinkNodeId stepSelfTemp.LinkNodeName = v.LinkNodeName stepSelfTemp.Types = domain.AssessSelf assessListTemp, err := srv.buildStaffAssessSelf(stepSelfTemp, userList, userDepartmentMap) if err != nil { return nil, err } assessList = append(assessList, assessListTemp...) } if v.LinkNodeType == domain.LinkNodeSuperiorAssessment { // 创建上级评估 stepSelfTemp.BeginTime = v.BeginTime stepSelfTemp.EndTime = v.EndTime stepSelfTemp.LinkNodeId = v.LinkNodeId stepSelfTemp.LinkNodeName = v.LinkNodeName stepSelfTemp.Types = domain.AssessSuper assessListTemp2, err := srv.buildStaffAssessSupper(stepSelfTemp, userList, userDepartmentMap) if err != nil { return nil, err } assessList = append(assessList, assessListTemp2...) } } return assessList, nil } // 构建员工自评 func (srv StaffAssessServeice) buildStaffAssessSelf( assessTemp domain.StaffAssess, userList []*domain.User, userDepartmentMap map[int64][]*domain.Department) ([]domain.StaffAssess, error) { transactionContext, err := factory.CreateTransactionContext(nil) if err != nil { return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) } if err := transactionContext.StartTransaction(); err != nil { return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) } defer func() { _ = transactionContext.RollbackTransaction() }() assessRepo := factory.CreateStaffAssessRepository(map[string]interface{}{ "transactionContext": transactionContext, }) beginDay := assessTemp.BeginTime.Local().Format("2006-01-02") _, assessListOld, err := assessRepo.Find(map[string]interface{}{"cycleId": assessTemp.CycleId, "beginDay": beginDay, "types": domain.AssessSelf}) if err != nil { return nil, err } userMapReal := map[int]*domain.User{} for _, val := range userList { userMapReal[int(val.Id)] = val } for _, val := range assessListOld { delete(userMapReal, val.TargetUser.UserId) } assessListNew := []domain.StaffAssess{} for _, usr := range userMapReal { assessTemp.TargetUser = domain.StaffDesc{ UserId: int(usr.Id), Account: usr.Account, UserName: usr.Name, } assessTemp.Executor = domain.StaffDesc{ UserId: int(usr.Id), Account: usr.Account, UserName: usr.Name, } if depList, ok := userDepartmentMap[usr.Id]; ok { for _, dep := range depList { assessTemp.TargetDepartment = append(assessTemp.TargetDepartment, domain.StaffDepartment{ DepartmentId: int(dep.Id), DepartmentName: dep.Name, }) } } assessListNew = append(assessListNew, assessTemp) } if err := transactionContext.CommitTransaction(); err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } return assessListNew, nil } // 构建员工的上级评估 func (srv StaffAssessServeice) buildStaffAssessSupper( assessTemp domain.StaffAssess, userList []*domain.User, userDepartmentMap map[int64][]*domain.Department, ) ([]domain.StaffAssess, error) { transactionContext, err := factory.CreateTransactionContext(nil) if err != nil { return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) } if err := transactionContext.StartTransaction(); err != nil { return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) } defer func() { _ = transactionContext.RollbackTransaction() }() assessRepo := factory.CreateStaffAssessRepository(map[string]interface{}{ "transactionContext": transactionContext, }) beginDay := assessTemp.BeginTime.Local().Format("2006-01-02") _, assessListOld, err := assessRepo.Find(map[string]interface{}{"cycleId": assessTemp.CycleId, "beginDay": beginDay, "types": domain.AssessSuper}) if err != nil { return nil, err } userMapReal := map[int]*domain.User{} for _, val := range userList { userMapReal[int(val.Id)] = val } for _, val := range assessListOld { delete(userMapReal, val.TargetUser.UserId) } var assessListNew []domain.StaffAssess for _, v := range userMapReal { //获取上级 chargeUserList, err := srv.getStaffSuper(transactionContext, *v) if err != nil { return nil, err } if len(chargeUserList) == 0 { continue } for _, v2 := range chargeUserList { assessTemp.TargetUser = domain.StaffDesc{ UserId: int(v.Id), Account: v.Account, UserName: v.Name, } assessTemp.Executor = domain.StaffDesc{ UserId: int(v2.Id), Account: v2.Account, UserName: v2.Name, } targetDepartment := []domain.StaffDepartment{} if departmentList, ok := userDepartmentMap[v.Id]; ok { for _, department := range departmentList { targetDepartment = append(targetDepartment, domain.StaffDepartment{ DepartmentId: int(department.Id), DepartmentName: department.Name, }) } } assessTemp.TargetDepartment = targetDepartment assessListNew = append(assessListNew, assessTemp) } } if err := transactionContext.CommitTransaction(); err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } return assessListNew, nil } // 按照评估模板中指标类型,创建里程碑任务 // staffAssess 每日自评评估 func (srv StaffAssessServeice) buildTaskRecord(staffAssess *domain.StaffAssess) ([]*domain.TaskRecord, error) { transactionContext, err := factory.CreateTransactionContext(nil) if err != nil { return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) } if err := transactionContext.StartTransaction(); err != nil { return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) } defer func() { _ = transactionContext.RollbackTransaction() }() projectRepo := factory.CreateEvaluationProjectRepository(map[string]interface{}{ "transactionContext": transactionContext, }) itemUsedRepo := factory.CreateEvaluationItemUsedRepository(map[string]interface{}{ "transactionContext": transactionContext, }) taskRepo := factory.CreateTaskRepository(map[string]interface{}{ "transactionContext": transactionContext, }) taskStageRepo := factory.CreateTaskStageRepository(map[string]interface{}{ "transactionContext": transactionContext, }) projectData, err := projectRepo.FindOne(map[string]interface{}{"id": staffAssess.EvaluationProjectId}) if err != nil { return nil, application.ThrowError(application.ARG_ERROR, "获取项目EvaluationProject信息"+err.Error()) } // projectData.PrincipalId userIdstr := strconv.Itoa(staffAssess.Executor.UserId) if projectData.PrincipalId != userIdstr { return nil, nil } // 获取指标为任务类型的评估项 _, evaluationItemList, err := itemUsedRepo.Find(map[string]interface{}{ "indicatorType": domain.IndicatorTypeTask, "evaluationProjectId": projectData.Id, }) if err != nil { return nil, application.ThrowError(application.ARG_ERROR, "获取评估项EvaluationItemUsed信息"+err.Error()) } if len(evaluationItemList) == 0 { return nil, nil } taskRecordList := []*domain.TaskRecord{} for _, val := range evaluationItemList { _, taskList, err := taskRepo.Find(map[string]interface{}{ "name": val.Name, "leaderId": projectData.PrincipalId, }) if err != nil { return nil, application.ThrowError(application.ARG_ERROR, "获取评估项指标任务task信息"+err.Error()) } if len(taskList) == 0 { continue } //获取里程碑数据 _, taskStageList, err := taskStageRepo.Find(map[string]interface{}{ "taskId": taskList[0].Id, }) if err != nil { return nil, application.ThrowError(application.ARG_ERROR, "获取评估项指标任务里程碑TaskStage信息"+err.Error()) } newTaskRecord := domain.TaskRecord{ Id: 0, CompanyId: staffAssess.CompanyId, StaffAssessId: staffAssess.Id, TaskId: taskList[0].Id, TaskCategory: val.Category, TaskName: taskList[0].Name, TaskAlias: taskList[0].Alias, TaskLeader: taskList[0].Leader, AssistLevel: 0, AssistContent: "", TaskStages: []domain.TaskStage{}, TaskStageCheck: domain.TaskStage{}, } sort.Slice(taskStageList, func(i, j int) bool { return taskStageList[i].SortBy < taskStageList[j].SortBy }) for i2, val2 := range taskStageList { newTaskRecord.TaskStages = append(newTaskRecord.TaskStages, *taskStageList[i2]) if newTaskRecord.TaskStageCheck.Id == 0 { //按顺序第一个未完成的里程碑 if val2.RealCompletedAt <= 0 { newTaskRecord.TaskStageCheck = *taskStageList[i2] } } } taskRecordList = append(taskRecordList, &newTaskRecord) } if err := transactionContext.CommitTransaction(); err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } return taskRecordList, nil }