|
|
@@ -2,16 +2,22 @@ package com.sundot.airport.ledger.service.impl;
|
|
2
|
2
|
|
|
3
|
3
|
import com.sundot.airport.common.core.domain.entity.SysRole;
|
|
4
|
4
|
import com.sundot.airport.common.core.domain.entity.SysUser;
|
|
|
5
|
+import com.sundot.airport.common.core.domain.entity.SysDept;
|
|
|
6
|
+import com.sundot.airport.common.enums.DeptTypeEnum;
|
|
5
|
7
|
import com.sundot.airport.ledger.domain.ScoreDimension;
|
|
6
|
8
|
import com.sundot.airport.ledger.domain.ScoreEvent;
|
|
7
|
9
|
import com.sundot.airport.ledger.dto.DeptMemberDistributionDTO;
|
|
8
|
10
|
import com.sundot.airport.ledger.dto.DeptMemberDTO;
|
|
9
|
11
|
import com.sundot.airport.ledger.dto.DeptPortraitQueryDTO;
|
|
|
12
|
+import com.sundot.airport.ledger.dto.StationTeamStatsDTO;
|
|
10
|
13
|
import com.sundot.airport.ledger.mapper.ScoreDimensionMapper;
|
|
11
|
14
|
import com.sundot.airport.ledger.mapper.ScoreEventMapper;
|
|
|
15
|
+import com.sundot.airport.ledger.dto.GroupPortraitDTO;
|
|
12
|
16
|
import com.sundot.airport.ledger.service.IDeptPortraitService;
|
|
|
17
|
+import com.sundot.airport.ledger.service.IGroupPortraitService;
|
|
13
|
18
|
import com.sundot.airport.system.domain.BasePosition;
|
|
14
|
19
|
import com.sundot.airport.system.mapper.BasePositionMapper;
|
|
|
20
|
+import com.sundot.airport.system.mapper.SysDeptMapper;
|
|
15
|
21
|
import com.sundot.airport.system.mapper.SysRoleMapper;
|
|
16
|
22
|
import com.sundot.airport.system.mapper.SysUserMapper;
|
|
17
|
23
|
import org.slf4j.Logger;
|
|
|
@@ -44,6 +50,9 @@ public class DeptPortraitServiceImpl implements IDeptPortraitService {
|
|
44
|
50
|
private SysUserMapper sysUserMapper;
|
|
45
|
51
|
|
|
46
|
52
|
@Autowired
|
|
|
53
|
+ private SysDeptMapper sysDeptMapper;
|
|
|
54
|
+
|
|
|
55
|
+ @Autowired
|
|
47
|
56
|
private SysRoleMapper sysRoleMapper;
|
|
48
|
57
|
|
|
49
|
58
|
@Autowired
|
|
|
@@ -55,6 +64,9 @@ public class DeptPortraitServiceImpl implements IDeptPortraitService {
|
|
55
|
64
|
@Autowired
|
|
56
|
65
|
private BasePositionMapper basePositionMapper;
|
|
57
|
66
|
|
|
|
67
|
+ @Autowired
|
|
|
68
|
+ private IGroupPortraitService groupPortraitService;
|
|
|
69
|
+
|
|
58
|
70
|
@Override
|
|
59
|
71
|
public List<DeptMemberDTO> getDeptMembers(DeptPortraitQueryDTO query) {
|
|
60
|
72
|
// 递归查询所有下级部门的用户
|
|
|
@@ -359,6 +371,132 @@ public class DeptPortraitServiceImpl implements IDeptPortraitService {
|
|
359
|
371
|
return total.setScale(1, RoundingMode.HALF_UP);
|
|
360
|
372
|
}
|
|
361
|
373
|
|
|
|
374
|
+ @Override
|
|
|
375
|
+ public List<StationTeamStatsDTO> getStationTeamStats(DeptPortraitQueryDTO query) {
|
|
|
376
|
+ // 1. 验证是站级别
|
|
|
377
|
+ SysDept station = sysDeptMapper.selectDeptById(query.getDeptId());
|
|
|
378
|
+ if (station == null || !"STATION".equals(station.getDeptType())) {
|
|
|
379
|
+ throw new RuntimeException("请选择站级别部门");
|
|
|
380
|
+ }
|
|
|
381
|
+
|
|
|
382
|
+ // 2. 查询站下所有部门(BRIGADE)
|
|
|
383
|
+ SysDept deptQuery = new SysDept();
|
|
|
384
|
+ deptQuery.setParentId(query.getDeptId());
|
|
|
385
|
+ deptQuery.setDeptType(DeptTypeEnum.BRIGADE.getCode());
|
|
|
386
|
+ deptQuery.setStatus("0");
|
|
|
387
|
+ List<SysDept> brigades = sysDeptMapper.selectDeptList(deptQuery);
|
|
|
388
|
+
|
|
|
389
|
+ if (brigades == null || brigades.isEmpty()) {
|
|
|
390
|
+ return Collections.emptyList();
|
|
|
391
|
+ }
|
|
|
392
|
+
|
|
|
393
|
+ // 3. 为每个部门计算统计信息
|
|
|
394
|
+ List<StationTeamStatsDTO> result = new ArrayList<>();
|
|
|
395
|
+ for (SysDept brigade : brigades) {
|
|
|
396
|
+ StationTeamStatsDTO stats = calculateDeptStats(brigade, query.getStartDate(), query.getEndDate());
|
|
|
397
|
+ if (stats != null) {
|
|
|
398
|
+ result.add(stats);
|
|
|
399
|
+ }
|
|
|
400
|
+ }
|
|
|
401
|
+
|
|
|
402
|
+ return result;
|
|
|
403
|
+ }
|
|
|
404
|
+
|
|
|
405
|
+ /**
|
|
|
406
|
+ * 计算单个部门的团队画像统计信息
|
|
|
407
|
+ */
|
|
|
408
|
+ private StationTeamStatsDTO calculateDeptStats(SysDept dept, String startDate, String endDate) {
|
|
|
409
|
+ // 查询部门所有成员
|
|
|
410
|
+ SysUser userQuery = new SysUser();
|
|
|
411
|
+ userQuery.setDeptId(dept.getDeptId());
|
|
|
412
|
+ userQuery.setStatus("0");
|
|
|
413
|
+ List<SysUser> members = sysUserMapper.selectUserList(userQuery);
|
|
|
414
|
+
|
|
|
415
|
+ if (members == null || members.isEmpty()) {
|
|
|
416
|
+ return null;
|
|
|
417
|
+ }
|
|
|
418
|
+
|
|
|
419
|
+ StationTeamStatsDTO stats = new StationTeamStatsDTO();
|
|
|
420
|
+ stats.setDeptId(dept.getDeptId());
|
|
|
421
|
+ stats.setDeptName(dept.getDeptName());
|
|
|
422
|
+ stats.setEmployeeCount(members.size());
|
|
|
423
|
+
|
|
|
424
|
+ // 计算各项统计
|
|
|
425
|
+ int partyCount = 0;
|
|
|
426
|
+ int totalAge = 0;
|
|
|
427
|
+ int totalWorkYears = 0;
|
|
|
428
|
+ int totalXrayOperatorYears = 0;
|
|
|
429
|
+ int validAgeCount = 0;
|
|
|
430
|
+ int validWorkYearsCount = 0;
|
|
|
431
|
+ int validXrayOperatorYearsCount = 0;
|
|
|
432
|
+ Map<String, Integer> qualLevelCount = new HashMap<>();
|
|
|
433
|
+
|
|
|
434
|
+ for (SysUser user : members) {
|
|
|
435
|
+ // 党员数量(中共党员 + 中共预备党员)
|
|
|
436
|
+ String politicalStatus = decodePoliticalStatus(user.getPoliticalStatus());
|
|
|
437
|
+ if ("中共党员".equals(politicalStatus) || "中共预备党员".equals(politicalStatus)) {
|
|
|
438
|
+ partyCount++;
|
|
|
439
|
+ }
|
|
|
440
|
+
|
|
|
441
|
+ // 年龄
|
|
|
442
|
+ Integer age = calculateAgeFromIdCard(user.getCardNumber());
|
|
|
443
|
+ if (age != null && age > 0) {
|
|
|
444
|
+ totalAge += age;
|
|
|
445
|
+ validAgeCount++;
|
|
|
446
|
+ }
|
|
|
447
|
+
|
|
|
448
|
+ // 工龄(从入职时间计算)
|
|
|
449
|
+ if (user.getEntryDate() != null) {
|
|
|
450
|
+ Integer workYears = calculateYears(user.getEntryDate());
|
|
|
451
|
+ if (workYears != null) {
|
|
|
452
|
+ totalWorkYears += workYears;
|
|
|
453
|
+ validWorkYearsCount++;
|
|
|
454
|
+ }
|
|
|
455
|
+ }
|
|
|
456
|
+
|
|
|
457
|
+ // 开机年限(从开机时间计算)
|
|
|
458
|
+ if (user.getXrayOperatorStarttime() != null) {
|
|
|
459
|
+ Integer xrayYears = calculateYears(user.getXrayOperatorStarttime());
|
|
|
460
|
+ if (xrayYears != null) {
|
|
|
461
|
+ totalXrayOperatorYears += xrayYears;
|
|
|
462
|
+ validXrayOperatorYearsCount++;
|
|
|
463
|
+ }
|
|
|
464
|
+ }
|
|
|
465
|
+
|
|
|
466
|
+ // 职业资格等级
|
|
|
467
|
+ if (user.getQualificationLevel() != null && !user.getQualificationLevel().isEmpty()) {
|
|
|
468
|
+ String level = decodeQualificationLevel(user.getQualificationLevel());
|
|
|
469
|
+ qualLevelCount.merge(level, 1, Integer::sum);
|
|
|
470
|
+ }
|
|
|
471
|
+ }
|
|
|
472
|
+
|
|
|
473
|
+ stats.setPartyMemberCount(partyCount);
|
|
|
474
|
+ stats.setAvgAge(validAgeCount > 0 ? Math.round((double) totalAge / validAgeCount * 10) / 10.0 : 0);
|
|
|
475
|
+ stats.setAvgWorkYears(validWorkYearsCount > 0 ? Math.round((double) totalWorkYears / validWorkYearsCount * 10) / 10.0 : 0);
|
|
|
476
|
+ stats.setAvgXrayOperatorYears(validXrayOperatorYearsCount > 0 ? Math.round((double) totalXrayOperatorYears / validXrayOperatorYearsCount * 10) / 10.0 : 0);
|
|
|
477
|
+
|
|
|
478
|
+ // 职业资格证书等级(总个数)
|
|
|
479
|
+ int totalQualificationCount = qualLevelCount.values().stream()
|
|
|
480
|
+ .mapToInt(Integer::intValue)
|
|
|
481
|
+ .sum();
|
|
|
482
|
+ stats.setQualificationLevel(String.valueOf(totalQualificationCount));
|
|
|
483
|
+
|
|
|
484
|
+ // 计算综合得分(使用维度得分一览的总分逻辑)
|
|
|
485
|
+ try {
|
|
|
486
|
+ DeptPortraitQueryDTO portraitQuery = new DeptPortraitQueryDTO();
|
|
|
487
|
+ portraitQuery.setDeptId(dept.getDeptId());
|
|
|
488
|
+ portraitQuery.setStartDate(startDate);
|
|
|
489
|
+ portraitQuery.setEndDate(endDate);
|
|
|
490
|
+ GroupPortraitDTO portrait = groupPortraitService.getGroupPortrait(portraitQuery);
|
|
|
491
|
+ stats.setTotalScore(portrait.getTotalScore() != null ? portrait.getTotalScore() : BigDecimal.ZERO);
|
|
|
492
|
+ } catch (Exception e) {
|
|
|
493
|
+ log.warn("计算部门[{}]综合得分失败: {}", dept.getDeptName(), e.getMessage());
|
|
|
494
|
+ stats.setTotalScore(BigDecimal.ZERO);
|
|
|
495
|
+ }
|
|
|
496
|
+
|
|
|
497
|
+ return stats;
|
|
|
498
|
+ }
|
|
|
499
|
+
|
|
362
|
500
|
private Integer calculateAgeFromIdCard(String idCard) {
|
|
363
|
501
|
if (idCard == null || idCard.length() < 14) {
|
|
364
|
502
|
return null;
|
|
|
@@ -405,4 +543,4 @@ public class DeptPortraitServiceImpl implements IDeptPortraitService {
|
|
405
|
543
|
default: return v;
|
|
406
|
544
|
}
|
|
407
|
545
|
}
|
|
408
|
|
-}
|
|
|
546
|
+}
|