package com.kingdee.eas.custom.perfweb.handler; import com.kingdee.bos.BOSException; import com.kingdee.bos.Context; import com.kingdee.bos.metadata.entity.EntityViewInfo; import com.kingdee.bos.metadata.entity.FilterInfo; import com.kingdee.bos.metadata.entity.FilterItemCollection; import com.kingdee.bos.metadata.entity.FilterItemInfo; import com.kingdee.bos.metadata.entity.SelectorItemCollection; import com.kingdee.bos.metadata.entity.SelectorItemInfo; import com.kingdee.bos.metadata.query.util.CompareType; import com.kingdee.eas.basedata.org.AdminOrgUnitInfo; import com.kingdee.eas.custom.perfweb.utils.CenterOrgUtil; import com.kingdee.shr.base.syssetting.context.SHRContext; import com.kingdee.shr.base.syssetting.exception.SHRWebException; import com.kingdee.shr.base.syssetting.exception.ShrWebBizException; import com.kingdee.shr.perfweb.app.base.evalplan.EvaResultSummaryCollection; import com.kingdee.shr.perfweb.app.base.evalplan.EvaResultSummaryFactory; import com.kingdee.shr.perfweb.app.base.evalplan.EvaResultSummaryInfo; import com.kingdee.shr.perfweb.app.base.evalplan.IEvaResultSummary; import com.kingdee.shr.perfweb.app.base.evalplan.PerfEvaObjectInfo; import com.kingdee.shr.perfweb.portal.handler.PerfTeamAssessmentResultListHandler; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.LinkedHashSet; import java.util.Set; /** * 团队历史穿透过滤:重写 getDefaultFilter(标品团队历史走此方法),参数从 request / custom_params 读取。 */ public class PerfTeamAssessmentResultListHandlerEx extends PerfTeamAssessmentResultListHandler { private static final Logger logger = LoggerFactory.getLogger(PerfTeamAssessmentResultListHandlerEx.class); private static final String DRILL_TYPE_GRADE = "GRADE"; private static final String EMPTY_PERSON_ID = "00000000-0000-0000-0000-000000000000"; private static final String[] GRADE_ORDER = {"S", "A+", "A", "B", "C"}; @Override protected FilterInfo getDefaultFilter(HttpServletRequest request, HttpServletResponse response) throws SHRWebException { FilterInfo filter = super.getDefaultFilter(request, response); DrillFilterParams drillParams = parseDrillFilterParams(request); logger.error("teamHistory getDefaultFilter enter,periodId=" + drillParams.periodId + ",centerOrgId=" + drillParams.centerOrgId + ",drillType=" + drillParams.drillType + ",grade=" + drillParams.grade + ",hasDrill=" + drillParams.hasDrillFilter()); if (!drillParams.hasDrillFilter() || StringUtils.isBlank(drillParams.periodId)) { return filter; } try { appendDrillPersonFilter(filter, drillParams); logger.error("teamHistory getDefaultFilter applied,personCount=" + drillParams.resolvedPersonCount); } catch (BOSException e) { logger.error("团队历史穿透过滤失败,msg=" + e.getMessage()); throw new ShrWebBizException("团队历史穿透过滤失败:" + e.getMessage()); } return filter; } private void appendDrillPersonFilter(FilterInfo filter, DrillFilterParams drillParams) throws BOSException { Context ctx = SHRContext.getInstance().getContext(); Set personIds = resolveDrillPersonIds(ctx, drillParams); drillParams.resolvedPersonCount = personIds.size(); FilterItemCollection items = filter.getFilterItems(); int baseSize = items.size(); if (personIds.isEmpty()) { items.add(new FilterItemInfo("person.id", EMPTY_PERSON_ID, CompareType.EQUALS)); } else { items.add(new FilterItemInfo("person.id", personIds, CompareType.INCLUDE)); } StringBuilder mask = new StringBuilder(StringUtils.defaultString(filter.getMaskString())); for (int i = baseSize; i < items.size(); i++) { mask.append(" AND #").append(i); } filter.setMaskString(mask.toString()); } private Set resolveDrillPersonIds(Context ctx, DrillFilterParams params) throws BOSException { AdminOrgUnitInfo centerOrg = StringUtils.isNotBlank(params.centerOrgId) ? CenterOrgUtil.loadOrg(ctx, params.centerOrgId) : null; IEvaResultSummary iEvaResultSummary = EvaResultSummaryFactory.getLocalInstance(ctx); FilterInfo filter = new FilterInfo(); filter.getFilterItems().add(new FilterItemInfo("period.id", params.periodId, CompareType.EQUALS)); SelectorItemCollection selector = new SelectorItemCollection(); selector.add(new SelectorItemInfo("person.id")); selector.add(new SelectorItemInfo("evaObj.*")); selector.add(new SelectorItemInfo("evaObj.adminOrgUnit.*")); selector.add(new SelectorItemInfo("auditGradeLevel")); selector.add(new SelectorItemInfo("reviseGradeLevel")); selector.add(new SelectorItemInfo("gradeLevel")); EntityViewInfo evi = new EntityViewInfo(); evi.setFilter(filter); evi.setSelector(selector); EvaResultSummaryCollection coll = iEvaResultSummary.getEvaResultSummaryCollection(evi); Set personIds = new LinkedHashSet<>(); if (coll == null) { return personIds; } for (int i = 0; i < coll.size(); i++) { EvaResultSummaryInfo info = coll.get(i); if (!matchCenterOrg(ctx, info, centerOrg)) { continue; } if (isGradeDrill(params)) { String drillGrade = normalizeGrade(params.grade); String rowGrade = resolveGradeLevel(info); if (StringUtils.isBlank(drillGrade) || !drillGrade.equalsIgnoreCase(rowGrade)) { continue; } } if (info.getPerson() != null && info.getPerson().getId() != null) { personIds.add(info.getPerson().getId().toString()); } } return personIds; } private boolean matchCenterOrg(Context ctx, EvaResultSummaryInfo info, AdminOrgUnitInfo centerOrg) throws BOSException { if (centerOrg == null) { return true; } PerfEvaObjectInfo evaObj = info.getEvaObj(); if (evaObj == null || evaObj.getAdminOrgUnit() == null) { return false; } return CenterOrgUtil.isUnderCenterOrg(ctx, evaObj.getAdminOrgUnit(), centerOrg); } private DrillFilterParams parseDrillFilterParams(HttpServletRequest request) throws SHRWebException { DrillFilterParams params = new DrillFilterParams(); params.periodId = firstNonBlank( getRequestParam(request, "periodId"), getRequestParam(request, "period")); params.centerOrgId = firstNonBlank( getRequestParam(request, "centerOrgId"), getRequestParam(request, "orgId"), getRequestParam(request, "adminOrg")); params.drillType = getRequestParam(request, "drillType"); params.grade = normalizeGrade(decodeGradeParam(getRequestParam(request, "grade"))); return params; } private String getRequestParam(HttpServletRequest request, String key) throws SHRWebException { Object value = getRequestParameter(request, key); if (value == null) { return null; } String text = String.valueOf(value).trim(); return text.isEmpty() ? null : text; } private boolean isGradeDrill(DrillFilterParams params) { return DRILL_TYPE_GRADE.equalsIgnoreCase(params.drillType) && StringUtils.isNotBlank(params.grade); } private String resolveGradeLevel(EvaResultSummaryInfo info) { if (info == null) { return ""; } if (StringUtils.isNotBlank(info.getAuditGradeLevel())) { return normalizeGrade(info.getAuditGradeLevel()); } if (StringUtils.isNotBlank(info.getReviseGradeLevel())) { return normalizeGrade(info.getReviseGradeLevel()); } return normalizeGrade(info.getGradeLevel()); } private String normalizeGrade(String grade) { if (StringUtils.isBlank(grade)) { return ""; } String trimmed = grade.trim(); // 穿透标题可能带「A+ (实现)」等后缀,只取等级部分 int paren = trimmed.indexOf('('); if (paren > 0) { trimmed = trimmed.substring(0, paren).trim(); } int fullWidthParen = trimmed.indexOf('('); if (fullWidthParen > 0) { trimmed = trimmed.substring(0, fullWidthParen).trim(); } // URL 误把 A+ 解成 "A " 或 "A" if ("A".equals(trimmed) || "A ".equals(trimmed)) { return "A+"; } if ("A+".equals(trimmed) || "A+".equalsIgnoreCase(trimmed)) { return "A+"; } for (String item : GRADE_ORDER) { if (item.equalsIgnoreCase(trimmed)) { return item; } } return trimmed; } private String firstNonBlank(String... values) { if (values == null) { return null; } for (String value : values) { if (StringUtils.isNotBlank(value)) { return value.trim(); } } return null; } private String decodeGradeParam(String value) { if (StringUtils.isBlank(value)) { return null; } try { // URL 表单编码会把 + 解码为空格,A+ 须先保护再 decode String safe = value.trim().replace("+", "%2B"); return URLDecoder.decode(safe, "UTF-8"); } catch (UnsupportedEncodingException e) { return value.trim(); } } private String decodeParam(String value) { if (StringUtils.isBlank(value)) { return null; } try { return URLDecoder.decode(value.trim(), "UTF-8"); } catch (UnsupportedEncodingException e) { return value.trim(); } } private static final class DrillFilterParams { private String periodId; private String centerOrgId; private String drillType; private String grade; private int resolvedPersonCount; private boolean hasDrillFilter() { return StringUtils.isNotBlank(periodId) || StringUtils.isNotBlank(centerOrgId) || (DRILL_TYPE_GRADE.equalsIgnoreCase(drillType) && StringUtils.isNotBlank(grade)); } } }