|
|
@@ -19,6 +19,11 @@ import java.util.regex.Pattern;
|
|
|
* (剂量/用法用量/疗程),命中即收集为合规违规(violation),不阻断流程
|
|
|
* (E4 弱提示口径),由报告侧 {@code sections.complianceGate} 暴露。
|
|
|
*
|
|
|
+ * <p><b>G-3 证据码隔离</b>:另含 T11(G-3)证据码隔离执行器——证据标 PUB/KB
|
|
|
+ * (可进推荐依据)、COM 仅作存在性记录(不进推荐依据)、未核实编号标「未核实」,
|
|
|
+ * 见 {@link #tagEvidence} / {@link #canEnterRecommendationBasis} /
|
|
|
+ * {@link #isExistenceRecordOnly} / {@link #isolateForRecommendation}。
|
|
|
+ *
|
|
|
* <p>纯规则、无 DB 依赖、无副作用(除设置 {@link IndicatorReading#setAssociationOnly(boolean)}),
|
|
|
* 可单测。挂载点:{@code AttributionAnalysisServiceImpl.analyze()}(L4 出结论前 enforce +
|
|
|
* L5 出文档前 scan)。
|
|
|
@@ -186,6 +191,61 @@ public class AttributionComplianceGate {
|
|
|
return new GateReport(base == null ? Collections.emptyList() : base.getNodes(), all);
|
|
|
}
|
|
|
|
|
|
+ // ==================== G-3 证据码隔离(T11,P1) ====================
|
|
|
+ //
|
|
|
+ // 证据码隔离口径:低侧机制证据标 PUB/KB(可进推荐依据);COM 只作存在性记录
|
|
|
+ // (绝不进推荐依据);未核实的编号(空/null/未知编号)统一标「未核实」,
|
|
|
+ // 不得充当推荐依据。纯规则、无 DB 依赖、无副作用,可单测。
|
|
|
+ // 挂载点:与 G-1 同处横切合规门禁(L4 出结论前 / L5 出文档前),推荐依据组装前调用。
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 证据码规范化:PUB/KB/COM 原样保留;空/null/未知编号 → {@link AttributionLowSideRules#EVIDENCE_UNVERIFIED}「未核实」。
|
|
|
+ */
|
|
|
+ public String tagEvidence(String evidenceCode) {
|
|
|
+ if (evidenceCode == null || evidenceCode.trim().isEmpty()) {
|
|
|
+ return AttributionLowSideRules.EVIDENCE_UNVERIFIED;
|
|
|
+ }
|
|
|
+ String code = evidenceCode.trim();
|
|
|
+ if (AttributionLowSideRules.EVIDENCE_PUB.equals(code)
|
|
|
+ || AttributionLowSideRules.EVIDENCE_KB.equals(code)
|
|
|
+ || AttributionLowSideRules.EVIDENCE_COM.equals(code)) {
|
|
|
+ return code;
|
|
|
+ }
|
|
|
+ return AttributionLowSideRules.EVIDENCE_UNVERIFIED;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 证据码是否可进推荐依据:仅 PUB/KB 为 true;
|
|
|
+ * COM(存在性记录)与「未核实」(空/null/未知编号)一律 false。
|
|
|
+ */
|
|
|
+ public boolean canEnterRecommendationBasis(String evidenceCode) {
|
|
|
+ String code = tagEvidence(evidenceCode);
|
|
|
+ return AttributionLowSideRules.EVIDENCE_PUB.equals(code)
|
|
|
+ || AttributionLowSideRules.EVIDENCE_KB.equals(code);
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 证据码是否为「仅存在性记录」:仅 COM 为 true,PUB/KB/未核实 均为 false。 */
|
|
|
+ public boolean isExistenceRecordOnly(String evidenceCode) {
|
|
|
+ return AttributionLowSideRules.EVIDENCE_COM.equals(tagEvidence(evidenceCode));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 推荐依据隔离:从证据码清单中过滤仅保留 PUB/KB(保序),
|
|
|
+ * 剔除 COM(存在性记录)与「未核实」(空/null/未知编号)。
|
|
|
+ */
|
|
|
+ public List<String> isolateForRecommendation(List<String> evidenceCodes) {
|
|
|
+ if (evidenceCodes == null) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ List<String> out = new ArrayList<>();
|
|
|
+ for (String code : evidenceCodes) {
|
|
|
+ if (canEnterRecommendationBasis(code)) {
|
|
|
+ out.add(code);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return out;
|
|
|
+ }
|
|
|
+
|
|
|
// ==================== 内部 ====================
|
|
|
|
|
|
private List<Violation> matchAll(String text, List<Pattern> patterns, String rule,
|