package jnpf.base.model.ocr.model; import com.alibaba.fastjson.JSONObject; import io.swagger.v3.oas.annotations.media.Schema; import jnpf.base.model.ocr.OcrModel; import jnpf.util.DateUtil; import jnpf.util.StringUtil; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import java.util.*; import java.util.regex.Pattern; /** * ocr解析营业执照模型 * * @author JNPF开发平台组 * @version v6.1.0 * @copyright 引迈信息技术有限公司 * @date 2025/7/29 16:58:47 */ @EqualsAndHashCode(callSuper = true) @Data @Schema(description = "ocr解析营业执照模型") @NoArgsConstructor public class BusinessLicModel extends OcrModel { @Schema(description = TYSHXYDM) private String code; @Schema(description = "企业名称") private String name; @Schema(description = "企业类型") private String businessType; @Schema(description = "法定代表人") private String userName; @Schema(description = "经营范围") private String businessScope; @Schema(description = "注册资本") private String capital; @Schema(description = "成立日期") private Long createDate; @Schema(description = "营业期限") private String timeLimit; @Schema(description = "地址") private String address; private static final String TYSHXYDM = "统一社会信用代码"; @Override public void extract(String url, JSONObject body) { super.extract(url, body); if (StringUtil.isEmpty(this.getContent()) || !this.getContent().contains("营业执照")) { return; } this.setOther(); validateCode(); businessScope(); this.setContent(null); this.setStrList(null); } /** * 统一社会信用代码识别补充 */ public void validateCode() { Pattern pattern = Pattern.compile("^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$"); if (StringUtil.isEmpty(code) || code.trim().length() != 18 || pattern.matcher(code).matches()) { int index = this.getContent().indexOf(TYSHXYDM) + 8; String str = this.getContent().substring(index, index + 18); // 先进行正则表达式验证 if (pattern.matcher(str).matches()) { this.code = str; } else { for (String item : this.getStrList()) { if (pattern.matcher(item).matches()) { this.code = item; return; } } } } } /** * 经营范围和住所识别补充 */ public void businessScope() { int codeIndex = this.getContent().indexOf("经营范围"); int addressIndex = this.getContent().indexOf("住所"); if (codeIndex > 0 && addressIndex > 0 && codeIndex < addressIndex) { int start = 0; int end = 0; int size = this.getStrList().size(); int addressStart = 0; int addressEnd = 0; for (int i = 0; i < size; i++) { if (this.getStrList().get(i).startsWith("经营范围")) { start = i; } if (this.getStrList().get(i).startsWith("住")) { addressStart = i; } if (this.getStrList().get(i).startsWith("所")) { addressEnd = i; } if (this.getStrList().get(i).startsWith("登记机关")) { end = i; break; } } if (addressStart > 0 && start > 0 && end > start && addressEnd > addressStart) { List addList = this.getStrList().subList(addressStart, addressEnd + 1); String addressAll = String.join("", addList); if (addressAll.length() < 3) return; this.address = addressAll.substring(2); List scopeList = this.getStrList().subList(start, end); String scopeAll = String.join("", scopeList); this.businessScope = scopeAll.replace(addressAll, "").trim(); } } } /** * 根据关键词切割补全内容 */ public void setOther() { List properties = Arrays.asList(TYSHXYDM, "名称", "类型", "法定代表人", "经营范围", "注册资本", "成立日期", "营业期限", "住所", "登记机关"); Map result = extractProperties(this.getContent(), properties); for (Map.Entry entry : result.entrySet()) { switch (entry.getKey()) { case TYSHXYDM: this.code = entry.getValue(); break; case "名称": this.name = entry.getValue(); break; case "类型": this.businessType = entry.getValue(); break; case "法定代表人": this.userName = entry.getValue(); break; case "经营范围": this.businessScope = entry.getValue(); break; case "注册资本": this.capital = entry.getValue(); break; case "成立日期": this.createDate = DateUtil.checkDate(entry.getValue(), "yyyy年MM月dd日").getTime(); break; case "营业期限": this.timeLimit = entry.getValue(); break; case "住所": this.address = entry.getValue(); break; default: break; } } } /** * 整体切割 * * @param input * @param propertyNames * @return */ public static Map extractProperties(String input, List propertyNames) { // 存储属性和它们的起始位置 Map propertyPositions = new HashMap<>(); Map result = new LinkedHashMap<>(); // 查找每个属性的位置 for (String property : propertyNames) { int index = input.indexOf(property); if (index != -1) { propertyPositions.put(property, index); } } // 如果没有找到任何属性,返回空map if (propertyPositions.isEmpty()) { return result; } // 按位置排序属性 List> sortedEntries = new ArrayList<>(propertyPositions.entrySet()); sortedEntries.sort(Map.Entry.comparingByValue()); // 提取每个属性的内容 for (int i = 0; i < sortedEntries.size(); i++) { String currentProperty = sortedEntries.get(i).getKey(); int startPos = sortedEntries.get(i).getValue() + currentProperty.length(); // 确定结束位置(下一个属性的开始位置或字符串末尾) int endPos = (i < sortedEntries.size() - 1) ? sortedEntries.get(i + 1).getValue() : input.length(); // 提取内容并去除可能的冒号、空格等 String content = input.substring(startPos, endPos).trim(); content = content.replaceAll("^[::\\s]+", "").trim(); result.put(currentProperty, content); } return result; } }