From ee18a7074535d5c5a79e96fd57ea72eaf50b0d9f Mon Sep 17 00:00:00 2001 From: liss <1780094091@qq.com> Date: Thu, 18 Sep 2025 16:28:47 +0800 Subject: [PATCH] =?UTF-8?q?erp=E5=85=AC=E5=8F=B8=E3=80=81=E7=89=A9?= =?UTF-8?q?=E6=96=99=E3=80=81=E5=AE=A2=E5=95=86=E5=AE=9A=E6=97=B6=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/erp/common/conf/ErpConfig.java | 126 +++++++++++++ .../module/erp/common/conf/MyRedisConfig.java | 165 ++++++++++++++++++ .../module/erp/common/enums/OftenEnum.java | 74 +++++--- ...tatisticsTask.java => statisticstask.java} | 2 +- .../admin/erp/ErpCustomerController.java | 14 ++ .../admin/erp/ErpMaterialController.java | 14 ++ .../admin/erp/vo/ErpCustomerPageReqVO.java | 3 - .../admin/erp/vo/ErpCustomerRespVO.java | 4 - .../admin/erp/vo/ErpCustomerSaveReqVO.java | 4 - .../erp/dal/dataobject/erp/ErpCompanyDO.java | 11 +- .../erp/dal/dataobject/erp/ErpCustomerDO.java | 14 +- .../erp/dal/dataobject/erp/ErpMaterialDO.java | 9 +- .../erp/dal/mysql/erp/ErpCustomerMapper.java | 1 - .../service/erp/ErpCompanyServiceImpl.java | 143 ++++++++------- .../erp/service/erp/ErpCustomerService.java | 3 + .../service/erp/ErpCustomerServiceImpl.java | 148 +++++++++++++++- .../erp/service/erp/ErpMaterialService.java | 3 + .../service/erp/ErpMaterialServiceImpl.java | 143 +++++++++++++++ 18 files changed, 770 insertions(+), 111 deletions(-) create mode 100644 yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/conf/ErpConfig.java create mode 100644 yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/conf/MyRedisConfig.java rename yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/task/{statisticsTask.java => statisticstask.java} (96%) diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/conf/ErpConfig.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/conf/ErpConfig.java new file mode 100644 index 0000000..bed8b78 --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/conf/ErpConfig.java @@ -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 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 requestEntity = new HttpEntity<>(requestBody.toJSONString(), headers); + + // 发送POST请求 + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity 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> numbers(JSONArray dataArray, String key,String dataKey) { + // 使用 Redis 获取缓存数据 + Map> numbers = new HashMap<>(); + List cachedNumbers = (List) redisTemplate.opsForValue().get(key); + if (cachedNumbers == null) { + cachedNumbers = new ArrayList<>(); + } + + // 提取有效的 BUKRS 编号 + List 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 cachedNumberSet = new HashSet<>(cachedNumbers != null ? cachedNumbers : new ArrayList<>()); + List commonNumbers = existingNumbers.stream() + .filter(cachedNumberSet::contains) + .collect(Collectors.toList()); + numbers.put("com", commonNumbers); + + List newNumbers = existingNumbers.stream() + .filter(num -> !cachedNumberSet.contains(num)) + .collect(Collectors.toList()); + + // 合并所有编号 + List allNumbers = new ArrayList<>(cachedNumbers); + allNumbers.addAll(newNumbers); + numbers.put("all", allNumbers); + return numbers; + } + + public void updateRedisCache(String key, List allnumbers) { + // 使用 Redis 更新缓存数据 + redisTemplate.opsForValue().set(key, allnumbers); + } +} diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/conf/MyRedisConfig.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/conf/MyRedisConfig.java new file mode 100644 index 0000000..d8dfa42 --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/conf/MyRedisConfig.java @@ -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 redisTemplate(RedisConnectionFactory redisConnectionFactory) { + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(redisConnectionFactory); + + // 通过 Jackson 组件进行序列化 + RedisSerializer 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 redisSerializer() { + //创建JSON序列化器 + Jackson2JsonRedisSerializer 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 redisTemplate(JedisConnectionFactory jedisConnectionFactory){ +// RedisTemplate redisTemplate = new RedisTemplate<>(); +// redisTemplate.setKeySerializer(new StringRedisSerializer()); +// redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); +// redisTemplate.setConnectionFactory(jedisConnectionFactory); +// return redisTemplate; +// } + + + /** + * 序列化乱码问题解决 + */ +// @Bean +// public RedisTemplate redisTemplate(JedisConnectionFactory jedisConnectionFactory){ +// RedisTemplate redisTemplate = new RedisTemplate<>(); +// redisTemplate.setKeySerializer(new StringRedisSerializer()); +// redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); +// redisTemplate.setConnectionFactory(jedisConnectionFactory); +// return redisTemplate; +// } + + +} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/enums/OftenEnum.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/enums/OftenEnum.java index c369956..2023e46 100644 --- a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/enums/OftenEnum.java +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/enums/OftenEnum.java @@ -13,32 +13,60 @@ public class OftenEnum { //接口编号枚举 public enum FuncnrEnum { - 公司代码("001"), - 工厂信息("002"), - 客商信息("003"), - 成本中心("004"), - 内部订单("005"), - 库位信息("006"), - 采购组织("007"), - 销售组织("008"), - 合同信息("009"), - 资产卡片("010"), - 库存信息("011"), - 辅组编码("012"), - 生产订单("013"), - BOM清单("014"), - 工艺路线("015"), - 生产版本("016"), - 生产投料("017"), - 生产订单明细("018"), - 库存明细("019"), - 发票状态("020"), - 物料数据("021"); + 公司代码("001", "BUKRS", ""), + 工厂信息("002", "", ""), + 客商信息("003", "PARTNER", "DATUM"), + 成本中心("004", "", ""), + 内部订单("005", "", ""), + 库位信息("006", "", ""), + 采购组织("007", "", ""), + 销售组织("008", "", ""), + 合同信息("009", "", ""), + 资产卡片("010", "", ""), + 库存信息("011", "", ""), + 辅组编码("012", "", ""), + 生产订单("013", "", ""), + BOM清单("014", "", ""), + 工艺路线("015", "", ""), + 生产版本("016", "", ""), + 生产投料("017", "", ""), + 生产订单明细("018", "", ""), + 库存明细("019", "", ""), + 发票状态("020", "", ""), + 物料数据("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.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; } } } diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/task/statisticsTask.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/task/statisticstask.java similarity index 96% rename from yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/task/statisticsTask.java rename to yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/task/statisticstask.java index 12d62a9..ed38050 100644 --- a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/task/statisticsTask.java +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/common/task/statisticstask.java @@ -15,7 +15,7 @@ import org.springframework.transaction.annotation.Transactional; **/ @Configuration @EnableScheduling -public class statisticsTask { +public class statisticstask { @Resource private ErpCompanyService erpCompanyService; diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/ErpCustomerController.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/ErpCustomerController.java index c3e41ac..c7e267c 100644 --- a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/ErpCustomerController.java +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/ErpCustomerController.java @@ -104,4 +104,18 @@ public class ErpCustomerController { 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(); + } + } \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/ErpMaterialController.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/ErpMaterialController.java index 33ec30e..764dd9c 100644 --- a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/ErpMaterialController.java +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/ErpMaterialController.java @@ -104,4 +104,18 @@ public class ErpMaterialController { 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(); + } + } \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/vo/ErpCustomerPageReqVO.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/vo/ErpCustomerPageReqVO.java index 8a32458..d4de504 100644 --- a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/vo/ErpCustomerPageReqVO.java +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/vo/ErpCustomerPageReqVO.java @@ -41,7 +41,4 @@ public class ErpCustomerPageReqVO extends PageParam { @Schema(description = "冻结标识") private String isProvisional; - @Schema(description = "类型", example = "2") - private String type; - } \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/vo/ErpCustomerRespVO.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/vo/ErpCustomerRespVO.java index 5878fa1..3c88824 100644 --- a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/vo/ErpCustomerRespVO.java +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/vo/ErpCustomerRespVO.java @@ -51,8 +51,4 @@ public class ErpCustomerRespVO { @ExcelProperty("冻结标识") private String isProvisional; - @Schema(description = "类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - @ExcelProperty("类型") - private String type; - } \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/vo/ErpCustomerSaveReqVO.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/vo/ErpCustomerSaveReqVO.java index cddb3c1..a451e8d 100644 --- a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/vo/ErpCustomerSaveReqVO.java +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/erp/vo/ErpCustomerSaveReqVO.java @@ -45,8 +45,4 @@ public class ErpCustomerSaveReqVO { @Schema(description = "冻结标识") private String isProvisional; - @Schema(description = "类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - @NotEmpty(message = "类型不能为空") - private String type; - } \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/erp/ErpCompanyDO.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/erp/ErpCompanyDO.java index 779d839..bc7888e 100644 --- a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/erp/ErpCompanyDO.java +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/erp/ErpCompanyDO.java @@ -12,7 +12,8 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; @TableName("sply_erp_cpn") @KeySequence("sply_erp_cpn_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data -@EqualsAndHashCode(callSuper = true) +//@EqualsAndHashCode(callSuper = true) +@EqualsAndHashCode @ToString(callSuper = true) @Builder @NoArgsConstructor @@ -20,9 +21,8 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.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") private String currency; + @TableField(exist = false) + private Integer TENANT_ID; + } \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/erp/ErpCustomerDO.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/erp/ErpCustomerDO.java index 742755e..d3c6ae7 100644 --- a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/erp/ErpCustomerDO.java +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/erp/ErpCustomerDO.java @@ -14,7 +14,8 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; @TableName("sply_erp_cstm") @KeySequence("sply_erp_cstm_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data -@EqualsAndHashCode(callSuper = true) +//@EqualsAndHashCode(callSuper = true) +@EqualsAndHashCode @ToString(callSuper = true) @Builder @NoArgsConstructor @@ -22,7 +23,8 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.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") private String isProvisional; - /** - * 类型 - */ - @TableField("TP") - private String type; + + @TableField(exist = false) + private Integer TENANT_ID; } \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/erp/ErpMaterialDO.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/erp/ErpMaterialDO.java index 423e687..e1f685e 100644 --- a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/erp/ErpMaterialDO.java +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/erp/ErpMaterialDO.java @@ -13,7 +13,8 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; @TableName("sply_erp_mtrl") @KeySequence("sply_erp_mtrl_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data -@EqualsAndHashCode(callSuper = true) +//@EqualsAndHashCode(callSuper = true) +@EqualsAndHashCode @ToString(callSuper = true) @Builder @NoArgsConstructor @@ -21,7 +22,8 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.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") private String materialLengthDescription; + @TableField(exist = false) + private Integer TENANT_ID; + } \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/erp/ErpCustomerMapper.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/erp/ErpCustomerMapper.java index 6e882ae..ba4b0a5 100644 --- a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/erp/ErpCustomerMapper.java +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/erp/ErpCustomerMapper.java @@ -26,7 +26,6 @@ public interface ErpCustomerMapper extends BaseMapperX { .betweenIfPresent(ErpCustomerDO::getRepairDate, reqVO.getRepairDate()) .eqIfPresent(ErpCustomerDO::getIsGiveback, reqVO.getIsGiveback()) .eqIfPresent(ErpCustomerDO::getIsProvisional, reqVO.getIsProvisional()) - .eqIfPresent(ErpCustomerDO::getType, reqVO.getType()) .orderByDesc(ErpCustomerDO::getId)); } diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpCompanyServiceImpl.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpCompanyServiceImpl.java index 147e6c2..bc1bfdd 100644 --- a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpCompanyServiceImpl.java +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpCompanyServiceImpl.java @@ -2,26 +2,24 @@ package cn.iocoder.yudao.module.erp.service.erp; import cn.hutool.core.collection.CollUtil; 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.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.ErpCompanySaveReqVO; import cn.iocoder.yudao.module.erp.dal.dataobject.erp.ErpCompanyDO; import cn.iocoder.yudao.module.erp.dal.mysql.erp.ErpCompanyMapper; -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.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import jakarta.annotation.Resource; +import org.springframework.transaction.annotation.Transactional; 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.stream.Collectors; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; @@ -38,15 +36,12 @@ import static dm.jdbc.util.DriverUtil.log; @Validated public class ErpCompanyServiceImpl implements ErpCompanyService { - @Value("${erp.address}") - private String erpAddress; - - @Value("${erp.sapsys}") - private String sapsys; - @Resource private ErpCompanyMapper erpCompanyMapper; + @Resource + private ErpConfig erpConfig; + @Override public ErpCompanyRespVO createErpCompany(ErpCompanySaveReqVO createReqVO) { // 插入 @@ -105,61 +100,91 @@ public class ErpCompanyServiceImpl implements ErpCompanyService { } @Override + @Transactional public void callErpRfcInterface() { try { - // 构建完整URL - String url = "http://" + erpAddress + "/api/rfc/get"; - // 构建请求参数 - JSONObject requestBody = new JSONObject(); - requestBody.put("sapsys", sapsys); - requestBody.put("funcnr", OftenEnum.FuncnrEnum.公司代码.funcnr); // 获取枚举值 - - // 设置请求头 - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - - // 创建HTTP请求实体 - HttpEntity requestEntity = new HttpEntity<>(requestBody.toJSONString(), headers); - - // 发送POST请求 - RestTemplate restTemplate = new RestTemplate(); - ResponseEntity 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 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接口调用失败或返回错误标志"); + OftenEnum.FuncnrEnum funcnrEnum =OftenEnum.FuncnrEnum.公司代码; + String funcnr = funcnrEnum.getFuncnr(); + // 1. 调用ERP接口获取数据 + JSONArray dataArray = erpConfig.fetchDataFromERP(funcnr, null); + 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> numbers = erpConfig.numbers(dataArray, key,funcnr.getDatakey()); + List allnumbers = numbers.get("all"); + List comnumbers = numbers.get("com"); + List toUpdate = new ArrayList<>(); + List 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 toUpdate; + private final List toInsert; + private final String key; + private final List allnumbers; + + public ProcessingResult(List toUpdate, List toInsert,String key,List allnumbers) { + this.toUpdate = toUpdate; + this.toInsert = toInsert; + this.key = key; + this.allnumbers = allnumbers; + } + } } \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpCustomerService.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpCustomerService.java index dc27963..9b3c9a2 100644 --- a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpCustomerService.java +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpCustomerService.java @@ -61,4 +61,7 @@ public interface ErpCustomerService { */ PageResult getErpCustomerPage(ErpCustomerPageReqVO pageReqVO); + void callErpRfcInterface(); + + void initialize(); } \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpCustomerServiceImpl.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpCustomerServiceImpl.java index d6b7e83..52ac298 100644 --- a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpCustomerServiceImpl.java +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpCustomerServiceImpl.java @@ -1,22 +1,33 @@ package cn.iocoder.yudao.module.erp.service.erp; 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.mysql.erp.ErpCustomerMapper; 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.ErpCustomerSaveReqVO; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import jakarta.annotation.Resource; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.*; +import java.util.stream.Collectors; + import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.ERP_CUSTOMER_NOT_EXISTS; +import static dm.jdbc.util.DriverUtil.log; /** * ERP客商主数据 Service 实现类 @@ -27,6 +38,12 @@ import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.ERP_CUSTOMER_ @Validated public class ErpCustomerServiceImpl implements ErpCustomerService { + @Resource + private RedisTemplate redisTemplate; + + @Resource + private ErpConfig erpConfig; + @Resource private ErpCustomerMapper erpCustomerMapper; @@ -57,12 +74,12 @@ public class ErpCustomerServiceImpl implements ErpCustomerService { } @Override - public void deleteErpCustomerListByIds(List ids) { + public void deleteErpCustomerListByIds(List ids) { // 校验存在 validateErpCustomerExists(ids); // 删除 erpCustomerMapper.deleteByIds(ids); - } + } private void validateErpCustomerExists(List ids) { List list = erpCustomerMapper.selectByIds(ids); @@ -87,4 +104,129 @@ public class ErpCustomerServiceImpl implements ErpCustomerService { return erpCustomerMapper.selectPage(pageReqVO); } + @Override + @Transactional + public void callErpRfcInterface() { + try { + OftenEnum.FuncnrEnum funcnrEnum = OftenEnum.FuncnrEnum.客商信息; + String funcnr = funcnrEnum.getFuncnr(); + // 构建req参数 + Map req = new HashMap<>(); + List> datumList = new ArrayList<>(); + Map 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> numbers = erpConfig.numbers(dataArray, key, funcnrEnum.getDatakey()); + List allnumbers = numbers.get("all"); + List comnumbers = numbers.get("com"); + + List toUpdate = new ArrayList<>(); + List 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 toUpdate; + private final List toInsert; + private final String key; + private final List allnumbers; + + public ProcessingResult(List toUpdate, List toInsert, String key, List allnumbers) { + this.toUpdate = toUpdate; + this.toInsert = toInsert; + this.key = key; + this.allnumbers = allnumbers; + } + } + + @Override + public void initialize() { + List existingNumbers = erpCustomerMapper.selectList(new LambdaQueryWrapperX()) + .stream() + .map(ErpCustomerDO::getNumber) + .collect(Collectors.toList()); + String key = "erp" + OftenEnum.FuncnrEnum.客商信息.getFuncnr(); + redisTemplate.opsForValue().set(key, existingNumbers); + } + } \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpMaterialService.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpMaterialService.java index f64eaa5..26fbe31 100644 --- a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpMaterialService.java +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpMaterialService.java @@ -61,4 +61,7 @@ public interface ErpMaterialService { */ PageResult getErpMaterialPage(ErpMaterialPageReqVO pageReqVO); + void callErpRfcInterface(); + + void initialize(); } \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpMaterialServiceImpl.java b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpMaterialServiceImpl.java index 71e1c06..4c33f77 100644 --- a/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpMaterialServiceImpl.java +++ b/yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/erp/ErpMaterialServiceImpl.java @@ -1,22 +1,43 @@ package cn.iocoder.yudao.module.erp.service.erp; 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.ErpMaterialRespVO; 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.ErpCustomerDO; +import cn.iocoder.yudao.module.erp.dal.dataobject.erp.ErpMaterialDO; 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 jakarta.annotation.Resource; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; +import java.time.LocalDate; +import java.time.LocalDateTime; 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.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.module.erp.enums.ErrorCodeConstants.ERP_MATERIAL_NOT_EXISTS; +import static dm.jdbc.util.DriverUtil.log; /** * ERP物料数据 Service 实现类 @@ -29,6 +50,8 @@ public class ErpMaterialServiceImpl implements ErpMaterialService { @Resource private ErpMaterialMapper erpMaterialMapper; + @Resource + private ErpConfig erpConfig; @Override public ErpMaterialRespVO createErpMaterial(ErpMaterialSaveReqVO createReqVO) { @@ -87,4 +110,124 @@ public class ErpMaterialServiceImpl implements ErpMaterialService { return erpMaterialMapper.selectPage(pageReqVO); } + @Override + @Transactional + public void callErpRfcInterface() { + try { + OftenEnum.FuncnrEnum funcnrEnum =OftenEnum.FuncnrEnum.物料数据; + String funcnr = funcnrEnum.getFuncnr(); + // 构建req参数 + Map req = new HashMap<>(); + List> datumList = new ArrayList<>(); + Map 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> numbers = erpConfig.numbers(dataArray, key,funcnr.getDatakey()); + List allnumbers = numbers.get("all"); + List comnumbers = numbers.get("com"); + List toUpdate = new ArrayList<>(); + List 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 toUpdate; + private final List toInsert; + private final String key; + private final List allnumbers; + + public ProcessingResult(List toUpdate, List toInsert,String key,List allnumbers) { + this.toUpdate = toUpdate; + this.toInsert = toInsert; + this.key = key; + this.allnumbers = allnumbers; + } + } + + @Override + public void initialize() { + List existingNumbers = erpMaterialMapper.selectList(new LambdaQueryWrapperX()) + .stream() + .map(ErpMaterialDO::getDownCenterNumber) + .collect(Collectors.toList()); + String key = "erp" + OftenEnum.FuncnrEnum.物料数据.getFuncnr(); + erpConfig.updateRedisCache(key, existingNumbers); + } } \ No newline at end of file