封装接口,erp定时任务,调用缓存map替换list

This commit is contained in:
liss
2025-09-23 15:52:48 +08:00
parent b3e65d4732
commit db4d708978
37 changed files with 893 additions and 427 deletions

View File

@@ -51,7 +51,7 @@ spring:
redis:
host: 172.16.46.63 # 地址
port: 30379 # 端口
database: 0 # 数据库索引
database: 6 # 数据库索引
# password: 123456 # 密码,建议生产环境开启
xxl:

View File

@@ -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<String> submitDataToErp(@Valid @RequestBody ErpSubmitReqDTO reqDTO);
}

View File

@@ -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<String, Object> req;
}

View File

@@ -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";
}

View File

@@ -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<String> submitDataToErp(ErpSubmitReqDTO reqDTO) {
return erpConfig.pushDataToErp(reqDTO);
}
}

View File

@@ -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<String, Object> 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<String> 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<String, List<String>> numbers(JSONArray dataArray, String key,String dataKey) {
// 创建HTTP请求实体
HttpEntity<String> requestEntity = new HttpEntity<>(requestBody.toJSONString(), headers);
// 发送POST请求
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> 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<String, List<String>> numbers(JSONArray dataArray, String key, String dataKey) {
// 使用 Redis 获取缓存数据
Map<String, List<String>> numbers = new HashMap<>();
List<String> cachedNumbers = (List<String>) redisTemplate.opsForValue().get(key);
@@ -92,7 +130,7 @@ public class ErpConfig {
}
// 提取有效的 BUKRS 编号
List<String> existingNumbers = new ArrayList<>();
List<String> 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<String> deleteNumbers = cachedNumberSet.stream()
.filter(num -> !existingNumbers.contains(num))
.collect(Collectors.toList());
numbers.put("delete", deleteNumbers);
// 找出需要新增的编号
List<String> newNumbers = existingNumbers.stream()
.filter(num -> !cachedNumberSet.contains(num))
.collect(Collectors.toList());
.toList();
// 合并所有编号
List<String> allNumbers = new ArrayList<>(cachedNumbers);
allNumbers.addAll(newNumbers);
numbers.put("all", allNumbers);
return numbers;
}
@@ -145,23 +193,35 @@ public class ErpConfig {
public List<String> getRedisCache(String key) {
// 使用 Redis 更新缓存数据
return (List<String>)redisTemplate.opsForValue().get("erp"+key);
return (List<String>) redisTemplate.opsForValue().get(key);
}
public Map<String, String> numbersMap(String key) {
//map
public Map<String, Long> getRedisCacheMap(String key) {
// 使用 Redis 获取缓存数据
Map<String, String> result = (Map<String, String>) redisTemplate.opsForValue().get(key);
Map<String, Long> result = (Map<String, Long>) redisTemplate.opsForHash().entries(key);
return result;
}
// public void updateRedisCache(String key, List<String> allnumbers) {
// // 使用 Redis 更新缓存数据
// redisTemplate.opsForValue().set(key, allnumbers);
// }
//
// public List<String> getRedisCache(String key) {
// // 使用 Redis 更新缓存数据
// return (List<String>)redisTemplate.opsForValue().get("erp"+key);
// }
public void addRedisCacheMap(String key, Map<String, Long> allnumbers) {
// 使用 Redis 更新缓存数据
redisTemplate.opsForHash().putAll(key, allnumbers);
}
public void deleteRedisCacheMap(String key, List<String> 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;
}
}
}

View File

@@ -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<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> 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<String, Serializable> redisTemplate(JedisConnectionFactory jedisConnectionFactory){
// RedisTemplate<String, Serializable> redisTemplate = new RedisTemplate<>();
// redisTemplate.setKeySerializer(new StringRedisSerializer());
// redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
// redisTemplate.setConnectionFactory(jedisConnectionFactory);
// return redisTemplate;
// }
/**
* 序列化乱码问题解决
*/
// @Bean
// public RedisTemplate<String, Serializable> redisTemplate(JedisConnectionFactory jedisConnectionFactory){
// RedisTemplate<String, Serializable> redisTemplate = new RedisTemplate<>();
// redisTemplate.setKeySerializer(new StringRedisSerializer());
// redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
// redisTemplate.setConnectionFactory(jedisConnectionFactory);
// return redisTemplate;
// }
}

View File

@@ -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;

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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;

View File

@@ -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("物料编码")

View File

@@ -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 = "物料编码不能为空")

View File

@@ -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;

View File

@@ -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;

View File

@@ -34,7 +34,7 @@ public class ErpProductiveVersionDO {
* 工厂编码
*/
@TableField("FACT_NUM")
private BigDecimal factoryNumber;
private String factoryNumber;
/**
* 物料编码
*/

View File

@@ -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")

View File

@@ -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<ErpCostcenterDO> {
.orderByDesc(ErpCostcenterDO::getId));
}
void updateBatchByNumber(@Param("list") List<ErpCostcenterDO> toUpdate);
}

View File

@@ -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<ErpMaterialDO> {
.orderByDesc(ErpMaterialDO::getId));
}
void updateBatchByNumber(@Param("toUpdate") List<ErpMaterialDO> toUpdate);
}

View File

@@ -19,7 +19,7 @@ public interface ErpWarehouseMapper extends BaseMapperX<ErpWarehouseDO> {
return selectPage(reqVO, new LambdaQueryWrapperX<ErpWarehouseDO>()
.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));
}

View File

@@ -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<String, Object> req = new HashMap<>();
List<Map<String, String>> datumList = new ArrayList<>();
Map<String, String> datumEntry = new HashMap<>();
datumEntry.put("sign", "I");
datumEntry.put("option", "EQ");
datumEntry.put("low", LocalDate.now().toString());
datumList.add(datumEntry);
req.put(funcnrEnum.getDatekey(), datumList);
// List<Map<String, String>> datumList = new ArrayList<>();
// Map<String, String> 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<String> redisCache = erpConfig.getRedisCache(OftenEnum.FuncnrEnum.公司代码.getFuncnr());
String companyKey ="erpMap"+ OftenEnum.FuncnrEnum.公司代码.getFuncnr();
Map<String,Long> 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<String, List<String>> numbers = erpConfig.numbers(dataArray, key, funcnr.getDatakey());
List<String> allnumbers = numbers.get("all");
List<String> comnumbers = numbers.get("com");
private ProcessingResult processData(JSONArray dataArray, OftenEnum.FuncnrEnum funcnrEnum) {
String key = "erpMap" + funcnrEnum.getFuncnr();
Map<String, Long> numbers = erpConfig.getRedisCacheMap(key);
List<ErpAssetDO> toUpdate = new ArrayList<>();
List<ErpAssetDO> toInsert = new ArrayList<>();
List<String> 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<String, Long> 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<ErpAssetDO> insertedRecords = erpAssetMapper.selectList(
new LambdaQueryWrapperX<ErpAssetDO>()
.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<String, Long> 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<Long> 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<ErpAssetDO> toUpdate;
private final List<ErpAssetDO> toInsert;
private final Map<String,Long> deleteNumbers;
private final String key;
private final List<String> allnumbers;
public ProcessingResult(List<ErpAssetDO> toUpdate, List<ErpAssetDO> toInsert, String key, List<String> allnumbers) {
public ProcessingResult(List<ErpAssetDO> toUpdate, List<ErpAssetDO> toInsert, Map<String,Long> deleteNumbers, String key) {
this.toUpdate = toUpdate;
this.toInsert = toInsert;
this.deleteNumbers = deleteNumbers;
this.key = key;
this.allnumbers = allnumbers;
}
}
private void initializeMap(String key) {
List<ErpAssetDO> assets = erpAssetMapper.selectList(new LambdaQueryWrapperX<ErpAssetDO>());
Map<String, Long> existingNumbers = new HashMap<>();
for (ErpAssetDO asset : assets) {
String mapKey = asset.getCompanyNumber() + "-" + asset.getMainAssetNumber();
existingNumbers.put(mapKey, asset.getId());
}
erpConfig.addRedisCacheMap(key, existingNumbers);
}
}

View File

@@ -141,8 +141,8 @@ public class ErpBomServiceImpl implements ErpBomService {
*/
private ProcessingResult processData(JSONArray dataArray, OftenEnum.FuncnrEnum funcnr) {
String key = "erp" + funcnr.getFuncnr();
Map<String, String> numbers = erpConfig.numbersMap(key);
Map<String, String> numberDels = erpConfig.numbersMap(key+"del");
Map<String, Long> numbers = erpConfig.getRedisCacheMap(key);
Map<String, Long> numberDetails = erpConfig.getRedisCacheMap(key+"details");
List<ErpBomDO> toUpdate = new ArrayList<>();
List<ErpBomDO> 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"));

View File

@@ -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<String,List<String>> numbers = erpConfig.numbers(dataArray, key,funcnr.getDatakey());
List<String> allnumbers = numbers.get("all");
List<String> comnumbers = numbers.get("com");
String key = "erpMap" + funcnr.getFuncnr();
Map<String, Long> numbers = erpConfig.getRedisCacheMap(key);
List<ErpCompanyDO> toUpdate = new ArrayList<>();
List<ErpCompanyDO> toInsert = new ArrayList<>();
List<String> 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)) {
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<String> 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<String> insertedNumbers = result.toInsert.stream()
.map(ErpCompanyDO::getNumber)
.collect(Collectors.toList());
List<ErpCompanyDO> insertedRecords = erpCompanyMapper.selectList(
new LambdaQueryWrapperX<ErpCompanyDO>()
.in(ErpCompanyDO::getNumber, insertedNumbers)
);
Map<String, Long> 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<ErpCompanyDO>().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<ErpCompanyDO> toUpdate;
private final List<ErpCompanyDO> toInsert;
private final List<String> deleteNumbers;
private final String key;
private final List<String> allnumbers;
public ProcessingResult(List<ErpCompanyDO> toUpdate, List<ErpCompanyDO> toInsert,String key,List<String> allnumbers) {
public ProcessingResult(List<ErpCompanyDO> toUpdate, List<ErpCompanyDO> toInsert, List<String> deleteNumbers, String key) {
this.toUpdate = toUpdate;
this.toInsert = toInsert;
this.deleteNumbers = deleteNumbers;
this.key = key;
this.allnumbers = allnumbers;
}
}
private void initializeMap(String key) {
Map<String, Long> existingNumbers = erpCompanyMapper.selectList(new LambdaQueryWrapperX<ErpCompanyDO>())
.stream()
.collect(Collectors.toMap(ErpCompanyDO::getNumber, ErpCompanyDO::getId));
erpConfig.addRedisCacheMap(key, existingNumbers);
}
}

View File

@@ -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<String, Object> req = new HashMap<>();
JSONArray dataArrayALL = new JSONArray();
List<String> redisCache = erpConfig.getRedisCache(OftenEnum.FuncnrEnum.公司代码.getFuncnr());
String commanyKey ="erpMap"+ OftenEnum.FuncnrEnum.公司代码.getFuncnr();
Map<String,Long> 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<String,List<String>> numbers = erpConfig.numbers(dataArray, key,funcnr.getDatakey());
List<String> allnumbers = numbers.get("all");
List<String> comnumbers = numbers.get("com");
String key = "erpMap" + funcnr.getFuncnr();
Map<String, Long> numbers = erpConfig.getRedisCacheMap(key);
List<ErpCostcenterDO> toUpdate = new ArrayList<>();
List<ErpCostcenterDO> toInsert = new ArrayList<>();
List<String> 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<String> 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<String> insertedNumbers = result.toInsert.stream()
.map(ErpCostcenterDO::getNumber)
.collect(Collectors.toList());
List<ErpCostcenterDO> insertedRecords = erpCostcenterMapper.selectList(
new LambdaQueryWrapperX<ErpCostcenterDO>()
.in(ErpCostcenterDO::getNumber, insertedNumbers)
);
Map<String, Long> 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<ErpCostcenterDO>().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<ErpCostcenterDO> toUpdate;
private final List<ErpCostcenterDO> toInsert;
private final List<String> deleteNumbers;
private final String key;
private final List<String> allnumbers;
public ProcessingResult(List<ErpCostcenterDO> toUpdate, List<ErpCostcenterDO> toInsert,String key,List<String> allnumbers) {
public ProcessingResult(List<ErpCostcenterDO> toUpdate, List<ErpCostcenterDO> toInsert,List<String> deleteNumbers,String key) {
this.toUpdate = toUpdate;
this.toInsert = toInsert;
this.deleteNumbers = deleteNumbers;
this.key = key;
this.allnumbers = allnumbers;
}
}
private void initializeMap(String key) {
Map<String, Long> existingNumbers = erpCostcenterMapper.selectList(new LambdaQueryWrapperX<ErpCostcenterDO>())
.stream()
.collect(Collectors.toMap(ErpCostcenterDO::getNumber, ErpCostcenterDO::getId));
erpConfig.addRedisCacheMap(key, existingNumbers);
}
}

View File

@@ -62,6 +62,4 @@ public interface ErpCustomerService {
PageResult<ErpCustomerDO> getErpCustomerPage(ErpCustomerPageReqVO pageReqVO);
void callErpRfcInterface();
void initialize();
}

View File

@@ -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<String, Object> req = new HashMap<>();
List<Map<String, String>> datumList = new ArrayList<>();
@@ -126,19 +129,21 @@ 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;
}
dataArrayALL.addAll(dataArray);
}
// 2. 处理数据,区分新增和更新
ProcessingResult result = processData(dataArray, funcnrEnum);
ProcessingResult result = processData(dataArrayALL, funcnrEnum);
// 3. 批量保存数据
saveData(result);
}
} catch (Exception e) {
log.error("调用ERP RFC接口失败: {}", e);
@@ -150,10 +155,8 @@ public class ErpCustomerServiceImpl implements ErpCustomerService {
* 处理数据,区分新增和更新
*/
private ProcessingResult processData(JSONArray dataArray, OftenEnum.FuncnrEnum funcnrEnum) {
String key = "erp" + funcnrEnum.getFuncnr();
Map<String, List<String>> numbers = erpConfig.numbers(dataArray, key, funcnrEnum.getDatakey());
List<String> allnumbers = numbers.get("all");
List<String> comnumbers = numbers.get("com");
String key = "erpMap" + funcnrEnum.getFuncnr();
Map<String, Long> numbers = erpConfig.getRedisCacheMap(key);
List<ErpCustomerDO> toUpdate = new ArrayList<>();
List<ErpCustomerDO> toInsert = new ArrayList<>();
@@ -162,22 +165,26 @@ 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"));
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)) {
if (numbers.get(number)!=null) {
// 更新
DO.setId(numbers.get(number));
toUpdate.add(DO);
} else {
// 新增
@@ -185,9 +192,8 @@ public class ErpCustomerServiceImpl implements ErpCustomerService {
}
}
}
}
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<String> insertedNumbers = result.toInsert.stream()
.map(ErpCustomerDO::getNumber)
.collect(Collectors.toList());
List<ErpCustomerDO> insertedRecords = erpCustomerMapper.selectList(
new LambdaQueryWrapperX<ErpCustomerDO>()
.in(ErpCustomerDO::getNumber, insertedNumbers)
);
Map<String, Long> 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<ErpCustomerDO> toUpdate;
private final List<ErpCustomerDO> toInsert;
private final String key;
private final List<String> allnumbers;
public ProcessingResult(List<ErpCustomerDO> toUpdate, List<ErpCustomerDO> toInsert, String key, List<String> allnumbers) {
public ProcessingResult(List<ErpCustomerDO> toUpdate, List<ErpCustomerDO> toInsert, String key) {
this.toUpdate = toUpdate;
this.toInsert = toInsert;
this.key = key;
this.allnumbers = allnumbers;
}
}
@Override
public void initialize() {
List<String> existingNumbers = erpCustomerMapper.selectList(new LambdaQueryWrapperX<ErpCustomerDO>())
private void initializeMap(String key) {
Map<String, Long> existingNumbers = erpCustomerMapper.selectList(new LambdaQueryWrapperX<ErpCustomerDO>())
.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);
}
}

View File

@@ -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<String, Object> req = new HashMap<>();
JSONArray dataArrayALL = new JSONArray();
List<String> redisCache = erpConfig.getRedisCache(OftenEnum.FuncnrEnum.公司代码.getFuncnr());
String companykey = "erp" + OftenEnum.FuncnrEnum.公司代码.getFuncnr();
Map<String,Long> 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<String,List<String>> numbers = erpConfig.numbers(dataArray, key,funcnr.getDatakey());
List<String> allnumbers = numbers.get("all");
List<String> comnumbers = numbers.get("com");
String key = "erpMap" + funcnr.getFuncnr();
Map<String, Long> numbers = erpConfig.getRedisCacheMap(key);
List<ErpFactoryDO> toUpdate = new ArrayList<>();
List<ErpFactoryDO> toInsert = new ArrayList<>();
List<String> 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<String> 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<String> insertedNumbers = result.toInsert.stream()
.map(ErpFactoryDO::getNumber)
.collect(Collectors.toList());
List<ErpFactoryDO> insertedRecords = erpFactoryMapper.selectList(
new LambdaQueryWrapperX<ErpFactoryDO>()
.in(ErpFactoryDO::getNumber, insertedNumbers)
);
Map<String, Long> 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<ErpFactoryDO>().in(ErpFactoryDO::getNumber, result.deleteNumbers));
erpConfig.deleteRedisCacheMap(result.key, result.deleteNumbers);
}
}
/**
@@ -196,13 +228,20 @@ public class ErpFactoryServiceImpl implements ErpFactoryService {
private final List<ErpFactoryDO> toUpdate;
private final List<ErpFactoryDO> toInsert;
private final String key;
private final List<String> allnumbers;
private final List<String> deleteNumbers;
public ProcessingResult(List<ErpFactoryDO> toUpdate, List<ErpFactoryDO> toInsert,String key,List<String> allnumbers) {
public ProcessingResult(List<ErpFactoryDO> toUpdate, List<ErpFactoryDO> toInsert,String key,List<String> deleteNumbers) {
this.toUpdate = toUpdate;
this.toInsert = toInsert;
this.key = key;
this.allnumbers = allnumbers;
this.deleteNumbers = deleteNumbers;
}
}
private void initializeMap(String key) {
Map<String, Long> existingNumbers = erpFactoryMapper.selectList(new LambdaQueryWrapperX<ErpFactoryDO>())
.stream()
.collect(Collectors.toMap(ErpFactoryDO::getNumber, ErpFactoryDO::getId));
erpConfig.addRedisCacheMap(key, existingNumbers);
}
}

View File

@@ -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;
@@ -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<String, Object> req = new HashMap<>();
JSONArray dataArrayALL = new JSONArray();
List<String> redisCache = erpConfig.getRedisCache(OftenEnum.FuncnrEnum.公司代码.getFuncnr());
String companyCode = "erpMap" + OftenEnum.FuncnrEnum.公司代码.getFuncnr();
Map<String,Long> 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<String,List<String>> numbers = erpConfig.numbers(dataArray, key,funcnr.getDatakey());
List<String> allnumbers = numbers.get("all");
List<String> comnumbers = numbers.get("com");
String key = "erpMap" + funcnr.getFuncnr();
Map<String, Long> numbers = erpConfig.getRedisCacheMap(key);
List<ErpInternalOrderDO> toUpdate = new ArrayList<>();
List<ErpInternalOrderDO> toInsert = new ArrayList<>();
List<String> 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<String> 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<String> insertedNumbers = result.toInsert.stream()
.map(ErpInternalOrderDO::getNumber)
.collect(Collectors.toList());
List<ErpInternalOrderDO> insertedRecords = erpInternalOrderMapper.selectList(
new LambdaQueryWrapperX<ErpInternalOrderDO>()
.in(ErpInternalOrderDO::getNumber, insertedNumbers)
);
Map<String, Long> 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<ErpInternalOrderDO>().in(ErpInternalOrderDO::getNumber, result.deleteNumbers));
erpConfig.deleteRedisCacheMap(result.key, result.deleteNumbers);
}
}
/**
@@ -191,13 +224,20 @@ public class ErpInternalOrderServiceImpl implements ErpInternalOrderService {
private final List<ErpInternalOrderDO> toUpdate;
private final List<ErpInternalOrderDO> toInsert;
private final String key;
private final List<String> allnumbers;
private final List<String> deleteNumbers;
public ProcessingResult(List<ErpInternalOrderDO> toUpdate, List<ErpInternalOrderDO> toInsert,String key,List<String> allnumbers) {
public ProcessingResult(List<ErpInternalOrderDO> toUpdate, List<ErpInternalOrderDO> toInsert, String key, List<String> deleteNumbers) {
this.toUpdate = toUpdate;
this.toInsert = toInsert;
this.key = key;
this.allnumbers = allnumbers;
this.deleteNumbers = deleteNumbers;
}
}
private void initializeMap(String key) {
Map<String, Long> existingNumbers = erpInternalOrderMapper.selectList(new LambdaQueryWrapperX<ErpInternalOrderDO>())
.stream()
.collect(Collectors.toMap(ErpInternalOrderDO::getNumber, ErpInternalOrderDO::getId));
erpConfig.addRedisCacheMap(key, existingNumbers);
}
}

View File

@@ -62,6 +62,4 @@ public interface ErpMaterialService {
PageResult<ErpMaterialDO> getErpMaterialPage(ErpMaterialPageReqVO pageReqVO);
void callErpRfcInterface();
void initialize();
}

View File

@@ -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<String, Object> req = new HashMap<>();
List<Map<String, String>> datumList = new ArrayList<>();
Map<String, String> datumEntry = new HashMap<>();
datumEntry.put("sign", "I");
datumEntry.put("option", "EQ");
datumEntry.put("low", "2021-05-16");
// datumEntry.put("low", LocalDate.now().toString());
// 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<String> existingNumbers = erpMaterialMapper.selectList(new LambdaQueryWrapperX<ErpMaterialDO>())
.stream()
.map(ErpMaterialDO::getDownCenterNumber)
.collect(Collectors.toList());
String key = "erp" + OftenEnum.FuncnrEnum.物料数据.getFuncnr();
erpConfig.updateRedisCache(key, existingNumbers);
}
}

View File

@@ -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<String, Object> req = new HashMap<>();
JSONArray dataArrayALL = new JSONArray();
List<String> redisCache = erpConfig.getRedisCache(OftenEnum.FuncnrEnum.工厂信息.getFuncnr());
String factKey ="erpMap"+ OftenEnum.FuncnrEnum.工厂信息.getFuncnr();
Map<String,Long> 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<String,List<String>> numbers = erpConfig.numbers(dataArray, key,funcnr.getDatakey());
List<String> allnumbers = numbers.get("all");
List<String> comnumbers = numbers.get("com");
String key = "erpMap" + funcnr.getFuncnr();
Map<String, Long> numbers = erpConfig.getRedisCacheMap(key);
List<ErpProductiveVersionDO> toUpdate = new ArrayList<>();
List<ErpProductiveVersionDO> toInsert = new ArrayList<>();
List<String> 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<String, Long> 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<ErpProductiveVersionDO> insertedRecords = erpProductiveVersionMapper.selectList(
new LambdaQueryWrapperX<ErpProductiveVersionDO>()
.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<String, Long> 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<Long> 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<ErpProductiveVersionDO> toUpdate;
private final List<ErpProductiveVersionDO> toInsert;
private final String key;
private final List<String> allnumbers;
private final Map<String, Long> deleteNumbers;
public ProcessingResult(List<ErpProductiveVersionDO> toUpdate, List<ErpProductiveVersionDO> toInsert,String key,List<String> allnumbers) {
public ProcessingResult(List<ErpProductiveVersionDO> toUpdate, List<ErpProductiveVersionDO> toInsert,String key,Map<String, Long> deleteNumbers) {
this.toUpdate = toUpdate;
this.toInsert = toInsert;
this.key = key;
this.allnumbers = allnumbers;
this.deleteNumbers = deleteNumbers;
}
}
private void initializeMap(String key) {
List<ErpProductiveVersionDO> assets = erpProductiveVersionMapper.selectList(new LambdaQueryWrapperX<ErpProductiveVersionDO>());
Map<String, Long> existingNumbers = new HashMap<>();
for (ErpProductiveVersionDO asset : assets) {
String mapKey = asset.getFactoryNumber() + "-" + asset.getMaterialNumber() + "-" + asset.getProductiveVersionNumber();
existingNumbers.put(mapKey, asset.getId());
}
erpConfig.addRedisCacheMap(key, existingNumbers);
}
}

View File

@@ -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<String, Object> req = new HashMap<>();
JSONArray dataArrayALL = new JSONArray();
List<String> redisCache = erpConfig.getRedisCache(OftenEnum.FuncnrEnum.工厂信息.getFuncnr());
// String factKey ="erpMap"+ OftenEnum.FuncnrEnum.工厂信息.getFuncnr();
String factKey ="erpMap"+ OftenEnum.FuncnrEnum.公司代码.getFuncnr();
Map<String,Long> 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<String,List<String>> numbers = erpConfig.numbers(dataArray, key,funcnr.getDatakey());
List<String> allnumbers = numbers.get("all");
List<String> comnumbers = numbers.get("com");
String key = "erpMap" + funcnr.getFuncnr();
Map<String, Long> numbers = erpConfig.getRedisCacheMap(key);
List<ErpPurchaseOrganizationDO> toUpdate = new ArrayList<>();
List<ErpPurchaseOrganizationDO> toInsert = new ArrayList<>();
List<String> 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<String> 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<String> insertedNumbers = result.toInsert.stream()
.map(ErpPurchaseOrganizationDO::getNumber)
.collect(Collectors.toList());
List<ErpPurchaseOrganizationDO> insertedRecords = erpPurchaseOrganizationMapper.selectList(
new LambdaQueryWrapperX<ErpPurchaseOrganizationDO>()
.in(ErpPurchaseOrganizationDO::getNumber, insertedNumbers)
);
Map<String, Long> 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<ErpPurchaseOrganizationDO>().in(ErpPurchaseOrganizationDO::getNumber, result.deleteNumbers));
erpConfig.deleteRedisCacheMap(result.key, result.deleteNumbers);
}
}
/**
@@ -188,13 +231,20 @@ public class ErpPurchaseOrganizationServiceImpl implements ErpPurchaseOrganizati
private final List<ErpPurchaseOrganizationDO> toUpdate;
private final List<ErpPurchaseOrganizationDO> toInsert;
private final String key;
private final List<String> allnumbers;
private final List<String> deleteNumbers;
public ProcessingResult(List<ErpPurchaseOrganizationDO> toUpdate, List<ErpPurchaseOrganizationDO> toInsert,String key,List<String> allnumbers) {
public ProcessingResult(List<ErpPurchaseOrganizationDO> toUpdate, List<ErpPurchaseOrganizationDO> toInsert,String key,List<String> deleteNumbers) {
this.toUpdate = toUpdate;
this.toInsert = toInsert;
this.key = key;
this.allnumbers = allnumbers;
this.deleteNumbers = deleteNumbers;
}
}
private void initializeMap(String key) {
Map<String, Long> existingNumbers = erpPurchaseOrganizationMapper.selectList(new LambdaQueryWrapperX<ErpPurchaseOrganizationDO>())
.stream()
.collect(Collectors.toMap(ErpPurchaseOrganizationDO::getNumber, ErpPurchaseOrganizationDO::getId));
erpConfig.addRedisCacheMap(key, existingNumbers);
}
}

View File

@@ -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<String, Object> req = new HashMap<>();
JSONArray dataArrayALL = new JSONArray();
List<String> redisCache = erpConfig.getRedisCache(OftenEnum.FuncnrEnum.公司代码.getFuncnr());
String factKey ="erpMap"+ OftenEnum.FuncnrEnum.公司代码.getFuncnr();
Map<String,Long> 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<String,List<String>> numbers = erpConfig.numbers(dataArray, key,funcnr.getDatakey());
List<String> allnumbers = numbers.get("all");
List<String> comnumbers = numbers.get("com");
String key = "erpMap" + funcnr.getFuncnr();
Map<String, Long> numbers = erpConfig.getRedisCacheMap(key);
List<ErpSalesOrganizationDO> toUpdate = new ArrayList<>();
List<ErpSalesOrganizationDO> toInsert = new ArrayList<>();
List<String> 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<String> 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<String> insertedNumbers = result.toInsert.stream()
.map(ErpSalesOrganizationDO::getNumber)
.collect(Collectors.toList());
List<ErpSalesOrganizationDO> insertedRecords = erpSalesOrganizationMapper.selectList(
new LambdaQueryWrapperX<ErpSalesOrganizationDO>()
.in(ErpSalesOrganizationDO::getNumber, insertedNumbers)
);
Map<String, Long> 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<ErpSalesOrganizationDO>().in(ErpSalesOrganizationDO::getNumber, result.deleteNumbers));
erpConfig.deleteRedisCacheMap(result.key, result.deleteNumbers);
}
}
/**
@@ -196,13 +228,20 @@ public class ErpSalesOrganizationServiceImpl implements ErpSalesOrganizationServ
private final List<ErpSalesOrganizationDO> toUpdate;
private final List<ErpSalesOrganizationDO> toInsert;
private final String key;
private final List<String> allnumbers;
private final List<String> deleteNumbers;
public ProcessingResult(List<ErpSalesOrganizationDO> toUpdate, List<ErpSalesOrganizationDO> toInsert,String key,List<String> allnumbers) {
public ProcessingResult(List<ErpSalesOrganizationDO> toUpdate, List<ErpSalesOrganizationDO> toInsert,String key,List<String> deleteNumbers) {
this.toUpdate = toUpdate;
this.toInsert = toInsert;
this.key = key;
this.allnumbers = allnumbers;
this.deleteNumbers = deleteNumbers;
}
}
private void initializeMap(String key) {
Map<String, Long> existingNumbers = erpSalesOrganizationMapper.selectList(new LambdaQueryWrapperX<ErpSalesOrganizationDO>())
.stream()
.collect(Collectors.toMap(ErpSalesOrganizationDO::getNumber, ErpSalesOrganizationDO::getId));
erpConfig.addRedisCacheMap(key, existingNumbers);
}
}

View File

@@ -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;
@@ -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<String, Object> req = new HashMap<>();
JSONArray dataArrayALL = new JSONArray();
List<String> redisCache = erpConfig.getRedisCache(OftenEnum.FuncnrEnum.工厂信息.getFuncnr());
String factKey = "erpMap" + OftenEnum.FuncnrEnum.工厂信息.getFuncnr();
Map<String, Long> 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<String,List<String>> numbers = erpConfig.numbers(dataArray, key,funcnr.getDatakey());
List<String> allnumbers = numbers.get("all");
List<String> comnumbers = numbers.get("com");
String key = "erpMap" + funcnr.getFuncnr();
Map<String, Long> numbers = erpConfig.getRedisCacheMap(key);
List<ErpWarehouseDO> toUpdate = new ArrayList<>();
List<ErpWarehouseDO> toInsert = new ArrayList<>();
List<String> 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<String, Long> 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<ErpWarehouseDO> insertedRecords = erpWarehouseMapper.selectList(
new LambdaQueryWrapperX<ErpWarehouseDO>()
.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<String, Long> 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<Long> 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<ErpWarehouseDO> toUpdate;
private final List<ErpWarehouseDO> toInsert;
private final String key;
private final List<String> allnumbers;
private final Map<String, Long> deleteNumbers;
public ProcessingResult(List<ErpWarehouseDO> toUpdate, List<ErpWarehouseDO> toInsert,String key,List<String> allnumbers) {
public ProcessingResult(List<ErpWarehouseDO> toUpdate, List<ErpWarehouseDO> toInsert, String key, Map<String, Long> deleteNumbers) {
this.toUpdate = toUpdate;
this.toInsert = toInsert;
this.key = key;
this.allnumbers = allnumbers;
this.deleteNumbers = deleteNumbers;
}
}
private void initializeMap(String key) {
List<ErpWarehouseDO> assets = erpWarehouseMapper.selectList(new LambdaQueryWrapperX<ErpWarehouseDO>());
Map<String, Long> existingNumbers = new HashMap<>();
for (ErpWarehouseDO asset : assets) {
String mapKey = asset.getFactoryNumber() + "-" + asset.getNumber();
existingNumbers.put(mapKey, asset.getId());
}
erpConfig.addRedisCacheMap(key, existingNumbers);
}
}

View File

@@ -9,14 +9,61 @@
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
<update id="updateBatch">
<foreach collection="toUpdate" item="item" separator=";">
UPDATE sply_erp_fact
<set>
<if test="item.name != null">NAME = #{item.name},</if>
<if test="item.number != null">CPN_ID = #{item.companyId},</if>
</set>
WHERE NUM = #{item.number}
<update id="updateBatchByNumber">
UPDATE sply_erp_cctr
SET
NAME = CASE NUM
<foreach collection="list" item="item">
<if test="item.name != null and item.name != ''">
WHEN #{item.number} THEN #{item.name}
</if>
</foreach>
ELSE NAME
END,
IS_USE = CASE NUM
<foreach collection="list" item="item">
<if test="item.isUse != null and item.isUse != ''">
WHEN #{item.number} THEN #{item.isUse}
</if>
</foreach>
ELSE IS_USE
END,
SCO_NUM = CASE NUM
<foreach collection="list" item="item">
<if test="item.scopeNumber != null and item.scopeNumber != ''">
WHEN #{item.number} THEN #{item.scopeNumber}
</if>
</foreach>
ELSE SCO_NUM
END,
STRT_DT = CASE NUM
<foreach collection="list" item="item">
<if test="item.startDate != null">
WHEN #{item.number} THEN #{item.startDate}
</if>
</foreach>
ELSE STRT_DT
END,
END_DT = CASE NUM
<foreach collection="list" item="item">
<if test="item.endDate != null">
WHEN #{item.number} THEN #{item.endDate}
</if>
</foreach>
ELSE END_DT
END,
SCO_NAME = CASE NUM
<foreach collection="list" item="item">
<if test="item.scopeName != null and item.scopeName != ''">
WHEN #{item.number} THEN #{item.scopeName}
</if>
</foreach>
ELSE SCO_NAME
END
WHERE NUM IN
<foreach collection="list" item="item" open="(" separator="," close=")">
#{item.number}
</foreach>
</update>
</mapper>

View File

@@ -9,14 +9,28 @@
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
<update id="updateBatch">
<foreach collection="toUpdate" item="item" separator=";">
UPDATE sply_erp_fact
<update id="updateBatchByNumber">
<foreach collection="toUpdate" item="item" separator=";" open="BEGIN" close=";END;">
UPDATE SPLY_ERP_MTRL
<set>
<if test="item.name != null">NAME = #{item.name},</if>
<if test="item.number != null">CPN_ID = #{item.companyId},</if>
<if test="item.downCtrNum != null">DOWN_CTR_NUM = #{item.downCtrNum},</if>
<if test="item.ctrNum != null">CTR_NUM = #{item.ctrNum},</if>
<if test="item.crtDt != null">CRT_DT = #{item.crtDt},</if>
<if test="item.mtrlTp != null">MTRL_TP = #{item.mtrlTp},</if>
<if test="item.mtrlGrpDt != null">MTRL_GRP_DT = #{item.mtrlGrpDt},</if>
<if test="item.extMtrlGrpDt != null">EXT_MTRL_GRP_DT = #{item.extMtrlGrpDt},</if>
<if test="item.unt != null">UNT = #{item.unt},</if>
<if test="item.untDsp != null">UNT_DSP = #{item.untDsp},</if>
<if test="item.mtrlTpDsp != null">MTRL_TP_DSP = #{item.mtrlTpDsp},</if>
<if test="item.mtrlGrpDsp != null">MTRL_GRP_DSP = #{item.mtrlGrpDsp},</if>
<if test="item.extMtrlGrpDsp != null">EXT_MTRL_GRP_DSP = #{item.extMtrlGrpDsp},</if>
<if test="item.mtrlName != null">MTRL_NAME = #{item.mtrlName},</if>
<if test="item.mtrlLenDsp != null">MTRL_LEN_DSP = #{item.mtrlLenDsp},</if>
<if test="item.tenantId != null">TENANT_ID = #{item.tenantId},</if>
</set>
WHERE NUM = #{item.number}
WHERE DOWN_CTR_NUM = #{item.number}
</foreach>
</update>
</update>
</mapper>