package jnpf.bizcommon.audit.service.sign; import jnpf.util.JsonUtil; import java.util.Map; /** * 解析 {@code lims_sign.meta_data}——前端签名时一并提交的业务元数据。 * *

本类只暴露 D5 认可的三样:按钮名、是否复核、原始 biz_data(仅供留档)。 * 刻意不提供从 {@code biz_data} 取业务字段值的方法:业务数据一律以后端查库为准 * (D2),开了这个口子迟早有人拿前端报文当事实——而它是可篡改的。 * *

前端实测两种形态: *

 * {"is_review_button": true,  "biz_button": "复核",     "biz_data": [...], "is_biz_form": true}
 * {"is_review_button": false, "biz_button": "批量按钮", "biz_data": [...], "is_biz_form": false}
 * 
* {@code biz_module} / {@code biz_title} 前端永远是空串(三个组装点全硬编码),别指望。 * *

永不抛异常:解析失败返回 {@link #EMPTY}。动作语义拿不到只该让 action_label 糙一点, * 不该让「这次改过」缺席。 */ public final class AuditSignMetaData { public static final AuditSignMetaData EMPTY = new AuditSignMetaData(null, false, null); private final String bizButton; private final boolean reviewButton; private final String rawBizData; private AuditSignMetaData(String bizButton, boolean reviewButton, String rawBizData) { this.bizButton = bizButton; this.reviewButton = reviewButton; this.rawBizData = rawBizData; } public static AuditSignMetaData parse(String json) { if (json == null || json.trim().isEmpty()) { return EMPTY; } try { Map root = JsonUtil.stringToMap(json); if (root == null) { return EMPTY; } Object button = root.get("biz_button"); String name = button == null ? null : String.valueOf(button).trim(); if (name != null && name.isEmpty()) { name = null; } boolean review = Boolean.TRUE.equals(root.get("is_review_button")); Object data = root.get("biz_data"); String rawData = data == null ? null : JsonUtil.getObjectToString(data); return new AuditSignMetaData(name, review, rawData); } catch (Throwable t) { return EMPTY; } } /** 用户点的按钮文案,如「确定」「复核」「批量按钮」。取不到返回 null。 */ public String bizButton() { return bizButton; } /** 是否复核按钮。层 0 从 type 分不出复核与普通保存,只能靠它。 */ public boolean isReviewButton() { return reviewButton; } /** 前端当时展示的数据,原样 JSON。仅供 extra 留档,不作准。 */ public String rawBizData() { return rawBizData; } }