添加对SAP的支持
This commit is contained in:
parent
a4f3dff2e1
commit
26cb7bf1a2
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,9 @@
|
|||
Manifest-Version: 1.0
|
||||
|
||||
keyname: SAP JCO
|
||||
keyvendor: sap.com
|
||||
keylocation: SAP SE
|
||||
|
||||
sapjco release: 3.1
|
||||
sapjco patch level: 12
|
||||
sapjco os: darwinarm64
|
||||
|
|
@ -38,6 +38,13 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sap.conn.jco</groupId>
|
||||
<artifactId>sapjco3</artifactId>
|
||||
<version>3.1.12</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/lib/sapjco3.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jcraft</groupId>
|
||||
<artifactId>jsch</artifactId>
|
||||
|
|
@ -55,6 +62,32 @@
|
|||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-external-libs</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!-- 指定源目录(项目根目录下的lib) -->
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${project.basedir}/lib</directory>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<!-- 指定目标目录(与依赖库相同的目录) -->
|
||||
<outputDirectory>${project.build.directory}/lib</outputDirectory>
|
||||
<!-- 自动创建目标目录 -->
|
||||
<overwrite>true</overwrite>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,119 @@
|
|||
package com.nflg.wms.srm.receive.config;
|
||||
|
||||
import com.sap.conn.jco.JCoDestination;
|
||||
import com.sap.conn.jco.JCoDestinationManager;
|
||||
import com.sap.conn.jco.JCoException;
|
||||
import com.sap.conn.jco.JCoRepository;
|
||||
import com.sap.conn.jco.ext.DestinationDataEventListener;
|
||||
import com.sap.conn.jco.ext.DestinationDataProvider;
|
||||
import com.sap.conn.jco.ext.Environment;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class SAPConfig {
|
||||
|
||||
public static final String ABAP_AS_POOLED = "ABAP_AS_WITH_POOL";
|
||||
private final String sapHost;
|
||||
private final String sapSysnr;
|
||||
private final String sapClient;
|
||||
private final String sapUsername;
|
||||
private final String sapPassword;
|
||||
private final String sapLang;
|
||||
private final String sapPool;
|
||||
private String sapPeak;
|
||||
|
||||
public SAPConfig(
|
||||
@Value("${custom.sap.host}") String sapHost,
|
||||
@Value("${custom.sap.sysnr}") String sapSysnr,
|
||||
@Value("${custom.sap.client}") String sapClient,
|
||||
@Value("${custom.sap.username}") String sapUsername,
|
||||
@Value("${custom.sap.password}") String sapPassword,
|
||||
@Value("${custom.sap.lang}") String sapLang,
|
||||
@Value("${custom.sap.pool}") String sapPool,
|
||||
@Value("${custom.sap.peak}") String sapPeak
|
||||
) {
|
||||
this.sapHost = sapHost;
|
||||
this.sapSysnr = sapSysnr;
|
||||
this.sapClient = sapClient;
|
||||
this.sapUsername = sapUsername;
|
||||
this.sapPassword = sapPassword;
|
||||
this.sapLang = sapLang;
|
||||
this.sapPool = sapPool;
|
||||
this.sapPeak = sapPeak;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void initDestination() {
|
||||
try {
|
||||
// 验证连接池配置有效性
|
||||
validatePoolConfig();
|
||||
// 直接注册到JCo内存环境(避免文件IO)
|
||||
Environment.registerDestinationDataProvider(new SimpleDestinationDataProvider(ABAP_AS_POOLED, buildConnectionProperties()));
|
||||
} catch (Exception e) {
|
||||
log.error("SAP JCo目的地初始化失败", e);
|
||||
throw new IllegalStateException("SAP JCo配置初始化失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Properties buildConnectionProperties() {
|
||||
Properties props = new Properties();
|
||||
props.setProperty(DestinationDataProvider.JCO_ASHOST, sapHost);
|
||||
props.setProperty(DestinationDataProvider.JCO_SYSNR, sapSysnr);
|
||||
props.setProperty(DestinationDataProvider.JCO_CLIENT, sapClient);
|
||||
props.setProperty(DestinationDataProvider.JCO_USER, sapUsername);
|
||||
props.setProperty(DestinationDataProvider.JCO_PASSWD, sapPassword);
|
||||
props.setProperty(DestinationDataProvider.JCO_LANG, sapLang);
|
||||
props.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, sapPeak);
|
||||
props.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, sapPool);
|
||||
return props;
|
||||
}
|
||||
// 连接池配置验证
|
||||
private void validatePoolConfig() {
|
||||
try {
|
||||
int peak = Integer.parseInt(sapPeak);
|
||||
int pool = Integer.parseInt(sapPool);
|
||||
if (peak < pool) {
|
||||
log.warn("JCO_PEAK_LIMIT({}) 不应小于 JCO_POOL_CAPACITY({}),已自动修正", peak, pool);
|
||||
sapPeak = sapPool;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("SAP连接池配置必须是数字");
|
||||
}
|
||||
}
|
||||
|
||||
@Bean(destroyMethod = "")
|
||||
public JCoDestination jcoDestination() throws JCoException {
|
||||
return JCoDestinationManager.getDestination(ABAP_AS_POOLED);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JCoRepository getJCoRepository() throws JCoException {
|
||||
return jcoDestination().getRepository();
|
||||
}
|
||||
|
||||
private static class SimpleDestinationDataProvider implements DestinationDataProvider {
|
||||
private final Map<String, Properties> destinations = new HashMap<>();
|
||||
public SimpleDestinationDataProvider(String destName, Properties props) {
|
||||
destinations.put(destName, props);
|
||||
}
|
||||
@Override
|
||||
public Properties getDestinationProperties(String destinationName) {
|
||||
return destinations.get(destinationName);
|
||||
}
|
||||
@Override
|
||||
public void setDestinationDataEventListener(DestinationDataEventListener listener) {}
|
||||
@Override
|
||||
public boolean supportsEvents() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
package com.nflg.wms.srm.receive.pojo.dto;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.nflg.wms.common.util.BomUtil;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class SAPMaterialInfoInOrderDTO {
|
||||
|
||||
/**
|
||||
* 未收货数量
|
||||
*/
|
||||
@JsonProperty("WSHSL")
|
||||
private BigDecimal transportNum;
|
||||
|
||||
/**
|
||||
* 仓库编号
|
||||
*/
|
||||
@JsonProperty("LGORT")
|
||||
private String warehouseNo;
|
||||
|
||||
/**
|
||||
* 采购凭证号
|
||||
*/
|
||||
private String ebeln;
|
||||
|
||||
/**
|
||||
* 采购凭证行项目
|
||||
*/
|
||||
private String ebelp;
|
||||
|
||||
public String getEbelp() {
|
||||
return StrUtil.removeAllPrefix(ebelp, "0");
|
||||
}
|
||||
|
||||
/**
|
||||
* 物料号
|
||||
*/
|
||||
private String matnr;
|
||||
|
||||
/**
|
||||
* 物料描述
|
||||
*/
|
||||
private String maktx;
|
||||
|
||||
/**
|
||||
* 标志:关键部件(是否质检)
|
||||
*/
|
||||
private String kzkri;
|
||||
|
||||
/**
|
||||
* 采购订单数量
|
||||
*/
|
||||
private BigDecimal menge;
|
||||
|
||||
/**
|
||||
* 收货数量
|
||||
*/
|
||||
|
||||
private BigDecimal wemng;
|
||||
|
||||
/**
|
||||
* 单位
|
||||
*/
|
||||
private String meins;
|
||||
|
||||
public String getMeins() {
|
||||
return BomUtil.changeMeins(meins);
|
||||
}
|
||||
|
||||
/**
|
||||
* 物料组
|
||||
*/
|
||||
private String matkl;
|
||||
|
||||
/**
|
||||
* 物料描述描述
|
||||
*/
|
||||
private String wgbez;
|
||||
|
||||
/**
|
||||
* 工厂
|
||||
*/
|
||||
private String werks;
|
||||
|
||||
/**
|
||||
* 标识:基于收获的发票验证
|
||||
*/
|
||||
private String webre;
|
||||
|
||||
/**
|
||||
* 打印参数
|
||||
*/
|
||||
private String lbprt;
|
||||
|
||||
/**
|
||||
* 特性值
|
||||
*/
|
||||
private String atwrt;
|
||||
|
||||
/**
|
||||
* 采购组
|
||||
*/
|
||||
private String ekgrp;
|
||||
|
||||
/**
|
||||
* 订单类型
|
||||
*/
|
||||
private String bsart;
|
||||
|
||||
/**
|
||||
* 供应商账号
|
||||
*/
|
||||
private String lifnr;
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package com.nflg.wms.srm.receive.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ZWM3A17DTO {
|
||||
|
||||
/**
|
||||
* 采购凭证号
|
||||
*/
|
||||
private String ebeln;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String usnam;
|
||||
|
||||
private List<ZWM3A17Item1DTO> item1 = new ArrayList<>();
|
||||
|
||||
private List<ZWM3A17Item2DTO> item2 = new ArrayList<>();
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package com.nflg.wms.srm.receive.pojo.dto;
|
||||
|
||||
import com.nflg.wms.common.util.BomUtil;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ZWM3A17Item1DTO {
|
||||
|
||||
/**
|
||||
* 采购凭证的项目编号
|
||||
*/
|
||||
private String EBELP;
|
||||
|
||||
/**
|
||||
* 物料号
|
||||
*/
|
||||
private String MATNR;
|
||||
|
||||
/**
|
||||
* 以输入单位计的数量
|
||||
*/
|
||||
private BigDecimal ERFMG;
|
||||
|
||||
/**
|
||||
* 基本计量单位
|
||||
*/
|
||||
private String MEINS;
|
||||
|
||||
public String getMeins() {
|
||||
return BomUtil.changeMeins(MEINS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批号
|
||||
*/
|
||||
private String CHARG;
|
||||
|
||||
/**
|
||||
* 工厂
|
||||
*/
|
||||
private String WERKS;
|
||||
|
||||
/**
|
||||
* 库存地点
|
||||
*/
|
||||
private String LGORT;
|
||||
|
||||
/**
|
||||
* 标志:关键部件
|
||||
*/
|
||||
private String KZKRI;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.nflg.wms.srm.receive.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ZWM3A17Item2DTO {
|
||||
|
||||
/**
|
||||
* 采购凭证的项目编号
|
||||
*/
|
||||
private String EBELP;
|
||||
|
||||
/**
|
||||
* 序列号
|
||||
*/
|
||||
private String SERNR;
|
||||
|
||||
/**
|
||||
* 标志,X表示合格品,空表示不合格品
|
||||
*/
|
||||
private String FLAG;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package com.nflg.wms.srm.receive.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ZWM3A18DTO {
|
||||
|
||||
/**
|
||||
* 采购凭证号
|
||||
*/
|
||||
private String ebeln;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String usnam;
|
||||
|
||||
/**
|
||||
* 物料凭证编号
|
||||
*/
|
||||
private String mblnr;
|
||||
|
||||
/**
|
||||
* 物料凭证年度
|
||||
*/
|
||||
private String mjahr;
|
||||
|
||||
private List<ZWM3A18Item1DTO> item1;
|
||||
|
||||
private List<ZWM3A17Item2DTO> item2;
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package com.nflg.wms.srm.receive.pojo.dto;
|
||||
|
||||
import com.nflg.wms.common.util.BomUtil;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ZWM3A18Item1DTO {
|
||||
|
||||
/**
|
||||
* 报检数量
|
||||
*/
|
||||
private BigDecimal erfmg;
|
||||
|
||||
/**
|
||||
* 质检合格数量
|
||||
*/
|
||||
private BigDecimal erfmg1;
|
||||
|
||||
/**
|
||||
* 质检不合格数量
|
||||
*/
|
||||
private BigDecimal erfmg2;
|
||||
|
||||
/**
|
||||
* 采购凭证的项目编号
|
||||
*/
|
||||
private String ebelp;
|
||||
|
||||
/**
|
||||
* 物料号
|
||||
*/
|
||||
private String matnr;
|
||||
|
||||
/**
|
||||
* 单位
|
||||
*/
|
||||
private String meins;
|
||||
|
||||
public String getMeins() {
|
||||
return BomUtil.changeMeins(meins);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批号
|
||||
*/
|
||||
private String charg;
|
||||
|
||||
/**
|
||||
* 库存地点
|
||||
*/
|
||||
private String lgort;
|
||||
|
||||
/**
|
||||
* 项目文本
|
||||
*/
|
||||
private String sgtxt;
|
||||
|
||||
/**
|
||||
* 工厂
|
||||
*/
|
||||
private String werks;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,103 @@
|
|||
package com.nflg.wms.srm.receive.util;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.MapperFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||
import com.nflg.wms.common.util.BeanUtil;
|
||||
import com.sap.conn.jco.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class JCoUtil {
|
||||
|
||||
private static final ObjectMapper MAPPER = JsonMapper.builder()
|
||||
.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
|
||||
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* 将 JCoTable 转换为 Java Bean 列表
|
||||
* @param table JCoTable 对象
|
||||
* @param clazz 目标实体类
|
||||
* @param <T> 泛型
|
||||
* @return List<T> 列表
|
||||
*/
|
||||
public static <T> List<T> toBeanList(JCoTable table, Class<T> clazz) {
|
||||
List<Map<String, Object>> mapList = toMapList(table);
|
||||
List<T> resultList = new ArrayList<>(mapList.size());
|
||||
for (Map<String, Object> map : mapList) {
|
||||
resultList.add(MAPPER.convertValue(map, clazz));
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
public static List<Map<String, Object>> toMapList(JCoTable table) {
|
||||
if (CollectionUtil.isEmpty(table) || table.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Map<String, Object>> mapList = new ArrayList<>();
|
||||
JCoRecordMetaData meta = table.getRecordMetaData();
|
||||
table.firstRow();
|
||||
do {
|
||||
Map<String, Object> rowMap = new HashMap<>();
|
||||
for (int i = 0; i < meta.getFieldCount(); i++) {
|
||||
rowMap.put(meta.getName(i), table.getField(i).getValue());
|
||||
}
|
||||
mapList.add(rowMap);
|
||||
} while (table.nextRow());
|
||||
return mapList;
|
||||
}
|
||||
|
||||
public static <T> List<Map<String, Object>> toMapList(List<T> datas) {
|
||||
return datas.stream().map(BeanUtil::toMap)
|
||||
.map(list -> list.entrySet().stream()
|
||||
.collect(Collectors.toMap(entry -> entry.getKey().toUpperCase(),
|
||||
Map.Entry::getValue)))
|
||||
.toList();
|
||||
}
|
||||
|
||||
public static <T> List<Map<String, Object>> toMapList(T data) {
|
||||
return Collections.singletonList(BeanUtil.toMap(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 JCoStructure 转换为 Java Bean
|
||||
* @param structure JCoStructure 对象
|
||||
* @param clazz 目标实体类
|
||||
* @param <T> 泛型
|
||||
* @return T 实体对象
|
||||
*/
|
||||
public static <T> T toBean(JCoStructure structure, Class<T> clazz) {
|
||||
if (Objects.isNull(structure)) {
|
||||
return null;
|
||||
}
|
||||
JCoRecordMetaData meta = structure.getRecordMetaData();
|
||||
Map<String, Object> rowMap = new HashMap<>();
|
||||
for (int i = 0; i < meta.getFieldCount(); i++) {
|
||||
rowMap.put(meta.getName(i), structure.getField(i).getValue());
|
||||
}
|
||||
return MAPPER.convertValue(rowMap, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 JCoParameterList 转换为 Java Bean
|
||||
* @param parameters JCoParameterList 对象
|
||||
* @param clazz 目标实体类
|
||||
* @param <T> 泛型
|
||||
* @return T 实体对象
|
||||
*/
|
||||
public static <T> T toBean(JCoParameterList parameters, Class<T> clazz) {
|
||||
if (Objects.isNull(parameters)) {
|
||||
return null;
|
||||
}
|
||||
JCoListMetaData meta = parameters.getListMetaData();
|
||||
Map<String, Object> rowMap = new HashMap<>();
|
||||
for (int i = 0; i < meta.getFieldCount(); i++) {
|
||||
rowMap.put(meta.getName(i), parameters.getField(i).getValue());
|
||||
}
|
||||
return MAPPER.convertValue(rowMap, clazz);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,410 @@
|
|||
package com.nflg.wms.srm.receive;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.sap.conn.jco.*;
|
||||
import com.sap.conn.jco.ext.DestinationDataEventListener;
|
||||
import com.sap.conn.jco.ext.DestinationDataProvider;
|
||||
import com.sap.conn.jco.ext.Environment;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SapMetaPrintTest {
|
||||
|
||||
@Test
|
||||
public void ZWM3A22() throws JCoException {
|
||||
printMeta("ZWM3A22");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A23() throws JCoException {
|
||||
printMeta("ZWM3A23");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZIM_004() throws JCoException {
|
||||
printMeta("ZIM_004");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A02() throws JCoException {
|
||||
printMeta("ZWM3A02");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZRFC_MM_SMXT() throws JCoException {
|
||||
printMeta("ZRFC_MM_SMXT");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A17() throws JCoException {
|
||||
printMeta("ZWM3A17");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A18() throws JCoException {
|
||||
printMeta("ZWM3A18");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM00_MB007() throws JCoException {
|
||||
printMeta("ZWM00_MB007");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM00_MB107() throws JCoException {
|
||||
printMeta("ZWM00_MB107");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZIM_001_QUERY() throws JCoException {
|
||||
printMeta("ZIM_001_QUERY");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A05() throws JCoException {
|
||||
printMeta("ZWM3A05");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZIM_001() throws JCoException {
|
||||
printMeta("ZIM_001");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A06() throws JCoException {
|
||||
printMeta("ZWM3A06");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM00_MB017() throws JCoException {
|
||||
printMeta("ZWM00_MB017");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM00_MB112() throws JCoException {
|
||||
printMeta("ZWM00_MB112");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM00_MB026() throws JCoException {
|
||||
printMeta("ZWM00_MB026");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM00_MB115() throws JCoException {
|
||||
printMeta("ZWM00_MB115");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A03() throws JCoException {
|
||||
printMeta("ZWM3A03");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A04() throws JCoException {
|
||||
printMeta("ZWM3A04");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A07() throws JCoException {
|
||||
printMeta("ZWM3A07");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A10() throws JCoException {
|
||||
printMeta("ZWM3A10");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A08() throws JCoException {
|
||||
printMeta("ZWM3A08");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A09() throws JCoException {
|
||||
printMeta("ZWM3A09");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A11() throws JCoException {
|
||||
printMeta("ZWM3A11");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A12() throws JCoException {
|
||||
printMeta("ZWM3A12");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A13() throws JCoException {
|
||||
printMeta("ZWM3A13");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A14() throws JCoException {
|
||||
printMeta("ZWM3A14");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A15() throws JCoException {
|
||||
printMeta("ZWM3A15");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A16() throws JCoException {
|
||||
printMeta("ZWM3A16");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM00_MB113() throws JCoException {
|
||||
printMeta("ZWM00_MB113");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM00_MB116() throws JCoException {
|
||||
printMeta("ZWM00_MB116");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A21() throws JCoException {
|
||||
printMeta("ZWM3A21");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void ZWM3A19() throws JCoException {
|
||||
printMeta("ZWM3A19");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void ZWM3A20() throws JCoException {
|
||||
printMeta("ZWM3A20");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A24() throws JCoException {
|
||||
printMeta("ZWM3A24");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ZWM3A25() throws JCoException {
|
||||
printMeta("ZWM3A25");
|
||||
}
|
||||
|
||||
|
||||
public void printMeta(String functionName) throws JCoException {
|
||||
functionName = functionName.toUpperCase();
|
||||
JCoFunction function = repository.getFunction(functionName);
|
||||
if (Objects.isNull(function)) {
|
||||
print("方法" + functionName + "不存在");
|
||||
} else {
|
||||
printMeta(function);
|
||||
}
|
||||
}
|
||||
|
||||
private void printMeta(JCoFunction function) {
|
||||
print("SAP {} 方法参数信息", function.getName());
|
||||
printParameterField("Import", function.getImportParameterList());
|
||||
printParameterField("Changing", function.getChangingParameterList());
|
||||
printParameterField("Export", function.getExportParameterList());
|
||||
printParameterField("Table", function.getTableParameterList());
|
||||
}
|
||||
|
||||
private void printParameterField(String name, JCoParameterList parameterList) {
|
||||
print("▶ " + name);
|
||||
if (Objects.nonNull(parameterList)) {
|
||||
JCoParameterFieldIterator iterator = parameterList.getParameterFieldIterator();
|
||||
if (Objects.nonNull(iterator)) {
|
||||
List<JCoParameterField> fields = new ArrayList<>();
|
||||
List<String[]> data = new ArrayList<>();
|
||||
JSONObject jo = new JSONObject();
|
||||
while (iterator.hasNextField()) {
|
||||
JCoParameterField field = iterator.nextParameterField();
|
||||
data.add(new String[]{field.getName(), field.getTypeAsString(), field.getDescription()});
|
||||
if (field.isTable() || field.isStructure()) {
|
||||
fields.add(field);
|
||||
}
|
||||
jo.putOnce(field.getName(), field.getDescription());
|
||||
}
|
||||
printTable(data);
|
||||
printJson(jo);
|
||||
fields.forEach(this::print);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void print(JCoParameterField field) {
|
||||
print("★★ {}({}) 参数", field.getName(), field.getDescription());
|
||||
if (field.isTable()) {
|
||||
print(field.getTable().getRecordFieldIterator());
|
||||
} else if (field.isStructure()) {
|
||||
print(field.getStructure().getRecordFieldIterator());
|
||||
}
|
||||
}
|
||||
|
||||
private void print(JCoRecordFieldIterator iterator) {
|
||||
List<String[]> data = new ArrayList<>();
|
||||
JSONObject jo = new JSONObject();
|
||||
while (iterator.hasNextField()) {
|
||||
JCoRecordField field = iterator.nextRecordField();
|
||||
data.add(new String[]{field.getName(), field.getTypeAsString(), field.getDescription()});
|
||||
jo.putOnce(field.getName(), field.getDescription());
|
||||
}
|
||||
printTable(data);
|
||||
printJson(jo);
|
||||
}
|
||||
|
||||
private void printJson(JSONObject jo) {
|
||||
print("JSON形式:");
|
||||
print(JSONUtil.toJsonPrettyStr(jo).toLowerCase());
|
||||
}
|
||||
|
||||
private void printTable(List<String[]> datas) {
|
||||
print("表格形式:");
|
||||
SimpleTable table = new SimpleTable();
|
||||
table.addHeader("序号", "名称", "类型", "描述");
|
||||
for (int i = 0; i < datas.size(); i++) {
|
||||
table.addRow(String.valueOf(i + 1), datas.get(i)[0], datas.get(i)[1], datas.get(i)[2]);
|
||||
}
|
||||
table.print();
|
||||
}
|
||||
|
||||
private void print(String content) {
|
||||
System.out.println(content);
|
||||
}
|
||||
|
||||
private void print(String template, Object... args) {
|
||||
System.out.println(StrUtil.format(template, args));
|
||||
}
|
||||
|
||||
// 简单实现示例
|
||||
private static class SimpleTable {
|
||||
private final List<String[]> rows = new ArrayList<>();
|
||||
private final List<String> headers = new ArrayList<>();
|
||||
|
||||
public void addHeader(String... headers) {
|
||||
this.headers.addAll(Arrays.asList(headers));
|
||||
}
|
||||
|
||||
public void addRow(String... values) {
|
||||
rows.add(values);
|
||||
}
|
||||
|
||||
public void print() {
|
||||
// 计算每列最大宽度
|
||||
int[] maxWidths = new int[headers.size()];
|
||||
for (int i = 0; i < headers.size(); i++) {
|
||||
maxWidths[i] = getWeightedLength(headers.get(i));
|
||||
}
|
||||
|
||||
for (String[] row : rows) {
|
||||
for (int i = 0; i < row.length && i < maxWidths.length; i++) {
|
||||
maxWidths[i] = Math.max(maxWidths[i], getWeightedLength(row[i]));
|
||||
}
|
||||
}
|
||||
|
||||
// 打印表格
|
||||
printLine(maxWidths);
|
||||
printRow(headers.toArray(new String[0]), maxWidths);
|
||||
printLine(maxWidths);
|
||||
|
||||
for (String[] row : rows) {
|
||||
printRow(row, maxWidths);
|
||||
}
|
||||
printLine(maxWidths);
|
||||
}
|
||||
|
||||
private void printLine(int[] widths) {
|
||||
System.out.print("+");
|
||||
for (int width : widths) {
|
||||
for (int i = 0; i < width + 2; i++) {
|
||||
System.out.print("-");
|
||||
}
|
||||
System.out.print("+");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
private void printRow(String[] row, int[] widths) {
|
||||
System.out.print("|");
|
||||
for (int i = 0; i < widths.length; i++) {
|
||||
String value = i < row.length ? row[i] : "";
|
||||
System.out.printf(" %-" + (widths[i] - getChineseNum(value) / 2) + "s |", value);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
private static final String CHINESE_REGEX = "[\\u4e00-\\u9fff]";
|
||||
|
||||
public static int getWeightedLength(String str) {
|
||||
if (str == null || str.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
return str.chars()
|
||||
.map(c -> String.valueOf((char) c).matches(CHINESE_REGEX) ? 2 : 1)
|
||||
.sum();
|
||||
}
|
||||
|
||||
public static int getChineseNum(String str) {
|
||||
if (str == null || str.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
return str.chars()
|
||||
.map(c -> String.valueOf((char) c).matches(CHINESE_REGEX) ? 1 : 0)
|
||||
.sum();
|
||||
}
|
||||
}
|
||||
|
||||
private static JCoRepository repository;
|
||||
|
||||
@BeforeAll
|
||||
static void initOnce() throws JCoException {
|
||||
Environment.registerDestinationDataProvider(new SimpleDestinationDataProvider(ABAP_AS_POOLED, buildConnectionProperties()));
|
||||
repository = JCoDestinationManager.getDestination(ABAP_AS_POOLED).getRepository();
|
||||
}
|
||||
|
||||
private static final String ABAP_AS_POOLED = "ABAP_AS_WITH_POOL";
|
||||
|
||||
private static Properties buildConnectionProperties() {
|
||||
Properties props = new Properties();
|
||||
props.setProperty(DestinationDataProvider.JCO_ASHOST, "192.168.0.24");
|
||||
props.setProperty(DestinationDataProvider.JCO_SYSNR, "03");
|
||||
props.setProperty(DestinationDataProvider.JCO_CLIENT, "800");
|
||||
props.setProperty(DestinationDataProvider.JCO_USER, "mdm_back");
|
||||
props.setProperty(DestinationDataProvider.JCO_PASSWD, "sap-mdm");
|
||||
props.setProperty(DestinationDataProvider.JCO_LANG, "ZH");
|
||||
props.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "10");
|
||||
props.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "20");
|
||||
return props;
|
||||
}
|
||||
|
||||
private static class SimpleDestinationDataProvider implements DestinationDataProvider {
|
||||
private final Map<String, Properties> destinations = new HashMap<>();
|
||||
|
||||
public SimpleDestinationDataProvider(String destName, Properties props) {
|
||||
destinations.put(destName, props);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties getDestinationProperties(String destinationName) {
|
||||
return destinations.get(destinationName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDestinationDataEventListener(DestinationDataEventListener listener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsEvents() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue