作者 郑周

1. 导出绩效指标 优化

@@ -13,7 +13,7 @@ type MemberSummaryListCommand struct { @@ -13,7 +13,7 @@ type MemberSummaryListCommand struct {
13 // MemberPerformanceIndicatorCommand 成员绩效导出-指标 13 // MemberPerformanceIndicatorCommand 成员绩效导出-指标
14 type MemberPerformanceIndicatorCommand struct { 14 type MemberPerformanceIndicatorCommand struct {
15 CycleId int `cname:"周期ID" json:"cycleId,string"` 15 CycleId int `cname:"周期ID" json:"cycleId,string"`
16 - UserName string `cname:"用户名称" json:"userName"` 16 + UserName string `cname:"搜索用户名称" json:"userName"`
17 UserIds []string `cname:"用户ID" json:"userIds"` 17 UserIds []string `cname:"用户ID" json:"userIds"`
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"`
@@ -231,105 +231,250 @@ func (srv StaffAssessServeice) QueryMemberPerformanceIndicator(in *query.MemberP @@ -231,105 +231,250 @@ func (srv StaffAssessServeice) QueryMemberPerformanceIndicator(in *query.MemberP
231 transactionContext.RollbackTransaction() 231 transactionContext.RollbackTransaction()
232 }() 232 }()
233 233
234 - hrbp, err := srv.getHRBP(transactionContext, in.CompanyId, in.OperatorId)  
235 - if err != nil {  
236 - return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) 234 + var projectItemUsed = map[int][]*domain.EvaluationItemUsed{} // 项目ID-> 评估内容项
  235 + var userProjectMap = map[int][]*dao.IndicatorUserProject{} // 用户ID-> 用户评估的项目(用户在周期内可能有多个项目模板,激活状态只能是1个)
  236 + var projectIds = make([]int, 0)
  237 +
  238 + if len(in.UserIds) > 0 {
  239 + staffAssessRepository := factory.CreateStaffAssessRepository(map[string]interface{}{"transactionContext": transactionContext})
  240 + _, assessList, err := staffAssessRepository.Find(map[string]interface{}{
  241 + "cycleId": in.CycleId,
  242 + "targetUserIds": in.UserIds,
  243 + "types": domain.AssessSelf,
  244 + })
  245 + if err != nil {
  246 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  247 + }
  248 +
  249 + projectIdsMap := map[int]int{}
  250 + for i := range assessList {
  251 + it := assessList[i]
  252 + projectIdsMap[it.EvaluationProjectId] = it.EvaluationProjectId
  253 +
  254 + // 用户存在多个项目模板
  255 + array, ok := userProjectMap[it.TargetUser.UserId]
  256 + if !ok {
  257 + array = make([]*dao.IndicatorUserProject, 0)
  258 + }
  259 + userProjectMap[it.TargetUser.UserId] = append(array, &dao.IndicatorUserProject{
  260 + AssessId: it.Id,
  261 + EvaluationProjectId: it.EvaluationProjectId,
  262 + TargetUserId: it.TargetUser.UserId,
  263 + TargetUserName: it.TargetUser.UserName,
  264 + })
  265 + }
  266 + for k, _ := range projectIdsMap {
  267 + projectIds = append(projectIds, k)
  268 + }
  269 +
  270 + } else {
  271 + hrbp, err := srv.getHRBP(transactionContext, in.CompanyId, in.OperatorId)
  272 + if err != nil {
  273 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  274 + }
  275 + assessDao := dao.NewStaffAssessDao(map[string]interface{}{"transactionContext": transactionContext})
  276 + list, err := assessDao.MemberAllProjectId(
  277 + in.CompanyId,
  278 + in.UserName,
  279 + in.OperatorId,
  280 + in.CycleId,
  281 + hrbp)
  282 + if err != nil {
  283 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  284 + }
  285 +
  286 + projectIdsMap := map[int]int{}
  287 + for i := range list {
  288 + it := list[i]
  289 + projectIdsMap[it.EvaluationProjectId] = it.EvaluationProjectId
  290 +
  291 + // 用户存在多个项目模板
  292 + array, ok := userProjectMap[it.TargetUserId]
  293 + if !ok {
  294 + array = make([]*dao.IndicatorUserProject, 0)
  295 + }
  296 + userProjectMap[it.TargetUserId] = append(array, &it)
  297 + }
  298 +
  299 + for k, _ := range projectIdsMap {
  300 + projectIds = append(projectIds, k)
  301 + }
237 } 302 }
238 - assessDao := dao.NewStaffAssessDao(map[string]interface{}{"transactionContext": transactionContext})  
239 - list, err := assessDao.MemberPerformanceIndicator(  
240 - in.UserName,  
241 - in.CompanyId,  
242 - in.OperatorId,  
243 - in.CycleId,  
244 - hrbp,  
245 - string(domain.AssessSelf),  
246 - in.UserIds)  
247 - if err != nil { 303 +
  304 + // 项目ID->查询所有评估项
  305 + if len(projectIds) > 0 {
  306 + itemUsedRepository := factory.CreateEvaluationItemUsedRepository(map[string]interface{}{"transactionContext": transactionContext})
  307 + _, itemList, err := itemUsedRepository.Find(map[string]interface{}{"evaluationProjectIds": projectIds, "nodeType": domain.LinkNodeSelfAssessment})
  308 + if err != nil {
  309 + return nil, err
  310 + }
  311 + for i := range itemList {
  312 + it := itemList[i]
  313 + array, ok := projectItemUsed[it.EvaluationProjectId]
  314 + if !ok {
  315 + array = make([]*domain.EvaluationItemUsed, 0)
  316 + }
  317 + projectItemUsed[it.EvaluationProjectId] = append(array, it)
  318 + }
  319 + }
  320 + if err := transactionContext.CommitTransaction(); err != nil {
248 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) 321 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
249 } 322 }
250 323
251 - // (全部周期数据)筛选出第一个周期的数据,减少后续数据遍历  
252 - dupleMap := map[string]string{}  
253 - dupleList := make([]dao.PerformanceIndicatorAssess, 0)  
254 - for i := range list {  
255 - it := list[i]  
256 - if v, ok := dupleMap[it.TargetUserId]; ok {  
257 - if v == it.BeginDay {  
258 - dupleList = append(dupleList, it) 324 + adapterList := make([]*adapter.PerformanceIndicatorAdapter, 0)
  325 + categoryMap := map[string]int{} // 内容分类
  326 + for i := range in.UserIds {
  327 + userId := in.UserIds[i]
  328 + userIdInt, err := strconv.Atoi(userId)
  329 + if err != nil {
  330 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  331 + }
  332 +
  333 + iupArray, ok := userProjectMap[userIdInt]
  334 + if !ok {
  335 + continue
  336 + }
  337 + var pia = &adapter.PerformanceIndicatorAdapter{
  338 + TargetUserId: userId,
  339 + TargetUserName: iupArray[0].TargetUserName,
  340 + PIContents: make([]adapter.PIContent, 0),
  341 + }
  342 + adapterList = append(adapterList, pia)
  343 + for _, assess := range iupArray {
  344 + items, ok := projectItemUsed[assess.EvaluationProjectId]
  345 + if !ok {
  346 + continue
259 } 347 }
260 - } else {  
261 - // 有内容分类,才算正常数据,反之不显示  
262 - if len(it.ContentCategory) > 0 {  
263 - dupleMap[it.TargetUserId] = it.BeginDay  
264 - dupleList = append(dupleList, it) 348 + for _, item := range items {
  349 + if len(item.Category) == 0 {
  350 + continue
  351 + }
  352 + onlyKey1 := userId + item.Category
  353 + if _, ok := categoryMap[onlyKey1]; !ok {
  354 + categoryMap[onlyKey1] = 0
  355 + // 不存在分类时,创建分类内容
  356 + pia.PIContents = append(pia.PIContents, adapter.PIContent{
  357 + Category: item.Category,
  358 + Names: make([]string, 0),
  359 + })
  360 + }
  361 +
  362 + // 内容名称有值合并到数组
  363 + if len(item.Name) > 0 {
  364 + for index := range pia.PIContents {
  365 + piContent := &pia.PIContents[index]
  366 + if piContent.Category == item.Category {
  367 + piContent.Names = append(piContent.Names, item.Name)
  368 + break
  369 + }
  370 + }
  371 + }
265 } 372 }
266 } 373 }
267 } 374 }
268 375
269 - piaMap := map[string]*adapter.PerformanceIndicatorAdapter{}  
270 - categoryMap := map[string]int{} // 内容分类  
271 - //categoryNameMap := map[string]int{} // 内容分类下的名称 376 + /*
  377 + // 旧版(如果未填写自评会出现数据评估项丢失的BUG)
  378 + hrbp, err := srv.getHRBP(transactionContext, in.CompanyId, in.OperatorId)
  379 + if err != nil {
  380 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  381 + }
272 382
273 - adapterList := make([]*adapter.PerformanceIndicatorAdapter, 0)  
274 - for i := range dupleList {  
275 - it := dupleList[i]  
276 -  
277 - var pia *adapter.PerformanceIndicatorAdapter  
278 - if v, ok := piaMap[it.TargetUserId]; ok {  
279 - pia = v  
280 - } else {  
281 - pia = &adapter.PerformanceIndicatorAdapter{  
282 - TargetUserId: it.TargetUserId,  
283 - TargetUserName: it.TargetUserName,  
284 - PIContents: make([]adapter.PIContent, 0), 383 + assessDao := dao.NewStaffAssessDao(map[string]interface{}{"transactionContext": transactionContext})
  384 + list, err := assessDao.MemberPerformanceIndicator(
  385 + in.UserName,
  386 + in.CompanyId,
  387 + in.OperatorId,
  388 + in.CycleId,
  389 + hrbp,
  390 + string(domain.AssessSelf),
  391 + in.UserIds)
  392 + if err != nil {
  393 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  394 + }
  395 +
  396 + // (全部周期数据)筛选出第一个周期的数据,减少后续数据遍历
  397 + dupleMap := map[string]string{}
  398 + dupleList := make([]dao.PerformanceIndicatorAssess, 0)
  399 + for i := range list {
  400 + it := list[i]
  401 + if v, ok := dupleMap[it.TargetUserId]; ok {
  402 + if v == it.BeginDay {
  403 + dupleList = append(dupleList, it)
  404 + }
  405 + } else {
  406 + // 有内容分类,才算正常数据,反之不显示
  407 + if len(it.ContentCategory) > 0 {
  408 + dupleMap[it.TargetUserId] = it.BeginDay
  409 + dupleList = append(dupleList, it)
  410 + }
285 } 411 }
286 - piaMap[it.TargetUserId] = pia  
287 - adapterList = append(adapterList, pia)  
288 } 412 }
289 413
290 - // 分类名称有值才能合并分类数组  
291 - if len(it.ContentCategory) > 0 {  
292 - onlyKey1 := it.TargetUserId + it.ContentCategory  
293 - if _, ok := categoryMap[onlyKey1]; !ok {  
294 - categoryMap[onlyKey1] = 0  
295 -  
296 - // 不存在分类时,创建分类内容  
297 - pia.PIContents = append(pia.PIContents, adapter.PIContent{  
298 - Category: it.ContentCategory,  
299 - Names: make([]string, 0),  
300 - }) 414 + piaMap := map[string]*adapter.PerformanceIndicatorAdapter{}
  415 + categoryMap := map[string]int{} // 内容分类
  416 + //categoryNameMap := map[string]int{} // 内容分类下的名称
  417 +
  418 + adapterList := make([]*adapter.PerformanceIndicatorAdapter, 0)
  419 + for i := range dupleList {
  420 + it := dupleList[i]
  421 +
  422 + var pia *adapter.PerformanceIndicatorAdapter
  423 + if v, ok := piaMap[it.TargetUserId]; ok {
  424 + pia = v
  425 + } else {
  426 + pia = &adapter.PerformanceIndicatorAdapter{
  427 + TargetUserId: it.TargetUserId,
  428 + TargetUserName: it.TargetUserName,
  429 + PIContents: make([]adapter.PIContent, 0),
  430 + }
  431 + piaMap[it.TargetUserId] = pia
  432 + adapterList = append(adapterList, pia)
301 } 433 }
302 434
303 - // 内容名称有值合并到数组  
304 - if len(it.ContentName) > 0 {  
305 - // 周期筛选过的,不再需要唯一值验证判断,直接添加到对应的分类下  
306 - for index := range pia.PIContents {  
307 - piContent := &pia.PIContents[index]  
308 - if piContent.Category == it.ContentCategory {  
309 - piContent.Names = append(piContent.Names, it.ContentName)  
310 - break 435 + // 分类名称有值才能合并分类数组
  436 + if len(it.ContentCategory) > 0 {
  437 + onlyKey1 := it.TargetUserId + it.ContentCategory
  438 + if _, ok := categoryMap[onlyKey1]; !ok {
  439 + categoryMap[onlyKey1] = 0
  440 +
  441 + // 不存在分类时,创建分类内容
  442 + pia.PIContents = append(pia.PIContents, adapter.PIContent{
  443 + Category: it.ContentCategory,
  444 + Names: make([]string, 0),
  445 + })
  446 + }
  447 +
  448 + // 内容名称有值合并到数组
  449 + if len(it.ContentName) > 0 {
  450 + // 周期筛选过的,不再需要唯一值验证判断,直接添加到对应的分类下
  451 + for index := range pia.PIContents {
  452 + piContent := &pia.PIContents[index]
  453 + if piContent.Category == it.ContentCategory {
  454 + piContent.Names = append(piContent.Names, it.ContentName)
  455 + break
  456 + }
311 } 457 }
  458 + //onlyKey2 := it.TargetUserId + it.ContentCategory + it.ContentName
  459 + //if _, ok := categoryNameMap[onlyKey2]; !ok {
  460 + // categoryNameMap[onlyKey2] = 0
  461 + //
  462 + // for index := range pia.PIContents {
  463 + // piContent := pia.PIContents[index]
  464 + // if piContent.Category == it.ContentCategory {
  465 + // piContent.Names = append(piContent.Names, it.ContentName)
  466 + // break
  467 + // }
  468 + // }
  469 + //}
312 } 470 }
313 - //onlyKey2 := it.TargetUserId + it.ContentCategory + it.ContentName  
314 - //if _, ok := categoryNameMap[onlyKey2]; !ok {  
315 - // categoryNameMap[onlyKey2] = 0  
316 - //  
317 - // for index := range pia.PIContents {  
318 - // piContent := pia.PIContents[index]  
319 - // if piContent.Category == it.ContentCategory {  
320 - // piContent.Names = append(piContent.Names, it.ContentName)  
321 - // break  
322 - // }  
323 - // }  
324 - //}  
325 } 471 }
326 - }  
327 472
328 - }  
329 -  
330 - if err := transactionContext.CommitTransaction(); err != nil {  
331 - return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())  
332 - } 473 + }
  474 + */
  475 + //if err := transactionContext.CommitTransaction(); err != nil {
  476 + // return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  477 + //}
333 478
334 return tool_funs.SimpleWrapGridMap(int64(len(adapterList)), adapterList), nil 479 return tool_funs.SimpleWrapGridMap(int64(len(adapterList)), adapterList), nil
335 } 480 }
@@ -374,8 +519,7 @@ func (srv StaffAssessServeice) ExportPerformanceIndicator(in *query.ExportPerfor @@ -374,8 +519,7 @@ func (srv StaffAssessServeice) ExportPerformanceIndicator(in *query.ExportPerfor
374 for i := range list { 519 for i := range list {
375 it := list[i] 520 it := list[i]
376 if v, ok := selectedMap[it.TargetUserId]; ok { 521 if v, ok := selectedMap[it.TargetUserId]; ok {
377 - v.UserName = it.TargetUserName  
378 - 522 + //v.UserName = it.TargetUserName
379 if v.Category == it.ContentCategory && v.Name == it.ContentName { 523 if v.Category == it.ContentCategory && v.Name == it.ContentName {
380 conditionList = append(conditionList, it) 524 conditionList = append(conditionList, it)
381 conditionMap[it.TargetUserId+it.BeginDay] = it 525 conditionMap[it.TargetUserId+it.BeginDay] = it
@@ -383,7 +383,8 @@ func (d *StaffAssessDao) useTStaffAssess(companyId int, cycleId int, userId int, @@ -383,7 +383,8 @@ func (d *StaffAssessDao) useTStaffAssess(companyId int, cycleId int, userId int,
383 t_staff_assess_0.target_user_name, 383 t_staff_assess_0.target_user_name,
384 t_staff_assess_0.begin_day, 384 t_staff_assess_0.begin_day,
385 t_staff_assess_0.cycle_name, 385 t_staff_assess_0.cycle_name,
386 - t_staff_assess_0.cycle_id 386 + t_staff_assess_0.cycle_id,
  387 + t_staff_assess_0.evaluation_project_id
387 from t_staff_assess_0 388 from t_staff_assess_0
388 join t_project_3 on t_staff_assess_0.evaluation_project_id = t_project_3.project_id 389 join t_project_3 on t_staff_assess_0.evaluation_project_id = t_project_3.project_id
389 ) union (select t_staff_assess_0.assess_id, 390 ) union (select t_staff_assess_0.assess_id,
@@ -391,7 +392,8 @@ func (d *StaffAssessDao) useTStaffAssess(companyId int, cycleId int, userId int, @@ -391,7 +392,8 @@ func (d *StaffAssessDao) useTStaffAssess(companyId int, cycleId int, userId int,
391 t_staff_assess_0.target_user_name, 392 t_staff_assess_0.target_user_name,
392 t_staff_assess_0.begin_day, 393 t_staff_assess_0.begin_day,
393 t_staff_assess_0.cycle_name, 394 t_staff_assess_0.cycle_name,
394 - t_staff_assess_0.cycle_id 395 + t_staff_assess_0.cycle_id,
  396 + t_staff_assess_0.evaluation_project_id
395 from t_staff_assess_0 397 from t_staff_assess_0
396 join t_user_1 on t_staff_assess_0.target_user_id=t_user_1.user_id 398 join t_user_1 on t_staff_assess_0.target_user_id=t_user_1.user_id
397 ) 399 )
@@ -804,6 +806,38 @@ func (d *StaffAssessDao) MemberPerformanceIndicator(likeUserName string, company @@ -804,6 +806,38 @@ func (d *StaffAssessDao) MemberPerformanceIndicator(likeUserName string, company
804 806
805 } 807 }
806 808
  809 +type IndicatorUserProject struct {
  810 + AssessId int `json:"assessId"` // ID
  811 + TargetUserId int `json:"targetUserId"` // 目标用户ID
  812 + TargetUserName string `json:"targetUserName"` // 目标用户名称
  813 + EvaluationProjectId int `json:"evaluationProjectId"` // 项目ID
  814 +
  815 +}
  816 +
  817 +func (d *StaffAssessDao) MemberAllProjectId(companyId int, likeUserName string, operatorId int, cycleId int, hrbp int) ([]IndicatorUserProject, error) {
  818 + sqlStr := ` select
  819 + t_staff_assess_1.evaluation_project_id,
  820 + t_staff_assess_1.target_user_id,
  821 + t_staff_assess_1.target_user_name,
  822 + t_staff_assess_1.assess_id
  823 + from t_staff_assess_1
  824 + where 1=1
  825 + `
  826 + var condition []interface{}
  827 + if len(likeUserName) > 0 {
  828 + sqlStr += ` and t_staff_assess_1.target_user_name like ? `
  829 + condition = append(condition, "%"+likeUserName+"%")
  830 + }
  831 + // 获取前置sql语句
  832 + sqlStr0 := d.useTStaffAssess(companyId, cycleId, operatorId, "", hrbp, 0, 5000, string(domain.AssessSelf))
  833 + sqlStr = sqlStr0 + sqlStr
  834 + tx := d.transactionContext.PgTx
  835 + var result []IndicatorUserProject
  836 + _, err := tx.Query(&result, sqlStr, condition...)
  837 + return result, err
  838 +
  839 +}
  840 +
807 type ExportPerformanceIndicator struct { 841 type ExportPerformanceIndicator struct {
808 AssessId int `json:"assessId"` // ID 842 AssessId int `json:"assessId"` // ID
809 TargetUserId string `json:"targetUserId"` // 被评估人的id 843 TargetUserId string `json:"targetUserId"` // 被评估人的id
@@ -128,9 +128,15 @@ func (repo *StaffAssessRepository) Find(queryOptions map[string]interface{}) (in @@ -128,9 +128,15 @@ func (repo *StaffAssessRepository) Find(queryOptions map[string]interface{}) (in
128 if v, ok := queryOptions["offset"].(int); ok { 128 if v, ok := queryOptions["offset"].(int); ok {
129 query.Offset(v) 129 query.Offset(v)
130 } 130 }
  131 + if v, ok := queryOptions["id"]; ok {
  132 + query.Where("staff_assess.id=?", v)
  133 + }
131 if v, ok := queryOptions["targetUserId"]; ok { 134 if v, ok := queryOptions["targetUserId"]; ok {
132 query.Where(`staff_assess.target_user->>'userId'='?'`, v) 135 query.Where(`staff_assess.target_user->>'userId'='?'`, v)
133 } 136 }
  137 + if v, ok := queryOptions["targetUserIds"]; ok {
  138 + query.Where(`staff_assess.target_user->>'userId' in(?)`, pg.In(v))
  139 + }
134 140
135 if v, ok := queryOptions["targetUserName"].(string); ok { 141 if v, ok := queryOptions["targetUserName"].(string); ok {
136 query.Where(`staff_assess.target_user->>'userName' like ?`, fmt.Sprintf("%%%v%%", v)) 142 query.Where(`staff_assess.target_user->>'userName' like ?`, fmt.Sprintf("%%%v%%", v))
@@ -138,16 +144,14 @@ func (repo *StaffAssessRepository) Find(queryOptions map[string]interface{}) (in @@ -138,16 +144,14 @@ func (repo *StaffAssessRepository) Find(queryOptions map[string]interface{}) (in
138 if v, ok := queryOptions["executorId"]; ok { 144 if v, ok := queryOptions["executorId"]; ok {
139 query.Where(`staff_assess.executor->>'userId'='?'`, v) 145 query.Where(`staff_assess.executor->>'userId'='?'`, v)
140 } 146 }
141 -  
142 if v, ok := queryOptions["cycleId"]; ok { 147 if v, ok := queryOptions["cycleId"]; ok {
143 query.Where(`staff_assess.cycle_id=?`, v) 148 query.Where(`staff_assess.cycle_id=?`, v)
144 } 149 }
145 if v, ok := queryOptions["staffAssessTaskId"]; ok { 150 if v, ok := queryOptions["staffAssessTaskId"]; ok {
146 query.Where(`staff_assess.staff_assess_task_id=?`, v) 151 query.Where(`staff_assess.staff_assess_task_id=?`, v)
147 } 152 }
148 -  
149 - if v, ok := queryOptions["id"]; ok {  
150 - query.Where("staff_assess.id=?", v) 153 + if v, ok := queryOptions["types"]; ok {
  154 + query.Where(`staff_assess.types=?`, v)
151 } 155 }
152 if v, ok := queryOptions["typesList"].([]string); ok { 156 if v, ok := queryOptions["typesList"].([]string); ok {
153 query.Where("staff_assess.types in(?)", pg.In(v)) 157 query.Where("staff_assess.types in(?)", pg.In(v))