/*
|
* Copyright (c) 2018-2025, ztt All rights reserved.
|
*
|
* Redistribution and use in source and binary forms, with or without
|
* modification, are permitted provided that the following conditions are met:
|
*
|
* Redistributions of source code must retain the above copyright notice,
|
* this list of conditions and the following disclaimer.
|
* Redistributions in binary form must reproduce the above copyright
|
* notice, this list of conditions and the following disclaimer in the
|
* documentation and/or other materials provided with the distribution.
|
* Neither the name of the pig4cloud.com developer nor the names of its
|
* contributors may be used to endorse or promote products derived from
|
* this software without specific prior written permission.
|
* Author: ztt
|
*/
|
package com.chinaztt.mes.basic.service.impl;
|
|
import cn.hutool.core.collection.CollectionUtil;
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.chinaztt.ifs.api.feign.IfsFeignClient;
|
import com.chinaztt.mes.basic.entity.Part;
|
import com.chinaztt.mes.basic.excel.PartData;
|
import com.chinaztt.mes.basic.mapper.PartMapper;
|
import com.chinaztt.mes.basic.service.PartService;
|
import com.chinaztt.mes.basic.util.DictUtils;
|
import com.chinaztt.mes.basic.util.PartUtils;
|
import com.chinaztt.mes.basic.util.RedisUtils;
|
import com.chinaztt.ztt.common.core.util.R;
|
import com.google.gson.Gson;
|
import lombok.AllArgsConstructor;
|
import org.apache.http.HttpEntity;
|
import org.apache.http.client.config.RequestConfig;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.entity.ContentType;
|
import org.apache.http.entity.StringEntity;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.HttpClientBuilder;
|
import org.apache.http.params.CoreConnectionPNames;
|
import org.apache.http.util.EntityUtils;
|
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
import org.springframework.core.env.Environment;
|
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.util.StringUtils;
|
|
import java.io.IOException;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
/**
|
* 零件
|
*
|
* @author fenglang
|
* @date 2020-08-17 14:37:35
|
*/
|
@AllArgsConstructor
|
@Service
|
public class PartServiceImpl extends ServiceImpl<PartMapper, Part> implements PartService {
|
private DictUtils dictUtils;
|
private PartUtils partUtils;
|
private IfsFeignClient ifsFeignClient;
|
private DiscoveryClient discoveryClient;
|
private Environment environment;
|
private RedisTemplate redisTemplate;;
|
|
@Override
|
public void importPartExcel(List<PartData> list) {
|
if (CollectionUtil.isEmpty(list)) {
|
return;
|
}
|
List<String> partCodes = getBaseMapper().getPartConcatEcl();
|
Map<String, String> dicmattype = dictUtils.getDicKey("material_type");
|
Map<String, String> dicplanMethod = dictUtils.getDicKey("planning_method_type");
|
for (PartData data : list) {
|
if (StringUtils.isEmpty(data.getEngChgLevel())) {
|
data.setEngChgLevel("1");
|
}
|
if (partCodes.contains(data.getPartNo() + "_" + data.getEngChgLevel())) {
|
throw new RuntimeException("重复零件号:" + data.getPartNo() + "版本号:" + data.getEngChgLevel());
|
}
|
Part part = new Part();
|
part.setPartName(data.getPartName());
|
part.setPartNo(data.getPartNo());
|
part.setSpecs(data.getSpec());
|
part.setCharacteristic1(data.getCharacteristic1());
|
part.setCharacteristic2(data.getCharacteristic2());
|
part.setCharacteristic3(data.getCharacteristic3());
|
part.setPartModel(data.getPartModel());
|
part.setVoltageLevel(data.getVoltageLevel());
|
part.setUnit(data.getUnit());
|
// 默认是4
|
part.setMaterialType(StringUtils.isEmpty(data.getMaterialType()) ? "4" :
|
(StringUtils.isEmpty(dicmattype.get(data.getMaterialType())) ? "4" : dicmattype.get(data.getMaterialType())));
|
part.setAssortment(data.getAssortment());
|
part.setCategory(data.getCategory());
|
part.setThreeLevelClassification(data.getThreeLevelClassification());
|
// 默认是 A
|
part.setPlanningMethod(StringUtils.isEmpty(data.getPlanningMethod()) ? "A" :
|
(StringUtils.isEmpty(dicplanMethod.get(data.getPlanningMethod())) ? "A" : dicplanMethod.get(data.getPlanningMethod())));
|
part.setEngChgLevel(data.getEngChgLevel());
|
// 默认是 不启用批次管理
|
part.setLotTrackingIfs(data.getLotTrackingIfs() == null ? false : data.getLotTrackingIfs());
|
part.setDescription(data.getDescription());
|
partCodes.add(data.getPartNo() + "_" + part.getEngChgLevel());
|
baseMapper.insert(part);
|
}
|
}
|
|
@Override
|
public IPage<Part> getPartPage(Page page, QueryWrapper<Part> ew, Long bomId) {
|
return baseMapper.getPartPage(page, ew, bomId);
|
}
|
|
@Override
|
public List<Part> query(String keyword) {
|
if (StringUtils.isEmpty(keyword)) {
|
return null;
|
}
|
return baseMapper.query(keyword);
|
}
|
|
|
@Override
|
public IPage<List<Part>> getQualityPartPage(Page page, QueryWrapper<Part> ew) {
|
return baseMapper.getQualityPartPage(page, ew);
|
}
|
|
@Override
|
public IPage<List<Part>> getNotInQualityPartPage(Page page, QueryWrapper<Part> ew) {
|
return baseMapper.getNotInQualityPartPage(page, ew);
|
}
|
|
@Override
|
public IPage<List<Part>> getReportPartsPage(Page page, QueryWrapper<Part> ew) {
|
return baseMapper.getReportPartsPage(page, ew);
|
}
|
|
@Override
|
public R getPart(Part part) {
|
return R.ok(partUtils.getErpPart(part));
|
}
|
|
|
@Override
|
public R ifsSync(List<Long> ids) {
|
return ifsSyncById(ids);
|
}
|
|
|
private R ifsSyncById(List<Long> ids) {
|
JSONArray batchInfo = new JSONArray();
|
for (Long id : ids) {
|
Part part = baseMapper.selectById(id);
|
if (null == part) {
|
return R.failed("id为" + id + "的零件不存在");
|
} else {
|
batchInfo.add(ifsDataMake(part));
|
}
|
}
|
//这句话是判断ztt-ifs服务是否在线的日后有用
|
// List<ServiceInstance> instances = discoveryClient.getInstances("ztt-ifs");
|
return ifsFeignClient.importInventPartStd(new JSONObject().fluentPut("BATCH_INFO", batchInfo), true);
|
}
|
|
/**
|
* ifs 数据拼接
|
*
|
* @param part
|
* @return
|
*/
|
private JSONObject ifsDataMake(Part part) {
|
|
JSONObject p = new JSONObject();
|
//零件编号
|
p.put("PART_NO", part.getPartNo());
|
//零件描述
|
p.put("PART_DESC", part.getPartName());
|
//单位
|
p.put("UNIT_MEAS", part.getUnit());
|
//多层跟踪
|
p.put("MULTILEVEL_TRACKING_DB", "TRACKING_OFF");
|
//批次管理
|
p.put("LOT_TRACK_CODE", (part.getLotTrackingIfs() == null || !part.getLotTrackingIfs()) ? "NOT LOT TRACKING" : "LOT TRACKING");
|
//批次数量规则 NOT LOT TRACKING 对应 ONE_LOT ,LOT TRACKING 对应 MULTI_LOTS
|
p.put("LOT_QTY_RULE", (part.getLotTrackingIfs() == null || !part.getLotTrackingIfs()) ? "ONE_LOT" : "MULTI_LOTS");
|
//版本号
|
p.put("ENG_CHG_LEVEL", StringUtils.isEmpty(part.getEngChgLevel()) ? "1" : part.getEngChgLevel());
|
//零件类型
|
p.put("TYPE_CODE", part.getMaterialType());
|
//计划方法
|
p.put("PLANNING_METHOD", StringUtils.isEmpty(part.getPlanningMethod()) ? "A" : part.getPlanningMethod());
|
|
p.put("EFF_PHASE_IN_DATE", "2000-01-01");
|
|
return p;
|
}
|
|
|
/**
|
* 从主数据平台同步零件数据
|
*
|
* @param jsonObject
|
* @return
|
*/
|
@Override
|
public R parySync(JSONObject jsonObject) {
|
try {
|
String version = jsonObject.get("version") == null ? "1" : jsonObject.getString("version");
|
String partNo = jsonObject.getString("material_number");
|
//判断是否存在
|
Part part = getBaseMapper().selectOne(Wrappers.<Part>lambdaQuery().eq(Part::getPartNo, partNo).eq(Part::getEngChgLevel, version));
|
if (part == null) {
|
part = new Part();
|
}
|
//零件版本
|
part.setEngChgLevel(version);
|
//零件号
|
part.setPartNo(partNo);
|
String spec = jsonObject.get("material_spec") == null ? "" : jsonObject.getString("material_spec");
|
String name = jsonObject.get("material_name") == null ? "" : jsonObject.getString("material_name");
|
//规格型号
|
part.setSpecs(jsonObject.getString("material_spec"));
|
//主数据平台零件名称 + 空格 + 主数据平台规格 = 零件名称
|
part.setPartName((name + " " + spec).trim());
|
//物料描述
|
part.setDescription(spec);
|
//单位
|
part.setUnit(jsonObject.getString("unit"));
|
//一级分类
|
part.setAssortment(jsonObject.getString("firstCategoryName"));
|
//二级分类
|
part.setCategory(jsonObject.getString("secondCategoryName"));
|
//三级分类
|
part.setThreeLevelClassification(jsonObject.getString("thirdCategoryName"));
|
//自定义字段数据的插入
|
JSONArray jsonObjectProperty = jsonObject.getJSONArray("propertiesInfo");
|
if (CollectionUtil.isNotEmpty(jsonObjectProperty)) {
|
List<JSONObject> jsonObjectList = jsonObjectProperty.toJavaList(JSONObject.class);
|
Map<String, String> map = new HashMap<>();
|
jsonObjectList.forEach(e -> {
|
if (null != e.get("attribute") && null != e.get("attribute_value")) {
|
map.put(e.getString("attribute"), e.getString("attribute_value"));
|
}
|
});
|
part.setPartModel(map.get("型号"));
|
part.setCharacteristic1(map.get("特性1"));
|
part.setCharacteristic2(map.get("特性2"));
|
part.setCharacteristic3(map.get("特性3"));
|
part.setVoltageLevel(map.get("电压等级"));
|
}
|
if (part.getId() == null) {
|
//插入的时候默认插入批次管理为 false 计划方法为A 零件类型为 “3”
|
part.setLotTrackingIfs(false);
|
part.setPlanningMethod("A");
|
part.setMaterialType("3");
|
baseMapper.insert(part);
|
} else {
|
baseMapper.updateById(part);
|
}
|
//这边需要说明提下 因为 主数据平台的成功编码和本系统的成功编码是反的 所以 成功调用的是 R.falid 失败是 R.ok
|
return R.failed("推送成功");
|
} catch (Exception e) {
|
//这边需要说明提下 因为 主数据平台的成功编码和本系统的成功编码是反的 所以 成功调用的是 R.falid 失败是 R.ok
|
return R.ok().setMsg(e.getMessage());
|
}
|
}
|
|
@Override
|
public boolean doSave(Part part) {
|
Part partByFind = baseMapper.selectOne(Wrappers.<Part>lambdaQuery()
|
.eq(Part::getPartNo, part.getPartNo())
|
.eq(Part::getEngChgLevel, part.getEngChgLevel()));
|
if (partByFind != null) {
|
throw new RuntimeException("零件号版本号重复:" + partByFind.getPartName() + "-" + partByFind.getPartNo());
|
}
|
baseMapper.insert(part);
|
//对接IFS
|
// R result = ifsFeignClient.importInventPartStd(new JSONObject().fluentPut("BATCH_INFO", new JSONArray().fluentAdd(ifsDataMake(part))), true);
|
// if (result.getCode() == 1) {
|
// throw new RuntimeException("IFS错误——" + result.getMsg());
|
// }
|
return true;
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public boolean doUpdate(Part part) {
|
Part partByFind = baseMapper.selectOne(Wrappers.<Part>lambdaQuery()
|
.eq(Part::getPartNo, part.getPartNo())
|
.eq(Part::getEngChgLevel, part.getEngChgLevel())
|
.ne(Part::getId, part.getId()));
|
if (partByFind != null) {
|
throw new RuntimeException("零件号版本号重复:" + partByFind.getPartName() + "-" + partByFind.getPartNo());
|
}
|
//对接IFS
|
// R result = ifsFeignClient.importInventPartStd(new JSONObject().fluentPut("BATCH_INFO", new JSONArray().fluentAdd(ifsDataMake(part))), true);
|
// if (result.getCode() == 1) {
|
// throw new RuntimeException("IFS错误——" + result.getMsg());
|
// }
|
baseMapper.updateById(part);
|
return true;
|
}
|
|
@Override
|
public IPage<Part> getRoutingPartPage(Page page, QueryWrapper<Part> ew, Long bomId) {
|
Integer componentNum = this.baseMapper.countComponentNum(bomId);
|
if (componentNum > 1) {
|
return this.baseMapper.getPartPage(page, ew, bomId);
|
} else {
|
return this.baseMapper.getPartPageIncludeOwn(page, ew, bomId);
|
}
|
}
|
|
@Override
|
@Async
|
public void syncPart() {
|
String key = "syncPart_lock";
|
if (redisTemplate.hasKey(key)) {
|
throw new RuntimeException("有同步任务正在处理");
|
}
|
redisTemplate.opsForValue().set(key,1,1000 * 3600);
|
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
|
String syncErpUrl = environment.getProperty("erpPartUrl");
|
HttpPost httpPost = new HttpPost(syncErpUrl);
|
httpPost.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10000);
|
httpPost.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,1000 * 3600);
|
// 将参数转换为JSON字符串
|
Map<String, String> params = new HashMap<>();
|
// params.put("startTime", customOrderSyncDTO.getStartTime());
|
// params.put("endTime", customOrderSyncDTO.getEndTime());
|
String jsonParams = new Gson().toJson(params);
|
// 设置请求体为JSON格式
|
StringEntity requestEntity = new StringEntity(jsonParams, ContentType.APPLICATION_JSON);
|
httpPost.setEntity(requestEntity);
|
String responseString = null;
|
try {
|
CloseableHttpResponse response = httpClient.execute(httpPost);
|
HttpEntity entity = response.getEntity();
|
responseString = EntityUtils.toString(entity, "UTF-8");
|
// log.info(responseString);
|
response.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
throw new RuntimeException(e.getMessage());
|
} finally {
|
redisTemplate.delete(key);
|
try {
|
httpClient.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
|
}
|