package service import ( "fmt" "strconv" "strings" "github.com/linmadan/egglib-go/core/application" "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/query" "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) ListAllAssessCycle(companyid int) (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() }() assessDao := dao.NewStaffAssessDao(map[string]interface{}{ "transactionContext": transactionContext, }) cycleList, err := assessDao.AllAssessCycleList(companyid) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取周期列表"+err.Error()) } if err := transactionContext.CommitTransaction(); err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } result := map[string]interface{}{ "list": cycleList, } return result, nil } // 获取周期内的考核日期 func (srv StaffAssessServeice) ListAllAssessCycleDay(param *query.ListAssessCycleDay) (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() }() assessDao := dao.NewStaffAssessDao(map[string]interface{}{ "transactionContext": transactionContext, }) cycleDayList, err := assessDao.AllAssessCycleDayList(param.CompanyId, param.CycleId) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取周期列表"+err.Error()) } if err := transactionContext.CommitTransaction(); err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } result := map[string]interface{}{ "list": cycleDayList, } return result, nil } // 根据周期id和日期获取 员工填写评估内容 // 有过滤查看权限 func (srv StaffAssessServeice) ListUserAssessContentCycleDay(param *query.ListAssessContentCycleDay) (*adapter.ListUserAssessContent, 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() }() hrbp, err := srv.getHRBP(transactionContext, param.CompanyId, param.OperaterId) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } //roleRepo := factory.CreateRoleRepository(map[string]interface{}{ // "transactionContext": transactionContext, //}) //roleUserRepo := factory.CreateRoleUserRepository(map[string]interface{}{ // "transactionContext": transactionContext, //}) //_, roleList, err := roleRepo.Find(map[string]interface{}{ // "type": domain.RoleTypeSystem, // "companyId": param.CompanyId, //}) //if err != nil { // return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取角色信息列表"+err.Error()) //} //_, userRoleList, err := roleUserRepo.Find(map[string]interface{}{ // "companyId": param.CompanyId, // "userId": param.OperaterId, //}) //if err != nil { // return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取用户的角色信息列表"+err.Error()) //} //hrbp := -1 //for _, v := range userRoleList { // for _, v2 := range roleList { // if v.RoleId == v2.Id { // hrbp = 1 // break // } // } // if hrbp == 1 { // break // } //} assessDao := dao.NewStaffAssessDao(map[string]interface{}{ "transactionContext": transactionContext, }) limit := param.PageSize offset := (param.PageNumber - 1) * limit cnt, err := assessDao.CountUserAssess(dao.SearchConditin1{ CompanyId: param.CompanyId, CycleId: param.CycleId, BeginDay: param.BeginDay, TargetUserName: param.TargetUserName, Limit: 5000, Offset: 0, OperaterId: param.OperaterId, Hrbp: hrbp, }) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "统计总数"+err.Error()) } contentList, err := assessDao.SearchUserAssessContent(dao.SearchConditin1{ CompanyId: param.CompanyId, CycleId: param.CycleId, BeginDay: param.BeginDay, TargetUserName: param.TargetUserName, Limit: limit, Offset: offset, OperaterId: param.OperaterId, Hrbp: hrbp, }) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取数据列表"+err.Error()) } if err := transactionContext.CommitTransaction(); err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } log.Logger.Debug(fmt.Sprintf("获取到的数据列表%d", len(contentList))) //可变的表格列 changeableHeader := []adapter.ListTableHeader{ {Key: "targetUserName", Name: "姓名"}, //固定列 } //过滤重复的列 headerMap := map[string]string{} // 获取已经填报的内容 changeableRows := map[string]map[string]interface{}{} tableSort := []string{} //确定列表行数据的顺序 for i, v := range contentList { if _, ok := changeableRows[v.TargetUserId]; !ok { changeableRows[v.TargetUserId] = map[string]interface{}{} tableSort = append(tableSort, v.TargetUserId) } changeableRows[v.TargetUserId]["targetUserName"] = v.TargetUserName changeableRows[v.TargetUserId]["targetUserId"] = v.TargetUserId changeableRows[v.TargetUserId]["assessId"] = v.AssessId changeableRows[v.TargetUserId]["cycleId"] = v.CycleId changeableRows[v.TargetUserId]["beginDay"] = v.BeginDay if v.ContentId > 0 { name := fmt.Sprintf("%s-%s", v.Category, v.ContentName) key := fmt.Sprintf("k%d", i) if _, ok := headerMap[name]; !ok { changeableHeader = append(changeableHeader, adapter.ListTableHeader{ Key: key, Name: name, }) headerMap[name] = key } key = headerMap[name] changeableRows[v.TargetUserId][key] = v.Value } } list := []map[string]interface{}{} for _, v := range tableSort { for _, v2 := range changeableHeader { if _, ok := changeableRows[v][v2.Key]; ok { continue } changeableRows[v][v2.Key] = "" } list = append(list, changeableRows[v]) } result := adapter.ListUserAssessContent{ TableHeader: changeableHeader, Total: cnt, List: list, } return &result, nil } func (srv StaffAssessServeice) ExportUserAssess(param *query.ListAssessContentCycleDay) (*excelize.File, 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() }() hrbp, err := srv.getHRBP(transactionContext, param.CompanyId, param.OperaterId) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } assessDao := dao.NewStaffAssessDao(map[string]interface{}{ "transactionContext": transactionContext, }) contentList, err := assessDao.ExportDataUserAssess(dao.SearchConditin1{ CompanyId: param.CompanyId, CycleId: param.CycleId, BeginDay: param.BeginDay, TargetUserName: param.TargetUserName, TargetUserId: param.TargetUserId, Limit: 5000, Offset: 0, OperaterId: param.OperaterId, Hrbp: hrbp, }) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取数据列表"+err.Error()) } if err := transactionContext.CommitTransaction(); err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } //处理查询到的数据 //汇总 Excel表格的表头描述 level1 := []string{} //分类 level3 := map[string][]string{} // key=分类+得分项类型 val=名称 level4 := map[string]string{} //key=分类+名称 val=评估标准 for _, v := range contentList { if v.ContentId == 0 { continue } level1Item := "" for _, v1 := range level1 { if v.Category == v1 { level1Item = v1 } } if len(level1Item) == 0 { level1 = append(level1, v.Category) } if v.Weight == 0 { level3Key := v.Category + "-加分项" if _, ok := level3[level3Key]; !ok { level3[level3Key] = []string{} } level3Item := "" for _, v3 := range level3[level3Key] { if v3 == v.ContentName { level3Item = v.ContentName } } if len(level3Item) == 0 { level3[level3Key] = append(level3[level3Key], v.ContentName) } } if v.Weight > 0 { level3Key := v.Category + "-得分项" if _, ok := level3[level3Key]; !ok { level3[level3Key] = []string{} } level3Item := "" for _, v3 := range level3[level3Key] { if v3 == v.ContentName { level3Item = v.ContentName } } if len(level3Item) == 0 { level3[level3Key] = append(level3[level3Key], v.ContentName) } } level4Key := v.Category + "+" + v.ContentName if _, ok := level4[level4Key]; !ok { level4[level4Key] = v.PromptText } } //汇总表头,按列 headerList := []excelTableHeader{ { Level1: "日期", Level2: "", Level3: "", Level4: "评估标准", }, { Level1: "姓名", Level2: "", Level3: "", Level4: "", }, } for _, v := range level1 { item := excelTableHeader{ Level1: v, } level3Key := v + "-加分项" if _, ok := level3[level3Key]; ok { for _, v2 := range level3[level3Key] { item.Level2 = "加分项" item.Level3 = v2 level4Key := v + "+" + v2 item.Level4 = level4[level4Key] headerList = append(headerList, item) } } level3Key = v + "-得分项" if _, ok := level3[level3Key]; ok { for _, v2 := range level3[level3Key] { item.Level2 = "得分项" item.Level3 = v2 level4Key := v + "+" + v2 item.Level4 = level4[level4Key] headerList = append(headerList, item) } } } //数据形式 进行 行列转换 tableRows := map[string]map[string]string{} tableRowSort := []string{} for _, v := range contentList { if _, ok := tableRows[v.TargetUserId]; !ok { tableRows[v.TargetUserId] = map[string]string{} tableRowSort = append(tableRowSort, v.TargetUserId) } tableRows[v.TargetUserId]["TargetUserName"] = v.TargetUserName tableRows[v.TargetUserId]["BeginDay"] = v.BeginDay if v.ContentId > 0 { value := []string{v.Value} for _, v2 := range v.Remark { value = append(value, v2.RemarkText) } key := v.Category + "+" + v.ContentName tableRows[v.TargetUserId][key] = strings.Join(value, "\n") } } //将数据写入xlsx xlsxFile := excelize.NewFile() sheetIndex := xlsxFile.GetActiveSheetIndex() sheetName := xlsxFile.GetSheetName(sheetIndex) //写入第一行 xlsxFile.SetCellStr(sheetName, "A1", "每日绩效汇总") //写入二到五行 for k, v := range headerList { colName, _ := excelize.ColumnNumberToName(k + 1) xlsxFile.SetCellStr(sheetName, colName+"2", v.Level1) xlsxFile.SetCellStr(sheetName, colName+"3", v.Level2) xlsxFile.SetCellStr(sheetName, colName+"4", v.Level3) xlsxFile.SetCellStr(sheetName, colName+"5", v.Level4) } //从第六行开始写入用户填写的评估数据 for k, v := range tableRowSort { rowNum := strconv.Itoa(k + 6) row := tableRows[v] for k2, v2 := range headerList { if k2 == 0 { xlsxFile.SetCellStr(sheetName, "A"+rowNum, row["BeginDay"]) continue } if k2 == 1 { xlsxFile.SetCellStr(sheetName, "B"+rowNum, row["TargetUserName"]) continue } colName, _ := excelize.ColumnNumberToName(k2 + 1) key := v2.Level1 + "+" + v2.Level3 if mVal, ok := row[key]; ok { xlsxFile.SetCellStr(sheetName, colName+rowNum, mVal) } } } //TODO 调整样式 xlsxFile.MergeCell(sheetName, "A2", "A4") xlsxFile.MergeCell(sheetName, "B2", "B4") xlsxFile.MergeCell(sheetName, "B5", "B5") //设置行高 for i := range tableRowSort { xlsxFile.SetRowHeight(sheetName, i+5, 50) } //设置列宽 for i := range headerList { colName, _ := excelize.ColumnNumberToName(i + 1) if i == 0 { xlsxFile.SetColWidth(sheetName, colName, colName, 30) } } return xlsxFile, nil } //员工绩效-项目管理-矩阵分析 func (srv StaffAssessServeice) AnalysisData(param *query.ListAssessContentCycleDay) (*adapter.AssessAnalysisResp, 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() }() hrbp, err := srv.getHRBP(transactionContext, param.CompanyId, param.OperaterId) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } //roleRepo := factory.CreateRoleRepository(map[string]interface{}{ // "transactionContext": transactionContext, //}) //roleUserRepo := factory.CreateRoleUserRepository(map[string]interface{}{ // "transactionContext": transactionContext, //}) //_, roleList, err := roleRepo.Find(map[string]interface{}{ // "type": domain.RoleTypeSystem, // "companyId": param.CompanyId, //}) //if err != nil { // return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取角色信息列表"+err.Error()) //} //_, userRoleList, err := roleUserRepo.Find(map[string]interface{}{ // "companyId": param.CompanyId, // "userId": param.OperaterId, //}) //if err != nil { // return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取用户的角色信息列表"+err.Error()) //} //hrbp := -1 //for _, v := range userRoleList { // for _, v2 := range roleList { // if v.RoleId == v2.Id { // hrbp = 1 // break // } // } // if hrbp == 1 { // break // } //} assessDao := dao.NewStaffAssessDao(map[string]interface{}{ "transactionContext": transactionContext, }) contentList, err := assessDao.SearchUserAssessContent(dao.SearchConditin1{ CompanyId: param.CompanyId, CycleId: param.CycleId, BeginDay: param.BeginDay, TargetUserName: param.TargetUserName, Limit: 9000, Offset: 0, OperaterId: param.OperaterId, Hrbp: hrbp, }) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取数据列表"+err.Error()) } if err := transactionContext.CommitTransaction(); err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } log.Logger.Debug(fmt.Sprintf("获取到的数据列表%d", len(contentList))) var groupList []string //评估指标项列表 var uncompleteItems []string //未完成填写评估的员工 completeUser := map[string]struct{}{} //完成填写评估的员工 completeItems := map[string]adapter.AssessComplete{} //已完成填写的评估内容 for _, v := range contentList { if v.ContentId == 0 { uncompleteItems = append(uncompleteItems, v.TargetUserName) continue } completeUser[v.TargetUserId] = struct{}{} key := v.Category + "-" + v.ContentName if _, ok := completeItems[key]; !ok { groupList = append(groupList, key) //初始化数据结构 completeItems[key] = adapter.AssessComplete{ GroupKey: key, Items: []string{}, UserItem: map[string][]string{}, PercentItem: map[string]string{}, CountItem: map[string]int{}, } } completeItem := completeItems[key] if v.Rule.Type == domain.EvaluationTypeRating { //提取出所有可选的评级 for _, v2 := range v.Rule.Rating.Levels { if _, ok := completeItem.CountItem[v2.Code]; !ok { completeItem.CountItem[v2.Code] = 0 completeItem.PercentItem[v2.Code] = "" completeItem.UserItem[v2.Code] = []string{} completeItem.Items = append(completeItem.Items, v2.Code) } } } if v.Rule.Type == domain.EvaluationTypeScore { for _, v2 := range v.Rule.Score.Levels { //提取出所有可选的评级 if _, ok := completeItem.CountItem[v2.Code]; !ok { completeItem.CountItem[v2.Code] = 0 completeItem.PercentItem[v2.Code] = "" completeItem.UserItem[v2.Code] = []string{} completeItem.Items = append(completeItem.Items, v2.Code) } } } //根据填写的评级填充数据 completeItem.TotalUser = completeItem.TotalUser + 1 completeItem.CountItem[v.LevelValue] = completeItem.CountItem[v.LevelValue] + 1 percentSum := float64(completeItem.CountItem[v.LevelValue]) / float64(completeItem.TotalUser) * 100 completeItem.PercentItem[v.LevelValue] = fmt.Sprintf("%.2f %%", percentSum) completeItem.UserItem[v.LevelValue] = append(completeItem.UserItem[v.LevelValue], v.TargetUserName) completeItems[key] = completeItem } result := adapter.AssessAnalysisResp{ GroupList: groupList, Uncomplete: uncompleteItems, Complete: completeItems, UserCount: map[string]int{ "total": len(uncompleteItems) + len(completeUser), "uncomplete": len(uncompleteItems), "complete": len(completeUser), }, } return &result, nil } // 员工绩效-综合管理-导出绩效-个人 func (srv StaffAssessServeice) ExportUserAssess2(param *query.SummaryCommand) (*excelize.File, 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() }() hrbp, err := srv.getHRBP(transactionContext, param.CompanyId, param.OperatorId) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } assessDao := dao.NewStaffAssessDao(map[string]interface{}{ "transactionContext": transactionContext, }) // 获取所有的评估项 categoryNameList, err := assessDao.SearchContentCategoryName(param.CompanyId, param.CycleId, param.OperatorId, hrbp) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } //获取员工填写的评估 userAssessList, err := assessDao.ExportDataUserAssess2( param.CompanyId, param.CycleId, param.OperatorId, hrbp, ) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } if err := transactionContext.CommitTransaction(); err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } eData := newExportData() eData.setCategoryNameList(categoryNameList) eData.setData(userAssessList) xlsxFile := excelize.NewFile() //设置默认的第一个sheet sheetIndex := xlsxFile.GetActiveSheetIndex() firstSheetName := xlsxFile.GetSheetName(sheetIndex) cycleName := "" if len(userAssessList) > 0 { cycleName = userAssessList[0].CycleName } //填入excel 文件 for _, v := range eData.userName { // 根据员工名称 添加一个sheet xlsxFile.NewSheet(v) //填写前4行数据 tableHeader, ok := eData.tableHeader[v] if !ok { continue } xlsxFile.SetCellStr(v, "B2", v) //填充第一列数据 xlsxFile.SetCellStr(v, "A2", cycleName) xlsxFile.SetCellStr(v, "A1", tableHeader.Name) xlsxFile.SetCellStr(v, "A5", "权重") xlsxFile.SetCellStr(v, "A6", "评估标准") //日期 dayList := eData.userDayMap[v] for ii, vv := range dayList { if ii == 0 { axis := fmt.Sprintf("A%d", ii+7) xlsxFile.SetCellStr(v, axis, vv) } else { axis := fmt.Sprintf("A%d", 7+3*(ii+1)) xlsxFile.SetCellStr(v, axis, vv) } } for _, v2 := range tableHeader.Child { //第二行 for _, v3 := range v2.Child { //第三行 for i4, v4 := range v3.Child { //按列填充数据 colName, _ := excelize.ColumnNumberToName(i4 + 3) //第3列开始 xlsxFile.SetCellStr(v, colName+"2", v2.Name) //分类 xlsxFile.SetCellStr(v, colName+"3", v3.Name) //加分项 得分项 xlsxFile.SetCellStr(v, colName+"4", v4.Name) // 评估项名称 //权重 填写第5行数据 k23 := eData.data23Key(v, v2.Name, v3.Name, v4.Name) xlsxFile.SetCellStr(v, colName+"5", eData.data3[k23]) //评估标准 填写第6行数据 xlsxFile.SetCellStr(v, colName+"6", eData.data2[k23]) //按日期填充评估的填写的值 for i5, v5 := range dayList { k1 := eData.dataKey(v, v5, v2.Name, v3.Name, v4.Name) if i5 > 0 { axis := fmt.Sprintf("%s%d", colName, 7+3*(i5+1)) //单元格高度按三个单元格合并 xlsxFile.SetCellStr(v, axis, eData.data[k1].String()) } else { axis := fmt.Sprintf("%s%d", colName, i5+7) xlsxFile.SetCellStr(v, axis, eData.data[k1].String()) } } } } } } //删除默认的第一个sheet xlsxFile.DeleteSheet(firstSheetName) return xlsxFile, nil } // 获取所有的评估的指标 func (srv StaffAssessServeice) QueryPerformanceIndicator(param *query.ListAssessContentCycleDay) (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() }() hrbp, err := srv.getHRBP(transactionContext, param.CompanyId, param.OperaterId) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } assessDao := dao.NewStaffAssessDao(map[string]interface{}{ "transactionContext": transactionContext, }) contentItems, err := assessDao.SearchUserAssessContentItem(dao.SearchConditin1{ CompanyId: param.CompanyId, CycleId: param.CycleId, BeginDay: param.BeginDay, OperaterId: param.OperaterId, Hrbp: hrbp, }) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "统计总数"+err.Error()) } if err := transactionContext.CommitTransaction(); err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } headerList := HeaderLevel{} for _, v := range contentItems { child := headerList.addChild(v.Category) child.addChild(v.Name) } result := map[string]interface{}{ "headerList": headerList.Child, } return result, nil }