正在显示
5 个修改的文件
包含
323 行增加
和
1 行删除
@@ -18,3 +18,19 @@ type MemberPerformanceIndicatorCommand struct { | @@ -18,3 +18,19 @@ type MemberPerformanceIndicatorCommand struct { | ||
18 | CompanyId int `cname:"公司ID" json:"companyId"` | 18 | CompanyId int `cname:"公司ID" json:"companyId"` |
19 | OperatorId int `cname:"操作人ID" json:"operatorId"` | 19 | OperatorId int `cname:"操作人ID" json:"operatorId"` |
20 | } | 20 | } |
21 | + | ||
22 | +// ExportPerformanceIndicatorCommand 成员绩效导出-指标-导出表格 | ||
23 | +type ExportPerformanceIndicatorCommand struct { | ||
24 | + CycleId int `cname:"周期ID" json:"cycleId,string"` | ||
25 | + Title string `cname:"标题" json:"title"` | ||
26 | + Selected []ExportSelected `cname:"选中用户" json:"selected"` | ||
27 | + CompanyId int `cname:"公司ID" json:"companyId"` | ||
28 | + OperatorId int `cname:"操作人ID" json:"operatorId"` | ||
29 | +} | ||
30 | + | ||
31 | +type ExportSelected struct { | ||
32 | + UserId string `cname:"用户ID" json:"userId"` | ||
33 | + UserName string `cname:"用户名称" json:"userName"` | ||
34 | + Category string `cname:"评估内容分类" json:"category"` | ||
35 | + Name string `cname:"评估内容名称" json:"name"` | ||
36 | +} |
1 | package service | 1 | package service |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | + "fmt" | ||
4 | "github.com/linmadan/egglib-go/core/application" | 5 | "github.com/linmadan/egglib-go/core/application" |
5 | "github.com/linmadan/egglib-go/utils/tool_funs" | 6 | "github.com/linmadan/egglib-go/utils/tool_funs" |
7 | + "github.com/xuri/excelize/v2" | ||
6 | "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory" | 8 | "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory" |
7 | "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/staff_assess/adapter" | 9 | "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/staff_assess/adapter" |
8 | "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/staff_assess/command" | 10 | "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/staff_assess/command" |
@@ -10,6 +12,7 @@ import ( | @@ -10,6 +12,7 @@ import ( | ||
10 | "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain" | 12 | "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain" |
11 | "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/infrastructure/dao" | 13 | "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/infrastructure/dao" |
12 | "strconv" | 14 | "strconv" |
15 | + "strings" | ||
13 | ) | 16 | ) |
14 | 17 | ||
15 | // 调试用,手动调用CreateStaffAssessTask | 18 | // 调试用,手动调用CreateStaffAssessTask |
@@ -326,3 +329,150 @@ func (srv StaffAssessServeice) QueryMemberPerformanceIndicator(in *query.MemberP | @@ -326,3 +329,150 @@ func (srv StaffAssessServeice) QueryMemberPerformanceIndicator(in *query.MemberP | ||
326 | 329 | ||
327 | return tool_funs.SimpleWrapGridMap(int64(len(adapterList)), adapterList), nil | 330 | return tool_funs.SimpleWrapGridMap(int64(len(adapterList)), adapterList), nil |
328 | } | 331 | } |
332 | + | ||
333 | +func (srv StaffAssessServeice) ExportPerformanceIndicator(in *query.ExportPerformanceIndicatorCommand) (*excelize.File, error) { | ||
334 | + transactionContext, err := factory.ValidateStartTransaction(in) | ||
335 | + if err != nil { | ||
336 | + return nil, err | ||
337 | + } | ||
338 | + defer func() { | ||
339 | + transactionContext.RollbackTransaction() | ||
340 | + }() | ||
341 | + | ||
342 | + hrbp, err := srv.getHRBP(transactionContext, in.CompanyId, in.OperatorId) | ||
343 | + if err != nil { | ||
344 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
345 | + } | ||
346 | + | ||
347 | + // 用户ID | ||
348 | + userIds := make([]string, 0) | ||
349 | + selectedMap := map[string]*query.ExportSelected{} | ||
350 | + for i := range in.Selected { | ||
351 | + userIds = append(userIds, in.Selected[i].UserId) | ||
352 | + selectedMap[in.Selected[i].UserId] = &in.Selected[i] | ||
353 | + } | ||
354 | + assessDao := dao.NewStaffAssessDao(map[string]interface{}{"transactionContext": transactionContext}) | ||
355 | + list, err := assessDao.ExportPerformanceIndicator( | ||
356 | + in.CompanyId, | ||
357 | + in.OperatorId, | ||
358 | + in.CycleId, | ||
359 | + hrbp, | ||
360 | + string(domain.AssessSelf), | ||
361 | + userIds) | ||
362 | + if err != nil { | ||
363 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
364 | + } | ||
365 | + | ||
366 | + // 过滤当前选中的分类和指标 | ||
367 | + conditionMap := map[string]dao.ExportPerformanceIndicator{} | ||
368 | + conditionList := make([]dao.ExportPerformanceIndicator, 0) | ||
369 | + for i := range list { | ||
370 | + it := list[i] | ||
371 | + if v, ok := selectedMap[it.TargetUserId]; ok { | ||
372 | + v.UserName = it.TargetUserName | ||
373 | + | ||
374 | + if v.Category == it.ContentCategory && v.Name == it.ContentName { | ||
375 | + conditionList = append(conditionList, it) | ||
376 | + conditionMap[it.TargetUserId+it.BeginDay] = it | ||
377 | + } | ||
378 | + } | ||
379 | + } | ||
380 | + | ||
381 | + // 获取的所有的日期行 | ||
382 | + rowDayMap := map[string]int{} | ||
383 | + rowDayList := make([]string, 0) | ||
384 | + for i := range conditionList { | ||
385 | + it := conditionList[i] | ||
386 | + if _, ok := rowDayMap[it.BeginDay]; !ok { | ||
387 | + rowDayMap[it.BeginDay] = 0 | ||
388 | + rowDayList = append(rowDayList, it.BeginDay) | ||
389 | + } | ||
390 | + } | ||
391 | + | ||
392 | + sheetName := "个人绩效指标" | ||
393 | + f := excelize.NewFile() | ||
394 | + f.SetSheetName("Sheet1", sheetName) | ||
395 | + | ||
396 | + f.SetCellStr(sheetName, "A1", in.Title) | ||
397 | + f.SetRowHeight(sheetName, 1, 40) // 设置第1行高度 | ||
398 | + styleId1, _ := f.NewStyle(&excelize.Style{ | ||
399 | + Font: &excelize.Font{ | ||
400 | + Bold: true, | ||
401 | + Size: 20, | ||
402 | + Color: "#000000", | ||
403 | + }, | ||
404 | + Alignment: &excelize.Alignment{ | ||
405 | + Horizontal: "center", | ||
406 | + Vertical: "center", | ||
407 | + }, | ||
408 | + }) | ||
409 | + f.SetCellStyle(sheetName, "A1", "A1", styleId1) | ||
410 | + f.MergeCell(sheetName, "A1", "P1") // 合并第一行 | ||
411 | + | ||
412 | + f.SetCellStr(sheetName, "A2", "注:红色部分为林董标识:") | ||
413 | + f.SetRowHeight(sheetName, 2, 22) // 设置第2行高度 | ||
414 | + styleId2, _ := f.NewStyle(&excelize.Style{ | ||
415 | + Font: &excelize.Font{ | ||
416 | + Size: 14, | ||
417 | + Color: "#FF0000", | ||
418 | + }, | ||
419 | + }) | ||
420 | + f.SetCellStyle(sheetName, "A2", "A2", styleId2) | ||
421 | + | ||
422 | + // 内容居中自动换行样式 | ||
423 | + styleId100, _ := f.NewStyle(&excelize.Style{ | ||
424 | + Alignment: &excelize.Alignment{ | ||
425 | + Horizontal: "center", | ||
426 | + Vertical: "center", | ||
427 | + WrapText: true, | ||
428 | + }, | ||
429 | + }) | ||
430 | + | ||
431 | + f.SetCellStr(sheetName, "A3", "日期") | ||
432 | + for i := range rowDayList { | ||
433 | + var rowIndex = 4 + (i * 3) | ||
434 | + axisStart := fmt.Sprintf("A%d", rowIndex) | ||
435 | + axisEnd := fmt.Sprintf("A%d", rowIndex+2) | ||
436 | + | ||
437 | + f.SetCellStr(sheetName, axisStart, rowDayList[i]) // 设置日期 | ||
438 | + f.MergeCell(sheetName, axisStart, axisEnd) // 合并三行 | ||
439 | + f.SetCellStyle(sheetName, axisStart, axisEnd, styleId100) | ||
440 | + } | ||
441 | + | ||
442 | + var columnIndex = 'B' | ||
443 | + for i := range in.Selected { | ||
444 | + axis := fmt.Sprintf("%v3", string(columnIndex)) | ||
445 | + f.SetCellStr(sheetName, axis, in.Selected[i].UserName) // 设置名称 | ||
446 | + columnIndex += 1 | ||
447 | + } | ||
448 | + | ||
449 | + // 填写反馈内容 | ||
450 | + for i := range rowDayList { | ||
451 | + var columnIndex = 'B' // 从B4开始填充数据内容 | ||
452 | + var rowIndex = 4 + (i * 3) | ||
453 | + | ||
454 | + for j := range in.Selected { | ||
455 | + axisStart := fmt.Sprintf("%v%v", string(columnIndex), rowIndex) | ||
456 | + axisEnd := fmt.Sprintf("%v%v", string(columnIndex), rowIndex+2) | ||
457 | + | ||
458 | + key := in.Selected[j].UserId + rowDayList[i] // key = 用户ID+日期 | ||
459 | + if v, ok := conditionMap[key]; ok { | ||
460 | + var builder strings.Builder | ||
461 | + for _, r := range v.Remark { | ||
462 | + builder.WriteString(r.RemarkText) | ||
463 | + } | ||
464 | + f.SetCellStr(sheetName, axisStart, builder.String()) // 设置反馈内容 | ||
465 | + } | ||
466 | + f.MergeCell(sheetName, axisStart, axisEnd) // 合并三行 | ||
467 | + f.SetCellStyle(sheetName, axisStart, axisEnd, styleId100) | ||
468 | + | ||
469 | + columnIndex += 1 | ||
470 | + } | ||
471 | + } | ||
472 | + | ||
473 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
474 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
475 | + } | ||
476 | + | ||
477 | + return f, nil | ||
478 | +} |
@@ -795,6 +795,135 @@ func (d *StaffAssessDao) MemberPerformanceIndicator(likeUserName string, company | @@ -795,6 +795,135 @@ func (d *StaffAssessDao) MemberPerformanceIndicator(likeUserName string, company | ||
795 | 795 | ||
796 | } | 796 | } |
797 | 797 | ||
798 | +type ExportPerformanceIndicator struct { | ||
799 | + AssessId int `json:"assessId"` // ID | ||
800 | + TargetUserId string `json:"targetUserId"` // 被评估人的id | ||
801 | + TargetUserName string `json:"targetUserName"` // 被评估人的名称 | ||
802 | + BeginDay string `json:"beginDay"` // 评估的开始日期 | ||
803 | + CycleId int `json:"cycleId"` // 周期ID | ||
804 | + ContentId int `json:"contentId"` // 评估内容ID | ||
805 | + ContentCategory string `json:"contentCategory"` // 评估内容分类 | ||
806 | + ContentName string `json:"contentName"` // 评估内容名称 | ||
807 | + SortBy int `json:"sort_by"` // 评估内容排序 | ||
808 | + Remark []domain.AssessContemtRemark `json:"remark"` // 评估内容填写反馈内容 | ||
809 | +} | ||
810 | + | ||
811 | +func (d *StaffAssessDao) ExportPerformanceIndicator(companyId int, operatorId int, cycleId int, hrbp int, assessType string, userIds []string) ([]ExportPerformanceIndicator, error) { | ||
812 | + sqlString := ` | ||
813 | + set time zone 'PRC'; | ||
814 | + with t_user_department as ( | ||
815 | + select "user".id as user_id ,jsonb_array_elements_text ("user".department_id) as depart_id from "user" | ||
816 | + where "user".company_id= %d and "user".deleted_at isnull | ||
817 | + ), | ||
818 | + t_department as ( | ||
819 | + select department.id::text as depart_id from department where charge_user_ids @>'[%d]' | ||
820 | + and "department".deleted_at isnull | ||
821 | + ), | ||
822 | + -- 部门主管(所有下级用户ID) | ||
823 | + t_user_1 as ( | ||
824 | + select t_user_department.user_id::text from t_user_department | ||
825 | + join t_department on t_user_department.depart_id = t_department.depart_id | ||
826 | + ), | ||
827 | + -- 如果是HRBP | ||
828 | + t_project_1 as( | ||
829 | + select evaluation_project.id as project_id | ||
830 | + from evaluation_project | ||
831 | + where evaluation_project.cycle_id =%d | ||
832 | + and evaluation_project.hr_bp = %d | ||
833 | + and evaluation_project.deleted_at isnull | ||
834 | + ), | ||
835 | + -- 如果的项目管理员 | ||
836 | + t_project_2 as( | ||
837 | + select evaluation_project.id as project_id | ||
838 | + from evaluation_project | ||
839 | + where evaluation_project.cycle_id =%d | ||
840 | + and evaluation_project.pmp =1 | ||
841 | + and evaluation_project.pmp_ids @>'["%d"]' | ||
842 | + and evaluation_project.deleted_at isnull | ||
843 | + ), | ||
844 | + -- 合并数据 | ||
845 | + t_project_3 as ( | ||
846 | + select t_project_2.project_id from t_project_2 | ||
847 | + union | ||
848 | + select t_project_1.project_id from t_project_1 | ||
849 | + ), | ||
850 | + -- 初步过滤数据 | ||
851 | + t_staff_assess_0 as ( | ||
852 | + select | ||
853 | + staff_assess.id as assess_id, | ||
854 | + staff_assess.cycle_id, | ||
855 | + staff_assess.target_user->>'userId' as target_user_id, | ||
856 | + staff_assess.target_user->>'userName' as target_user_name, | ||
857 | + to_char(staff_assess.begin_time,'YYYY-MM-DD') as begin_day, | ||
858 | + staff_assess.evaluation_project_id | ||
859 | + from staff_assess | ||
860 | + join staff_assess_task on staff_assess.staff_assess_task_id = staff_assess_task.id | ||
861 | + and staff_assess_task.deleted_at isnull | ||
862 | + where | ||
863 | + staff_assess.cycle_id = %d | ||
864 | + and staff_assess.types ='%s' | ||
865 | + ), | ||
866 | + -- 根据查看权限过滤合并数据 | ||
867 | + t_staff_assess_1 as ( | ||
868 | + ( select | ||
869 | + t_staff_assess_0.assess_id, | ||
870 | + t_staff_assess_0.target_user_id, | ||
871 | + t_staff_assess_0.target_user_name, | ||
872 | + t_staff_assess_0.begin_day, | ||
873 | + t_staff_assess_0.cycle_id | ||
874 | + from t_staff_assess_0 | ||
875 | + join t_project_3 on t_staff_assess_0.evaluation_project_id = t_project_3.project_id | ||
876 | + ) union ( | ||
877 | + select | ||
878 | + t_staff_assess_0.assess_id, | ||
879 | + t_staff_assess_0.target_user_id, | ||
880 | + t_staff_assess_0.target_user_name, | ||
881 | + t_staff_assess_0.begin_day, | ||
882 | + t_staff_assess_0.cycle_id | ||
883 | + from t_staff_assess_0 | ||
884 | + join t_user_1 on t_staff_assess_0.target_user_id = t_user_1.user_id | ||
885 | + ) | ||
886 | + ) | ||
887 | + ` | ||
888 | + params := []interface{}{companyId, operatorId, cycleId, hrbp, cycleId, operatorId, cycleId, assessType} | ||
889 | + sqlString = fmt.Sprintf(sqlString, params...) | ||
890 | + | ||
891 | + sqlString += ` select | ||
892 | + t_staff_assess_1.target_user_id, | ||
893 | + t_staff_assess_1.target_user_name, | ||
894 | + t_staff_assess_1.begin_day, | ||
895 | + t_staff_assess_1.cycle_id, | ||
896 | + t_staff_assess_1.assess_id, | ||
897 | + staff_assess_content.id as content_id, | ||
898 | + staff_assess_content.name as content_name, | ||
899 | + staff_assess_content.category as content_category, | ||
900 | + staff_assess_content.remark, | ||
901 | + staff_assess_content.sort_by | ||
902 | + from t_staff_assess_1 | ||
903 | + left join staff_assess_content on t_staff_assess_1.assess_id = staff_assess_content.staff_assess_id | ||
904 | + where 1=1 | ||
905 | + -- AND staff_assess_content.id NOTNULL 部分脏数据 | ||
906 | + ` | ||
907 | + condition := make([]interface{}, 0) | ||
908 | + //if len(likeUserName) > 0 { | ||
909 | + // sqlString += ` and t_staff_assess_1.target_user_name like ? ` | ||
910 | + // condition = append(condition, "%"+likeUserName+"%") | ||
911 | + //} | ||
912 | + if len(userIds) > 0 { | ||
913 | + sqlString += ` and t_staff_assess_1.target_user_id in (?) ` | ||
914 | + condition = append(condition, pg.In(userIds)) | ||
915 | + } | ||
916 | + //sqlString += ` order by convert_to(t_staff_assess_1.target_user_name,'GBK'), staff_assess_content.sort_by` | ||
917 | + sqlString += ` order by t_staff_assess_1.begin_day` | ||
918 | + | ||
919 | + tx := d.transactionContext.PgTx | ||
920 | + var result = make([]ExportPerformanceIndicator, 0) | ||
921 | + _, err := tx.Query(&result, sqlString, condition...) | ||
922 | + | ||
923 | + return result, err | ||
924 | + | ||
925 | +} | ||
926 | + | ||
798 | type ExportData1 struct { | 927 | type ExportData1 struct { |
799 | AssessId string | 928 | AssessId string |
800 | ContentId int | 929 | ContentId int |
@@ -981,7 +1110,7 @@ type ExportData2 struct { | @@ -981,7 +1110,7 @@ type ExportData2 struct { | ||
981 | Remark []domain.AssessContemtRemark `pg:"remark"` | 1110 | Remark []domain.AssessContemtRemark `pg:"remark"` |
982 | } | 1111 | } |
983 | 1112 | ||
984 | -// 员工绩效-综合管理-导出绩效指标 | 1113 | +// 员工绩效-综合管理-导出绩效-个人 |
985 | // companyId int 公司id | 1114 | // companyId int 公司id |
986 | // cycleId int, 评估周期id | 1115 | // cycleId int, 评估周期id |
987 | // userId int, 用户id,谁要查看数据 | 1116 | // userId int, 用户id,谁要查看数据 |
@@ -404,6 +404,32 @@ func (c *StaffAssessController) QueryMemberPerformanceIndicator() { | @@ -404,6 +404,32 @@ func (c *StaffAssessController) QueryMemberPerformanceIndicator() { | ||
404 | } | 404 | } |
405 | } | 405 | } |
406 | 406 | ||
407 | +// ExportPerformanceIndicator 导出表格-员工绩效-综合管理-绩效导出指标- | ||
408 | +func (c *StaffAssessController) ExportPerformanceIndicator() { | ||
409 | + srv := service.NewStaffAssessServeice() | ||
410 | + in := &query.ExportPerformanceIndicatorCommand{} | ||
411 | + if err := c.Unmarshal(in); err != nil { | ||
412 | + c.Response(nil, application.ThrowError(application.ARG_ERROR, err.Error())) | ||
413 | + } else { | ||
414 | + if user := middlewares.GetUser(c.Ctx); user != nil { | ||
415 | + in.CompanyId = int(user.CompanyId) | ||
416 | + in.OperatorId = int(user.UserId) | ||
417 | + } | ||
418 | + f, err := srv.ExportPerformanceIndicator(in) | ||
419 | + if err != nil { | ||
420 | + c.Response(nil, err) | ||
421 | + return | ||
422 | + } | ||
423 | + fileName := "个人绩效指标" | ||
424 | + c.Ctx.Output.Header("Content-Disposition", "attachment;filename="+fileName) | ||
425 | + c.Ctx.Output.Header("Content-Description", "FileTransfer") | ||
426 | + c.Ctx.Output.Header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") | ||
427 | + c.Ctx.Output.Header("Content-Transfer-Encoding", "binary") | ||
428 | + c.Ctx.Output.Header("Expires", "0") | ||
429 | + f.Write(c.Ctx.ResponseWriter) | ||
430 | + } | ||
431 | +} | ||
432 | + | ||
407 | // 员工绩效-项目管理-矩阵分析 | 433 | // 员工绩效-项目管理-矩阵分析 |
408 | func (c *StaffAssessController) AnalysisData() { | 434 | func (c *StaffAssessController) AnalysisData() { |
409 | srv := service.NewStaffAssessServeice() | 435 | srv := service.NewStaffAssessServeice() |
@@ -32,6 +32,7 @@ func init() { | @@ -32,6 +32,7 @@ func init() { | ||
32 | web.NSCtrlPost("/summary", (*controllers.StaffAssessController).QuerySummary), //员工绩效-项目管理-总览 | 32 | web.NSCtrlPost("/summary", (*controllers.StaffAssessController).QuerySummary), //员工绩效-项目管理-总览 |
33 | web.NSCtrlPost("/summary/users", (*controllers.StaffAssessController).QueryMemberSummary), //员工绩效-综合管理-成员列表 | 33 | web.NSCtrlPost("/summary/users", (*controllers.StaffAssessController).QueryMemberSummary), //员工绩效-综合管理-成员列表 |
34 | web.NSCtrlPost("/summary/users-indicator", (*controllers.StaffAssessController).QueryMemberPerformanceIndicator), //员工绩效-综合管理-绩效导出指标 | 34 | web.NSCtrlPost("/summary/users-indicator", (*controllers.StaffAssessController).QueryMemberPerformanceIndicator), //员工绩效-综合管理-绩效导出指标 |
35 | + web.NSCtrlPost("/summary/export-indicator", (*controllers.StaffAssessController).ExportPerformanceIndicator), //员工绩效-综合管理-绩效导出指标 | ||
35 | ) | 36 | ) |
36 | //v2 改版 | 37 | //v2 改版 |
37 | assessTaskV2NS := web.NewNamespace("/v2/staff-assess-task", | 38 | assessTaskV2NS := web.NewNamespace("/v2/staff-assess-task", |
-
请 注册 或 登录 后发表评论