erp公司、物料、客商定时任务接口

This commit is contained in:
liss
2025-09-18 16:28:47 +08:00
parent 65249fe9d4
commit ee18a70745
18 changed files with 770 additions and 111 deletions

View File

@@ -0,0 +1,126 @@
package cn.iocoder.yudao.module.erp.common.conf;
import cn.iocoder.yudao.module.erp.common.enums.OftenEnum;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.util.*;
import java.util.stream.Collectors;
import static dm.jdbc.util.DriverUtil.log;
@Configuration
public class ErpConfig {
@Value("${erp.address}")
private String erpAddress;
@Value("${erp.sapsys}")
private String sapsys;
@Resource
private RedisTemplate redisTemplate;
/**
* 调用ERP接口获取公司数据
*/
public JSONArray fetchDataFromERP(String funcnr, Map<String, Object> req) {
// 构建完整URL
String url = "http://" + erpAddress + "/api/rfc/get";
// 构建请求参数
JSONObject requestBody = new JSONObject();
requestBody.put("sapsys", sapsys);
requestBody.put("funcnr", funcnr); // 获取枚举值
if (req != null) {
requestBody.put("req", req);
}
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 创建HTTP请求实体
HttpEntity<String> requestEntity = new HttpEntity<>(requestBody.toJSONString(), headers);
// 发送POST请求
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);
// 解析响应结果
String responseBody = response.getBody();
if (responseBody == null) {
log.warn("ERP接口返回空响应");
return null;
}
JSONObject jsonResponse = JSON.parseObject(responseBody);
if (jsonResponse == null) {
log.warn("ERP接口响应无法解析为JSON");
return null;
}
// 正确获取E_DATA数组
JSONObject dataObject = jsonResponse.getJSONObject("data");
if (dataObject != null && "S".equals(dataObject.getString("E_FLAG"))) {
return dataObject.getJSONArray("E_DATA");
} else {
log.warn("ERP接口调用失败或返回错误标志");
return null;
}
}
public Map<String, List<String>> numbers(JSONArray dataArray, String key,String dataKey) {
// 使用 Redis 获取缓存数据
Map<String, List<String>> numbers = new HashMap<>();
List<String> cachedNumbers = (List<String>) redisTemplate.opsForValue().get(key);
if (cachedNumbers == null) {
cachedNumbers = new ArrayList<>();
}
// 提取有效的 BUKRS 编号
List<String> existingNumbers = new ArrayList<>();
if (dataArray != null) {
existingNumbers = dataArray.stream()
.filter(Objects::nonNull)
.map(dataJson -> ((JSONObject) dataJson).getString(dataKey))
.filter(Objects::nonNull)
.map(String::trim) // 去除字符串首尾空格
.collect(Collectors.toList());
}
// 找出共同存在的编号
Set<String> cachedNumberSet = new HashSet<>(cachedNumbers != null ? cachedNumbers : new ArrayList<>());
List<String> commonNumbers = existingNumbers.stream()
.filter(cachedNumberSet::contains)
.collect(Collectors.toList());
numbers.put("com", commonNumbers);
List<String> newNumbers = existingNumbers.stream()
.filter(num -> !cachedNumberSet.contains(num))
.collect(Collectors.toList());
// 合并所有编号
List<String> allNumbers = new ArrayList<>(cachedNumbers);
allNumbers.addAll(newNumbers);
numbers.put("all", allNumbers);
return numbers;
}
public void updateRedisCache(String key, List<String> allnumbers) {
// 使用 Redis 更新缓存数据
redisTemplate.opsForValue().set(key, allnumbers);
}
}

View File

@@ -0,0 +1,165 @@
package cn.iocoder.yudao.module.erp.common.conf;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
//import redis.clients.jedis.JedisPoolConfig;
/**
* @author wuxz
* @create 2022-06-07 20:54
*/
@Primary
@Configuration
public class MyRedisConfig {
/*
@Value("${spring.redis.database}")
private Integer database;
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private Integer port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.jedis.pool.max-idle}")
private Integer max_idle;
@Value("${spring.redis.jedis.pool.min-idle}")
private Integer min_idle;
@Value("${spring.redis.jedis.pool.max-active}")
private Integer max_active;
@Value("${spring.redis.jedis.pool.max-wait}")
private Integer max_wait;
*/
@Bean(value = "MyRedisTemplate")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 通过 Jackson 组件进行序列化
RedisSerializer<Object> serializer = redisSerializer();
// key 和 value
// 一般来说, redis-key采用字符串序列化
// redis-value采用json序列化 json的体积小可读性高不需要实现serializer接口。
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(serializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(serializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
public RedisSerializer<Object> redisSerializer() {
//创建JSON序列化器
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// objectMapper.enableDefaultTyping()被弃用
objectMapper.activateDefaultTyping(
LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.WRAPPER_ARRAY);
serializer.setObjectMapper(objectMapper);
return serializer;
}
// @Bean
// public JedisPoolConfig jedisPoolConfig() {
// JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// //最小空闲连接数
// jedisPoolConfig.setMinIdle(min_idle);
// jedisPoolConfig.setMaxIdle(max_idle);
// jedisPoolConfig.setMaxTotal(max_active);
// //当池内没有可用的连接时,最大等待时间
// jedisPoolConfig.setMaxWaitMillis(max_wait);
// //------其他属性根据需要自行添加-------------
// return jedisPoolConfig;
// }
//
//
// /**
// * jedis连接工厂
// * @param jedisPoolConfig
// * @return
// */
// @Bean
// public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
// //单机版jedis
// RedisStandaloneConfiguration redisStandaloneConfiguration =
// new RedisStandaloneConfiguration();
// //设置redis服务器的host或者ip地址
// redisStandaloneConfiguration.setHostName(host);
// //设置默认使用的数据库
// redisStandaloneConfiguration.setDatabase(database);
// //设置密码
// redisStandaloneConfiguration.setPassword(password);
// //设置redis的服务的端口号
// redisStandaloneConfiguration.setPort(port);
// //获得默认的连接池构造器
// JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jc =
// (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder)JedisClientConfiguration.builder();
// //指定jedisPoolConifig
// jc.poolConfig(jedisPoolConfig);
// //通过构造器来构造jedis客户端配置
// JedisClientConfiguration jedisClientConfiguration = jc.build();
// return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
// }
//
//
// @Bean
// @ConditionalOnMissingBean(name = {"redisTemplate"})
// public RedisTemplate<String, Serializable> redisTemplate(JedisConnectionFactory jedisConnectionFactory){
// RedisTemplate<String, Serializable> redisTemplate = new RedisTemplate<>();
// redisTemplate.setKeySerializer(new StringRedisSerializer());
// redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
// redisTemplate.setConnectionFactory(jedisConnectionFactory);
// return redisTemplate;
// }
/**
* 序列化乱码问题解决
*/
// @Bean
// public RedisTemplate<String, Serializable> redisTemplate(JedisConnectionFactory jedisConnectionFactory){
// RedisTemplate<String, Serializable> redisTemplate = new RedisTemplate<>();
// redisTemplate.setKeySerializer(new StringRedisSerializer());
// redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
// redisTemplate.setConnectionFactory(jedisConnectionFactory);
// return redisTemplate;
// }
}

View File

@@ -13,32 +13,60 @@ public class OftenEnum {
//接口编号枚举 //接口编号枚举
public enum FuncnrEnum { public enum FuncnrEnum {
公司代码("001"), 公司代码("001", "BUKRS", ""),
工厂信息("002"), 工厂信息("002", "", ""),
客商信息("003"), 客商信息("003", "PARTNER", "DATUM"),
成本中心("004"), 成本中心("004", "", ""),
内部订单("005"), 内部订单("005", "", ""),
库位信息("006"), 库位信息("006", "", ""),
采购组织("007"), 采购组织("007", "", ""),
销售组织("008"), 销售组织("008", "", ""),
合同信息("009"), 合同信息("009", "", ""),
资产卡片("010"), 资产卡片("010", "", ""),
库存信息("011"), 库存信息("011", "", ""),
辅组编码("012"), 辅组编码("012", "", ""),
生产订单("013"), 生产订单("013", "", ""),
BOM清单("014"), BOM清单("014", "", ""),
工艺路线("015"), 工艺路线("015", "", ""),
生产版本("016"), 生产版本("016", "", ""),
生产投料("017"), 生产投料("017", "", ""),
生产订单明细("018"), 生产订单明细("018", "", ""),
库存明细("019"), 库存明细("019", "", ""),
发票状态("020"), 发票状态("020", "", ""),
物料数据("021"); 物料数据("021", "", "ERSDA");
public String funcnr = null; private final String funcnr;
private final String datakey;
private final String datekey;
FuncnrEnum(String funcnr) { FuncnrEnum(String funcnr, String datakey,String datekey) {
this.funcnr = funcnr; this.funcnr = funcnr;
this.datakey = datakey;
this.datekey = datekey;
}
public String getFuncnr() {
return funcnr;
}
public String getDatakey() {
return datakey;
}
public String getDatekey() {
return datekey;
}
}
//接口编号枚举
public enum ModeTypeEnum {
供应商("K"),
客户("D");
public String modetype = null;
ModeTypeEnum(String modetype) {
this.modetype = modetype;
} }
} }
} }

View File

@@ -15,7 +15,7 @@ import org.springframework.transaction.annotation.Transactional;
**/ **/
@Configuration @Configuration
@EnableScheduling @EnableScheduling
public class statisticsTask { public class statisticstask {
@Resource @Resource
private ErpCompanyService erpCompanyService; private ErpCompanyService erpCompanyService;

View File

@@ -104,4 +104,18 @@ public class ErpCustomerController {
BeanUtils.toBean(list, ErpCustomerRespVO.class)); BeanUtils.toBean(list, ErpCustomerRespVO.class));
} }
@PostMapping("/getErpCustomerTask")
@Operation(summary = "定时获得erp更新客商主数据")
@PreAuthorize("@ss.hasPermission('sply:erp-customer:create')")
public void getErpCustomerTask() {
erpCustomerService.callErpRfcInterface();
}
@PostMapping("/initialize")
@Operation(summary = "把数据库数据number搞到redis")
@PreAuthorize("@ss.hasPermission('sply:erp-customer:create')")
public void initialize() {
erpCustomerService.initialize();
}
} }

View File

@@ -104,4 +104,18 @@ public class ErpMaterialController {
BeanUtils.toBean(list, ErpMaterialRespVO.class)); BeanUtils.toBean(list, ErpMaterialRespVO.class));
} }
@PostMapping("/callErpRfcInterface")
@Operation(summary = "定时获得erp更新公司")
@PreAuthorize("@ss.hasPermission('sply:erp-material:create')")
public void callErpRfcInterface() {
erpMaterialService.callErpRfcInterface();
}
@PostMapping("/initialize")
@Operation(summary = "把数据库数据number搞到redis")
@PreAuthorize("@ss.hasPermission('sply:erp-material:create')")
public void initialize() {
erpMaterialService.initialize();
}
} }

View File

@@ -41,7 +41,4 @@ public class ErpCustomerPageReqVO extends PageParam {
@Schema(description = "冻结标识") @Schema(description = "冻结标识")
private String isProvisional; private String isProvisional;
@Schema(description = "类型", example = "2")
private String type;
} }

View File

@@ -51,8 +51,4 @@ public class ErpCustomerRespVO {
@ExcelProperty("冻结标识") @ExcelProperty("冻结标识")
private String isProvisional; private String isProvisional;
@Schema(description = "类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty("类型")
private String type;
} }

View File

@@ -45,8 +45,4 @@ public class ErpCustomerSaveReqVO {
@Schema(description = "冻结标识") @Schema(description = "冻结标识")
private String isProvisional; private String isProvisional;
@Schema(description = "类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotEmpty(message = "类型不能为空")
private String type;
} }

View File

@@ -12,7 +12,8 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@TableName("sply_erp_cpn") @TableName("sply_erp_cpn")
@KeySequence("sply_erp_cpn_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @KeySequence("sply_erp_cpn_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data @Data
@EqualsAndHashCode(callSuper = true) //@EqualsAndHashCode(callSuper = true)
@EqualsAndHashCode
@ToString(callSuper = true) @ToString(callSuper = true)
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@@ -20,9 +21,8 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/** /**
* 支持业务基类继承isBusiness=true 时继承 BusinessBaseDO否则继承 BaseDO * 支持业务基类继承isBusiness=true 时继承 BusinessBaseDO否则继承 BaseDO
*/ */
public class ErpCompanyDO extends BaseDO { //public class ErpCompanyDO extends BaseDO {
public class ErpCompanyDO{
/** /**
* 主键 * 主键
@@ -45,4 +45,7 @@ public class ErpCompanyDO extends BaseDO {
@TableField("CUR") @TableField("CUR")
private String currency; private String currency;
@TableField(exist = false)
private Integer TENANT_ID;
} }

View File

@@ -14,7 +14,8 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@TableName("sply_erp_cstm") @TableName("sply_erp_cstm")
@KeySequence("sply_erp_cstm_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @KeySequence("sply_erp_cstm_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data @Data
@EqualsAndHashCode(callSuper = true) //@EqualsAndHashCode(callSuper = true)
@EqualsAndHashCode
@ToString(callSuper = true) @ToString(callSuper = true)
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@@ -22,7 +23,8 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/** /**
* 支持业务基类继承isBusiness=true 时继承 BusinessBaseDO否则继承 BaseDO * 支持业务基类继承isBusiness=true 时继承 BusinessBaseDO否则继承 BaseDO
*/ */
public class ErpCustomerDO extends BaseDO { //public class ErpCustomerDO extends BaseDO {
public class ErpCustomerDO{
@@ -76,10 +78,8 @@ public class ErpCustomerDO extends BaseDO {
*/ */
@TableField("IS_PRVS") @TableField("IS_PRVS")
private String isProvisional; private String isProvisional;
/**
* 类型 @TableField(exist = false)
*/ private Integer TENANT_ID;
@TableField("TP")
private String type;
} }

View File

@@ -13,7 +13,8 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@TableName("sply_erp_mtrl") @TableName("sply_erp_mtrl")
@KeySequence("sply_erp_mtrl_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @KeySequence("sply_erp_mtrl_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data @Data
@EqualsAndHashCode(callSuper = true) //@EqualsAndHashCode(callSuper = true)
@EqualsAndHashCode
@ToString(callSuper = true) @ToString(callSuper = true)
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@@ -21,7 +22,8 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/** /**
* 支持业务基类继承isBusiness=true 时继承 BusinessBaseDO否则继承 BaseDO * 支持业务基类继承isBusiness=true 时继承 BusinessBaseDO否则继承 BaseDO
*/ */
public class ErpMaterialDO extends BaseDO { //public class ErpMaterialDO extends BaseDO {
public class ErpMaterialDO {
@@ -96,4 +98,7 @@ public class ErpMaterialDO extends BaseDO {
@TableField("MTRL_LEN_DSP") @TableField("MTRL_LEN_DSP")
private String materialLengthDescription; private String materialLengthDescription;
@TableField(exist = false)
private Integer TENANT_ID;
} }

View File

@@ -26,7 +26,6 @@ public interface ErpCustomerMapper extends BaseMapperX<ErpCustomerDO> {
.betweenIfPresent(ErpCustomerDO::getRepairDate, reqVO.getRepairDate()) .betweenIfPresent(ErpCustomerDO::getRepairDate, reqVO.getRepairDate())
.eqIfPresent(ErpCustomerDO::getIsGiveback, reqVO.getIsGiveback()) .eqIfPresent(ErpCustomerDO::getIsGiveback, reqVO.getIsGiveback())
.eqIfPresent(ErpCustomerDO::getIsProvisional, reqVO.getIsProvisional()) .eqIfPresent(ErpCustomerDO::getIsProvisional, reqVO.getIsProvisional())
.eqIfPresent(ErpCustomerDO::getType, reqVO.getType())
.orderByDesc(ErpCustomerDO::getId)); .orderByDesc(ErpCustomerDO::getId));
} }

View File

@@ -2,26 +2,24 @@ package cn.iocoder.yudao.module.erp.service.erp;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.erp.common.conf.ErpConfig;
import cn.iocoder.yudao.module.erp.common.enums.OftenEnum; import cn.iocoder.yudao.module.erp.common.enums.OftenEnum;
import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpCompanyPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpCompanyPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpCompanyRespVO; import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpCompanyRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpCompanySaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpCompanySaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.erp.ErpCompanyDO; import cn.iocoder.yudao.module.erp.dal.dataobject.erp.ErpCompanyDO;
import cn.iocoder.yudao.module.erp.dal.mysql.erp.ErpCompanyMapper; import cn.iocoder.yudao.module.erp.dal.mysql.erp.ErpCompanyMapper;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
@@ -38,15 +36,12 @@ import static dm.jdbc.util.DriverUtil.log;
@Validated @Validated
public class ErpCompanyServiceImpl implements ErpCompanyService { public class ErpCompanyServiceImpl implements ErpCompanyService {
@Value("${erp.address}")
private String erpAddress;
@Value("${erp.sapsys}")
private String sapsys;
@Resource @Resource
private ErpCompanyMapper erpCompanyMapper; private ErpCompanyMapper erpCompanyMapper;
@Resource
private ErpConfig erpConfig;
@Override @Override
public ErpCompanyRespVO createErpCompany(ErpCompanySaveReqVO createReqVO) { public ErpCompanyRespVO createErpCompany(ErpCompanySaveReqVO createReqVO) {
// 插入 // 插入
@@ -105,61 +100,91 @@ public class ErpCompanyServiceImpl implements ErpCompanyService {
} }
@Override @Override
@Transactional
public void callErpRfcInterface() { public void callErpRfcInterface() {
try { try {
// 构建完整URL OftenEnum.FuncnrEnum funcnrEnum =OftenEnum.FuncnrEnum.公司代码;
String url = "http://" + erpAddress + "/api/rfc/get"; String funcnr = funcnrEnum.getFuncnr();
// 构建请求参数 // 1. 调用ERP接口获取数据
JSONObject requestBody = new JSONObject(); JSONArray dataArray = erpConfig.fetchDataFromERP(funcnr, null);
requestBody.put("sapsys", sapsys); if (dataArray == null || dataArray.isEmpty()) {
requestBody.put("funcnr", OftenEnum.FuncnrEnum.公司代码.funcnr); // 获取枚举值 return;
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 创建HTTP请求实体
HttpEntity<String> requestEntity = new HttpEntity<>(requestBody.toJSONString(), headers);
// 发送POST请求
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);
// 解析响应结果
JSONObject jsonResponse = JSON.parseObject(response.getBody());
// 正确获取E_DATA数组
JSONObject dataObject = jsonResponse.getJSONObject("data");
if (dataObject != null && "S".equals(dataObject.getString("E_FLAG"))) {
JSONArray companyArray = dataObject.getJSONArray("E_DATA");
// 批量插入公司数据
if (companyArray != null && !companyArray.isEmpty()) {
List<ErpCompanyDO> erpCompanyDOS = new ArrayList<>();
for (int i = 0; i < companyArray.size(); i++) {
JSONObject companyJson = companyArray.getJSONObject(i);
if (companyJson != null) {
ErpCompanyDO companyDO = new ErpCompanyDO();
companyDO.setName(companyJson.getString("BUTXT"));
companyDO.setNumber(companyJson.getString("BUKRS"));
companyDO.setCurrency(companyJson.getString("WAERS"));
erpCompanyDOS.add(companyDO);
}
}
// 批量插入数据库
if (!erpCompanyDOS.isEmpty()) {
erpCompanyMapper.insertBatch(erpCompanyDOS);
}
}
} else {
log.warn("ERP接口调用失败或返回错误标志");
} }
// 2. 处理公司数据,区分新增和更新
ProcessingResult result = processData(dataArray,funcnrEnum);
// 3. 批量保存数据
saveData(result);
} catch (Exception e) { } catch (Exception e) {
log.error("调用ERP RFC接口失败: {}", e); log.error("调用ERP RFC接口失败: {}", e);
throw new RuntimeException("调用ERP RFC接口失败: " + e.getMessage(), e); throw new RuntimeException("调用ERP RFC接口失败: " + e.getMessage(), e);
} }
} }
/**
* 处理数据,区分新增和更新
*/
private ProcessingResult processData(JSONArray dataArray, OftenEnum.FuncnrEnum funcnr) {
String key = "erp" + funcnr.getFuncnr();
Map<String,List<String>> numbers = erpConfig.numbers(dataArray, key,funcnr.getDatakey());
List<String> allnumbers = numbers.get("all");
List<String> comnumbers = numbers.get("com");
List<ErpCompanyDO> toUpdate = new ArrayList<>();
List<ErpCompanyDO> toInsert = new ArrayList<>();
for (int i = 0; i < dataArray.size(); i++) {
JSONObject dataJson = dataArray.getJSONObject(i);
if (dataJson != null) {
String number = dataJson.getString("BUKRS").trim();
if (number != null) {
ErpCompanyDO DO = new ErpCompanyDO();
DO.setName(dataJson.getString("BUTXT"));
DO.setNumber(number);
DO.setCurrency(dataJson.getString("WAERS"));
if (comnumbers.contains(number)) {
// 更新
toUpdate.add(DO);
} else {
// 新增
toInsert.add(DO);
}
}
}
}
return new ProcessingResult(toUpdate, toInsert,key,allnumbers);
}
/**
* 批量保存数据
*/
private void saveData(ProcessingResult result) {
// 批量新增和更新
if (!result.toInsert.isEmpty()) {
erpCompanyMapper.insertBatch(result.toInsert);
}
if (!result.toUpdate.isEmpty()) {
erpCompanyMapper.updateBatch(result.toUpdate);
}
erpConfig.updateRedisCache(result.key,result.allnumbers);
}
/**
* 数据处理结果封装类
*/
private static class ProcessingResult {
private final List<ErpCompanyDO> toUpdate;
private final List<ErpCompanyDO> toInsert;
private final String key;
private final List<String> allnumbers;
public ProcessingResult(List<ErpCompanyDO> toUpdate, List<ErpCompanyDO> toInsert,String key,List<String> allnumbers) {
this.toUpdate = toUpdate;
this.toInsert = toInsert;
this.key = key;
this.allnumbers = allnumbers;
}
}
} }

View File

@@ -61,4 +61,7 @@ public interface ErpCustomerService {
*/ */
PageResult<ErpCustomerDO> getErpCustomerPage(ErpCustomerPageReqVO pageReqVO); PageResult<ErpCustomerDO> getErpCustomerPage(ErpCustomerPageReqVO pageReqVO);
void callErpRfcInterface();
void initialize();
} }

View File

@@ -1,22 +1,33 @@
package cn.iocoder.yudao.module.erp.service.erp; package cn.iocoder.yudao.module.erp.service.erp;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.erp.common.conf.ErpConfig;
import cn.iocoder.yudao.module.erp.common.enums.OftenEnum;
import cn.iocoder.yudao.module.erp.dal.dataobject.erp.ErpCustomerDO; import cn.iocoder.yudao.module.erp.dal.dataobject.erp.ErpCustomerDO;
import cn.iocoder.yudao.module.erp.dal.mysql.erp.ErpCustomerMapper; import cn.iocoder.yudao.module.erp.dal.mysql.erp.ErpCustomerMapper;
import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpCustomerPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpCustomerPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpCustomerRespVO; import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpCustomerRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpCustomerSaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpCustomerSaveReqVO;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.ERP_CUSTOMER_NOT_EXISTS; import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.ERP_CUSTOMER_NOT_EXISTS;
import static dm.jdbc.util.DriverUtil.log;
/** /**
* ERP客商主数据 Service 实现类 * ERP客商主数据 Service 实现类
@@ -27,6 +38,12 @@ import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.ERP_CUSTOMER_
@Validated @Validated
public class ErpCustomerServiceImpl implements ErpCustomerService { public class ErpCustomerServiceImpl implements ErpCustomerService {
@Resource
private RedisTemplate redisTemplate;
@Resource
private ErpConfig erpConfig;
@Resource @Resource
private ErpCustomerMapper erpCustomerMapper; private ErpCustomerMapper erpCustomerMapper;
@@ -87,4 +104,129 @@ public class ErpCustomerServiceImpl implements ErpCustomerService {
return erpCustomerMapper.selectPage(pageReqVO); return erpCustomerMapper.selectPage(pageReqVO);
} }
@Override
@Transactional
public void callErpRfcInterface() {
try {
OftenEnum.FuncnrEnum funcnrEnum = OftenEnum.FuncnrEnum.客商信息;
String funcnr = funcnrEnum.getFuncnr();
// 构建req参数
Map<String, Object> req = new HashMap<>();
List<Map<String, String>> datumList = new ArrayList<>();
Map<String, String> datumEntry = new HashMap<>();
// 构建datum参数数组
datumEntry.put("sign", "I");
datumEntry.put("option", "EQ");
datumEntry.put("low", LocalDate.now().toString());
// datumEntry.put("low", "2021-05-17");
datumList.add(datumEntry);
req.put(funcnrEnum.getDatekey(), datumList);
// req.put("BUKRS", "3001");
// 1. 调用ERP接口获取数据
for (OftenEnum.ModeTypeEnum type : OftenEnum.ModeTypeEnum.values()) {
req.put("mode", type.modetype);
JSONArray dataArray = erpConfig.fetchDataFromERP(funcnr, req);
if (dataArray == null || dataArray.isEmpty()) {
continue;
}
// 2. 处理数据,区分新增和更新
ProcessingResult result = processData(dataArray, funcnrEnum);
// 3. 批量保存数据
saveData(result);
}
} catch (Exception e) {
log.error("调用ERP RFC接口失败: {}", e);
throw new RuntimeException("调用ERP RFC接口失败: " + e.getMessage(), e);
}
}
/**
* 处理数据,区分新增和更新
*/
private ProcessingResult processData(JSONArray dataArray, OftenEnum.FuncnrEnum funcnrEnum) {
String key = "erp" + funcnrEnum.getFuncnr();
Map<String, List<String>> numbers = erpConfig.numbers(dataArray, key, funcnrEnum.getDatakey());
List<String> allnumbers = numbers.get("all");
List<String> comnumbers = numbers.get("com");
List<ErpCustomerDO> toUpdate = new ArrayList<>();
List<ErpCustomerDO> toInsert = new ArrayList<>();
for (int i = 0; i < dataArray.size(); i++) {
JSONObject dataJson = dataArray.getJSONObject(i);
if (dataJson != null) {
String number = dataJson.getString("PARTNER").trim();
if (number != null) {
ErpCustomerDO DO = new ErpCustomerDO();
DO.setName(dataJson.getString("NAME_ORG1"));
DO.setNumber(number);
DO.setAccountGroup(dataJson.getString("BU_GROUP"));
DO.setDescription(dataJson.getString("BU_SORT1"));
DO.setCenterNumber(dataJson.getString("BU_SORT2"));
DO.setCreateDate(LocalDateTime.parse(dataJson.getString("CRDAT")+"T00:00:00"));
DO.setRepairDate(LocalDateTime.parse(dataJson.getString("CHDAT")+"T00:00:00"));
DO.setIsGiveback(dataJson.getString("XDELE"));
DO.setIsProvisional(dataJson.getString("XBLCK"));
// DO.setType(type.modetype);
// 使用 Map 优化查找效率,避免每次遍历 comnumbers 列表
if (comnumbers.contains(number)) {
// 更新
toUpdate.add(DO);
} else {
// 新增
toInsert.add(DO);
}
}
}
}
return new ProcessingResult(toUpdate, toInsert, key, allnumbers);
}
/**
* 批量保存数据
*/
private void saveData(ProcessingResult result) {
// 批量新增和更新
if (!result.toInsert.isEmpty()) {
erpCustomerMapper.insertBatch(result.toInsert);
}
if (!result.toUpdate.isEmpty()) {
erpCustomerMapper.updateBatch(result.toUpdate);
}
erpConfig.updateRedisCache(result.key, result.allnumbers);
}
/**
* 数据处理结果封装类
*/
private static class ProcessingResult {
private final List<ErpCustomerDO> toUpdate;
private final List<ErpCustomerDO> toInsert;
private final String key;
private final List<String> allnumbers;
public ProcessingResult(List<ErpCustomerDO> toUpdate, List<ErpCustomerDO> toInsert, String key, List<String> allnumbers) {
this.toUpdate = toUpdate;
this.toInsert = toInsert;
this.key = key;
this.allnumbers = allnumbers;
}
}
@Override
public void initialize() {
List<String> existingNumbers = erpCustomerMapper.selectList(new LambdaQueryWrapperX<ErpCustomerDO>())
.stream()
.map(ErpCustomerDO::getNumber)
.collect(Collectors.toList());
String key = "erp" + OftenEnum.FuncnrEnum.客商信息.getFuncnr();
redisTemplate.opsForValue().set(key, existingNumbers);
}
} }

View File

@@ -61,4 +61,7 @@ public interface ErpMaterialService {
*/ */
PageResult<ErpMaterialDO> getErpMaterialPage(ErpMaterialPageReqVO pageReqVO); PageResult<ErpMaterialDO> getErpMaterialPage(ErpMaterialPageReqVO pageReqVO);
void callErpRfcInterface();
void initialize();
} }

View File

@@ -1,22 +1,43 @@
package cn.iocoder.yudao.module.erp.service.erp; package cn.iocoder.yudao.module.erp.service.erp;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.erp.common.conf.ErpConfig;
import cn.iocoder.yudao.module.erp.common.enums.OftenEnum;
import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpMaterialPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpMaterialPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpMaterialRespVO; import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpMaterialRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpMaterialSaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.erp.vo.ErpMaterialSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.erp.ErpMaterialDO; import cn.iocoder.yudao.module.erp.dal.dataobject.erp.ErpMaterialDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.erp.ErpCustomerDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.erp.ErpMaterialDO;
import cn.iocoder.yudao.module.erp.dal.mysql.erp.ErpMaterialMapper; import cn.iocoder.yudao.module.erp.dal.mysql.erp.ErpMaterialMapper;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import org.springframework.web.client.RestTemplate;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.ERP_MATERIAL_NOT_EXISTS; import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.ERP_MATERIAL_NOT_EXISTS;
import static dm.jdbc.util.DriverUtil.log;
/** /**
* ERP物料数据 Service 实现类 * ERP物料数据 Service 实现类
@@ -29,6 +50,8 @@ public class ErpMaterialServiceImpl implements ErpMaterialService {
@Resource @Resource
private ErpMaterialMapper erpMaterialMapper; private ErpMaterialMapper erpMaterialMapper;
@Resource
private ErpConfig erpConfig;
@Override @Override
public ErpMaterialRespVO createErpMaterial(ErpMaterialSaveReqVO createReqVO) { public ErpMaterialRespVO createErpMaterial(ErpMaterialSaveReqVO createReqVO) {
@@ -87,4 +110,124 @@ public class ErpMaterialServiceImpl implements ErpMaterialService {
return erpMaterialMapper.selectPage(pageReqVO); return erpMaterialMapper.selectPage(pageReqVO);
} }
@Override
@Transactional
public void callErpRfcInterface() {
try {
OftenEnum.FuncnrEnum funcnrEnum =OftenEnum.FuncnrEnum.物料数据;
String funcnr = funcnrEnum.getFuncnr();
// 构建req参数
Map<String, Object> req = new HashMap<>();
List<Map<String, String>> datumList = new ArrayList<>();
Map<String, String> datumEntry = new HashMap<>();
datumEntry.put("sign", "I");
datumEntry.put("option", "EQ");
datumEntry.put("low", "2021-05-16");
// datumEntry.put("low", LocalDate.now().toString());
datumList.add(datumEntry);
req.put(funcnrEnum.getDatakey(), datumList);
// 1. 调用ERP接口获取数据
JSONArray dataArray = erpConfig.fetchDataFromERP(funcnr, req);
if (dataArray == null || dataArray.isEmpty()) {
return;
}
// 2. 处理公司数据,区分新增和更新
ProcessingResult result = processData(dataArray,funcnrEnum);
// 3. 批量保存数据
saveData(result);
} catch (Exception e) {
log.error("调用ERP RFC接口失败: {}", e);
throw new RuntimeException("调用ERP RFC接口失败: " + e.getMessage(), e);
}
}
/**
* 处理数据,区分新增和更新
*/
private ProcessingResult processData(JSONArray dataArray, OftenEnum.FuncnrEnum funcnr) {
String key = "erp" + funcnr.getFuncnr();
Map<String,List<String>> numbers = erpConfig.numbers(dataArray, key,funcnr.getDatakey());
List<String> allnumbers = numbers.get("all");
List<String> comnumbers = numbers.get("com");
List<ErpMaterialDO> toUpdate = new ArrayList<>();
List<ErpMaterialDO> toInsert = new ArrayList<>();
for (int i = 0; i < dataArray.size(); i++) {
JSONObject dataJson = dataArray.getJSONObject(i);
if (dataJson != null) {
String number = dataJson.getString("MATNR").trim();
if (number != null) {
ErpMaterialDO DO = new ErpMaterialDO();
DO.setDownCenterNumber(number);
DO.setCenterNumber(dataJson.getString("BISMT"));
DO.setCreateDate(LocalDateTime.parse(dataJson.getString("ERSDA")));
DO.setMaterialType(dataJson.getString("MTART"));
DO.setMaterialGroupDate(dataJson.getString("MATKL"));
DO.setExternalMaterialGroupDate(dataJson.getString("EXTWG"));
DO.setUnit(dataJson.getString("MEINS"));
DO.setUnitDescription(dataJson.getString("MSEHT"));
DO.setMaterialTypeDescription(dataJson.getString("MTBEZ"));
DO.setMaterialGroupDescription(dataJson.getString("WGBEZ"));
DO.setExternalMaterialGroupDescription(dataJson.getString("EWBEZ"));
DO.setMaterialName(dataJson.getString("MAKTX"));
DO.setMaterialLengthDescription(dataJson.getString("LDESC"));
if (comnumbers.contains(number)) {
// 更新
toUpdate.add(DO);
} else {
// 新增
toInsert.add(DO);
}
}
}
}
return new ProcessingResult(toUpdate, toInsert,key,allnumbers);
}
/**
* 批量保存数据
*/
private void saveData(ProcessingResult result) {
// 批量新增和更新
if (!result.toInsert.isEmpty()) {
erpMaterialMapper.insertBatch(result.toInsert);
}
if (!result.toUpdate.isEmpty()) {
erpMaterialMapper.updateBatch(result.toUpdate);
}
erpConfig.updateRedisCache(result.key,result.allnumbers);
}
/**
* 数据处理结果封装类
*/
private static class ProcessingResult {
private final List<ErpMaterialDO> toUpdate;
private final List<ErpMaterialDO> toInsert;
private final String key;
private final List<String> allnumbers;
public ProcessingResult(List<ErpMaterialDO> toUpdate, List<ErpMaterialDO> toInsert,String key,List<String> allnumbers) {
this.toUpdate = toUpdate;
this.toInsert = toInsert;
this.key = key;
this.allnumbers = allnumbers;
}
}
@Override
public void initialize() {
List<String> existingNumbers = erpMaterialMapper.selectList(new LambdaQueryWrapperX<ErpMaterialDO>())
.stream()
.map(ErpMaterialDO::getDownCenterNumber)
.collect(Collectors.toList());
String key = "erp" + OftenEnum.FuncnrEnum.物料数据.getFuncnr();
erpConfig.updateRedisCache(key, existingNumbers);
}
} }