package service import ( "fmt" "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()) } 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) 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()) } 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.ExportUserAssess2Commad) (*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, param.ExportUserId) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } //获取员工填写的评估 userAssessList, err := assessDao.ExportDataUserAssess2( param.CompanyId, param.CycleId, param.OperatorId, hrbp, param.ExportUserId, ) 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.MergeCell(v, "B2", "B4") //填充第一列数据 xlsxFile.SetCellStr(v, "A1", tableHeader.Name) xlsxFile.SetCellStr(v, "A2", cycleName) xlsxFile.MergeCell(v, "A2", "A4") xlsxFile.SetCellStr(v, "A5", "权重") xlsxFile.MergeCell(v, "A5", "B5") xlsxFile.SetCellStr(v, "A6", "评估标准") xlsxFile.MergeCell(v, "A6", "B6") //日期 dayList := eData.userDayMap[v] for ii, vv := range dayList { //填写在第几行 axisNum := 7 + 3*ii axis := fmt.Sprintf("A%d", axisNum) xlsxFile.SetCellStr(v, axis, vv) axisEnd := fmt.Sprintf("B%d", axisNum+2) xlsxFile.MergeCell(v, axis, axisEnd) //单元格高度按三个单元格合并 } allColNum := 0 //计算总共有多少列 //第一行 for _, v2 := range tableHeader.Child { //第二行 for _, v3 := range v2.Child { //第三行 for _, v4 := range v3.Child { allColNum++ //按列填充数据 colName, _ := excelize.ColumnNumberToName(allColNum + 2) //第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) //填写在第几行 axisNum := 7 + 3*i5 axis := fmt.Sprintf("%s%d", colName, axisNum) if d, ok := eData.data[k1]; ok { xlsxFile.SetCellStr(v, axis, d.String()) } //单元格高度按三个单元格合并 axisEnd := fmt.Sprintf("%s%d", colName, axisNum+2) xlsxFile.MergeCell(v, axis, axisEnd) } } } } // colName, _ := excelize.ColumnNumberToName(allColNum + 2) xlsxFile.MergeCell(v, "A1", fmt.Sprintf("%s1", colName)) } //删除默认的第一个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{ Name: "", Filter: map[string]int{}, Child: []HeaderLevel{}, } for _, v := range contentItems { child := headerList.addChild(v.Category) child.addChild(v.Name) } result := map[string]interface{}{ "headerList": headerList.Child, } return result, nil } // 员工绩效-项目管理-成员列表导出 func (srv *StaffAssessServeice) ExportUserAssess(param *query.ExportAssessContentCycleDay) (*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: "", 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()) } //选择导出的评估项 includeCol := map[string]struct{}{} for _, v := range param.ExportItems { includeCol[v.Category+"+"+v.Name] = struct{}{} } includeBeginDay := map[string]struct{}{} for _, v := range param.BeginDayList { includeBeginDay[v] = struct{}{} } eData := newExportData2() eData.setData(contentList) //将数据写入xlsx xlsxFile := excelize.NewFile() sheetIndex := xlsxFile.GetActiveSheetIndex() sheetName := xlsxFile.GetSheetName(sheetIndex) //写入第一行 xlsxFile.SetCellStr(sheetName, "A1", "每日绩效汇总") xlsxFile.SetCellStr(sheetName, "A2", "日期") xlsxFile.MergeCell(sheetName, "A2", "A4") xlsxFile.SetCellStr(sheetName, "B2", "姓名") xlsxFile.MergeCell(sheetName, "B2", "B4") xlsxFile.SetCellStr(sheetName, "A5", "评估标准") //行数量 rowNum := 0 for _, v := range eData.rowSort.Child { //纵向-索引-第一列-日期 if len(includeBeginDay) > 0 { if _, ok := includeBeginDay[v.Name]; !ok { continue } } for _, v2 := range v.Child { //纵向-索引-第二列-员工id //填充1,2 列 rowNum++ axisNum := fmt.Sprintf("%d", (rowNum-1)*3+6) userName := eData.userIdMap[v2.Name] xlsxFile.SetCellStr(sheetName, "A"+axisNum, v.Name) xlsxFile.SetCellStr(sheetName, "B"+axisNum, userName) axisEnd := fmt.Sprintf("%d", (rowNum-1)*3+6+2) xlsxFile.MergeCell(sheetName, "A"+axisNum, "A"+axisEnd) xlsxFile.MergeCell(sheetName, "B"+axisNum, "B"+axisEnd) } } //列数量 colNum := 0 for _, v := range eData.tableHeader.Child { //横向-评估指标-分类 for _, v2 := range v.Child { //横向-评估指标-加分项、得分项 for _, v3 := range v2.Child { // 横向-评估指标-名称 //检查是否在指定的导出选项中 if len(includeCol) > 0 { if _, ok := includeCol[v.Name+"+"+v3.Name]; !ok { continue } } colNum++ //第几列 colName, _ := excelize.ColumnNumberToName(colNum + 2) //填充 分类 xlsxFile.SetCellStr(sheetName, colName+"2", v.Name) // 填充 加分项、得分项 xlsxFile.SetCellStr(sheetName, colName+"3", v2.Name) // 填充 名称 xlsxFile.SetCellStr(sheetName, colName+"4", v3.Name) if len(v3.Child) > 0 { //填充, 评估标准 xlsxFile.SetCellStr(sheetName, colName+"5", v3.Child[0].Name) } xlsxFile.SetColWidth(sheetName, colName, colName, 30) rowNum = 0 for _, v4 := range eData.rowSort.Child { //纵向-索引-第一列-日期 if len(includeBeginDay) > 0 { if _, ok := includeBeginDay[v4.Name]; !ok { continue } } for _, v5 := range v4.Child { //纵向-索引-第二列-员工id rowNum++ axis := fmt.Sprintf("%s%d", colName, (rowNum-1)*3+6) key := eData.dataKey(v5.Name, v4.Name, v.Name, v3.Name) if d, ok := eData.data[key]; ok { xlsxFile.SetCellStr(sheetName, axis, d.String()) } axisEnd := fmt.Sprintf("%s%d", colName, (rowNum-1)*3+6+2) xlsxFile.MergeCell(sheetName, axis, axisEnd) } } } } } colName, _ := excelize.ColumnNumberToName(colNum + 2) xlsxFile.MergeCell(sheetName, "A1", colName+"1") return xlsxFile, nil }