| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- package com.kingdee.eas.custom.perfweb.handler;
- import com.alibaba.fastjson.JSONObject;
- import com.kingdee.bos.BOSException;
- import com.kingdee.bos.Context;
- import com.kingdee.bos.ctrl.swing.StringUtils;
- import com.kingdee.eas.custom.perfweb.util.PersonnelStatUtil;
- import com.kingdee.eas.custom.perfweb.util.ReportFilterUtil;
- import com.kingdee.eas.custom.perfweb.util.ReportOrgUtil;
- import com.kingdee.shr.base.syssetting.context.SHRContext;
- import com.kingdee.shr.base.syssetting.exception.SHRWebException;
- import com.kingdee.shr.base.syssetting.json.GridDataEntity;
- import com.kingdee.shr.base.syssetting.web.handler.ListHandler;
- import org.apache.log4j.Logger;
- import org.springframework.ui.ModelMap;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.sql.SQLException;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- /**
- * 类名称: DeptPersonnelStatHandler
- * 功能描述: 按部门统计人员结构报表数据处理
- * 创建日期: 2026-06-05
- * 作 者: 青梧
- * 版 本: 1.0
- *
- * 返回字段说明:
- * deptCode - 部门编码(FNUMBER)
- * centerName - 部门名称(列表列名沿用centerName)
- * personCount - 在职总人数(含下级组织)
- * personPercentage - 人数占全部部门在职合计的百分比
- * formalCount - 正式员工人数(员工类型001)
- * formalPercentage - 正式员工占本部门总人数的百分比
- * trialCount - 试用员工人数(员工类型002)
- * trialPercentage - 试用员工占本部门总人数的百分比
- * keyTalentCount - 关键人才人数(CFGjrc=1)
- */
- public class DeptPersonnelStatHandler extends ListHandler {
- private static Logger logger = Logger.getLogger(DeptPersonnelStatHandler.class);
- Context ctx = SHRContext.getInstance().getContext();
- /**
- * 列表查询入口:按部门汇总在职人数、正式/试用/关键人才人数及占比,末尾追加合计行。
- */
- @Override
- protected GridDataEntity getGridRequestData(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) throws SHRWebException {
- logger.error("DeptPersonnelStatHandler getGridRequestData------------");
- GridDataEntity gridDataEntity = new GridDataEntity();
- try {
- // 快筛(company字段可能为中心F7) + 列表筛选 filterItems
- String filterItem = ReportFilterUtil.getFilterItems(request);
- JSONObject fastFilterItemsJson = ReportFilterUtil.parseFastFilterJson(request);
- logger.error("filterItem: " + filterItem);
- logger.error("fastFilterItemsJson: " + fastFilterItemsJson);
- Map<String, String> paramMap = ReportFilterUtil.parseCompanyParams(fastFilterItemsJson, logger, true);
- ReportOrgUtil.OrgScope centerScope = ReportFilterUtil.buildCenterOrgScope(ctx, fastFilterItemsJson, logger);
- logger.error("查询参数: company=" + paramMap + ", centerScope=" + centerScope.orgName
- + ", adminOrg=" + centerScope.adminOrg);
- // 公司F7: 限定人员FCompanyID(company字段非中心层级时生效)
- String companyId = paramMap.get("companyId");
- String centerName = centerScope.orgName;
- String adminOrgId = centerScope.adminOrg;
- List<ReportOrgUtil.OrgNameCode> deptList = getDeptList(centerName, adminOrgId, companyId, filterItem);
- logger.error("中心[" + centerName + "]下部门数量: " + deptList.size());
- int totalCount = 0;
- int totalFormalCount = 0;
- int totalTrialCount = 0;
- int totalKeyTalentCount = 0;
- List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>();
- for (ReportOrgUtil.OrgNameCode dept : deptList) {
- String deptName = dept.orgName;
- PersonnelStatUtil.PersonnelStat stat = countDeptStat(centerName, adminOrgId, dept.orgCode, deptName, companyId);
- Map<String, Object> row = new HashMap<String, Object>();
- row.put("deptCode", dept.orgCode); // deptCode: 部门编码(同名取第一个)
- row.put("centerName", deptName); // centerName: 部门名称
- row.put("personCount", stat.totalCount);
- row.put("personPercentage", 0.0);
- row.put("formalCount", stat.formalCount);
- row.put("formalPercentage", 0.0);
- row.put("trialCount", stat.trialCount);
- row.put("trialPercentage", 0.0);
- row.put("keyTalentCount", stat.keyTalentCount);
- dataList.add(row);
- totalCount += stat.totalCount;
- totalFormalCount += stat.formalCount;
- totalTrialCount += stat.trialCount;
- totalKeyTalentCount += stat.keyTalentCount;
- }
- // 第二遍循环:基于全部部门合计数回填各行占比
- for (Map<String, Object> row : dataList) {
- int personCount = (Integer) row.get("personCount");
- int formalCount = (Integer) row.get("formalCount");
- int trialCount = (Integer) row.get("trialCount");
- // 人数占比 = 本部门人数 / 全部部门在职合计
- double personPercentage = totalCount > 0 ? (personCount * 100.0 / totalCount) : 0.0;
- row.put("personPercentage", String.format("%.2f", personPercentage) + "%");
- // 正式员工占比 = 本部门正式人数 / 本部门总人数
- double formalPercentage = personCount > 0 ? (formalCount * 100.0 / personCount) : 0.0;
- row.put("formalPercentage", String.format("%.2f", formalPercentage) + "%");
- // 试用员工占比 = 本部门试用人数 / 本部门总人数
- double trialPercentage = personCount > 0 ? (trialCount * 100.0 / personCount) : 0.0;
- row.put("trialPercentage", String.format("%.2f", trialPercentage) + "%");
- }
- // 合计行
- Map<String, Object> totalRow = new HashMap<String, Object>();
- totalRow.put("deptCode", "");
- totalRow.put("centerName", "合计");
- totalRow.put("personCount", totalCount);
- totalRow.put("personPercentage", totalCount > 0 ? "100.00%" : "0.00%");
- totalRow.put("formalCount", totalFormalCount);
- totalRow.put("formalPercentage", totalCount > 0 ? String.format("%.2f", totalFormalCount * 100.0 / totalCount) + "%" : "0.00%");
- totalRow.put("trialCount", totalTrialCount);
- totalRow.put("trialPercentage", totalCount > 0 ? String.format("%.2f", totalTrialCount * 100.0 / totalCount) + "%" : "0.00%");
- totalRow.put("keyTalentCount", totalKeyTalentCount);
- dataList.add(totalRow);
- gridDataEntity.setRows(dataList);
- gridDataEntity.setTotal(dataList.size());
- gridDataEntity.setPage(1);
- gridDataEntity.setRecords(dataList.size());
- logger.error("按部门统计报表数据查询成功,总记录数: " + dataList.size());
- } catch (SQLException e) {
- logger.error("数据库查询失败", e);
- throw new SHRWebException("数据查询失败: " + e.getMessage());
- } catch (BOSException e) {
- logger.error("业务异常", e);
- throw new SHRWebException("业务处理失败: " + e.getMessage());
- } catch (Exception e) {
- logger.error("未知异常", e);
- throw new SHRWebException("系统异常: " + e.getMessage());
- }
- ReportFilterUtil.applyGridUserData(request, gridDataEntity);
- return gridDataEntity;
- }
- /**
- * 查询部门列表:有中心名称时按名称跨公司合并,仅无名称时才用行政组织FID子树。
- */
- private List<ReportOrgUtil.OrgNameCode> getDeptList(String centerName, String adminOrgId, String companyId,
- String filterItemsStr) throws BOSException, SQLException {
- List<ReportOrgUtil.OrgNameCode> depts;
- if (!StringUtils.isEmpty(centerName)) {
- depts = ReportOrgUtil.getDistinctDeptNameCodesUnderCenter(ctx, centerName, companyId);
- } else if (!StringUtils.isEmpty(adminOrgId)) {
- depts = ReportOrgUtil.getDistinctDeptNameCodesUnderAdminOrg(ctx, adminOrgId, companyId);
- } else {
- depts = ReportOrgUtil.getDistinctOrgNameCodes(ctx, ReportOrgUtil.LAYER_DEPT, companyId);
- }
- List<ReportOrgUtil.OrgNameCode> result = ReportOrgUtil.filterOrgNameCodes(depts, filterItemsStr);
- logger.error("部门数量: " + result.size());
- return result;
- }
- private PersonnelStatUtil.PersonnelStat countDeptStat(String centerName, String adminOrgId, String deptCode,
- String deptName, String companyId) throws BOSException, SQLException {
- if (StringUtils.isEmpty(deptName)) {
- return new PersonnelStatUtil.PersonnelStat();
- }
- PersonnelStatUtil.StatScope scope = buildDeptStatScope(centerName, adminOrgId, deptCode, deptName, companyId);
- PersonnelStatUtil.PersonnelStat stat = PersonnelStatUtil.countStructure(ctx, scope, logger);
- logger.error("部门[" + deptName + "/" + deptCode + "]统计: " + stat.totalCount);
- return stat;
- }
- private PersonnelStatUtil.StatScope buildDeptStatScope(String centerName, String adminOrgId, String deptCode,
- String deptName, String companyId) {
- if (!StringUtils.isEmpty(centerName) && !StringUtils.isEmpty(deptCode)) {
- return PersonnelStatUtil.StatScope.deptUnderCenterByCode(centerName, deptCode, companyId);
- }
- if (!StringUtils.isEmpty(centerName)) {
- return PersonnelStatUtil.StatScope.deptUnderCenter(centerName, deptName, companyId);
- }
- if (!StringUtils.isEmpty(adminOrgId) && !StringUtils.isEmpty(deptCode)) {
- return PersonnelStatUtil.StatScope.deptUnderAdminOrgByCode(adminOrgId, deptCode, companyId);
- }
- if (!StringUtils.isEmpty(adminOrgId)) {
- return PersonnelStatUtil.StatScope.deptUnderAdminOrg(adminOrgId, deptName, companyId);
- }
- return PersonnelStatUtil.StatScope.dept(deptName, companyId);
- }
- }
|