diff --git a/pom.xml b/pom.xml index 19930fb..4a98ab4 100644 --- a/pom.xml +++ b/pom.xml @@ -61,6 +61,12 @@ dynamic-datasource-spring-boot-starter 3.4.1 + + + org.apache.commons + commons-lang3 + 3.9 + diff --git a/src/main/java/com/glxp/mipsdl/client/njxyy/NjxyyClient.java b/src/main/java/com/glxp/mipsdl/client/njxyy/NjxyyClient.java index b506798..c8411eb 100644 --- a/src/main/java/com/glxp/mipsdl/client/njxyy/NjxyyClient.java +++ b/src/main/java/com/glxp/mipsdl/client/njxyy/NjxyyClient.java @@ -33,6 +33,7 @@ import com.glxp.mipsdl.entity.basic.BasicUdirelEntity; import com.glxp.mipsdl.entity.inout.*; import com.glxp.mipsdl.entity.njxyy.ProductEntity; import com.glxp.mipsdl.entity.njxyy.SickerEntity; +import com.glxp.mipsdl.entity.system.UdiEntity; import com.glxp.mipsdl.entity.thrsys.*; import com.glxp.mipsdl.http.HttpClient; import com.glxp.mipsdl.req.base.*; @@ -660,6 +661,19 @@ public class NjxyyClient extends CommonHttpClient { return ResultVOUtils.error(500, "耗材数量不能为空!"); } codeRequest.setCount(IntUtil.value(highvalue.getQuantity())); + + UdiEntity udiEntity = FilterUdiUtils.getUdi(codeRequest.getCode()); + if (udiEntity == null || StrUtil.isEmpty(udiEntity.getUdi())) { + return ResultVOUtils.error(500, "UDI码格式错误!"); + } + + BasicUdirelEntity udirelEntity = basicUdirelDao.selectByNameCode(udiEntity.getUdi()); + if (udirelEntity == null) { + return ResultVOUtils.error(500, "耗材字典未对照!"); + } + if (IntUtil.value(udirelEntity.getPurType()) == 2) { + return ResultVOUtils.success("YAS" + CustomUtil.getUnitId()); + } if (codeRequest.getCount() > 0) { //收费入库 ioOrderRequest.setAction("SC20250702001"); @@ -675,7 +689,6 @@ public class NjxyyClient extends CommonHttpClient { } } } - codeRequestList.add(codeRequest); } forInvOutScanCodeRequest.setCodeRequestList(codeRequestList); diff --git a/src/main/java/com/glxp/mipsdl/client/zzzyy/ZzzyyClient.java b/src/main/java/com/glxp/mipsdl/client/zzzyy/ZzzyyClient.java index 79a3fd0..3300274 100644 --- a/src/main/java/com/glxp/mipsdl/client/zzzyy/ZzzyyClient.java +++ b/src/main/java/com/glxp/mipsdl/client/zzzyy/ZzzyyClient.java @@ -52,7 +52,7 @@ import java.util.List; import java.util.stream.Collectors; /** - * 漳州中医院客户端--智业接口对接 + * 漳州中医院客户端--HIS接口对接 */ @Slf4j diff --git a/src/main/java/com/glxp/mipsdl/dao/basic/BasicProductsDao.java b/src/main/java/com/glxp/mipsdl/dao/basic/BasicProductsDao.java index febdb0e..9ff9980 100644 --- a/src/main/java/com/glxp/mipsdl/dao/basic/BasicProductsDao.java +++ b/src/main/java/com/glxp/mipsdl/dao/basic/BasicProductsDao.java @@ -6,4 +6,6 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface BasicProductsDao extends BaseMapper { + + } diff --git a/src/main/java/com/glxp/mipsdl/dao/basic/BasicUdirelDao.java b/src/main/java/com/glxp/mipsdl/dao/basic/BasicUdirelDao.java index 5fb19da..1600814 100644 --- a/src/main/java/com/glxp/mipsdl/dao/basic/BasicUdirelDao.java +++ b/src/main/java/com/glxp/mipsdl/dao/basic/BasicUdirelDao.java @@ -6,4 +6,6 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface BasicUdirelDao extends BaseMapper { + + public BasicUdirelEntity selectByNameCode(String nameCode); } diff --git a/src/main/java/com/glxp/mipsdl/entity/basic/BasicUdirelEntity.java b/src/main/java/com/glxp/mipsdl/entity/basic/BasicUdirelEntity.java index d78dadc..fbbee85 100644 --- a/src/main/java/com/glxp/mipsdl/entity/basic/BasicUdirelEntity.java +++ b/src/main/java/com/glxp/mipsdl/entity/basic/BasicUdirelEntity.java @@ -153,4 +153,12 @@ public class BasicUdirelEntity { @TableField(value = "hcType") private Integer hcType; + + /** + * 采购类型 1:入账产品;2:预验收产品;3:寄售产品 + */ + @TableField(value = "purType") + private Integer purType; + + } diff --git a/src/main/java/com/glxp/mipsdl/entity/system/UdiEntity.java b/src/main/java/com/glxp/mipsdl/entity/system/UdiEntity.java new file mode 100644 index 0000000..de4497e --- /dev/null +++ b/src/main/java/com/glxp/mipsdl/entity/system/UdiEntity.java @@ -0,0 +1,65 @@ +package com.glxp.mipsdl.entity.system; + +/** + * @author 彭于晏 + * @date 2020/9/22. + */ +public class UdiEntity { + + private String batchNo; + private String produceDate; + private String expireDate; + private String serialNo; + private String udi; + + public String getBatchNo() { + return batchNo; + } + + public void setBatchNo(String batchNo) { + this.batchNo = batchNo; + } + + public String getProduceDate() { + return produceDate; + } + + public void setProduceDate(String produceDate) { + this.produceDate = produceDate; + } + + public String getExpireDate() { + return expireDate; + } + + public void setExpireDate(String expireDate) { + this.expireDate = expireDate; + } + + public String getSerialNo() { + return serialNo; + } + + public void setSerialNo(String serialNo) { + this.serialNo = serialNo; + } + + public String getUdi() { + return udi; + } + + public void setUdi(String udi) { + this.udi = udi; + } + + @Override + public String toString() { + return "UdiEntity{" + + "batchNo='" + batchNo + '\'' + + ", produceDate='" + produceDate + '\'' + + ", expireDate='" + expireDate + '\'' + + ", serialNo='" + serialNo + '\'' + + ", udi='" + udi + '\'' + + '}'; + } +} diff --git a/src/main/java/com/glxp/mipsdl/util/FilterUdiUtils.java b/src/main/java/com/glxp/mipsdl/util/FilterUdiUtils.java new file mode 100644 index 0000000..8b92cb1 --- /dev/null +++ b/src/main/java/com/glxp/mipsdl/util/FilterUdiUtils.java @@ -0,0 +1,158 @@ +package com.glxp.mipsdl.util; + + +import cn.hutool.core.util.StrUtil; +import com.glxp.mipsdl.entity.system.UdiEntity; +import com.glxp.mipsdl.util.gs1.AI; +import com.glxp.mipsdl.util.gs1.AIs; +import com.glxp.mipsdl.util.gs1.Gs1128Decoder; +import com.glxp.mipsdl.util.gs1.Gs1128Engine; + +import java.util.Map; + +public class FilterUdiUtils { + private static final String TAG = "FilterUdiUtils"; + + public static UdiEntity getUdi(String data) { + if (data != null && data.length() > 2) { + if (data.substring(0, 2).toUpperCase().equals("MA")) { + return getZGCUdi(data); + } else if (data.substring(0, 2).equals("01")) { + return getGS1Udi(data); + } else if (data.substring(0, 1).equals("#")) { + return getGLXPUdi(data); + } + } + return null; + } + + + public static UdiEntity getGS1Udi(String data) { + Gs1128Engine engine = new Gs1128Engine(); + Gs1128Decoder decoder = engine.decoder(); + Map result = decoder.decode("]C1" + data); + UdiEntity udiEntity = new UdiEntity(); + int length = 0; + for (Map.Entry entry : result.entrySet()) { + length = length + entry.getValue().length(); + if (entry.getKey() == AIs.GTIN) { + udiEntity.setUdi(entry.getValue()); + } else if (entry.getKey() == AIs.BATCH_LOT) { + udiEntity.setBatchNo(entry.getValue()); + } else if (entry.getKey() == AIs.EXPIRY) { + udiEntity.setExpireDate(entry.getValue()); + } else if (entry.getKey() == AIs.PROD_DATE) { + udiEntity.setProduceDate(entry.getValue()); + } else if (entry.getKey() == AIs.SERIAL) { + udiEntity.setSerialNo(entry.getValue()); + } + } + if (data.length() - length > 22) { + return null; + } + if (StrUtil.isEmpty(udiEntity.getUdi())) { + return null; + } + if (udiEntity.getUdi().length() < 14 + ) { + return null; + } else + return udiEntity; + } + + public static UdiEntity getZGCUdi(String data) { + String batchNo = ""; + String produceDate = ""; + String expireDate = ""; + String serialNo = null; + String nameCode = ""; + String[] spilts = data.split("[.]"); + if (spilts != null && spilts.length >= 5) { + for (int i = 0; i < 5; i++) { + nameCode = nameCode + "." + spilts[i]; + } + nameCode = nameCode.substring(1); + for (int i = 0; i < spilts.length; i++) { + String tempStr = spilts[i]; + if (tempStr != null && tempStr.length() > 1 && tempStr.substring(0, 1).equals("M")) { + produceDate = tempStr.substring(1); + } else if (tempStr != null && tempStr.length() > 1 && tempStr.substring(0, 1).equals("L")) { + batchNo = tempStr.substring(1); + } else if (tempStr != null && tempStr.length() > 1 && tempStr.substring(0, 1).equals("E")) { + expireDate = tempStr.substring(1); + } else if (tempStr != null && tempStr.length() > 1 && tempStr.substring(0, 1).equals("S")) { + serialNo = tempStr.substring(1); + } + } + } + + UdiEntity udiEntity = new UdiEntity(); + udiEntity.setBatchNo(batchNo); + udiEntity.setExpireDate(expireDate); + udiEntity.setProduceDate(produceDate); + udiEntity.setUdi(nameCode); + udiEntity.setSerialNo(serialNo); + return udiEntity; + + } + + + public static UdiEntity getGLXPUdi(String data) { + String batchNo = ""; + String produceDate = ""; + String expireDate = ""; + String serialNo = null; + String udi = ""; + String[] spilts = data.split("#", data.length()); + if (spilts != null && spilts.length >= 5) { + udi = spilts[1]; + produceDate = spilts[2]; + expireDate = spilts[3]; + batchNo = spilts[4]; + if (spilts.length > 6) { + serialNo = spilts[5]; + } + + if (StrUtil.isEmpty(batchNo)) { + batchNo = null; + } + if (StrUtil.isEmpty(serialNo)) { + serialNo = null; + } + + } + UdiEntity udiEntity = new UdiEntity(); + udiEntity.setBatchNo(batchNo); + udiEntity.setExpireDate(expireDate); + udiEntity.setProduceDate(produceDate); + udiEntity.setUdi(udi); + udiEntity.setSerialNo(serialNo); + return udiEntity; + } + + public static String getDiStr(String data) { + String prefix = ""; + if (data != null && data.length() > 2) { + if (data.substring(0, 2).equals("MA")) { + String[] spilts = data.split("[.]"); + if (spilts != null && spilts.length >= 5) { + for (int i = 0; i < 5; i++) { + prefix = prefix + "." + spilts[i]; + } + prefix = prefix.substring(1); + } + } else if (data.substring(0, 2).equals("01") && data.length() >= 16) { + prefix = data.substring(2, 16); + } else if (data.substring(0, 1).equals("#")) { + String[] spilts = data.split("#"); + if (spilts != null && spilts.length >= 1) + prefix = spilts[1]; + } + } + if (prefix.equals("")) + return data; + return prefix; + } + + +} diff --git a/src/main/java/com/glxp/mipsdl/util/gs1/AI.java b/src/main/java/com/glxp/mipsdl/util/gs1/AI.java new file mode 100644 index 0000000..5614cc5 --- /dev/null +++ b/src/main/java/com/glxp/mipsdl/util/gs1/AI.java @@ -0,0 +1,14 @@ +package com.glxp.mipsdl.util.gs1; + +/** + * @author guilherme.pacheco + */ +public interface AI { + + String getCode(); + + String getDescription(); + + String getFormat(); + +} diff --git a/src/main/java/com/glxp/mipsdl/util/gs1/AIs.java b/src/main/java/com/glxp/mipsdl/util/gs1/AIs.java new file mode 100644 index 0000000..ffa3f2f --- /dev/null +++ b/src/main/java/com/glxp/mipsdl/util/gs1/AIs.java @@ -0,0 +1,112 @@ +package com.glxp.mipsdl.util.gs1; + +/** + * @author guilherme.pacheco + */ +public enum AIs implements AI { + + SSCC("00", "Serial Shipping Container Code", "n2+n18"), + GTIN("01", "GTIN-14", "n2+n14"), + CONTENT("02", "Number of containers", "n2+n14"), + BATCH_LOT("10", "Batch Number", "n2+an..20"), + PROD_DATE("11", "Production Date", "n2+n6"), + DUE_DATE("12", "Production Date", "n2+n6"), + PACK_DATE("13", "Packaging Date", "n2+n6"), + BEST_BEFORE("15", "Sell by Date (Quality Control) ", "n2+n6"), + EXPIRY("17", "Expiration Date", "n2+n6"), + VARIANT("20", "Product Variant", "n2+n2"), + SERIAL("21", "Serial Number", "n2+an..20"), + INTERNAL("91", "Company Internal Information", "n2+an..30"), + ADDITIONAL_ID("240", "Additional Product Identification", "n3+an..30"), + CUSTOMER_PART("241", "Customer Part Number", "n3+an..30"), + VARIATION_NUMBER("242", "242 Made-to-Order variation no", "n2+n..30"), + SECONDARY_SERIAL("250", "Secondary Serial Number", "n3+an..30"), + REF_TO_SOURCE("251", "Reference to source entity", "n3+an..30"), + DOC_ID("253", "Global Document Type Identifier", "n3+n13+n..17"), + GLN_EXTENSION("254", "GLN extension component ", "n3+an..20"), + VAR_COUNT("30", "Quantity Each", "n2+n..8"), + NET_WEIGHT("310n", "Product Net Weight in kg", "n4+n6"), + LENGTH("311n", "Product Length/1st Dimension, in meters", "n4+n6"), + WIDTH("312n", "Product Width/Diameter/2nd Dimension, in meters", "n4+n6"), + HEIGHT("313n", "Product Depth/Thickness/3rd Dimension, in meters", "n4+n6"), + AREA("314n", "Product Area, in square meters", "n4+n6"), + NET_VOLUME_LITERS("315n", " Product Volume, in liters", "n4+n6"), + NET_VOLUME_CUBICS("316n", " product Volume, in cubic meters", "n4+n6"), + NET_WEIGHT_POUNDS("320n", "Product Net Weight, in pounds", "n4+n6"), + LENGTH_INCHES("321n", "Product Length/1st Dimension, in inches", "n4+n6"), + LENGTH_PES("322n", "Product Length/1st Dimension, in feet", "n4+n6"), + LENGTH_YARDS("323n", "Product Length/1st Dimension, in yards", "n4+n6"), + WIDTH_INCHES("324n", "Product Width/Diameter/2nd Dimension, in inches", "n4+n6"), + WIDTH_FEET("325n", "Product Width/Diameter/2nd Dimension, in feet", "n4+n6"), + WIDTH_YARDS("326n", "Product Width/Diameter/2nd Dimension, in yards", "n4+n6"), + HEIGHT_INCHES("327n", "Product Depth/Thickness/3rd Dimension, in inches", "n4+n6"), + HEIGHT_FEET("328n", "Product Depth/Thickness/3rd Dimension, in feet", "n4+n6"), + HEIGHT_YARDS("329n", "Product Depth/Thickness/3rd Dimension, in yards", "n4+n6"), + PRODUCT_AREA_INCHES("350n", "Product Area (Square Inches)", "n4+n6"), + PRODUCT_AREA_FEET("351n", "Product Area (Square Feet)", "n4+n6"), + PRODUCT_AREA_YARDS("352n", "Product Area (Square Yards)", "n4+n6"), + CONTAINER_AREA_INCHES("353n", "Container Area (Square Inches) ", "n4+n6"), + CONTAINER_AREA_FEET("354n", "Container Area (Square Feet) ", "n4+n6"), + CONTAINER_AREA_YARDS("355n", "Container Area (Square Yards) ", "n4+n6"), + NET_WEIGHT_OUNCES("356n", "Net Weight (Troy Ounces)", "n4+n6"), + PRODUCT_VOLUME_QUARTS("360n", " Product Volume (Quarts)", "n4+n6"), + PRODUCT_VOLUME_GALLONS("361n", " Product Volume (Gallons)", "n4+n6"), + CONTAINER_VOLUME_QUARTS("362n", " Container Gross Volume (Quarts)", "n4+n6"), + CONTAINER_VOLUME_GALLONS("363n", " Container Gross Volume (Gallons)", "n4+n6"), + PRODUCT_VOLUME_INCHES("364n", " Product Volume (Cubic Inches)", "n4+n6"), + PRODUCT_VOLUME_FEET("365n", " Product Volume (Cubic Feet)", "n4+n6"), + PRODUCT_VOLUME_YARDS("366n", " Product Volume (Cubic Yards)", "n4+n6"), + CONTAINER_VOLUME_INCHES("367n", " Container Gross Volume (Cubic Inches)", "n4+n6"), + CONTAINER_VOLUME_FEET("368n", " Container Gross Volume (Cubic Feet)", "n4+n6"), + CONTAINER_VOLUME_YARDS("369n", " Container Gross Volume (Cubic Yards)", "n4+n6"), + COUNT("37", " Number of Units Contained", "n2+n..8"), + ORDER_NUMBER("400", "Customer Purchase Order Number", "n3+an..30"), + SHIP_TO_DELIVER_TO_LOCATION_CODE("410", "Ship To/Deliver To Location Code (EAN13 or DUNS code)", "n3+n13"), + BILL_TO_INVOICEE_TO_LOCATION_CODE("411", "Bill To/Invoice Location Code (EAN13 or DUNS code)", "n3+n13"), + PURCHASE_FROM_LOCATION_CODE("412", "Purchase From Location Code (EAN13 or DUNS code)", "n3+n13"), + SHIP_TO_DELIVER_TO_POSTALCODE("420", "Ship To/Deliver To Postal Code (Single Postal Authority)", "n3+an..9"), + SHIP_TO_DELIVER_TO_MULTI_POSTALCODE("421", "Ship To/Deliver To Postal Code (Multiple Postal Authority)", + "n3+n3+an..9"), + ORIGIN("422", "Country orign", "n3+n3"), + COUNTRY_INITIAL_PROCESS("423", "County initial processing", "n3+n3+n..12"), + COUNTRY_PROCESS("424", "County processing", "n3+n3"), + COUNTRY_DISASSEMBLY("425", "Country disassembly", "n3+n3"), + COUNTRY_FULL_PROCESS("426", "Country pull processing", "n3+n3"), + ROLL_PRODUCTS("8001", "Roll Products – Width/Length/Core Diameter", "n4+n14"), + ESN("8002", "Electronic Serial Number (ESN) for Cellular Phone", "n4+an..20"), + UPC_EAN_RETURNABLE_ASSET("8003", "UPC/EAN Number and Serial Number of Returnable Asset", "n4+an..30"), + UPC_EAN_SERIAL_IDENTIFICATION("8004", "UPC/EAN Serial Identification", "n4+an..30"), + PRICE_UNIT_MEASURE("8005", "Price per Unit of Measure", "n4+n6"), + ; + + private final String code; + private final String description; + private final String format; + + private AIs(String code, String description, String format) { + this.code = code; + this.description = description; + this.format = format; + } + + @Override + public String getCode() { + return code; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getFormat() { + return format; + } + + @Override + public String toString() { + return description; + } + +} diff --git a/src/main/java/com/glxp/mipsdl/util/gs1/AiFactory.java b/src/main/java/com/glxp/mipsdl/util/gs1/AiFactory.java new file mode 100644 index 0000000..98e2155 --- /dev/null +++ b/src/main/java/com/glxp/mipsdl/util/gs1/AiFactory.java @@ -0,0 +1,32 @@ +package com.glxp.mipsdl.util.gs1; + +/** + * @author guilherme.pacheco + */ +public final class AiFactory { + + private AiFactory() { + super(); + } + + public static AI create(String code, String description, String format) { + return new AI() { + + @Override + public String getFormat() { + return format; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getCode() { + return code; + } + }; + } + +} diff --git a/src/main/java/com/glxp/mipsdl/util/gs1/Format.java b/src/main/java/com/glxp/mipsdl/util/gs1/Format.java new file mode 100644 index 0000000..f3641b0 --- /dev/null +++ b/src/main/java/com/glxp/mipsdl/util/gs1/Format.java @@ -0,0 +1,71 @@ +package com.glxp.mipsdl.util.gs1; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author guilherme.pacheco + */ +final class Format { + + private static final String JOIN_SYMBOL = "+"; + private final List sessions; + + public Format(List sessions) { + this.sessions = Validate.notEmpty(sessions); + } + + public Format(Session... sessions) { + this(Arrays.asList(sessions)); + } + + public Session getIdentifier() { + return sessions.get(0); + } + + public List getDataSessions() { + return sessions.subList(1, sessions.size()); + } + + @Override + public String toString() { + return sessions.stream().map(String::valueOf).collect(Collectors.joining(JOIN_SYMBOL)); + } + + public boolean isValid(String value) { + if (StringUtils.isBlank(value)) { + return false; + } + if (!validLength(value)) { + return false; + } + return validate(value); + } + + private boolean validate(String value) { + return getDataSessions().stream().allMatch(s -> s.getType().isValid(Gs1128Utils.value(s, value))); + } + + private boolean validLength(String value) { + return isVaried() ? value.length() <= getLength() : value.length() == getLength(); + } + + public int getLength() { + return getDataSessions().stream().mapToInt(Session::getLength).sum(); + } + + public boolean isVaried() { + return getDataSessions().stream().anyMatch(Session::isVaried); + } + + public static Format valueOf(String value) { + String[] split = StringUtils.split(value, JOIN_SYMBOL); + List list = Arrays.stream(split).map(Session::valueOf).collect(Collectors.toList()); + return new Format(list); + } + +} diff --git a/src/main/java/com/glxp/mipsdl/util/gs1/Gs1128Decoder.java b/src/main/java/com/glxp/mipsdl/util/gs1/Gs1128Decoder.java new file mode 100644 index 0000000..b79996d --- /dev/null +++ b/src/main/java/com/glxp/mipsdl/util/gs1/Gs1128Decoder.java @@ -0,0 +1,57 @@ +package com.glxp.mipsdl.util.gs1; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; + +import java.util.*; +import java.util.function.Function; + +/** + * @author guilherme.pacheco + */ +public final class Gs1128Decoder { + + private final Collection ais; + + Gs1128Decoder(Collection ais) { + this.ais = ais; + } + + public Map decode(final String barcode) { + validateBarcode(barcode); + String barcodeValue = StringUtils.remove(barcode, Gs1128Utils.PREFIX); + return extract(barcodeValue); + } + + private Map extract(String barcode) { + final Iterator iterator = Gs1128Utils.iterator(barcode); + final Map result = new WeakHashMap<>(4); + StringBuilder builder = new StringBuilder(); + while (iterator.hasNext()) { + builder.append(iterator.next()); + Optional> mapAi = mapAi(iterator, builder.toString()); + if (mapAi.isPresent()) { + result.putAll(mapAi.get()); + builder = new StringBuilder(); + } + } + return result; + } + + private Optional> mapAi(Iterator iterator, String builder) { + return ais.stream().filter(v -> v.getCode().equals(builder)).findFirst().map(aiValue(iterator)); + } + + private Function> aiValue(Iterator iterator) { + return ai -> { + String value = Gs1128Utils.value(ai, iterator); + return Map.of(ai, value); + }; + } + + private void validateBarcode(String barcode) { + Validate.notBlank(barcode, "Barcode cannot be blank"); + Validate.isTrue(StringUtils.startsWith(barcode, Gs1128Utils.PREFIX), "Barcode must start with prefix Gs1-128 \"]C1\""); + } + +} diff --git a/src/main/java/com/glxp/mipsdl/util/gs1/Gs1128Encoder.java b/src/main/java/com/glxp/mipsdl/util/gs1/Gs1128Encoder.java new file mode 100644 index 0000000..d889d88 --- /dev/null +++ b/src/main/java/com/glxp/mipsdl/util/gs1/Gs1128Encoder.java @@ -0,0 +1,33 @@ +package com.glxp.mipsdl.util.gs1; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; + +import java.util.Collection; +import java.util.stream.Collectors; + +/** + * @author guilherme.pacheco + */ +public final class Gs1128Encoder { + + Gs1128Encoder() { + super(); + } + + public String encode(Collection segments) { + Validate.notEmpty(segments); + String barcode = joinSegments(segments); + return checkBarcode(barcode); + } + + private String checkBarcode(String barcode) { + return StringUtils.removeEnd(barcode, String.valueOf(Gs1128Utils.END_AI_VARIED)); + } + + private String joinSegments(Collection segments) { + String joinValue = segments.stream().map(Segment::encode).collect(Collectors.joining()); + return Gs1128Utils.PREFIX.concat(joinValue); + } + +} diff --git a/src/main/java/com/glxp/mipsdl/util/gs1/Gs1128Engine.java b/src/main/java/com/glxp/mipsdl/util/gs1/Gs1128Engine.java new file mode 100644 index 0000000..d58986c --- /dev/null +++ b/src/main/java/com/glxp/mipsdl/util/gs1/Gs1128Engine.java @@ -0,0 +1,35 @@ +package com.glxp.mipsdl.util.gs1; + +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Set; + +/** + * @author guilherme.pacheco + */ +public final class Gs1128Engine { + + private final Set aisRegistred = new HashSet<>(); + + public Gs1128Engine() { + aisRegistred.addAll(EnumSet.allOf(AIs.class)); + } + + public void registerAi(AI ai) { + aisRegistred.add(ai); + } + + public Set getAisRegistred() { + return Collections.unmodifiableSet(aisRegistred); + } + + public Gs1128Encoder encoder() { + return new Gs1128Encoder(); + } + + public Gs1128Decoder decoder() { + return new Gs1128Decoder(aisRegistred); + } + +} diff --git a/src/main/java/com/glxp/mipsdl/util/gs1/Gs1128Utils.java b/src/main/java/com/glxp/mipsdl/util/gs1/Gs1128Utils.java new file mode 100644 index 0000000..bebbfa7 --- /dev/null +++ b/src/main/java/com/glxp/mipsdl/util/gs1/Gs1128Utils.java @@ -0,0 +1,61 @@ +package com.glxp.mipsdl.util.gs1; + +import java.util.Iterator; + +/** + * @author guilherme.pacheco + */ +final class Gs1128Utils { + + public static final String PREFIX = "]C1"; + public static final char END_AI_VARIED = (char) 29; + + private Gs1128Utils() { + super(); + } + + public static Iterator iterator(String value) { + return value.chars().mapToObj(c -> (char) c).iterator(); + } + + public static String value(AI ai, Iterator iterator) { + Format format = Format.valueOf(ai.getFormat()); + if (format.isVaried()) { + return variedValue(iterator); + } else { + return fixedValue(format.getLength(), iterator); + } + } + + public static String value(Session session, String value) { + Iterator iterator = iterator(value); + if (session.isVaried()) { + return variedValue(iterator); + } else { + return fixedValue(session.getLength(), iterator); + } + } + + private static String fixedValue(int size, Iterator iterator) { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < size; i++) { + if (iterator.hasNext()) { + builder.append(iterator.next()); + } + } + return builder.toString(); + } + + private static String variedValue(Iterator iterator) { + StringBuilder builder = new StringBuilder(); + while (iterator.hasNext()) { + char value = iterator.next(); + if (value == END_AI_VARIED) { + break; + } + builder.append(value); + } + return builder.toString(); + } + +} diff --git a/src/main/java/com/glxp/mipsdl/util/gs1/Segment.java b/src/main/java/com/glxp/mipsdl/util/gs1/Segment.java new file mode 100644 index 0000000..77321fb --- /dev/null +++ b/src/main/java/com/glxp/mipsdl/util/gs1/Segment.java @@ -0,0 +1,35 @@ +package com.glxp.mipsdl.util.gs1; + +import org.apache.commons.lang3.Validate; + +/** + * @author guilherme.pacheco + */ +public final class Segment { + + private final AI ai; + private final String value; + private final Format format; + + public Segment(AI ai, String value) { + this.ai = Validate.notNull(ai, "Invalid AI"); + format = Format.valueOf(ai.getFormat()); + this.value = validateValue(format, value); + } + + private String validateValue(Format format, String value) { + Validate.notBlank(value, "Invalid segment value"); + Validate.notNull(format, "Invalid format"); + Validate.isTrue(format.isValid(value)); + return value; + } + + String encode() { + String codeValue = ai.getCode().concat(value); + if (format.isVaried()) { + return codeValue + Gs1128Utils.END_AI_VARIED; + } + return codeValue; + } + +} diff --git a/src/main/java/com/glxp/mipsdl/util/gs1/Session.java b/src/main/java/com/glxp/mipsdl/util/gs1/Session.java new file mode 100644 index 0000000..5f4ca7a --- /dev/null +++ b/src/main/java/com/glxp/mipsdl/util/gs1/Session.java @@ -0,0 +1,69 @@ +package com.glxp.mipsdl.util.gs1; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; + +/** + * @author guilherme.pacheco + */ +final class Session { + + private static final String VARIED_CONSTANT = ".."; + + private final SessionType type; + private final boolean varied; + private final int length; + + public Session(SessionType type, int length, boolean varied) { + this.type = Validate.notNull(type); + Validate.isTrue(length > 0, "Session invalid length"); + this.length = length; + this.varied = varied; + } + + public SessionType getType() { + return type; + } + + public int getLength() { + return length; + } + + public boolean isVaried() { + return varied; + } + + public static Session valueOf(String value) { + Validate.notBlank(value, "Session cannot be blank"); + SessionType type = sessionType(value); + String strLength = value.substring(type.length()); + boolean varied = strLength.startsWith(VARIED_CONSTANT); + int length = createLength(strLength, varied); + return new Session(type, length, varied); + } + + private static SessionType sessionType(String value) { + return SessionType.valueByPrefix(value).orElseThrow(() -> new IllegalArgumentException("Invalid session type")); + } + + private static Integer createLength(String strLength, boolean varied) { + try { + if (varied) { + String lengthValue = StringUtils.substringAfter(strLength, VARIED_CONSTANT); + return Integer.parseInt(lengthValue); + } + return Integer.valueOf(strLength); + } catch (NumberFormatException ex) { + throw new IllegalArgumentException(String.format("Invalid length: '%s'", strLength), ex); + } + } + + @Override + public String toString() { + return new StringBuilder(type.getSymbol()) + .append(varied ? VARIED_CONSTANT : StringUtils.EMPTY) + .append(length) + .toString(); + } + +} diff --git a/src/main/java/com/glxp/mipsdl/util/gs1/SessionType.java b/src/main/java/com/glxp/mipsdl/util/gs1/SessionType.java new file mode 100644 index 0000000..41268cf --- /dev/null +++ b/src/main/java/com/glxp/mipsdl/util/gs1/SessionType.java @@ -0,0 +1,50 @@ +package com.glxp.mipsdl.util.gs1; + +import org.apache.commons.lang3.StringUtils; + +import java.util.EnumSet; +import java.util.Optional; +import java.util.function.Predicate; + +/** + * @author guilherme.pacheco + */ +enum SessionType { + + ALPHANUMERIC("an", v -> Character.isAlphabetic(v) || Character.isDigit(v)), + ALPHABETIC("a", v -> Character.isAlphabetic(v)), + NUMERIC("n", v -> Character.isDigit(v)); + + private final String symbol; + private final Predicate validator; + + private SessionType(String symbol, Predicate validator) { + this.symbol = symbol; + this.validator = validator; + } + + public boolean isValid(String value) { + if (StringUtils.isBlank(value)) { + return false; + } + return value.chars().mapToObj(c -> (char) c).allMatch(validator::test); + } + + public String getSymbol() { + return symbol; + } + + public int length() { + return symbol.length(); + } + + public static Optional valueByPrefix(String value) { + if (StringUtils.isBlank(value)) { + return Optional.empty(); + } + return EnumSet.allOf(SessionType.class).stream() + .filter(v -> StringUtils.startsWithIgnoreCase(value, v.symbol)) + .findFirst(); + } + +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 9cedc0e..5e10841 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -5,7 +5,7 @@ spring: strict: false datasource: master: - url: jdbc:p6spy:mysql://127.0.0.1:3306/udi_wms_pt2?allowMultiQueries=true&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true + url: jdbc:p6spy:mysql://127.0.0.1:3306/udi_wms_ct?allowMultiQueries=true&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true username: root password: 123456 driver-class-name: com.p6spy.engine.spy.P6SpyDriver diff --git a/src/main/resources/mybatis/mapper/master/basic/BasicProductsDao.xml b/src/main/resources/mybatis/mapper/master/basic/BasicProductsDao.xml index 0bcc66f..09d9930 100644 --- a/src/main/resources/mybatis/mapper/master/basic/BasicProductsDao.xml +++ b/src/main/resources/mybatis/mapper/master/basic/BasicProductsDao.xml @@ -74,4 +74,5 @@ basicPrductRemak4, basicPrductRemak5, basicPrductRemak6, basicPrductRemak7, basicPrductRemak8, createTime, updateTime, `createUser`, updateUser, remark + diff --git a/src/main/resources/mybatis/mapper/master/basic/BasicUdirelDao.xml b/src/main/resources/mybatis/mapper/master/basic/BasicUdirelDao.xml index 042735c..b9b58a4 100644 --- a/src/main/resources/mybatis/mapper/master/basic/BasicUdirelDao.xml +++ b/src/main/resources/mybatis/mapper/master/basic/BasicUdirelDao.xml @@ -1,37 +1,45 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - id, uuid, mainId, thirdId, thirdId1, thirdId2, thirdId3, thirdId4, udplatCode, isUseDy, - isDisable, isLock, lockStatus, isAdavence, useMuti, useNum, supName, createTime, - updateTime, modifyTime, `createUser`, updateUser, remark - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, uuid, mainId, thirdId, thirdId1, thirdId2, thirdId3, thirdId4, udplatCode, isUseDy, + isDisable, isLock, lockStatus, isAdavence, useMuti, useNum, supName, createTime, + updateTime, modifyTime, `createUser`, updateUser, remark + + +