From db4d708978bb18c28e017623225613c2cc8179e4 Mon Sep 17 00:00:00 2001 From: liss <1780094091@qq.com> Date: Tue, 23 Sep 2025 15:52:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=81=E8=A3=85=E6=8E=A5=E5=8F=A3=EF=BC=8Cer?= =?UTF-8?q?p=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1=EF=BC=8C=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E7=BC=93=E5=AD=98map=E6=9B=BF=E6=8D=A2list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-dev.yml | 2 +- .../plat/module/erp/api/ErpExternalApi.java | 24 ++++ .../module/erp/api/dto/ErpSubmitReqDTO.java | 35 ++++++ .../plat/module/erp/enums/ApiConstants.java | 23 ++++ .../module/erp/api/ErpExternalApiImpl.java | 27 +++++ .../module/erp/common/conf/ErpConfig.java | 98 +++++++++++++---- .../module/erp/common/conf/MyRedisConfig.java | 104 ------------------ .../module/erp/common/enums/OftenEnum.java | 4 +- .../admin/erp/ErpAssetController.java | 3 +- .../admin/erp/ErpCustomerController.java | 8 -- .../admin/erp/ErpMaterialController.java | 9 +- .../erp/vo/ErpProductiveVersionPageReqVO.java | 2 +- .../erp/vo/ErpProductiveVersionRespVO.java | 2 +- .../erp/vo/ErpProductiveVersionSaveReqVO.java | 2 +- .../admin/erp/vo/ErpWarehousePageReqVO.java | 4 - .../admin/erp/vo/ErpWarehouseRespVO.java | 4 - .../erp/ErpProductiveVersionDO.java | 2 +- .../dal/dataobject/erp/ErpWarehouseDO.java | 31 +----- .../dal/mysql/erp/ErpCostcenterMapper.java | 4 + .../erp/dal/mysql/erp/ErpMaterialMapper.java | 4 + .../erp/dal/mysql/erp/ErpWarehouseMapper.java | 2 +- .../erp/service/erp/ErpAssetServiceImpl.java | 89 +++++++++++---- .../erp/service/erp/ErpBomServiceImpl.java | 14 +-- .../service/erp/ErpCompanyServiceImpl.java | 86 +++++++++++---- .../service/erp/ErpCostcenterServiceImpl.java | 76 +++++++++---- .../erp/service/erp/ErpCustomerService.java | 2 - .../service/erp/ErpCustomerServiceImpl.java | 100 +++++++++-------- .../service/erp/ErpFactoryServiceImpl.java | 63 +++++++++-- .../erp/ErpInternalOrderServiceImpl.java | 74 ++++++++++--- .../erp/service/erp/ErpMaterialService.java | 2 - .../service/erp/ErpMaterialServiceImpl.java | 24 ++-- .../erp/ErpProductiveVersionServiceImpl.java | 77 ++++++++++--- .../ErpPurchaseOrganizationServiceImpl.java | 76 ++++++++++--- .../erp/ErpSalesOrganizationServiceImpl.java | 65 ++++++++--- .../service/erp/ErpWarehouseServiceImpl.java | 79 +++++++++---- .../resources/mapper/ErpCostcenterMapper.xml | 63 +++++++++-- .../resources/mapper/ErpMaterialMapper.xml | 36 ++++-- 37 files changed, 893 insertions(+), 427 deletions(-) create mode 100644 zt-module-erp/zt-module-erp-api/src/main/java/com/zt/plat/module/erp/api/ErpExternalApi.java create mode 100644 zt-module-erp/zt-module-erp-api/src/main/java/com/zt/plat/module/erp/api/dto/ErpSubmitReqDTO.java create mode 100644 zt-module-erp/zt-module-erp-api/src/main/java/com/zt/plat/module/erp/enums/ApiConstants.java create mode 100644 zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/api/ErpExternalApiImpl.java diff --git a/base-server/src/main/resources/application-dev.yml b/base-server/src/main/resources/application-dev.yml index 210b907..5203b43 100644 --- a/base-server/src/main/resources/application-dev.yml +++ b/base-server/src/main/resources/application-dev.yml @@ -51,7 +51,7 @@ spring: redis: host: 172.16.46.63 # 地址 port: 30379 # 端口 - database: 0 # 数据库索引 + database: 6 # 数据库索引 # password: 123456 # 密码,建议生产环境开启 xxl: diff --git a/zt-module-erp/zt-module-erp-api/src/main/java/com/zt/plat/module/erp/api/ErpExternalApi.java b/zt-module-erp/zt-module-erp-api/src/main/java/com/zt/plat/module/erp/api/ErpExternalApi.java new file mode 100644 index 0000000..f55cdfb --- /dev/null +++ b/zt-module-erp/zt-module-erp-api/src/main/java/com/zt/plat/module/erp/api/ErpExternalApi.java @@ -0,0 +1,24 @@ +package com.zt.plat.module.erp.api; + +import com.alibaba.fastjson.JSONArray; +import com.zt.plat.module.erp.api.dto.ErpSubmitReqDTO; +import com.zt.plat.module.erp.enums.ApiConstants; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +@FeignClient(name = ApiConstants.NAME) +@Tag(name = "RPC 服务 - ERP") +public interface ErpExternalApi { + + String PREFIX = ApiConstants.PREFIX + "/erp-external"; + + @PostMapping(PREFIX + "/submit") + @Operation(summary = "erp数据提交") + ResponseEntity submitDataToErp(@Valid @RequestBody ErpSubmitReqDTO reqDTO); + +} diff --git a/zt-module-erp/zt-module-erp-api/src/main/java/com/zt/plat/module/erp/api/dto/ErpSubmitReqDTO.java b/zt-module-erp/zt-module-erp-api/src/main/java/com/zt/plat/module/erp/api/dto/ErpSubmitReqDTO.java new file mode 100644 index 0000000..6926f5f --- /dev/null +++ b/zt-module-erp/zt-module-erp-api/src/main/java/com/zt/plat/module/erp/api/dto/ErpSubmitReqDTO.java @@ -0,0 +1,35 @@ +package com.zt.plat.module.erp.api.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotEmpty; +import lombok.Data; + +import java.util.Map; + +@Schema(description = "RPC 服务 - 提交 ERP DTO") +@Data +public class ErpSubmitReqDTO { + /** + * 调用ERP接口更新erp数据 + * + * 请求参数说明: + * "uuid": 请求uuid,必须 + * "sapsys": SAP系统ID, 必须 + * "srcsys": 源调用系统ID,必须 + * "funcnr": 接口编号,必须,参见RFC功能列表,可调用接口编号范围051-900 + * "bskey": 调用系统业务单据编号,必须,在外部系统唯一,用于关联 + * "usrid": 外部系统用户id + * "usrnm": 外部系统用户名 + * "sign": 签名,uuid+srcsys+密码,MD5 32位小写签名,密码另行约定 + * "req": {具体参数,参见RFC功能列表} + */ + private String uuid; + private String srcsys; + private String funcnr; + private String bskey; + private String usrid; + private String usrnm; + private String sign; + private Map req; + +} diff --git a/zt-module-erp/zt-module-erp-api/src/main/java/com/zt/plat/module/erp/enums/ApiConstants.java b/zt-module-erp/zt-module-erp-api/src/main/java/com/zt/plat/module/erp/enums/ApiConstants.java new file mode 100644 index 0000000..18dd594 --- /dev/null +++ b/zt-module-erp/zt-module-erp-api/src/main/java/com/zt/plat/module/erp/enums/ApiConstants.java @@ -0,0 +1,23 @@ +package com.zt.plat.module.erp.enums; + +import com.zt.plat.framework.common.enums.RpcConstants; + +/** + * API 相关的枚举 + * + * @author ZT + */ +public class ApiConstants { + + /** + * 服务名 + * + * 注意,需要保证和 spring.application.name 保持一致 + */ + public static final String NAME = "erp-server"; + + public static final String PREFIX = RpcConstants.RPC_API_PREFIX + "/erp"; + + public static final String VERSION = "1.0.0"; + +} diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/api/ErpExternalApiImpl.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/api/ErpExternalApiImpl.java new file mode 100644 index 0000000..6861777 --- /dev/null +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/api/ErpExternalApiImpl.java @@ -0,0 +1,27 @@ +package com.zt.plat.module.erp.api; + +import com.zt.plat.module.erp.api.dto.ErpSubmitReqDTO; +import com.zt.plat.module.erp.common.conf.ErpConfig; +import jakarta.annotation.Resource; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RestController; + +/** + * ERP Api 实现类 + * + * @author ZT + * @author jason + */ +@RestController +@Validated +public class ErpExternalApiImpl implements ErpExternalApi { + + @Resource + private ErpConfig erpConfig; + + @Override + public ResponseEntity submitDataToErp(ErpSubmitReqDTO reqDTO) { + return erpConfig.pushDataToErp(reqDTO); + } +} diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/common/conf/ErpConfig.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/common/conf/ErpConfig.java index 394c860..74ce304 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/common/conf/ErpConfig.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/common/conf/ErpConfig.java @@ -3,6 +3,7 @@ package com.zt.plat.module.erp.common.conf; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.zt.plat.module.erp.api.dto.ErpSubmitReqDTO; import jakarta.annotation.Resource; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; @@ -32,7 +33,7 @@ public class ErpConfig { /** - * 调用ERP接口获取公司数据 + * 调用ERP接口获取erp数据 */ public JSONArray fetchDataFromERP(String funcnr, Map req) { try { @@ -60,7 +61,7 @@ public class ErpConfig { // 解析响应结果 String responseBody = response.getBody(); if (responseBody.isEmpty()) { - log.warn("无所选条件的查询数据"+req); + log.warn("无所选条件的查询数据" + req); } JSONObject jsonResponse = JSON.parseObject(responseBody); @@ -73,7 +74,6 @@ public class ErpConfig { if (dataObject != null && "S".equals(dataObject.getString("E_FLAG"))) { return dataObject.getJSONArray("E_DATA"); } else { - log.warn("ERP接口调用失败或返回错误标志"); return null; } } catch (Exception e) { @@ -82,8 +82,46 @@ public class ErpConfig { } } + /** + * 调用ERP接口更新erp数据 + */ + public ResponseEntity pushDataToErp(ErpSubmitReqDTO reqDTO) { + try { + // 构建完整URL + String url = "http://" + erpAddress + "/api/rfc/post"; + // 构建请求参数 + JSONObject requestBody = new JSONObject(); + requestBody.put("uuid", reqDTO.getUuid()); + requestBody.put("sapsys", sapsys); + requestBody.put("srcsys", reqDTO.getSrcsys()); + requestBody.put("funcnr", reqDTO.getFuncnr()); + requestBody.put("bskey", reqDTO.getBskey()); + requestBody.put("usrid", reqDTO.getUsrid()); + requestBody.put("usrnm", reqDTO.getUsrnm()); + requestBody.put("sign", reqDTO.getSign()); + if (reqDTO.getReq() != null) { + requestBody.put("req", reqDTO.getReq()); + } + // 设置请求头 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); - public Map> numbers(JSONArray dataArray, String key,String dataKey) { + // 创建HTTP请求实体 + HttpEntity requestEntity = new HttpEntity<>(requestBody.toJSONString(), headers); + + // 发送POST请求 + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity response = restTemplate.postForEntity(url, requestEntity, String.class); + + return response; + } catch (Exception e) { + log.error("调用ERP RFC接口失败: {}", e); + return ResponseEntity.status(500).body("调用ERP接口失败: " + e.getMessage()); + } + } + + //list + public Map> numbers(JSONArray dataArray, String key, String dataKey) { // 使用 Redis 获取缓存数据 Map> numbers = new HashMap<>(); List cachedNumbers = (List) redisTemplate.opsForValue().get(key); @@ -92,7 +130,7 @@ public class ErpConfig { } // 提取有效的 BUKRS 编号 - List existingNumbers = new ArrayList<>(); + List existingNumbers; if (dataArray != null) { // 将dataKey按"-"分割成多个部分 String[] keyParts = dataKey.split("-"); @@ -118,6 +156,8 @@ public class ErpConfig { }) .filter(Objects::nonNull) // 过滤掉无效值 .collect(Collectors.toList()); + } else { + existingNumbers = new ArrayList<>(); } // 找出共同存在的编号 @@ -127,14 +167,22 @@ public class ErpConfig { .collect(Collectors.toList()); numbers.put("com", commonNumbers); + //找出需要删除的字段。只有erp查询全部的接口能用到 + List deleteNumbers = cachedNumberSet.stream() + .filter(num -> !existingNumbers.contains(num)) + .collect(Collectors.toList()); + numbers.put("delete", deleteNumbers); + + // 找出需要新增的编号 List newNumbers = existingNumbers.stream() .filter(num -> !cachedNumberSet.contains(num)) - .collect(Collectors.toList()); + .toList(); // 合并所有编号 List allNumbers = new ArrayList<>(cachedNumbers); allNumbers.addAll(newNumbers); numbers.put("all", allNumbers); + return numbers; } @@ -145,23 +193,35 @@ public class ErpConfig { public List getRedisCache(String key) { // 使用 Redis 更新缓存数据 - return (List)redisTemplate.opsForValue().get("erp"+key); + return (List) redisTemplate.opsForValue().get(key); } - - public Map numbersMap(String key) { + //map + public Map getRedisCacheMap(String key) { // 使用 Redis 获取缓存数据 - Map result = (Map) redisTemplate.opsForValue().get(key); + Map result = (Map) redisTemplate.opsForHash().entries(key); return result; } -// public void updateRedisCache(String key, List allnumbers) { -// // 使用 Redis 更新缓存数据 -// redisTemplate.opsForValue().set(key, allnumbers); -// } -// -// public List getRedisCache(String key) { -// // 使用 Redis 更新缓存数据 -// return (List)redisTemplate.opsForValue().get("erp"+key); -// } + public void addRedisCacheMap(String key, Map allnumbers) { + // 使用 Redis 更新缓存数据 + redisTemplate.opsForHash().putAll(key, allnumbers); + } + + public void deleteRedisCacheMap(String key, List deleteNumbers) { + if (deleteNumbers == null || deleteNumbers.isEmpty()) { + log.debug("No items to delete from Redis hash: {}", key); + return; + } + + try { + Object[] keysToDelete = deleteNumbers.toArray(new String[0]); + Long deletedCount = redisTemplate.opsForHash().delete(key, keysToDelete); + log.debug("Deleted" + deletedCount + "items from Redis hash:" + key); + } catch (Exception e) { + log.error("Failed to delete items from Redis hash:" + key, e); + throw e; + } + } + } diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/common/conf/MyRedisConfig.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/common/conf/MyRedisConfig.java index 71d8b88..c213195 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/common/conf/MyRedisConfig.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/common/conf/MyRedisConfig.java @@ -13,7 +13,6 @@ 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; /** @@ -23,37 +22,6 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; @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<>(); @@ -90,76 +58,4 @@ public class MyRedisConfig { 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/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/common/enums/OftenEnum.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/common/enums/OftenEnum.java index 3371c03..6155c96 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/common/enums/OftenEnum.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/common/enums/OftenEnum.java @@ -16,7 +16,7 @@ public class OftenEnum { 公司代码("001", "BUKRS", ""), 工厂信息("002", "WERKS", ""), 客商信息("003", "PARTNER", "DATUM"), - 成本中心("004", "", ""), + 成本中心("004", "KOSTL", ""), 内部订单("005", "", ""), 库位信息("006", "", ""), 采购组织("007", "", ""), @@ -33,7 +33,7 @@ public class OftenEnum { 生产订单明细("018", "", ""), 库存明细("019", "", ""), 发票状态("020", "", ""), - 物料数据("021", "", "ERSDA"); + 物料数据("021", "MATNR", "ERSDA"); private final String funcnr; private final String datakey; diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/ErpAssetController.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/ErpAssetController.java index 40a1e3a..2f09d5e 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/ErpAssetController.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/ErpAssetController.java @@ -103,9 +103,8 @@ public class ErpAssetController { @PostMapping("/getErpAssetTask") @Operation(summary = "定时获得erp更新资产卡片") - @PreAuthorize("@ss.hasPermission('sply:erp-asset:query')") + @PreAuthorize("@ss.hasPermission('sply:erp-asset:create')") public void getErpCompanyTask() { erpAssetService.callErpRfcInterface(); } - } \ No newline at end of file diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/ErpCustomerController.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/ErpCustomerController.java index 5bbd308..97c72bf 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/ErpCustomerController.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/ErpCustomerController.java @@ -107,12 +107,4 @@ public class ErpCustomerController { 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/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/ErpMaterialController.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/ErpMaterialController.java index 82098b4..3d19c67 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/ErpMaterialController.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/ErpMaterialController.java @@ -102,17 +102,10 @@ public class ErpMaterialController { } @PostMapping("/getErpMaterialTask") - @Operation(summary = "定时获得erp更新公司") + @Operation(summary = "定时获得erp更新物料") @PreAuthorize("@ss.hasPermission('sply:erp-material:create')") public void getErpMaterialTask() { 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/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpProductiveVersionPageReqVO.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpProductiveVersionPageReqVO.java index 429288b..f24a352 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpProductiveVersionPageReqVO.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpProductiveVersionPageReqVO.java @@ -11,7 +11,7 @@ import java.math.BigDecimal; public class ErpProductiveVersionPageReqVO extends PageParam { @Schema(description = "工厂编码") - private BigDecimal factoryNumber; + private String factoryNumber; @Schema(description = "物料编码") private String materialNumber; diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpProductiveVersionRespVO.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpProductiveVersionRespVO.java index 463cec5..e3bdcaa 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpProductiveVersionRespVO.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpProductiveVersionRespVO.java @@ -18,7 +18,7 @@ public class ErpProductiveVersionRespVO { @Schema(description = "工厂编码", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("工厂编码") - private BigDecimal factoryNumber; + private String factoryNumber; @Schema(description = "物料编码", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("物料编码") diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpProductiveVersionSaveReqVO.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpProductiveVersionSaveReqVO.java index b75c2ad..9e4c0b0 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpProductiveVersionSaveReqVO.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpProductiveVersionSaveReqVO.java @@ -16,7 +16,7 @@ public class ErpProductiveVersionSaveReqVO { @Schema(description = "工厂编码", requiredMode = Schema.RequiredMode.REQUIRED) @NotNull(message = "工厂编码不能为空") - private BigDecimal factoryNumber; + private String factoryNumber; @Schema(description = "物料编码", requiredMode = Schema.RequiredMode.REQUIRED) @NotEmpty(message = "物料编码不能为空") diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpWarehousePageReqVO.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpWarehousePageReqVO.java index 3d0c8ea..347a828 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpWarehousePageReqVO.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpWarehousePageReqVO.java @@ -19,10 +19,6 @@ public class ErpWarehousePageReqVO extends PageParam { @Schema(description = "库位描述", example = "张三") private String name; - @Schema(description = "创建时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] createTime; - @Schema(description = "库位编码") private String number; diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpWarehouseRespVO.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpWarehouseRespVO.java index a703bc6..66c19c5 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpWarehouseRespVO.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/controller/admin/erp/vo/ErpWarehouseRespVO.java @@ -24,10 +24,6 @@ public class ErpWarehouseRespVO { @ExcelProperty("库位描述") private String name; - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("创建时间") - private LocalDateTime createTime; - @Schema(description = "库位编码", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("库位编码") private String number; diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/dataobject/erp/ErpProductiveVersionDO.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/dataobject/erp/ErpProductiveVersionDO.java index 74e1a6e..1403ff9 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/dataobject/erp/ErpProductiveVersionDO.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/dataobject/erp/ErpProductiveVersionDO.java @@ -34,7 +34,7 @@ public class ErpProductiveVersionDO { * 工厂编码 */ @TableField("FACT_NUM") - private BigDecimal factoryNumber; + private String factoryNumber; /** * 物料编码 */ diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/dataobject/erp/ErpWarehouseDO.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/dataobject/erp/ErpWarehouseDO.java index 10cbd60..6c6668c 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/dataobject/erp/ErpWarehouseDO.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/dataobject/erp/ErpWarehouseDO.java @@ -11,7 +11,7 @@ import lombok.*; @TableName("sply_erp_wrh") @KeySequence("sply_erp_wrh_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data -@EqualsAndHashCode(callSuper = true) +@EqualsAndHashCode @ToString(callSuper = true) @Builder @NoArgsConstructor @@ -19,9 +19,7 @@ import lombok.*; /** * 支持业务基类继承:isBusiness=true 时继承 BusinessBaseDO,否则继承 BaseDO */ -public class ErpWarehouseDO extends BaseDO { - - +public class ErpWarehouseDO { /** * 主键 @@ -39,31 +37,6 @@ public class ErpWarehouseDO extends BaseDO { @TableField("NAME") private String name; /** - * 公司编号 - */ - @TableField("COMPANY_ID") - private Long companyId; - /** - * 公司名称 - */ - @TableField("COMPANY_NAME") - private String companyName; - /** - * 部门编号 - */ - @TableField("DEPT_ID") - private Long deptId; - /** - * 部门名称 - */ - @TableField("DEPT_NAME") - private String deptName; - /** - * 岗位编号 - */ - @TableField("POST_ID") - private Long postId; - /** * 库位编码 */ @TableField("NUM") diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/mysql/erp/ErpCostcenterMapper.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/mysql/erp/ErpCostcenterMapper.java index 6fe99ad..5365316 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/mysql/erp/ErpCostcenterMapper.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/mysql/erp/ErpCostcenterMapper.java @@ -6,6 +6,9 @@ import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpCostcenterPageReqVO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpCostcenterDO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** * ERP成本中心 Mapper @@ -27,4 +30,5 @@ public interface ErpCostcenterMapper extends BaseMapperX { .orderByDesc(ErpCostcenterDO::getId)); } + void updateBatchByNumber(@Param("list") List toUpdate); } \ No newline at end of file diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/mysql/erp/ErpMaterialMapper.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/mysql/erp/ErpMaterialMapper.java index c7b6cf8..1330186 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/mysql/erp/ErpMaterialMapper.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/mysql/erp/ErpMaterialMapper.java @@ -6,6 +6,9 @@ import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpMaterialPageReqVO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpMaterialDO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** * ERP物料数据 Mapper @@ -33,4 +36,5 @@ public interface ErpMaterialMapper extends BaseMapperX { .orderByDesc(ErpMaterialDO::getId)); } + void updateBatchByNumber(@Param("toUpdate") List toUpdate); } \ No newline at end of file diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/mysql/erp/ErpWarehouseMapper.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/mysql/erp/ErpWarehouseMapper.java index 685018c..80bb229 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/mysql/erp/ErpWarehouseMapper.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/dal/mysql/erp/ErpWarehouseMapper.java @@ -19,7 +19,7 @@ public interface ErpWarehouseMapper extends BaseMapperX { return selectPage(reqVO, new LambdaQueryWrapperX() .eqIfPresent(ErpWarehouseDO::getFactoryNumber, reqVO.getFactoryNumber()) .likeIfPresent(ErpWarehouseDO::getName, reqVO.getName()) - .betweenIfPresent(ErpWarehouseDO::getCreateTime, reqVO.getCreateTime()) +// .betweenIfPresent(ErpWarehouseDO::getCreateTime, reqVO.getCreateTime()) .eqIfPresent(ErpWarehouseDO::getNumber, reqVO.getNumber()) .orderByDesc(ErpWarehouseDO::getId)); } diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpAssetServiceImpl.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpAssetServiceImpl.java index b5e8dca..a92d0ad 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpAssetServiceImpl.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpAssetServiceImpl.java @@ -1,14 +1,18 @@ package com.zt.plat.module.erp.service.erp; import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.common.util.object.BeanUtils; +import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX; import com.zt.plat.module.erp.common.conf.ErpConfig; import com.zt.plat.module.erp.common.enums.OftenEnum; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpAssetPageReqVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpAssetRespVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpAssetSaveReqVO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpAssetDO; +import com.zt.plat.module.erp.dal.dataobject.erp.ErpCompanyDO; +import com.zt.plat.module.erp.dal.dataobject.erp.ErpCostcenterDO; import com.zt.plat.module.erp.dal.mysql.erp.ErpAssetMapper; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; @@ -24,6 +28,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.zt.plat.module.erp.enums.ErrorCodeConstants.ERP_ASSET_NOT_EXISTS; @@ -108,22 +113,26 @@ public class ErpAssetServiceImpl implements ErpAssetService { try { OftenEnum.FuncnrEnum funcnrEnum = OftenEnum.FuncnrEnum.资产卡片; String funcnr = funcnrEnum.getFuncnr(); + String key = "erpMap" + funcnr; + if (erpConfig.getRedisCacheMap(key).isEmpty()) { + initializeMap(key); + } // 构建req参数 Map req = new HashMap<>(); - List> datumList = new ArrayList<>(); - Map datumEntry = new HashMap<>(); - datumEntry.put("sign", "I"); - datumEntry.put("option", "EQ"); - datumEntry.put("low", LocalDate.now().toString()); - datumList.add(datumEntry); - req.put(funcnrEnum.getDatekey(), datumList); - +// List> datumList = new ArrayList<>(); +// Map datumEntry = new HashMap<>(); +// datumEntry.put("sign", "I"); +// datumEntry.put("option", "EQ"); +// datumEntry.put("low", LocalDate.now().toString()); +// datumList.add(datumEntry); +// req.put(funcnrEnum.getDatekey(), datumList); JSONArray dataArrayALL = new JSONArray(); - List redisCache = erpConfig.getRedisCache(OftenEnum.FuncnrEnum.公司代码.getFuncnr()); + String companyKey ="erpMap"+ OftenEnum.FuncnrEnum.公司代码.getFuncnr(); + Map redisCache = erpConfig.getRedisCacheMap(companyKey); if (CollUtil.isEmpty(redisCache)) { return; } - for (String number : redisCache) { + for (String number : redisCache.keySet()) { req.put("BUKRS", number); // 1. 调用ERP接口获取数据 JSONArray dataArray = erpConfig.fetchDataFromERP(funcnr, req); @@ -148,20 +157,19 @@ public class ErpAssetServiceImpl implements ErpAssetService { /** * 处理数据,区分新增和更新 */ - 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"); + private ProcessingResult processData(JSONArray dataArray, OftenEnum.FuncnrEnum funcnrEnum) { + String key = "erpMap" + funcnrEnum.getFuncnr(); + Map numbers = erpConfig.getRedisCacheMap(key); List toUpdate = new ArrayList<>(); List toInsert = new ArrayList<>(); + List dataArrayNumbers = new ArrayList<>(); for (int i = 0; i < dataArray.size(); i++) { JSONObject dataJson = dataArray.getJSONObject(i); if (dataJson != null) { ErpAssetDO DO = new ErpAssetDO(); - DO.setCompanyNumber(dataJson.getString("BUKRS")); - DO.setMainAssetNumber(dataJson.getString("ANLN1")); + DO.setCompanyNumber(dataJson.getString("BUKRS").trim()); + DO.setMainAssetNumber(dataJson.getString("ANLN1").trim()); if (!dataJson.getString("ERDAT").equals("0000-00-00")) { DO.setRecordCreateDate(LocalDateTime.parse(dataJson.getString("ERDAT") + "T00:00:00")); } @@ -181,17 +189,26 @@ public class ErpAssetServiceImpl implements ErpAssetService { DO.setPlanYearDate(dataJson.getString("NDJAR")); DO.setCostcenterNumber(dataJson.getString("KOSTL")); DO.setDutyCostcenterNumber(dataJson.getString("KOSTLV")); - if (comnumbers.contains(DO.getMainAssetNumber()+"-"+DO.getCompanyNumber())) { + String number = DO.getCompanyNumber() + "-" + DO.getMainAssetNumber(); + if (numbers.get(number) != null) { // 更新 + DO.setId(numbers.get(number)); toUpdate.add(DO); } else { // 新增 toInsert.add(DO); } + dataArrayNumbers.add(number); } } - - return new ProcessingResult(toUpdate, toInsert, key, allnumbers); + // 过滤出numbers中有,但dataArray中KOSTL没有的记录,即为需要删除的数据 + Map deleteNumbers = new HashMap<>(); + for (String number : numbers.keySet()) { + if (!dataArrayNumbers.contains(number)) { + deleteNumbers.put(number,numbers.get(number)); + } + } + return new ProcessingResult(toUpdate, toInsert, deleteNumbers, key); } /** @@ -201,11 +218,25 @@ public class ErpAssetServiceImpl implements ErpAssetService { // 批量新增和更新 if (!result.toInsert.isEmpty()) { erpAssetMapper.insertBatch(result.toInsert); + // 批量查询刚插入数据的id,提升效率 + List insertedRecords = erpAssetMapper.selectList( + new LambdaQueryWrapperX() + .in(ErpAssetDO::getCompanyNumber, result.toInsert.stream().map(ErpAssetDO::getCompanyNumber).collect(Collectors.toList())) + .in(ErpAssetDO::getMainAssetNumber, result.toInsert.stream().map(ErpAssetDO::getMainAssetNumber).collect(Collectors.toList())) + ); + Map numberIdMap = insertedRecords.stream() + .collect(Collectors.toMap(asset -> asset.getCompanyNumber() + "-" + asset.getMainAssetNumber(), ErpAssetDO::getId)); + erpConfig.addRedisCacheMap(result.key,numberIdMap); } if (!result.toUpdate.isEmpty()) { erpAssetMapper.updateBatch(result.toUpdate); } - erpConfig.updateRedisCache(result.key, result.allnumbers); + if (!result.deleteNumbers.isEmpty()) { + // 使用流式处理和批处理优化删除逻辑 + List idsToDelete = new ArrayList<>(result.deleteNumbers.values()); + erpAssetMapper.deleteByIds(idsToDelete); + erpConfig.deleteRedisCacheMap(result.key, new ArrayList<>(result.deleteNumbers.keySet())); + } } /** @@ -214,15 +245,25 @@ public class ErpAssetServiceImpl implements ErpAssetService { private static class ProcessingResult { private final List toUpdate; private final List toInsert; + private final Map deleteNumbers; private final String key; - private final List allnumbers; - public ProcessingResult(List toUpdate, List toInsert, String key, List allnumbers) { + public ProcessingResult(List toUpdate, List toInsert, Map deleteNumbers, String key) { this.toUpdate = toUpdate; this.toInsert = toInsert; + this.deleteNumbers = deleteNumbers; this.key = key; - this.allnumbers = allnumbers; } } + private void initializeMap(String key) { + List assets = erpAssetMapper.selectList(new LambdaQueryWrapperX()); + Map existingNumbers = new HashMap<>(); + for (ErpAssetDO asset : assets) { + String mapKey = asset.getCompanyNumber() + "-" + asset.getMainAssetNumber(); + existingNumbers.put(mapKey, asset.getId()); + } + erpConfig.addRedisCacheMap(key, existingNumbers); + } + } \ No newline at end of file diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpBomServiceImpl.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpBomServiceImpl.java index 37b9243..f559337 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpBomServiceImpl.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpBomServiceImpl.java @@ -141,8 +141,8 @@ public class ErpBomServiceImpl implements ErpBomService { */ private ProcessingResult processData(JSONArray dataArray, OftenEnum.FuncnrEnum funcnr) { String key = "erp" + funcnr.getFuncnr(); - Map numbers = erpConfig.numbersMap(key); - Map numberDels = erpConfig.numbersMap(key+"del"); + Map numbers = erpConfig.getRedisCacheMap(key); + Map numberDetails = erpConfig.getRedisCacheMap(key+"details"); List toUpdate = new ArrayList<>(); List toInsert = new ArrayList<>(); @@ -159,11 +159,9 @@ public class ErpBomServiceImpl implements ErpBomService { DO.setQuantity(dataJson.getBigDecimal("BMENG")); DO.setUnit(dataJson.getString("BMEIN")); String number =DO.getUpMaterial()+"-"+DO.getUseItem()+"-"+DO.getFactoryNumber(); - String domId = null; if (numbers.get(number)!=null) { // 更新 - domId = numbers.get(number); - DO.setId(Long.valueOf(domId)); + DO.setId(numbers.get(number)); toUpdate.add(DO); } else { // 新增 @@ -177,10 +175,10 @@ public class ErpBomServiceImpl implements ErpBomService { JSONObject dataJsonItemJson = dataJsonItem.getJSONObject(j); ErpBomDetailDO detailDO = new ErpBomDetailDO(); String numberDel = number+dataJsonItemJson.getString("STVKN"); - if (numberDels.get( numberDel) != null){ - detailDO.setId(Long.valueOf(numberDels.get( numberDel))); + if (numberDetails.get( numberDel) != null){ + detailDO.setId(Long.valueOf(numberDetails.get( numberDel))); } - detailDO.setBomId(domId); + detailDO.setBomId(String.valueOf(numbers.get(number))); detailDO.setErpBomId(dataJsonItemJson.getString("STVKN")); detailDO.setErpBomId(dataJsonItemJson.getString("IDNRK")); detailDO.setErpBomId(dataJsonItemJson.getString("OJTXP")); diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpCompanyServiceImpl.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpCompanyServiceImpl.java index 78bd6d8..93b9d55 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpCompanyServiceImpl.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpCompanyServiceImpl.java @@ -3,12 +3,15 @@ package com.zt.plat.module.erp.service.erp; import cn.hutool.core.collection.CollUtil; import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.common.util.object.BeanUtils; +import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX; import com.zt.plat.module.erp.common.conf.ErpConfig; import com.zt.plat.module.erp.common.enums.OftenEnum; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpCompanyPageReqVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpCompanyRespVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpCompanySaveReqVO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpCompanyDO; +import com.zt.plat.module.erp.dal.dataobject.erp.ErpCostcenterDO; +import com.zt.plat.module.erp.dal.dataobject.erp.ErpCustomerDO; import com.zt.plat.module.erp.dal.mysql.erp.ErpCompanyMapper; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; @@ -19,8 +22,10 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.zt.plat.module.erp.enums.ErrorCodeConstants.ERP_COMPANY_NOT_EXISTS; @@ -103,8 +108,13 @@ public class ErpCompanyServiceImpl implements ErpCompanyService { @XxlJob("getCompanyTask") public void callErpRfcInterface() { try { - OftenEnum.FuncnrEnum funcnrEnum =OftenEnum.FuncnrEnum.公司代码; + OftenEnum.FuncnrEnum funcnrEnum = OftenEnum.FuncnrEnum.公司代码; String funcnr = funcnrEnum.getFuncnr(); + //防止缓存数据丢失 + String key = "erpMap" + funcnrEnum.getFuncnr(); + if (erpConfig.getRedisCacheMap(key).isEmpty()) { + initializeMap(key); + } // 1. 调用ERP接口获取数据 JSONArray dataArray = erpConfig.fetchDataFromERP(funcnr, null); if (dataArray == null || dataArray.isEmpty()) { @@ -112,7 +122,7 @@ public class ErpCompanyServiceImpl implements ErpCompanyService { } // 2. 处理公司数据,区分新增和更新 - ProcessingResult result = processData(dataArray,funcnrEnum); + ProcessingResult result = processData(dataArray, funcnrEnum); // 3. 批量保存数据 saveData(result); @@ -127,34 +137,40 @@ public class ErpCompanyServiceImpl implements ErpCompanyService { * 处理数据,区分新增和更新 */ 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"); + String key = "erpMap" + funcnr.getFuncnr(); + Map numbers = erpConfig.getRedisCacheMap(key); List toUpdate = new ArrayList<>(); List toInsert = new ArrayList<>(); + List dataArrayNumbers = 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); - } + ErpCompanyDO DO = new ErpCompanyDO(); + DO.setName(dataJson.getString("BUTXT")); + DO.setNumber(number); + DO.setCurrency(dataJson.getString("WAERS")); + if (numbers.get(number) != null) { + // 更新 + DO.setId(numbers.get(number)); + toUpdate.add(DO); + } else { + // 新增 + toInsert.add(DO); } + dataArrayNumbers.add(number); } } - return new ProcessingResult(toUpdate, toInsert,key,allnumbers); + // 过滤出numbers中有,但dataArray中KOSTL没有的记录,即为需要删除的数据 + List deleteNumbers = new ArrayList<>(); + for (String number : numbers.keySet()) { + if (!dataArrayNumbers.contains(number)) { + deleteNumbers.add(number); + } + } + return new ProcessingResult(toUpdate, toInsert, deleteNumbers, key); } /** @@ -164,11 +180,26 @@ public class ErpCompanyServiceImpl implements ErpCompanyService { // 批量新增和更新 if (!result.toInsert.isEmpty()) { erpCompanyMapper.insertBatch(result.toInsert); + // 批量查询刚插入数据的id,提升效率 + List insertedNumbers = result.toInsert.stream() + .map(ErpCompanyDO::getNumber) + .collect(Collectors.toList()); + List insertedRecords = erpCompanyMapper.selectList( + new LambdaQueryWrapperX() + .in(ErpCompanyDO::getNumber, insertedNumbers) + ); + Map numberIdMap = insertedRecords.stream() + .collect(Collectors.toMap(ErpCompanyDO::getNumber, ErpCompanyDO::getId)); + erpConfig.addRedisCacheMap(result.key,numberIdMap); } if (!result.toUpdate.isEmpty()) { erpCompanyMapper.updateBatch(result.toUpdate); } - erpConfig.updateRedisCache(result.key,result.allnumbers); + if (!result.deleteNumbers.isEmpty()) { + // 使用 in 条件批量删除,提高删除效率 + erpCompanyMapper.delete(new LambdaQueryWrapperX().in(ErpCompanyDO::getNumber, result.deleteNumbers)); + erpConfig.deleteRedisCacheMap(result.key, result.deleteNumbers); + } } /** @@ -177,14 +208,23 @@ public class ErpCompanyServiceImpl implements ErpCompanyService { private static class ProcessingResult { private final List toUpdate; private final List toInsert; + private final List deleteNumbers; private final String key; - private final List allnumbers; - public ProcessingResult(List toUpdate, List toInsert,String key,List allnumbers) { + + public ProcessingResult(List toUpdate, List toInsert, List deleteNumbers, String key) { this.toUpdate = toUpdate; this.toInsert = toInsert; + this.deleteNumbers = deleteNumbers; this.key = key; - this.allnumbers = allnumbers; } } + + private void initializeMap(String key) { + Map existingNumbers = erpCompanyMapper.selectList(new LambdaQueryWrapperX()) + .stream() + .collect(Collectors.toMap(ErpCompanyDO::getNumber, ErpCompanyDO::getId)); + erpConfig.addRedisCacheMap(key, existingNumbers); + } + } \ No newline at end of file diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpCostcenterServiceImpl.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpCostcenterServiceImpl.java index 8213d09..34f12d0 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpCostcenterServiceImpl.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpCostcenterServiceImpl.java @@ -1,13 +1,16 @@ package com.zt.plat.module.erp.service.erp; import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.common.util.object.BeanUtils; +import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX; import com.zt.plat.module.erp.common.conf.ErpConfig; import com.zt.plat.module.erp.common.enums.OftenEnum; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpCostcenterPageReqVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpCostcenterRespVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpCostcenterSaveReqVO; +import com.zt.plat.module.erp.dal.dataobject.erp.ErpCompanyDO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpCostcenterDO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpCostcenterDO; import com.zt.plat.module.erp.dal.mysql.erp.ErpCostcenterMapper; @@ -24,6 +27,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.zt.plat.module.erp.enums.ErrorCodeConstants.ERP_COSTCENTER_NOT_EXISTS; @@ -108,15 +112,20 @@ public class ErpCostcenterServiceImpl implements ErpCostcenterService { try { OftenEnum.FuncnrEnum funcnrEnum =OftenEnum.FuncnrEnum.成本中心; String funcnr = funcnrEnum.getFuncnr(); - + //防止缓存数据丢失 + String key = "erpMap" + funcnr; + if (erpConfig.getRedisCacheMap( key).isEmpty()){ + initializeMap(key); + } Map req = new HashMap<>(); JSONArray dataArrayALL = new JSONArray(); - List redisCache = erpConfig.getRedisCache(OftenEnum.FuncnrEnum.公司代码.getFuncnr()); + String commanyKey ="erpMap"+ OftenEnum.FuncnrEnum.公司代码.getFuncnr(); + Map redisCache = erpConfig.getRedisCacheMap(commanyKey); if (CollUtil.isEmpty(redisCache)) { return; } // 1. 调用ERP接口获取数据 - for (String number : redisCache) { + for (String number : redisCache.keySet()) { req.put("BUKRS", number); // 1. 调用ERP接口获取数据 JSONArray dataArray = erpConfig.fetchDataFromERP(funcnr, req); @@ -142,39 +151,47 @@ public class ErpCostcenterServiceImpl implements ErpCostcenterService { * 处理数据,区分新增和更新 */ 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"); + String key = "erpMap" + funcnr.getFuncnr(); + Map numbers = erpConfig.getRedisCacheMap(key); List toUpdate = new ArrayList<>(); List toInsert = new ArrayList<>(); + List dataArrayNumbers = new ArrayList<>(); for (int i = 0; i < dataArray.size(); i++) { JSONObject dataJson = dataArray.getJSONObject(i); if (dataJson != null) { ErpCostcenterDO DO = new ErpCostcenterDO(); - DO.setNumber(dataJson.getString("KOSTL")); - DO.setName(dataJson.getString("KTEX")); + String number = dataJson.getString("KOSTL").trim(); + DO.setNumber(number); + DO.setName(dataJson.getString("KTEXT")); DO.setIsUse(dataJson.getString("DRNAM")); DO.setScopeNumber(dataJson.getString("FKBER")); - if (!dataJson.getString("AKTIV").equals("0000-00-00")) { + if (!dataJson.getString("DATAB").equals("0000-00-00")) { DO.setStartDate(LocalDateTime.parse(dataJson.getString("DATAB") + "T00:00:00")); } - if (!dataJson.getString("AKTIV").equals("0000-00-00")) { - DO.setStartDate(LocalDateTime.parse(dataJson.getString("DATBI") + "T00:00:00")); + if (!dataJson.getString("DATBI").equals("0000-00-00")) { + DO.setEndDate(LocalDateTime.parse(dataJson.getString("DATBI") + "T00:00:00")); } DO.setScopeName(dataJson.getString("FKBTX")); - if (comnumbers.contains(dataJson.getString("KOSTL"))) { + if (numbers.get(number)!=null) { // 更新 + DO.setId(numbers.get(number)); toUpdate.add(DO); } else { // 新增 toInsert.add(DO); } + dataArrayNumbers.add(number); } } - - return new ProcessingResult(toUpdate, toInsert,key,allnumbers); + // 过滤出numbers中有,但dataArray中KOSTL没有的记录,即为需要删除的数据 + List deleteNumbers = new ArrayList<>(); + for (String number : numbers.keySet()) { + if (!dataArrayNumbers.contains(number)) { + deleteNumbers.add(number); + } + } + return new ProcessingResult(toUpdate, toInsert,deleteNumbers,key); } /** @@ -184,11 +201,26 @@ public class ErpCostcenterServiceImpl implements ErpCostcenterService { // 批量新增和更新 if (!result.toInsert.isEmpty()) { erpCostcenterMapper.insertBatch(result.toInsert); + // 批量查询刚插入数据的id,提升效率 + List insertedNumbers = result.toInsert.stream() + .map(ErpCostcenterDO::getNumber) + .collect(Collectors.toList()); + List insertedRecords = erpCostcenterMapper.selectList( + new LambdaQueryWrapperX() + .in(ErpCostcenterDO::getNumber, insertedNumbers) + ); + Map numberIdMap = insertedRecords.stream() + .collect(Collectors.toMap(ErpCostcenterDO::getNumber, ErpCostcenterDO::getId)); + erpConfig.addRedisCacheMap(result.key,numberIdMap); } if (!result.toUpdate.isEmpty()) { erpCostcenterMapper.updateBatch(result.toUpdate); } - erpConfig.updateRedisCache(result.key,result.allnumbers); + if (!result.deleteNumbers.isEmpty()) { + // 使用 in 条件批量删除,提高删除效率 + erpCostcenterMapper.delete(new LambdaQueryWrapperX().in(ErpCostcenterDO::getNumber, result.deleteNumbers)); + erpConfig.deleteRedisCacheMap(result.key,result.deleteNumbers); + } } /** @@ -197,14 +229,20 @@ public class ErpCostcenterServiceImpl implements ErpCostcenterService { private static class ProcessingResult { private final List toUpdate; private final List toInsert; + private final List deleteNumbers; private final String key; - private final List allnumbers; - public ProcessingResult(List toUpdate, List toInsert,String key,List allnumbers) { + public ProcessingResult(List toUpdate, List toInsert,List deleteNumbers,String key) { this.toUpdate = toUpdate; this.toInsert = toInsert; + this.deleteNumbers = deleteNumbers; this.key = key; - this.allnumbers = allnumbers; } } + private void initializeMap(String key) { + Map existingNumbers = erpCostcenterMapper.selectList(new LambdaQueryWrapperX()) + .stream() + .collect(Collectors.toMap(ErpCostcenterDO::getNumber, ErpCostcenterDO::getId)); + erpConfig.addRedisCacheMap(key, existingNumbers); + } } \ No newline at end of file diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpCustomerService.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpCustomerService.java index b80dcf7..f3db2fb 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpCustomerService.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpCustomerService.java @@ -62,6 +62,4 @@ public interface ErpCustomerService { PageResult getErpCustomerPage(ErpCustomerPageReqVO pageReqVO); void callErpRfcInterface(); - - void initialize(); } \ No newline at end of file diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpCustomerServiceImpl.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpCustomerServiceImpl.java index e75c21c..256b15f 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpCustomerServiceImpl.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpCustomerServiceImpl.java @@ -9,6 +9,7 @@ import com.zt.plat.module.erp.common.enums.OftenEnum; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpCustomerPageReqVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpCustomerRespVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpCustomerSaveReqVO; +import com.zt.plat.module.erp.dal.dataobject.erp.ErpCompanyDO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpCustomerDO; import com.zt.plat.module.erp.dal.mysql.erp.ErpCustomerMapper; import com.alibaba.fastjson.JSONArray; @@ -41,9 +42,6 @@ import static dm.jdbc.util.DriverUtil.log; @Validated public class ErpCustomerServiceImpl implements ErpCustomerService { - @Resource - private RedisTemplate redisTemplate; - @Resource private ErpConfig erpConfig; @@ -114,6 +112,11 @@ public class ErpCustomerServiceImpl implements ErpCustomerService { try { OftenEnum.FuncnrEnum funcnrEnum = OftenEnum.FuncnrEnum.客商信息; String funcnr = funcnrEnum.getFuncnr(); + + String key = "erpMap" + funcnrEnum.getFuncnr(); + if (erpConfig.getRedisCacheMap(key).isEmpty()) { + initializeMap(key); + } // 构建req参数 Map req = new HashMap<>(); List> datumList = new ArrayList<>(); @@ -126,20 +129,22 @@ public class ErpCustomerServiceImpl implements ErpCustomerService { req.put(funcnrEnum.getDatekey(), datumList); // 1. 调用ERP接口获取数据 + JSONArray dataArrayALL = new JSONArray(); 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); + dataArrayALL.addAll(dataArray); } + // 2. 处理数据,区分新增和更新 + ProcessingResult result = processData(dataArrayALL, funcnrEnum); + + // 3. 批量保存数据 + saveData(result); + } catch (Exception e) { log.error("调用ERP RFC接口失败: {}", e); throw new RuntimeException("调用ERP RFC接口失败: " + e.getMessage(), e); @@ -150,10 +155,8 @@ public class ErpCustomerServiceImpl implements ErpCustomerService { * 处理数据,区分新增和更新 */ 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"); + String key = "erpMap" + funcnrEnum.getFuncnr(); + Map numbers = erpConfig.getRedisCacheMap(key); List toUpdate = new ArrayList<>(); List toInsert = new ArrayList<>(); @@ -162,32 +165,35 @@ public class ErpCustomerServiceImpl implements ErpCustomerService { JSONObject dataJson = dataArray.getJSONObject(i); if (dataJson != null) { String number = dataJson.getString(funcnrEnum.getDatakey()).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")); + 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")); + if (!dataJson.getString("CRDAT").equals("0000-00-00")) { + DO.setCreateDate(LocalDateTime.parse(dataJson.getString("CRDAT") + "T00:00:00")); + } + if (!dataJson.getString("CHDAT").equals("0000-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); - } + // 使用 Map 优化查找效率,避免每次遍历 comnumbers 列表 + if (numbers.get(number)!=null) { + // 更新 + DO.setId(numbers.get(number)); + toUpdate.add(DO); + } else { + // 新增 + toInsert.add(DO); } } } - return new ProcessingResult(toUpdate, toInsert, key, allnumbers); + return new ProcessingResult(toUpdate, toInsert, key); } /** @@ -197,11 +203,21 @@ public class ErpCustomerServiceImpl implements ErpCustomerService { // 批量新增和更新 if (!result.toInsert.isEmpty()) { erpCustomerMapper.insertBatch(result.toInsert); + // 批量查询刚插入数据的id,提升效率 + List insertedNumbers = result.toInsert.stream() + .map(ErpCustomerDO::getNumber) + .collect(Collectors.toList()); + List insertedRecords = erpCustomerMapper.selectList( + new LambdaQueryWrapperX() + .in(ErpCustomerDO::getNumber, insertedNumbers) + ); + Map numberIdMap = insertedRecords.stream() + .collect(Collectors.toMap(ErpCustomerDO::getNumber, ErpCustomerDO::getId)); + erpConfig.addRedisCacheMap(result.key,numberIdMap); } if (!result.toUpdate.isEmpty()) { erpCustomerMapper.updateBatch(result.toUpdate); } - erpConfig.updateRedisCache(result.key, result.allnumbers); } /** @@ -211,24 +227,18 @@ public class ErpCustomerServiceImpl implements ErpCustomerService { 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) { + public ProcessingResult(List toUpdate, List toInsert, String key) { this.toUpdate = toUpdate; this.toInsert = toInsert; this.key = key; - this.allnumbers = allnumbers; } } - @Override - public void initialize() { - List existingNumbers = erpCustomerMapper.selectList(new LambdaQueryWrapperX()) + private void initializeMap(String key) { + Map existingNumbers = erpCustomerMapper.selectList(new LambdaQueryWrapperX()) .stream() - .map(ErpCustomerDO::getNumber) - .collect(Collectors.toList()); - String key = "erp" + OftenEnum.FuncnrEnum.客商信息.getFuncnr(); - redisTemplate.opsForValue().set(key, existingNumbers); + .collect(Collectors.toMap(ErpCustomerDO::getNumber, ErpCustomerDO::getId)); + erpConfig.addRedisCacheMap(key, existingNumbers); } - } \ No newline at end of file diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpFactoryServiceImpl.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpFactoryServiceImpl.java index 6c8f535..420363a 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpFactoryServiceImpl.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpFactoryServiceImpl.java @@ -3,11 +3,13 @@ package com.zt.plat.module.erp.service.erp; import cn.hutool.core.collection.CollUtil; import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.common.util.object.BeanUtils; +import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX; import com.zt.plat.module.erp.common.conf.ErpConfig; import com.zt.plat.module.erp.common.enums.OftenEnum; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpFactoryPageReqVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpFactoryRespVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpFactorySaveReqVO; +import com.zt.plat.module.erp.dal.dataobject.erp.ErpCompanyDO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpFactoryDO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpFactoryDO; import com.zt.plat.module.erp.dal.mysql.erp.ErpFactoryMapper; @@ -23,6 +25,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.zt.plat.module.erp.enums.ErrorCodeConstants.ERP_FACTORY_NOT_EXISTS; @@ -106,14 +109,20 @@ public class ErpFactoryServiceImpl implements ErpFactoryService { try { OftenEnum.FuncnrEnum funcnrEnum =OftenEnum.FuncnrEnum.工厂信息; String funcnr = funcnrEnum.getFuncnr(); + //防止缓存数据丢失 + String key = "erpMap" + funcnrEnum.getFuncnr(); + if (erpConfig.getRedisCacheMap(key).isEmpty()) { + initializeMap(key); + } // 1. 调用ERP接口获取数据 Map req = new HashMap<>(); JSONArray dataArrayALL = new JSONArray(); - List redisCache = erpConfig.getRedisCache(OftenEnum.FuncnrEnum.公司代码.getFuncnr()); + String companykey = "erp" + OftenEnum.FuncnrEnum.公司代码.getFuncnr(); + Map redisCache = erpConfig.getRedisCacheMap(companykey); if (CollUtil.isEmpty(redisCache)) { return; } - for (String companyNumber : redisCache) { + for (String companyNumber : redisCache.keySet()) { req.put("BUKRS", companyNumber); // 1. 调用ERP接口获取数据 JSONArray dataArray = erpConfig.fetchDataFromERP(funcnr, req); @@ -147,13 +156,12 @@ public class ErpFactoryServiceImpl implements ErpFactoryService { * 处理数据,区分新增和更新 */ 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"); + String key = "erpMap" + funcnr.getFuncnr(); + Map numbers = erpConfig.getRedisCacheMap(key); List toUpdate = new ArrayList<>(); List toInsert = new ArrayList<>(); + List dataArrayNumbers = new ArrayList<>(); for (int i = 0; i < dataArray.size(); i++) { JSONObject dataJson = dataArray.getJSONObject(i); if (dataJson != null) { @@ -162,17 +170,26 @@ public class ErpFactoryServiceImpl implements ErpFactoryService { DO.setName(dataJson.getString("NAME1")); DO.setNumber(number); DO.setCompanyId(dataJson.getString("BUKRS")); - if (comnumbers.contains(number)) { + if (numbers.get(number)!=null) { // 更新 + DO.setId(numbers.get(number)); toUpdate.add(DO); } else { // 新增 toInsert.add(DO); } + dataArrayNumbers.add(number); } } - return new ProcessingResult(toUpdate, toInsert,key,allnumbers); + // 过滤出numbers中有,但dataArray中KOSTL没有的记录,即为需要删除的数据 + List deleteNumbers = new ArrayList<>(); + for (String number : numbers.keySet()) { + if (!dataArrayNumbers.contains(number)) { + deleteNumbers.add(number); + } + } + return new ProcessingResult(toUpdate, toInsert,key,deleteNumbers); } /** @@ -182,11 +199,26 @@ public class ErpFactoryServiceImpl implements ErpFactoryService { // 批量新增和更新 if (!result.toInsert.isEmpty()) { erpFactoryMapper.insertBatch(result.toInsert); + // 批量查询刚插入数据的id,提升效率 + List insertedNumbers = result.toInsert.stream() + .map(ErpFactoryDO::getNumber) + .collect(Collectors.toList()); + List insertedRecords = erpFactoryMapper.selectList( + new LambdaQueryWrapperX() + .in(ErpFactoryDO::getNumber, insertedNumbers) + ); + Map numberIdMap = insertedRecords.stream() + .collect(Collectors.toMap(ErpFactoryDO::getNumber, ErpFactoryDO::getId)); + erpConfig.addRedisCacheMap(result.key,numberIdMap); } if (!result.toUpdate.isEmpty()) { erpFactoryMapper.updateBatch(result.toUpdate); } - erpConfig.updateRedisCache(result.key,result.allnumbers); + if (!result.deleteNumbers.isEmpty()) { + // 使用 in 条件批量删除,提高删除效率 + erpFactoryMapper.delete(new LambdaQueryWrapperX().in(ErpFactoryDO::getNumber, result.deleteNumbers)); + erpConfig.deleteRedisCacheMap(result.key, result.deleteNumbers); + } } /** @@ -196,13 +228,20 @@ public class ErpFactoryServiceImpl implements ErpFactoryService { private final List toUpdate; private final List toInsert; private final String key; - private final List allnumbers; + private final List deleteNumbers; - public ProcessingResult(List toUpdate, List toInsert,String key,List allnumbers) { + public ProcessingResult(List toUpdate, List toInsert,String key,List deleteNumbers) { this.toUpdate = toUpdate; this.toInsert = toInsert; this.key = key; - this.allnumbers = allnumbers; + this.deleteNumbers = deleteNumbers; } } + + private void initializeMap(String key) { + Map existingNumbers = erpFactoryMapper.selectList(new LambdaQueryWrapperX()) + .stream() + .collect(Collectors.toMap(ErpFactoryDO::getNumber, ErpFactoryDO::getId)); + erpConfig.addRedisCacheMap(key, existingNumbers); + } } \ No newline at end of file diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpInternalOrderServiceImpl.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpInternalOrderServiceImpl.java index 557376c..f17f0d0 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpInternalOrderServiceImpl.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpInternalOrderServiceImpl.java @@ -3,11 +3,13 @@ package com.zt.plat.module.erp.service.erp; import cn.hutool.core.collection.CollUtil; import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.common.util.object.BeanUtils; +import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX; import com.zt.plat.module.erp.common.conf.ErpConfig; import com.zt.plat.module.erp.common.enums.OftenEnum; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpInternalOrderPageReqVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpInternalOrderRespVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpInternalOrderSaveReqVO; +import com.zt.plat.module.erp.dal.dataobject.erp.ErpCompanyDO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpInternalOrderDO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpInternalOrderDO; import com.zt.plat.module.erp.dal.mysql.erp.ErpInternalOrderMapper; @@ -23,6 +25,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.zt.plat.module.erp.enums.ErrorCodeConstants.ERP_INTERNAL_ORDER_NOT_EXISTS; @@ -70,12 +73,12 @@ public class ErpInternalOrderServiceImpl implements ErpInternalOrderService { } @Override - public void deleteErpInternalOrderListByIds(List ids) { + public void deleteErpInternalOrderListByIds(List ids) { // 校验存在 validateErpInternalOrderExists(ids); // 删除 erpInternalOrderMapper.deleteByIds(ids); - } + } private void validateErpInternalOrderExists(List ids) { List list = erpInternalOrderMapper.selectByIds(ids); @@ -105,17 +108,23 @@ public class ErpInternalOrderServiceImpl implements ErpInternalOrderService { @XxlJob("getErpInternalOrderTask") public void callErpRfcInterface() { try { - OftenEnum.FuncnrEnum funcnrEnum =OftenEnum.FuncnrEnum.内部订单; + OftenEnum.FuncnrEnum funcnrEnum = OftenEnum.FuncnrEnum.内部订单; String funcnr = funcnrEnum.getFuncnr(); + //防止缓存数据丢失 + String key = "erpMap" + funcnrEnum.getFuncnr(); + if (erpConfig.getRedisCacheMap(key).isEmpty()) { + initializeMap(key); + } Map req = new HashMap<>(); JSONArray dataArrayALL = new JSONArray(); - List redisCache = erpConfig.getRedisCache(OftenEnum.FuncnrEnum.公司代码.getFuncnr()); + String companyCode = "erpMap" + OftenEnum.FuncnrEnum.公司代码.getFuncnr(); + Map redisCache = erpConfig.getRedisCacheMap(companyCode); if (CollUtil.isEmpty(redisCache)) { return; } // 1. 调用ERP接口获取数据 - for (String number : redisCache) { + for (String number : redisCache.keySet()) { req.put("BUKRS", number); // 1. 调用ERP接口获取数据 JSONArray dataArray = erpConfig.fetchDataFromERP(funcnr, req); @@ -126,7 +135,7 @@ public class ErpInternalOrderServiceImpl implements ErpInternalOrderService { } // 2. 处理公司数据,区分新增和更新 - ProcessingResult result = processData(dataArrayALL,funcnrEnum); + ProcessingResult result = processData(dataArrayALL, funcnrEnum); // 3. 批量保存数据 saveData(result); @@ -141,33 +150,42 @@ public class ErpInternalOrderServiceImpl implements ErpInternalOrderService { * 处理数据,区分新增和更新 */ 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"); + String key = "erpMap" + funcnr.getFuncnr(); + Map numbers = erpConfig.getRedisCacheMap(key); List toUpdate = new ArrayList<>(); List toInsert = new ArrayList<>(); + List dataArrayNumbers = new ArrayList<>(); for (int i = 0; i < dataArray.size(); i++) { JSONObject dataJson = dataArray.getJSONObject(i); if (dataJson != null) { ErpInternalOrderDO DO = new ErpInternalOrderDO(); + String number = dataJson.getString("AUFNR").trim(); DO.setName(dataJson.getString("KTEXT")); - DO.setNumber(dataJson.getString("AUFNR")); + DO.setNumber(number); DO.setType(dataJson.getString("AUART")); DO.setIsOff(dataJson.getString("PHAS3")); DO.setIsFinish(dataJson.getString("PHAS2")); - if (comnumbers.contains(dataJson.getString("AUFNR"))) { + if (numbers.get(number)!=null) { // 更新 + DO.setId(numbers.get(number)); toUpdate.add(DO); } else { // 新增 toInsert.add(DO); } + dataArrayNumbers.add(number); } } - return new ProcessingResult(toUpdate, toInsert,key,allnumbers); + // 过滤出numbers中有,但dataArray中KOSTL没有的记录,即为需要删除的数据 + List deleteNumbers = new ArrayList<>(); + for (String number : numbers.keySet()) { + if (!dataArrayNumbers.contains(number)) { + deleteNumbers.add(number); + } + } + return new ProcessingResult(toUpdate, toInsert, key, deleteNumbers); } /** @@ -177,11 +195,26 @@ public class ErpInternalOrderServiceImpl implements ErpInternalOrderService { // 批量新增和更新 if (!result.toInsert.isEmpty()) { erpInternalOrderMapper.insertBatch(result.toInsert); + // 批量查询刚插入数据的id,提升效率 + List insertedNumbers = result.toInsert.stream() + .map(ErpInternalOrderDO::getNumber) + .collect(Collectors.toList()); + List insertedRecords = erpInternalOrderMapper.selectList( + new LambdaQueryWrapperX() + .in(ErpInternalOrderDO::getNumber, insertedNumbers) + ); + Map numberIdMap = insertedRecords.stream() + .collect(Collectors.toMap(ErpInternalOrderDO::getNumber, ErpInternalOrderDO::getId)); + erpConfig.addRedisCacheMap(result.key,numberIdMap); } if (!result.toUpdate.isEmpty()) { erpInternalOrderMapper.updateBatch(result.toUpdate); } - erpConfig.updateRedisCache(result.key,result.allnumbers); + if (!result.deleteNumbers.isEmpty()) { + // 使用 in 条件批量删除,提高删除效率 + erpInternalOrderMapper.delete(new LambdaQueryWrapperX().in(ErpInternalOrderDO::getNumber, result.deleteNumbers)); + erpConfig.deleteRedisCacheMap(result.key, result.deleteNumbers); + } } /** @@ -191,13 +224,20 @@ public class ErpInternalOrderServiceImpl implements ErpInternalOrderService { private final List toUpdate; private final List toInsert; private final String key; - private final List allnumbers; + private final List deleteNumbers; - public ProcessingResult(List toUpdate, List toInsert,String key,List allnumbers) { + public ProcessingResult(List toUpdate, List toInsert, String key, List deleteNumbers) { this.toUpdate = toUpdate; this.toInsert = toInsert; this.key = key; - this.allnumbers = allnumbers; + this.deleteNumbers = deleteNumbers; } } + + private void initializeMap(String key) { + Map existingNumbers = erpInternalOrderMapper.selectList(new LambdaQueryWrapperX()) + .stream() + .collect(Collectors.toMap(ErpInternalOrderDO::getNumber, ErpInternalOrderDO::getId)); + erpConfig.addRedisCacheMap(key, existingNumbers); + } } \ No newline at end of file diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpMaterialService.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpMaterialService.java index 0061609..976b0ca 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpMaterialService.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpMaterialService.java @@ -62,6 +62,4 @@ public interface ErpMaterialService { PageResult getErpMaterialPage(ErpMaterialPageReqVO pageReqVO); void callErpRfcInterface(); - - void initialize(); } \ No newline at end of file diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpMaterialServiceImpl.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpMaterialServiceImpl.java index fcdab79..35e7f01 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpMaterialServiceImpl.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpMaterialServiceImpl.java @@ -9,6 +9,7 @@ import com.zt.plat.module.erp.common.enums.OftenEnum; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpMaterialPageReqVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpMaterialRespVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpMaterialSaveReqVO; +import com.zt.plat.module.erp.dal.dataobject.erp.ErpInternalOrderDO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpMaterialDO; import com.zt.plat.module.erp.dal.mysql.erp.ErpMaterialMapper; import com.alibaba.fastjson.JSONArray; @@ -19,6 +20,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.HashMap; @@ -108,16 +110,22 @@ public class ErpMaterialServiceImpl implements ErpMaterialService { try { OftenEnum.FuncnrEnum funcnrEnum =OftenEnum.FuncnrEnum.物料数据; String funcnr = funcnrEnum.getFuncnr(); + //防止缓存数据丢失 + String key = "erp" + funcnrEnum.getFuncnr(); + if (erpConfig.getRedisCache(key)==null) { + initialize(key); + } + // 构建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()); +// datumEntry.put("low", "2021-05-16"); + datumEntry.put("low", LocalDate.now().toString()); datumList.add(datumEntry); - req.put(funcnrEnum.getDatakey(), datumList); + req.put(funcnrEnum.getDatekey(), datumList); // 1. 调用ERP接口获取数据 JSONArray dataArray = erpConfig.fetchDataFromERP(funcnr, req); @@ -155,7 +163,9 @@ public class ErpMaterialServiceImpl implements ErpMaterialService { ErpMaterialDO DO = new ErpMaterialDO(); DO.setDownCenterNumber(number); DO.setCenterNumber(dataJson.getString("BISMT")); - DO.setCreateDate(LocalDateTime.parse(dataJson.getString("ERSDA"))); + if (!dataJson.getString("ERSDA").equals("0000-00-00")) { + DO.setCreateDate(LocalDateTime.parse(dataJson.getString("ERSDA")+"T00:00:00")); + } DO.setMaterialType(dataJson.getString("MTART")); DO.setMaterialGroupDate(dataJson.getString("MATKL")); DO.setExternalMaterialGroupDate(dataJson.getString("EXTWG")); @@ -189,7 +199,7 @@ public class ErpMaterialServiceImpl implements ErpMaterialService { erpMaterialMapper.insertBatch(result.toInsert); } if (!result.toUpdate.isEmpty()) { - erpMaterialMapper.updateBatch(result.toUpdate); + erpMaterialMapper.updateBatchByNumber(result.toUpdate); } erpConfig.updateRedisCache(result.key,result.allnumbers); } @@ -211,13 +221,11 @@ public class ErpMaterialServiceImpl implements ErpMaterialService { } } - @Override - public void initialize() { + private void initialize(String key) { 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 diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpProductiveVersionServiceImpl.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpProductiveVersionServiceImpl.java index 50cf0b9..cd84f13 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpProductiveVersionServiceImpl.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpProductiveVersionServiceImpl.java @@ -3,11 +3,14 @@ package com.zt.plat.module.erp.service.erp; import cn.hutool.core.collection.CollUtil; import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.common.util.object.BeanUtils; +import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX; import com.zt.plat.module.erp.common.conf.ErpConfig; import com.zt.plat.module.erp.common.enums.OftenEnum; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpProductiveVersionPageReqVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpProductiveVersionRespVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpProductiveVersionSaveReqVO; +import com.zt.plat.module.erp.dal.dataobject.erp.ErpAssetDO; +import com.zt.plat.module.erp.dal.dataobject.erp.ErpCompanyDO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpProductiveVersionDO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpProductiveVersionDO; import com.zt.plat.module.erp.dal.mysql.erp.ErpProductiveVersionMapper; @@ -23,6 +26,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.zt.plat.module.erp.enums.ErrorCodeConstants.ERP_PRODUCTIVE_VERSION_NOT_EXISTS; @@ -107,15 +111,21 @@ public class ErpProductiveVersionServiceImpl implements ErpProductiveVersionServ try { OftenEnum.FuncnrEnum funcnrEnum =OftenEnum.FuncnrEnum.生产版本; String funcnr = funcnrEnum.getFuncnr(); + //防止缓存数据丢失 + String key = "erpMap" + funcnrEnum.getFuncnr(); + if (erpConfig.getRedisCacheMap(key).isEmpty()) { + initializeMap(key); + } Map req = new HashMap<>(); JSONArray dataArrayALL = new JSONArray(); - List redisCache = erpConfig.getRedisCache(OftenEnum.FuncnrEnum.工厂信息.getFuncnr()); + String factKey ="erpMap"+ OftenEnum.FuncnrEnum.工厂信息.getFuncnr(); + Map redisCache = erpConfig.getRedisCacheMap(factKey); if (CollUtil.isEmpty(redisCache)) { return; } // 1. 调用ERP接口获取数据 - for (String number : redisCache) { + for (String number : redisCache.keySet()) { req.put("WERKS", number); // 1. 调用ERP接口获取数据 JSONArray dataArray = erpConfig.fetchDataFromERP(funcnr, req); @@ -141,36 +151,44 @@ public class ErpProductiveVersionServiceImpl implements ErpProductiveVersionServ * 处理数据,区分新增和更新 */ 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"); + String key = "erpMap" + funcnr.getFuncnr(); + Map numbers = erpConfig.getRedisCacheMap(key); List toUpdate = new ArrayList<>(); List toInsert = new ArrayList<>(); + List dataArrayNumbers = new ArrayList<>(); for (int i = 0; i < dataArray.size(); i++) { JSONObject dataJson = dataArray.getJSONObject(i); if (dataJson != null) { - String number = dataJson.getString("VERID").trim(); ErpProductiveVersionDO DO = new ErpProductiveVersionDO(); -// DO.setFactoryNumber(dataJson.getString("MATNR")); - DO.setMaterialNumber(dataJson.getString("WERKS")); - DO.setProductiveVersionNumber(number); + DO.setFactoryNumber(dataJson.getString("MATNR").trim()); + DO.setMaterialNumber(dataJson.getString("WERKS").trim()); + DO.setProductiveVersionNumber(dataJson.getString("VERID").trim()); DO.setProductiveVersionName(dataJson.getString("TEXT1")); DO.setBomNumber(dataJson.getString("STLAL")); DO.setBlineGroup(dataJson.getString("PLNNR")); -// DO.setGroupCount(dataJson.getString("ALNAL")); - if (comnumbers.contains(number)) { + DO.setGroupCount(Long.valueOf(dataJson.getString("ALNAL").trim())); + String number = dataJson.getString("MATNR").trim()+"-"+dataJson.getString("WERKS").trim()+"-"+dataJson.getString("VERID").trim(); + if (numbers.get(number)!=null) { // 更新 + DO.setId(numbers.get(number)); toUpdate.add(DO); } else { // 新增 toInsert.add(DO); } + dataArrayNumbers.add(number); + } + } + // 过滤出numbers中有,但dataArray中KOSTL没有的记录,即为需要删除的数据 + Map deleteNumbers = new HashMap<>(); + for (String number : numbers.keySet()) { + if (!dataArrayNumbers.contains(number)) { + deleteNumbers.put(number,numbers.get(number)); } } - return new ProcessingResult(toUpdate, toInsert,key,allnumbers); + return new ProcessingResult(toUpdate, toInsert,key,deleteNumbers); } /** @@ -180,11 +198,26 @@ public class ErpProductiveVersionServiceImpl implements ErpProductiveVersionServ // 批量新增和更新 if (!result.toInsert.isEmpty()) { erpProductiveVersionMapper.insertBatch(result.toInsert); + // 批量查询刚插入数据的id,提升效率 + List insertedRecords = erpProductiveVersionMapper.selectList( + new LambdaQueryWrapperX() + .in(ErpProductiveVersionDO::getFactoryNumber, result.toInsert.stream().map(ErpProductiveVersionDO::getFactoryNumber).collect(Collectors.toList())) + .in(ErpProductiveVersionDO::getMaterialNumber, result.toInsert.stream().map(ErpProductiveVersionDO::getMaterialNumber).collect(Collectors.toList())) + .in(ErpProductiveVersionDO::getProductiveVersionNumber, result.toInsert.stream().map(ErpProductiveVersionDO::getProductiveVersionNumber).collect(Collectors.toList())) + ); + Map numberIdMap = insertedRecords.stream() + .collect(Collectors.toMap(asset -> asset.getFactoryNumber() + "-" + asset.getMaterialNumber()+ "-" + asset.getProductiveVersionNumber(), ErpProductiveVersionDO::getId)); + erpConfig.addRedisCacheMap(result.key,numberIdMap); } if (!result.toUpdate.isEmpty()) { erpProductiveVersionMapper.updateBatch(result.toUpdate); } - erpConfig.updateRedisCache(result.key,result.allnumbers); + if (!result.deleteNumbers.isEmpty()){ + // 使用流式处理和批处理优化删除逻辑 + List idsToDelete = new ArrayList<>(result.deleteNumbers.values()); + erpProductiveVersionMapper.deleteByIds(idsToDelete); + erpConfig.deleteRedisCacheMap(result.key, new ArrayList<>(result.deleteNumbers.keySet())); + } } /** @@ -194,13 +227,23 @@ public class ErpProductiveVersionServiceImpl implements ErpProductiveVersionServ private final List toUpdate; private final List toInsert; private final String key; - private final List allnumbers; + private final Map deleteNumbers; - public ProcessingResult(List toUpdate, List toInsert,String key,List allnumbers) { + public ProcessingResult(List toUpdate, List toInsert,String key,Map deleteNumbers) { this.toUpdate = toUpdate; this.toInsert = toInsert; this.key = key; - this.allnumbers = allnumbers; + this.deleteNumbers = deleteNumbers; } } + + private void initializeMap(String key) { + List assets = erpProductiveVersionMapper.selectList(new LambdaQueryWrapperX()); + Map existingNumbers = new HashMap<>(); + for (ErpProductiveVersionDO asset : assets) { + String mapKey = asset.getFactoryNumber() + "-" + asset.getMaterialNumber() + "-" + asset.getProductiveVersionNumber(); + existingNumbers.put(mapKey, asset.getId()); + } + erpConfig.addRedisCacheMap(key, existingNumbers); + } } \ No newline at end of file diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpPurchaseOrganizationServiceImpl.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpPurchaseOrganizationServiceImpl.java index 0ed4f90..413d7ca 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpPurchaseOrganizationServiceImpl.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpPurchaseOrganizationServiceImpl.java @@ -3,11 +3,14 @@ package com.zt.plat.module.erp.service.erp; import cn.hutool.core.collection.CollUtil; import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.common.util.object.BeanUtils; +import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX; import com.zt.plat.module.erp.common.conf.ErpConfig; import com.zt.plat.module.erp.common.enums.OftenEnum; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpPurchaseOrganizationPageReqVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpPurchaseOrganizationRespVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpPurchaseOrganizationSaveReqVO; +import com.zt.plat.module.erp.dal.dataobject.erp.ErpCompanyDO; +import com.zt.plat.module.erp.dal.dataobject.erp.ErpProductiveVersionDO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpPurchaseOrganizationDO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpPurchaseOrganizationDO; import com.zt.plat.module.erp.dal.mysql.erp.ErpPurchaseOrganizationMapper; @@ -23,6 +26,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.zt.plat.module.erp.enums.ErrorCodeConstants.ERP_PURCHASE_ORGANIZATION_NOT_EXISTS; @@ -107,20 +111,35 @@ public class ErpPurchaseOrganizationServiceImpl implements ErpPurchaseOrganizati try { OftenEnum.FuncnrEnum funcnrEnum =OftenEnum.FuncnrEnum.采购组织; String funcnr = funcnrEnum.getFuncnr(); + //防止缓存数据丢失 + String key = "erpMap" + funcnrEnum.getFuncnr(); + if (erpConfig.getRedisCacheMap(key).isEmpty()) { + initializeMap(key); + } + Map req = new HashMap<>(); JSONArray dataArrayALL = new JSONArray(); - List redisCache = erpConfig.getRedisCache(OftenEnum.FuncnrEnum.工厂信息.getFuncnr()); +// String factKey ="erpMap"+ OftenEnum.FuncnrEnum.工厂信息.getFuncnr(); + String factKey ="erpMap"+ OftenEnum.FuncnrEnum.公司代码.getFuncnr(); + Map redisCache = erpConfig.getRedisCacheMap(factKey); if (CollUtil.isEmpty(redisCache)) { return; } // 1. 调用ERP接口获取数据 - for (String number : redisCache) { - req.put("WERKS", number); + for (String number : redisCache.keySet()) { + req.put("BUKRS", number); // 1. 调用ERP接口获取数据 JSONArray dataArray = erpConfig.fetchDataFromERP(funcnr, req); if (dataArray == null || dataArray.isEmpty()) { continue; } + // 往每个子项中添加BUKRS字段 + for (int j = 0; j < dataArray.size(); j++) { + JSONObject item = dataArray.getJSONObject(j); + if (item != null) { + item.put("BUKRS", number); + } + } dataArrayALL.addAll(dataArray); } @@ -140,13 +159,12 @@ public class ErpPurchaseOrganizationServiceImpl implements ErpPurchaseOrganizati * 处理数据,区分新增和更新 */ 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"); + String key = "erpMap" + funcnr.getFuncnr(); + Map numbers = erpConfig.getRedisCacheMap(key); List toUpdate = new ArrayList<>(); List toInsert = new ArrayList<>(); + List dataArrayNumbers = new ArrayList<>(); for (int i = 0; i < dataArray.size(); i++) { JSONObject dataJson = dataArray.getJSONObject(i); if (dataJson != null) { @@ -154,17 +172,27 @@ public class ErpPurchaseOrganizationServiceImpl implements ErpPurchaseOrganizati ErpPurchaseOrganizationDO DO = new ErpPurchaseOrganizationDO(); DO.setName(dataJson.getString("EKOTX")); DO.setNumber(number); - if (comnumbers.contains(number)) { + DO.setCompanyNumber(dataJson.getString("BUKRS")); + if (numbers.get(number)!=null) { // 更新 + DO.setId(numbers.get(number)); toUpdate.add(DO); } else { // 新增 toInsert.add(DO); } + dataArrayNumbers.add(number); + } + } + // 过滤出numbers中有,但dataArray中KOSTL没有的记录,即为需要删除的数据 + List deleteNumbers = new ArrayList<>(); + for (String number : numbers.keySet()) { + if (!dataArrayNumbers.contains(number)) { + deleteNumbers.add(number); } } - return new ProcessingResult(toUpdate, toInsert,key,allnumbers); + return new ProcessingResult(toUpdate, toInsert,key,deleteNumbers); } /** @@ -174,11 +202,26 @@ public class ErpPurchaseOrganizationServiceImpl implements ErpPurchaseOrganizati // 批量新增和更新 if (!result.toInsert.isEmpty()) { erpPurchaseOrganizationMapper.insertBatch(result.toInsert); + // 批量查询刚插入数据的id,提升效率 + List insertedNumbers = result.toInsert.stream() + .map(ErpPurchaseOrganizationDO::getNumber) + .collect(Collectors.toList()); + List insertedRecords = erpPurchaseOrganizationMapper.selectList( + new LambdaQueryWrapperX() + .in(ErpPurchaseOrganizationDO::getNumber, insertedNumbers) + ); + Map numberIdMap = insertedRecords.stream() + .collect(Collectors.toMap(ErpPurchaseOrganizationDO::getNumber, ErpPurchaseOrganizationDO::getId)); + erpConfig.addRedisCacheMap(result.key,numberIdMap); } if (!result.toUpdate.isEmpty()) { erpPurchaseOrganizationMapper.updateBatch(result.toUpdate); } - erpConfig.updateRedisCache(result.key,result.allnumbers); + if (!result.deleteNumbers.isEmpty()){ + // 使用 in 条件批量删除,提高删除效率 + erpPurchaseOrganizationMapper.delete(new LambdaQueryWrapperX().in(ErpPurchaseOrganizationDO::getNumber, result.deleteNumbers)); + erpConfig.deleteRedisCacheMap(result.key, result.deleteNumbers); + } } /** @@ -188,13 +231,20 @@ public class ErpPurchaseOrganizationServiceImpl implements ErpPurchaseOrganizati private final List toUpdate; private final List toInsert; private final String key; - private final List allnumbers; + private final List deleteNumbers; - public ProcessingResult(List toUpdate, List toInsert,String key,List allnumbers) { + public ProcessingResult(List toUpdate, List toInsert,String key,List deleteNumbers) { this.toUpdate = toUpdate; this.toInsert = toInsert; this.key = key; - this.allnumbers = allnumbers; + this.deleteNumbers = deleteNumbers; } } + + private void initializeMap(String key) { + Map existingNumbers = erpPurchaseOrganizationMapper.selectList(new LambdaQueryWrapperX()) + .stream() + .collect(Collectors.toMap(ErpPurchaseOrganizationDO::getNumber, ErpPurchaseOrganizationDO::getId)); + erpConfig.addRedisCacheMap(key, existingNumbers); + } } \ No newline at end of file diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpSalesOrganizationServiceImpl.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpSalesOrganizationServiceImpl.java index 4cae5ca..46363ed 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpSalesOrganizationServiceImpl.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpSalesOrganizationServiceImpl.java @@ -3,11 +3,13 @@ package com.zt.plat.module.erp.service.erp; import cn.hutool.core.collection.CollUtil; import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.common.util.object.BeanUtils; +import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX; import com.zt.plat.module.erp.common.conf.ErpConfig; import com.zt.plat.module.erp.common.enums.OftenEnum; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpSalesOrganizationPageReqVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpSalesOrganizationRespVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpSalesOrganizationSaveReqVO; +import com.zt.plat.module.erp.dal.dataobject.erp.ErpPurchaseOrganizationDO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpSalesOrganizationDO; import com.zt.plat.module.erp.dal.dataobject.erp.ErpSalesOrganizationDO; import com.zt.plat.module.erp.dal.mysql.erp.ErpSalesOrganizationMapper; @@ -23,6 +25,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.zt.plat.module.erp.enums.ErrorCodeConstants.ERP_SALES_ORGANIZATION_NOT_EXISTS; @@ -107,14 +110,21 @@ public class ErpSalesOrganizationServiceImpl implements ErpSalesOrganizationServ try { OftenEnum.FuncnrEnum funcnrEnum =OftenEnum.FuncnrEnum.销售组织; String funcnr = funcnrEnum.getFuncnr(); + //防止缓存数据丢失 + String key = "erpMap" + funcnrEnum.getFuncnr(); + if (erpConfig.getRedisCacheMap(key).isEmpty()) { + initializeMap(key); + } + Map req = new HashMap<>(); JSONArray dataArrayALL = new JSONArray(); - List redisCache = erpConfig.getRedisCache(OftenEnum.FuncnrEnum.公司代码.getFuncnr()); + String factKey ="erpMap"+ OftenEnum.FuncnrEnum.公司代码.getFuncnr(); + Map redisCache = erpConfig.getRedisCacheMap(factKey); if (CollUtil.isEmpty(redisCache)) { return; } // 1. 调用ERP接口获取数据 - for (String number : redisCache) { + for (String number : redisCache.keySet()) { req.put("BUKRS", number); // 1. 调用ERP接口获取数据 JSONArray dataArray = erpConfig.fetchDataFromERP(funcnr, req); @@ -147,13 +157,12 @@ public class ErpSalesOrganizationServiceImpl implements ErpSalesOrganizationServ * 处理数据,区分新增和更新 */ 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"); + String key = "erpMap" + funcnr.getFuncnr(); + Map numbers = erpConfig.getRedisCacheMap(key); List toUpdate = new ArrayList<>(); List toInsert = new ArrayList<>(); + List dataArrayNumbers = new ArrayList<>(); for (int i = 0; i < dataArray.size(); i++) { JSONObject dataJson = dataArray.getJSONObject(i); if (dataJson != null) { @@ -162,17 +171,25 @@ public class ErpSalesOrganizationServiceImpl implements ErpSalesOrganizationServ DO.setName(dataJson.getString("VTEXT")); DO.setNumber(number); DO.setCompanyNumber(dataJson.getString("BUKRS")); - if (comnumbers.contains(number)) { + if (numbers.get(number)!=null) { // 更新 + DO.setId(numbers.get(number)); toUpdate.add(DO); } else { // 新增 toInsert.add(DO); } + dataArrayNumbers.add( number); } } - - return new ProcessingResult(toUpdate, toInsert,key,allnumbers); + // 过滤出numbers中有,但dataArray中KOSTL没有的记录,即为需要删除的数据 + List deleteNumbers = new ArrayList<>(); + for (String number : numbers.keySet()) { + if (!dataArrayNumbers.contains(number)) { + deleteNumbers.add(number); + } + } + return new ProcessingResult(toUpdate, toInsert,key,deleteNumbers); } /** @@ -182,11 +199,26 @@ public class ErpSalesOrganizationServiceImpl implements ErpSalesOrganizationServ // 批量新增和更新 if (!result.toInsert.isEmpty()) { erpSalesOrganizationMapper.insertBatch(result.toInsert); + // 批量查询刚插入数据的id,提升效率 + List insertedNumbers = result.toInsert.stream() + .map(ErpSalesOrganizationDO::getNumber) + .collect(Collectors.toList()); + List insertedRecords = erpSalesOrganizationMapper.selectList( + new LambdaQueryWrapperX() + .in(ErpSalesOrganizationDO::getNumber, insertedNumbers) + ); + Map numberIdMap = insertedRecords.stream() + .collect(Collectors.toMap(ErpSalesOrganizationDO::getNumber, ErpSalesOrganizationDO::getId)); + erpConfig.addRedisCacheMap(result.key,numberIdMap); } if (!result.toUpdate.isEmpty()) { erpSalesOrganizationMapper.updateBatch(result.toUpdate); } - erpConfig.updateRedisCache(result.key,result.allnumbers); + if (!result.deleteNumbers.isEmpty()) { + // 使用 in 条件批量删除,提高删除效率 + erpSalesOrganizationMapper.delete(new LambdaQueryWrapperX().in(ErpSalesOrganizationDO::getNumber, result.deleteNumbers)); + erpConfig.deleteRedisCacheMap(result.key, result.deleteNumbers); + } } /** @@ -196,13 +228,20 @@ public class ErpSalesOrganizationServiceImpl implements ErpSalesOrganizationServ private final List toUpdate; private final List toInsert; private final String key; - private final List allnumbers; + private final List deleteNumbers; - public ProcessingResult(List toUpdate, List toInsert,String key,List allnumbers) { + public ProcessingResult(List toUpdate, List toInsert,String key,List deleteNumbers) { this.toUpdate = toUpdate; this.toInsert = toInsert; this.key = key; - this.allnumbers = allnumbers; + this.deleteNumbers = deleteNumbers; } } + + private void initializeMap(String key) { + Map existingNumbers = erpSalesOrganizationMapper.selectList(new LambdaQueryWrapperX()) + .stream() + .collect(Collectors.toMap(ErpSalesOrganizationDO::getNumber, ErpSalesOrganizationDO::getId)); + erpConfig.addRedisCacheMap(key, existingNumbers); + } } \ No newline at end of file diff --git a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpWarehouseServiceImpl.java b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpWarehouseServiceImpl.java index c25f534..216e49f 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpWarehouseServiceImpl.java +++ b/zt-module-erp/zt-module-erp-server/src/main/java/com/zt/plat/module/erp/service/erp/ErpWarehouseServiceImpl.java @@ -3,12 +3,13 @@ package com.zt.plat.module.erp.service.erp; import cn.hutool.core.collection.CollUtil; import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.common.util.object.BeanUtils; +import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX; import com.zt.plat.module.erp.common.conf.ErpConfig; import com.zt.plat.module.erp.common.enums.OftenEnum; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpWarehousePageReqVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpWarehouseRespVO; import com.zt.plat.module.erp.controller.admin.erp.vo.ErpWarehouseSaveReqVO; -import com.zt.plat.module.erp.dal.dataobject.erp.ErpWarehouseDO; +import com.zt.plat.module.erp.dal.dataobject.erp.*; import com.zt.plat.module.erp.dal.dataobject.erp.ErpWarehouseDO; import com.zt.plat.module.erp.dal.mysql.erp.ErpWarehouseMapper; import com.alibaba.fastjson.JSONArray; @@ -23,6 +24,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.zt.plat.module.erp.enums.ErrorCodeConstants.ERP_WAREHOUSE_NOT_EXISTS; @@ -70,12 +72,12 @@ public class ErpWarehouseServiceImpl implements ErpWarehouseService { } @Override - public void deleteErpWarehouseListByIds(List ids) { + public void deleteErpWarehouseListByIds(List ids) { // 校验存在 validateErpWarehouseExists(ids); // 删除 erpWarehouseMapper.deleteByIds(ids); - } + } private void validateErpWarehouseExists(List ids) { List list = erpWarehouseMapper.selectByIds(ids); @@ -105,16 +107,23 @@ public class ErpWarehouseServiceImpl implements ErpWarehouseService { @XxlJob("getErpWarehouseTask") public void callErpRfcInterface() { try { - OftenEnum.FuncnrEnum funcnrEnum =OftenEnum.FuncnrEnum.库位信息; + OftenEnum.FuncnrEnum funcnrEnum = OftenEnum.FuncnrEnum.库位信息; String funcnr = funcnrEnum.getFuncnr(); + //防止缓存数据丢失 + String key = "erpMap" + funcnrEnum.getFuncnr(); + if (erpConfig.getRedisCacheMap(key).isEmpty()) { + initializeMap(key); + } + Map req = new HashMap<>(); JSONArray dataArrayALL = new JSONArray(); - List redisCache = erpConfig.getRedisCache(OftenEnum.FuncnrEnum.工厂信息.getFuncnr()); + String factKey = "erpMap" + OftenEnum.FuncnrEnum.工厂信息.getFuncnr(); + Map redisCache = erpConfig.getRedisCacheMap(factKey); if (CollUtil.isEmpty(redisCache)) { return; } // 1. 调用ERP接口获取数据 - for (String number : redisCache) { + for (String number : redisCache.keySet()) { req.put("WERKS", number); // 1. 调用ERP接口获取数据 JSONArray dataArray = erpConfig.fetchDataFromERP(funcnr, req); @@ -133,7 +142,7 @@ public class ErpWarehouseServiceImpl implements ErpWarehouseService { } // 2. 处理公司数据,区分新增和更新 - ProcessingResult result = processData(dataArrayALL,funcnrEnum); + ProcessingResult result = processData(dataArrayALL, funcnrEnum); // 3. 批量保存数据 saveData(result); @@ -148,32 +157,40 @@ public class ErpWarehouseServiceImpl implements ErpWarehouseService { * 处理数据,区分新增和更新 */ 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"); + String key = "erpMap" + funcnr.getFuncnr(); + Map numbers = erpConfig.getRedisCacheMap(key); List toUpdate = new ArrayList<>(); List toInsert = new ArrayList<>(); + List dataArrayNumbers = new ArrayList<>(); for (int i = 0; i < dataArray.size(); i++) { JSONObject dataJson = dataArray.getJSONObject(i); if (dataJson != null) { - String number = dataJson.getString("LGORT").trim(); ErpWarehouseDO DO = new ErpWarehouseDO(); DO.setName(dataJson.getString("LGOBE")); - DO.setNumber(number); + DO.setNumber(dataJson.getString("LGORT").trim()); DO.setFactoryNumber(dataJson.getString("WERKS")); - if (comnumbers.contains(number)) { + String number = dataJson.getString("WERKS").trim() + "-" + dataJson.getString("LGORT").trim(); + if (numbers.get(number) != null) { // 更新 + DO.setId(numbers.get(number)); toUpdate.add(DO); } else { // 新增 toInsert.add(DO); } + dataArrayNumbers.add(number); + } + } + // 过滤出numbers中有,但dataArray中KOSTL没有的记录,即为需要删除的数据 + Map deleteNumbers = new HashMap<>(); + for (String number : numbers.keySet()) { + if (!dataArrayNumbers.contains(number)) { + deleteNumbers.put(number,numbers.get(number)); } } - return new ProcessingResult(toUpdate, toInsert,key,allnumbers); + return new ProcessingResult(toUpdate, toInsert, key, deleteNumbers); } /** @@ -183,11 +200,25 @@ public class ErpWarehouseServiceImpl implements ErpWarehouseService { // 批量新增和更新 if (!result.toInsert.isEmpty()) { erpWarehouseMapper.insertBatch(result.toInsert); + // 批量查询刚插入数据的id,提升效率 + List insertedRecords = erpWarehouseMapper.selectList( + new LambdaQueryWrapperX() + .in(ErpWarehouseDO::getFactoryNumber, result.toInsert.stream().map(ErpWarehouseDO::getFactoryNumber).collect(Collectors.toList())) + .in(ErpWarehouseDO::getNumber, result.toInsert.stream().map(ErpWarehouseDO::getNumber).collect(Collectors.toList())) + ); + Map numberIdMap = insertedRecords.stream() + .collect(Collectors.toMap(asset -> asset.getFactoryNumber() + "-" + asset.getNumber(), ErpWarehouseDO::getId)); + erpConfig.addRedisCacheMap(result.key,numberIdMap); } if (!result.toUpdate.isEmpty()) { erpWarehouseMapper.updateBatch(result.toUpdate); } - erpConfig.updateRedisCache(result.key,result.allnumbers); + if (!result.deleteNumbers.isEmpty()) { + // 使用流式处理和批处理优化删除逻辑 + List idsToDelete = new ArrayList<>(result.deleteNumbers.values()); + erpWarehouseMapper.deleteByIds(idsToDelete); + erpConfig.deleteRedisCacheMap(result.key, new ArrayList<>(result.deleteNumbers.keySet())); + } } /** @@ -197,13 +228,23 @@ public class ErpWarehouseServiceImpl implements ErpWarehouseService { private final List toUpdate; private final List toInsert; private final String key; - private final List allnumbers; + private final Map deleteNumbers; - public ProcessingResult(List toUpdate, List toInsert,String key,List allnumbers) { + public ProcessingResult(List toUpdate, List toInsert, String key, Map deleteNumbers) { this.toUpdate = toUpdate; this.toInsert = toInsert; this.key = key; - this.allnumbers = allnumbers; + this.deleteNumbers = deleteNumbers; } } + + private void initializeMap(String key) { + List assets = erpWarehouseMapper.selectList(new LambdaQueryWrapperX()); + Map existingNumbers = new HashMap<>(); + for (ErpWarehouseDO asset : assets) { + String mapKey = asset.getFactoryNumber() + "-" + asset.getNumber(); + existingNumbers.put(mapKey, asset.getId()); + } + erpConfig.addRedisCacheMap(key, existingNumbers); + } } \ No newline at end of file diff --git a/zt-module-erp/zt-module-erp-server/src/main/resources/mapper/ErpCostcenterMapper.xml b/zt-module-erp/zt-module-erp-server/src/main/resources/mapper/ErpCostcenterMapper.xml index 1e9a10c..498c4e0 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/resources/mapper/ErpCostcenterMapper.xml +++ b/zt-module-erp/zt-module-erp-server/src/main/resources/mapper/ErpCostcenterMapper.xml @@ -9,14 +9,61 @@ 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ --> - - - UPDATE sply_erp_fact - - NAME = #{item.name}, - CPN_ID = #{item.companyId}, - - WHERE NUM = #{item.number} + + UPDATE sply_erp_cctr + SET + NAME = CASE NUM + + + WHEN #{item.number} THEN #{item.name} + + + ELSE NAME + END, + IS_USE = CASE NUM + + + WHEN #{item.number} THEN #{item.isUse} + + + ELSE IS_USE + END, + SCO_NUM = CASE NUM + + + WHEN #{item.number} THEN #{item.scopeNumber} + + + ELSE SCO_NUM + END, + STRT_DT = CASE NUM + + + WHEN #{item.number} THEN #{item.startDate} + + + ELSE STRT_DT + END, + END_DT = CASE NUM + + + WHEN #{item.number} THEN #{item.endDate} + + + ELSE END_DT + END, + SCO_NAME = CASE NUM + + + WHEN #{item.number} THEN #{item.scopeName} + + + ELSE SCO_NAME + END + WHERE NUM IN + + #{item.number} + \ No newline at end of file diff --git a/zt-module-erp/zt-module-erp-server/src/main/resources/mapper/ErpMaterialMapper.xml b/zt-module-erp/zt-module-erp-server/src/main/resources/mapper/ErpMaterialMapper.xml index 7d3c0a2..666dc57 100644 --- a/zt-module-erp/zt-module-erp-server/src/main/resources/mapper/ErpMaterialMapper.xml +++ b/zt-module-erp/zt-module-erp-server/src/main/resources/mapper/ErpMaterialMapper.xml @@ -9,14 +9,28 @@ 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ --> - - - UPDATE sply_erp_fact - - NAME = #{item.name}, - CPN_ID = #{item.companyId}, - - WHERE NUM = #{item.number} - - - \ No newline at end of file + + + + UPDATE SPLY_ERP_MTRL + + DOWN_CTR_NUM = #{item.downCtrNum}, + CTR_NUM = #{item.ctrNum}, + CRT_DT = #{item.crtDt}, + MTRL_TP = #{item.mtrlTp}, + MTRL_GRP_DT = #{item.mtrlGrpDt}, + EXT_MTRL_GRP_DT = #{item.extMtrlGrpDt}, + UNT = #{item.unt}, + UNT_DSP = #{item.untDsp}, + MTRL_TP_DSP = #{item.mtrlTpDsp}, + MTRL_GRP_DSP = #{item.mtrlGrpDsp}, + EXT_MTRL_GRP_DSP = #{item.extMtrlGrpDsp}, + MTRL_NAME = #{item.mtrlName}, + MTRL_LEN_DSP = #{item.mtrlLenDsp}, + TENANT_ID = #{item.tenantId}, + + WHERE DOWN_CTR_NUM = #{item.number} + + + +