package service import ( "fmt" "strconv" "strings" "github.com/linmadan/egglib-go/core/application" "github.com/linmadan/egglib-go/utils/tool_funs" "github.com/xuri/excelize/v2" "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory" "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/staff_assess/adapter" "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/staff_assess/command" "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/staff_assess/query" "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain" "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/infrastructure/dao" ) // 调试用,手动调用CreateStaffAssessTask func (srv StaffAssessServeice) InvokCreateStaffAssessTask(param *command.CreateStaffAssessTask) (map[string]interface{}, 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() // }() // data, err := srv.CreateStaffAssessTask(transactionContext, param) // if err != nil { // return nil, err // } // if err := transactionContext.CommitTransaction(); err != nil { // return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) // } return nil, nil } // 员工绩效-项目管理-查询总览 func (srv StaffAssessServeice) QuerySummary(in *query.SummaryCommand) (map[string]interface{}, error) { transactionContext, err := factory.ValidateStartTransaction(in) if err != nil { return nil, err } defer func() { transactionContext.RollbackTransaction() }() hrbp, err := srv.getHRBP(transactionContext, in.CompanyId, in.OperatorId) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } assessDao := dao.NewStaffAssessDao(map[string]interface{}{"transactionContext": transactionContext}) data, err := assessDao.SummaryAssess(in.CompanyId, in.OperatorId, in.CycleId, in.BeginDay, hrbp) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取用户的角色信息列表"+err.Error()) } self := adapter.SummaryBlock{Name: "填写反馈自评"} invite := adapter.SummaryBlock{Name: "360°邀请"} inviteAssess := adapter.SummaryBlock{Name: "360°评估"} supper := adapter.SummaryBlock{Name: "上级评估"} inviteTargetIdMap := map[string]int{} // 过滤相同的目标用户ID for i := range data { d := data[i] d.EndTime = d.EndTime.Local() // 输出本地时间 switch d.Types { case domain.AssessSelf: self.Total++ if d.Status == domain.StaffAssessCompleted { self.Completed++ } if self.EndTime == nil { self.EndTime = &d.EndTime } invite.Total++ // 发起360邀请的人数 = 自评人数 if invite.EndTime == nil { invite.EndTime = &d.EndTime } case domain.AssessSuper: supper.Total++ if d.Status == domain.StaffAssessCompleted { supper.Completed++ } if supper.EndTime == nil { supper.EndTime = &d.EndTime } case domain.AssessInviteDiffSuper, domain.AssessInviteSameSuper: inviteAssess.Total++ if d.Status == domain.StaffAssessCompleted { inviteAssess.Completed++ } if inviteAssess.EndTime == nil { inviteAssess.EndTime = &d.EndTime } inviteTargetIdMap[d.TargetUserId] = 0 // 360评估类型都是被人邀请的评估,过滤相同的目标用户后,就是完成邀请的数量 } } invite.Completed = len(inviteTargetIdMap) if err := transactionContext.CommitTransaction(); err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } return map[string]interface{}{"list": []adapter.SummaryBlock{self, invite, inviteAssess, supper}}, nil } func (srv StaffAssessServeice) QueryMemberSummary(in *query.MemberSummaryListCommand) (map[string]interface{}, error) { transactionContext, err := factory.ValidateStartTransaction(in) if err != nil { return nil, err } defer func() { transactionContext.RollbackTransaction() }() hrbp, err := srv.getHRBP(transactionContext, in.CompanyId, in.OperatorId) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } assessDao := dao.NewStaffAssessDao(map[string]interface{}{"transactionContext": transactionContext}) userRepository := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext}) departmentRepository := factory.CreateDepartmentRepository(map[string]interface{}{"transactionContext": transactionContext}) positionRepository := factory.CreatePositionRepository(map[string]interface{}{"transactionContext": transactionContext}) total, list, err := assessDao.MemberSummaryList(in.UserName, in.CompanyId, in.OperatorId, in.CycleId, hrbp, in.PageNumber, in.PageSize) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } userMap := map[int]*domain.User{} departmentMap := map[int]*domain.Department{} positionMap := map[int]*domain.Position{} userIds := make([]int, 0) for i := range list { id, _ := strconv.Atoi(list[i].TargetUserId) userIds = append(userIds, id) } if len(userIds) > 0 { _, users, err := userRepository.Find(map[string]interface{}{"ids": userIds}) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } for i := range users { user := users[i] userMap[int(user.Id)] = user for i2 := range user.DepartmentId { departmentMap[user.DepartmentId[i2]] = nil } for i2 := range user.PositionId { positionMap[user.PositionId[i2]] = nil } } departmentIds := make([]int, 0) positionIds := make([]int, 0) for k := range departmentMap { departmentIds = append(departmentIds, k) } for k := range positionMap { positionIds = append(positionIds, k) } if len(departmentIds) > 0 { _, departments, err := departmentRepository.Find(map[string]interface{}{"ids": departmentIds}) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } for i := range departments { departmentMap[int(departments[i].Id)] = departments[i] } } if len(positionIds) > 0 { _, positions, err := positionRepository.Find(map[string]interface{}{"ids": positionIds}) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } for i := range positions { positionMap[int(positions[i].Id)] = positions[i] } } } adapters := make([]adapter.MemberSummaryAdapter, 0) for i := range list { it := list[i] id, _ := strconv.Atoi(it.TargetUserId) out := adapter.MemberSummaryAdapter{MemberSummaryAssess: it} if v := userMap[id]; v != nil { out.DepartmentNames = make([]string, 0) out.PositionNames = make([]string, 0) for i := range v.DepartmentId { if v := departmentMap[v.DepartmentId[i]]; v != nil { out.DepartmentNames = append(out.DepartmentNames, v.Name) } } for i := range v.PositionId { if v := positionMap[v.PositionId[i]]; v != nil { out.PositionNames = append(out.PositionNames, v.Name) } } } adapters = append(adapters, out) } if err := transactionContext.CommitTransaction(); err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } return tool_funs.SimpleWrapGridMap(int64(total), adapters), nil } func (srv StaffAssessServeice) QueryMemberPerformanceIndicator(in *query.MemberPerformanceIndicatorCommand) (map[string]interface{}, error) { transactionContext, err := factory.ValidateStartTransaction(in) if err != nil { return nil, err } defer func() { transactionContext.RollbackTransaction() }() var projectItemUsed = map[int][]*domain.EvaluationItemUsed{} // 项目ID-> 评估内容项 var userProjectMap = map[int][]*dao.IndicatorUserProject{} // 用户ID-> 用户评估的项目(用户在周期内可能有多个项目模板,激活状态只能是1个) var projectIds = make([]int, 0) var userIds = make([]string, 0) if len(in.UserIds) > 0 { userIds = in.UserIds // 赋值 staffAssessRepository := factory.CreateStaffAssessRepository(map[string]interface{}{"transactionContext": transactionContext}) _, assessList, err := staffAssessRepository.Find(map[string]interface{}{ "cycleId": in.CycleId, "targetUserIds": in.UserIds, "types": domain.AssessSelf, }) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } projectIdsMap := map[int]int{} for i := range assessList { it := assessList[i] projectIdsMap[it.EvaluationProjectId] = it.EvaluationProjectId // 用户存在多个项目模板 array, ok := userProjectMap[it.TargetUser.UserId] if !ok { array = make([]*dao.IndicatorUserProject, 0) } userProjectMap[it.TargetUser.UserId] = append(array, &dao.IndicatorUserProject{ AssessId: it.Id, EvaluationProjectId: it.EvaluationProjectId, TargetUserId: it.TargetUser.UserId, TargetUserName: it.TargetUser.UserName, }) } for k, _ := range projectIdsMap { projectIds = append(projectIds, k) } } else { hrbp, err := srv.getHRBP(transactionContext, in.CompanyId, in.OperatorId) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } assessDao := dao.NewStaffAssessDao(map[string]interface{}{"transactionContext": transactionContext}) list, err := assessDao.MemberAllProjectId( in.CompanyId, in.UserName, in.OperatorId, in.CycleId, hrbp) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } projectIdsMap := map[int]int{} for i := range list { it := list[i] projectIdsMap[it.EvaluationProjectId] = it.EvaluationProjectId // 用户存在多个项目模板 array, ok := userProjectMap[it.TargetUserId] if !ok { array = make([]*dao.IndicatorUserProject, 0) } userProjectMap[it.TargetUserId] = append(array, &it) } for k := range userProjectMap { userIds = append(userIds, strconv.Itoa(k)) } for k, _ := range projectIdsMap { projectIds = append(projectIds, k) } } // 项目ID->查询所有评估项 if len(projectIds) > 0 { itemUsedRepository := factory.CreateEvaluationItemUsedRepository(map[string]interface{}{"transactionContext": transactionContext}) _, itemList, err := itemUsedRepository.Find(map[string]interface{}{"evaluationProjectIds": projectIds, "nodeType": domain.LinkNodeSelfAssessment}) if err != nil { return nil, err } for i := range itemList { it := itemList[i] array, ok := projectItemUsed[it.EvaluationProjectId] if !ok { array = make([]*domain.EvaluationItemUsed, 0) } projectItemUsed[it.EvaluationProjectId] = append(array, it) } } if err := transactionContext.CommitTransaction(); err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } adapterList := make([]*adapter.PerformanceIndicatorAdapter, 0) categoryMap := map[string]int{} // 内容分类 categoryNameMap := map[string]int{} // 内容名称 for i := range userIds { userId := userIds[i] userIdInt, err := strconv.Atoi(userId) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } iupArray, ok := userProjectMap[userIdInt] if !ok { continue } var pia = &adapter.PerformanceIndicatorAdapter{ TargetUserId: userId, TargetUserName: iupArray[0].TargetUserName, PIContents: make([]adapter.PIContent, 0), } adapterList = append(adapterList, pia) for _, assess := range iupArray { items, ok := projectItemUsed[assess.EvaluationProjectId] if !ok { continue } for _, item := range items { if len(item.Category) == 0 { continue } onlyKey1 := userId + item.Category if _, ok := categoryMap[onlyKey1]; !ok { categoryMap[onlyKey1] = 0 // 不存在分类时,创建分类内容 pia.PIContents = append(pia.PIContents, adapter.PIContent{ Category: item.Category, Names: make([]string, 0), }) } // 内容名称有值合并到数组 if len(item.Name) > 0 { onlyKey2 := userId + item.Category + item.Name if _, ok := categoryNameMap[onlyKey2]; !ok { categoryNameMap[onlyKey2] = 0 for index := range pia.PIContents { piContent := &pia.PIContents[index] if piContent.Category == item.Category { piContent.Names = append(piContent.Names, item.Name) break } } } } } } } /* // 旧版(如果未填写自评会出现数据评估项丢失的BUG) hrbp, err := srv.getHRBP(transactionContext, in.CompanyId, in.OperatorId) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } assessDao := dao.NewStaffAssessDao(map[string]interface{}{"transactionContext": transactionContext}) list, err := assessDao.MemberPerformanceIndicator( in.UserName, in.CompanyId, in.OperatorId, in.CycleId, hrbp, string(domain.AssessSelf), in.UserIds) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } // (全部周期数据)筛选出第一个周期的数据,减少后续数据遍历 dupleMap := map[string]string{} dupleList := make([]dao.PerformanceIndicatorAssess, 0) for i := range list { it := list[i] if v, ok := dupleMap[it.TargetUserId]; ok { if v == it.BeginDay { dupleList = append(dupleList, it) } } else { // 有内容分类,才算正常数据,反之不显示 if len(it.ContentCategory) > 0 { dupleMap[it.TargetUserId] = it.BeginDay dupleList = append(dupleList, it) } } } piaMap := map[string]*adapter.PerformanceIndicatorAdapter{} categoryMap := map[string]int{} // 内容分类 //categoryNameMap := map[string]int{} // 内容分类下的名称 adapterList := make([]*adapter.PerformanceIndicatorAdapter, 0) for i := range dupleList { it := dupleList[i] var pia *adapter.PerformanceIndicatorAdapter if v, ok := piaMap[it.TargetUserId]; ok { pia = v } else { pia = &adapter.PerformanceIndicatorAdapter{ TargetUserId: it.TargetUserId, TargetUserName: it.TargetUserName, PIContents: make([]adapter.PIContent, 0), } piaMap[it.TargetUserId] = pia adapterList = append(adapterList, pia) } // 分类名称有值才能合并分类数组 if len(it.ContentCategory) > 0 { onlyKey1 := it.TargetUserId + it.ContentCategory if _, ok := categoryMap[onlyKey1]; !ok { categoryMap[onlyKey1] = 0 // 不存在分类时,创建分类内容 pia.PIContents = append(pia.PIContents, adapter.PIContent{ Category: it.ContentCategory, Names: make([]string, 0), }) } // 内容名称有值合并到数组 if len(it.ContentName) > 0 { // 周期筛选过的,不再需要唯一值验证判断,直接添加到对应的分类下 for index := range pia.PIContents { piContent := &pia.PIContents[index] if piContent.Category == it.ContentCategory { piContent.Names = append(piContent.Names, it.ContentName) break } } //onlyKey2 := it.TargetUserId + it.ContentCategory + it.ContentName //if _, ok := categoryNameMap[onlyKey2]; !ok { // categoryNameMap[onlyKey2] = 0 // // for index := range pia.PIContents { // piContent := pia.PIContents[index] // if piContent.Category == it.ContentCategory { // piContent.Names = append(piContent.Names, it.ContentName) // break // } // } //} } } } */ //if err := transactionContext.CommitTransaction(); err != nil { // return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) //} return tool_funs.SimpleWrapGridMap(int64(len(adapterList)), adapterList), nil } func (srv StaffAssessServeice) ExportPerformanceIndicator(in *query.ExportPerformanceIndicatorCommand) (*excelize.File, error) { transactionContext, err := factory.ValidateStartTransaction(in) if err != nil { return nil, err } defer func() { transactionContext.RollbackTransaction() }() hrbp, err := srv.getHRBP(transactionContext, in.CompanyId, in.OperatorId) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } // 用户ID userIds := make([]string, 0) selectedMap := map[string]*query.ExportSelected{} for i := range in.Selected { userIds = append(userIds, in.Selected[i].UserId) selectedMap[in.Selected[i].UserId] = &in.Selected[i] } assessDao := dao.NewStaffAssessDao(map[string]interface{}{"transactionContext": transactionContext}) list, err := assessDao.ExportPerformanceIndicator( in.CompanyId, in.OperatorId, in.CycleId, in.BeginDays, hrbp, string(domain.AssessSelf), userIds) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } // 过滤当前选中的分类和指标 conditionMap := map[string]dao.ExportPerformanceIndicator{} conditionList := make([]dao.ExportPerformanceIndicator, 0) for i := range list { it := list[i] if v, ok := selectedMap[it.TargetUserId]; ok { //v.UserName = it.TargetUserName if v.Category == it.ContentCategory && v.Name == it.ContentName { conditionList = append(conditionList, it) conditionMap[it.TargetUserId+it.BeginDay] = it } } } // 获取的所有的日期行 rowDayMap := map[string]int{} rowDayList := make([]string, 0) for i := range conditionList { it := conditionList[i] if _, ok := rowDayMap[it.BeginDay]; !ok { rowDayMap[it.BeginDay] = 0 rowDayList = append(rowDayList, it.BeginDay) } } sheetName := "个人绩效指标" f := excelize.NewFile() f.SetSheetName("Sheet1", sheetName) f.SetCellStr(sheetName, "A1", in.Title) f.SetRowHeight(sheetName, 1, 40) // 设置第1行高度 styleId1, _ := f.NewStyle(&excelize.Style{ Font: &excelize.Font{ Bold: true, Size: 20, Color: "#000000", }, Alignment: &excelize.Alignment{ Horizontal: "center", Vertical: "center", }, }) f.SetCellStyle(sheetName, "A1", "A1", styleId1) f.MergeCell(sheetName, "A1", "P1") // 合并第一行 f.SetCellStr(sheetName, "A2", "注:红色部分为林董标识:") f.SetRowHeight(sheetName, 2, 22) // 设置第2行高度 f.MergeCell(sheetName, "A2", "P2") // 合并第二行 styleId2, _ := f.NewStyle(&excelize.Style{ Font: &excelize.Font{ Size: 14, Color: "#FF0000", }, }) f.SetCellStyle(sheetName, "A2", "A2", styleId2) // 内容居中自动换行样式 styleId100, _ := f.NewStyle(&excelize.Style{ Alignment: &excelize.Alignment{ Horizontal: "center", Vertical: "center", WrapText: true, }, }) f.SetCellStr(sheetName, "A3", "日期") for i := range rowDayList { var rowIndex = 4 + (i * 3) axisStart := fmt.Sprintf("A%d", rowIndex) axisEnd := fmt.Sprintf("A%d", rowIndex+2) f.SetCellStr(sheetName, axisStart, rowDayList[i]) // 设置日期 f.MergeCell(sheetName, axisStart, axisEnd) // 合并三行 f.SetCellStyle(sheetName, axisStart, axisEnd, styleId100) } var columnIndex = 'B' for i := range in.Selected { axis := fmt.Sprintf("%v3", string(columnIndex)) f.SetCellStr(sheetName, axis, in.Selected[i].UserName) // 设置名称 columnIndex += 1 } // 填写反馈内容 for i := range rowDayList { var columnIndex = 'B' // 从B4开始填充数据内容 var rowIndex = 4 + (i * 3) for j := range in.Selected { axisStart := fmt.Sprintf("%v%v", string(columnIndex), rowIndex) axisEnd := fmt.Sprintf("%v%v", string(columnIndex), rowIndex+2) key := in.Selected[j].UserId + rowDayList[i] // key = 用户ID+日期 if v, ok := conditionMap[key]; ok { var builder strings.Builder for _, r := range v.Remark { builder.WriteString(r.RemarkText) } f.SetCellStr(sheetName, axisStart, builder.String()) // 设置反馈内容 } f.MergeCell(sheetName, axisStart, axisEnd) // 合并三行 f.SetCellStyle(sheetName, axisStart, axisEnd, styleId100) columnIndex += 1 } } if err := transactionContext.CommitTransaction(); err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } return f, nil }