diff --git a/src/main/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumber.java b/src/main/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumber.java index 27a1c29..2506950 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumber.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumber.java @@ -16,9 +16,11 @@ package xyz.zhouxy.plusone.commons.model; +import java.io.Serializable; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.Map; +import java.util.Objects; import java.util.regex.Matcher; import javax.annotation.Nullable; @@ -47,8 +49,11 @@ import xyz.zhouxy.plusone.commons.util.StringTools; @ValueObject @Immutable public class Chinese2ndGenIDCardNumber - extends ValidatableStringRecord - implements IDCardNumber { + implements IDCardNumber, Comparable, Serializable { + private static final long serialVersionUID = 5655592250204184210L; + + /** 身份证号码 */ + private final String value; /** 省份编码 */ private final String provinceCode; @@ -63,49 +68,58 @@ public class Chinese2ndGenIDCardNumber private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd"); - private Chinese2ndGenIDCardNumber(String value) { - super(value.toUpperCase(), PatternConsts.CHINESE_2ND_ID_CARD_NUMBER, () -> "二代居民身份证校验失败:" + value); - - final Matcher matcher = getMatcher(); - - final String provinceCodeValue = matcher.group("province"); - AssertTools.checkArgument(Chinese2ndGenIDCardNumber.PROVINCE_CODES.containsKey(provinceCodeValue)); - - final String cityCodeValue = matcher.group("city"); - final String countyCodeValue = matcher.group("county"); - - final Gender genderValue; - final LocalDate birthDateValue; + private Chinese2ndGenIDCardNumber(String value, + String provinceCode, String cityCode, String countyCode, + Gender gender, LocalDate birthDate) { + this.value = value; + this.provinceCode = provinceCode; + this.cityCode = cityCode; + this.countyCode = countyCode; + this.gender = gender; + this.birthDate = birthDate; + } + public static Chinese2ndGenIDCardNumber of(final String idCardNumber) { try { + AssertTools.checkArgument(StringTools.isNotBlank(idCardNumber), "二代居民身份证校验失败:号码为空"); + final String value = idCardNumber.toUpperCase(); + final Matcher matcher = PatternConsts.CHINESE_2ND_ID_CARD_NUMBER.matcher(value); + AssertTools.checkArgument(matcher.matches(), () -> "二代居民身份证校验失败:" + value); + + final String provinceCode = matcher.group("province"); + AssertTools.checkArgument(Chinese2ndGenIDCardNumber.PROVINCE_CODES.containsKey(provinceCode)); + + final String cityCode = matcher.group("city"); + final String countyCode = matcher.group("county"); + // 出生日期 final String birthDateStr = matcher.group("birthDate"); - birthDateValue = LocalDate.parse(birthDateStr, DATE_FORMATTER); + final LocalDate birthDate = LocalDate.parse(birthDateStr, DATE_FORMATTER); // 性别 final int genderCode = Integer.parseInt(matcher.group("gender")); - genderValue = genderCode % 2 == 0 ? Gender.FEMALE : Gender.MALE; + final Gender gender = genderCode % 2 == 0 ? Gender.FEMALE : Gender.MALE; + + return new Chinese2ndGenIDCardNumber(value, provinceCode, cityCode, countyCode, gender, birthDate); + } + catch (IllegalArgumentException e) { + throw e; } catch (Exception e) { throw new IllegalArgumentException(e); } - - this.provinceCode = provinceCodeValue; - this.cityCode = cityCodeValue; - this.countyCode = countyCodeValue; - this.gender = genderValue; - this.birthDate = birthDateValue; - } - - public static Chinese2ndGenIDCardNumber of(final String value) { - AssertTools.checkArgument(StringTools.isNotBlank(value), "二代居民身份证校验失败:号码为空"); - return new Chinese2ndGenIDCardNumber(value); } // ================================ // #region - reader methods // ================================ + @Override + @ReaderMethod + public String value() { + return value; + } + @ReaderMethod public String getProvinceCode() { return provinceCode; @@ -157,59 +171,72 @@ public class Chinese2ndGenIDCardNumber // #endregion - reader methods // ================================ - /** - * 省份代码表 - */ - public static final Map PROVINCE_CODES; + /** 省份代码表 */ + public static final Map PROVINCE_CODES = ImmutableMap.builder() + .put("11", "北京") + .put("12", "天津") + .put("13", "河北") + .put("14", "山西") + .put("15", "内蒙古") + .put("21", "辽宁") + .put("22", "吉林") + .put("23", "黑龙江") + .put("31", "上海") + .put("32", "江苏") + .put("33", "浙江") + .put("34", "安徽") + .put("35", "福建") + .put("36", "江西") + .put("37", "山东") + .put("41", "河南") + .put("42", "湖北") + .put("43", "湖南") + .put("44", "广东") + .put("45", "广西") + .put("46", "海南") + .put("50", "重庆") + .put("51", "四川") + .put("52", "贵州") + .put("53", "云南") + .put("54", "西藏") + .put("61", "陕西") + .put("62", "甘肃") + .put("63", "青海") + .put("64", "宁夏") + .put("65", "新疆") + .put("71", "台湾") + .put("81", "香港") + .put("82", "澳门") + .put("83", "台湾") // 台湾身份证号码以83开头,但是行政区划为71 + .put("91", "国外") + .build(); - static { - PROVINCE_CODES = ImmutableMap.builder() - .put("11", "北京") - .put("12", "天津") - .put("13", "河北") - .put("14", "山西") - .put("15", "内蒙古") - .put("21", "辽宁") - .put("22", "吉林") - .put("23", "黑龙江") - .put("31", "上海") - .put("32", "江苏") - .put("33", "浙江") - .put("34", "安徽") - .put("35", "福建") - .put("36", "江西") - .put("37", "山东") - .put("41", "河南") - .put("42", "湖北") - .put("43", "湖南") - .put("44", "广东") - .put("45", "广西") - .put("46", "海南") - .put("50", "重庆") - .put("51", "四川") - .put("52", "贵州") - .put("53", "云南") - .put("54", "西藏") - .put("61", "陕西") - .put("62", "甘肃") - .put("63", "青海") - .put("64", "宁夏") - .put("65", "新疆") - .put("71", "台湾") - .put("81", "香港") - .put("82", "澳门") - .put("83", "台湾") // 台湾身份证号码以83开头,但是行政区划为71 - .put("91", "国外") - .build(); + @SuppressWarnings("null") + @Override + public int compareTo(Chinese2ndGenIDCardNumber o) { + return value.compareTo(o.value); } @Override public int hashCode() { - return super.hashCode(); + return Objects.hash(value); } @Override public boolean equals(@Nullable Object obj) { - return super.equals(obj); + if (this == obj) { + return true; + } + if (!(obj instanceof Chinese2ndGenIDCardNumber)) { + return false; + } + Chinese2ndGenIDCardNumber other = (Chinese2ndGenIDCardNumber) obj; + return Objects.equals(value, other.value); } + + @Override + public String toString() { + return value(); + } + }