电器物料管理

物料禁用等等
0125
This commit is contained in:
tzy 2025-02-11 15:46:12 +08:00
parent f936d78407
commit 8684667167
61 changed files with 5423 additions and 387 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +0,0 @@
package com.ruoyi.web.controller.controller;
public class CuttingController {
public String solveCuttingStock() {
String filePath = "D:\\文件\\同规格无拼接线材下料\\test_glpk\\data\\problem.txt";
return filePath;
}
}

View File

@ -1,19 +0,0 @@
package com.ruoyi.web.controller.controller;
import com.ruoyi.web.controller.service.CuttingStockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CuttingStockController {
@Autowired
private CuttingStockService cuttingStockService;
@GetMapping("/solve")
public String solveCuttingStock() {
cuttingStockService.solveCuttingStockProblem();
return "切割库存问题已解决!";
}
}

View File

@ -1,26 +0,0 @@
package com.ruoyi.web.controller.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class JimuController {
@Autowired
Environment environment;
@GetMapping("/index")
@PreAuthorize("@ss.hasPermi('report:jimu:index')")
public String index(){
// String hostIp = IpUtils.getHostIp();
return environment.getProperty("ruoyi.reporturl")+"/jmreport/list";
}
@GetMapping("/view")
@PreAuthorize("@ss.hasPermi('report:jimu:view')")
public String view(){
return environment.getProperty("ruoyi.reporturl")+"/jmreport/view";
}
}

View File

@ -72,7 +72,7 @@ spring:
# 国际化资源文件路径
basename: i18n/messages
profiles:
active: @profiles.active@
active: '@profiles.active@'
# 文件上传
servlet:
multipart:

View File

@ -0,0 +1,87 @@
package com.ruoyi.test;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExcelSummaryTest {
@Test
public void testSummarizeExcelData() {
String inputDirectoryPath = "E:\\共享"; // 输入文件夹路径
String outputFilePath = "E:\\共享\\汇总.xlsx"; // 输出文件路径
File inputDirectory = new File(inputDirectoryPath);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date thresholdDate;
try {
thresholdDate = sdf.parse("2025-01-01 00:00:00");
} catch (ParseException e) {
throw new RuntimeException("日期格式错误", e);
}
// 创建新的工作簿用于汇总
Workbook newWorkbook = new XSSFWorkbook();
Sheet newSheet = newWorkbook.createSheet("汇总");
// 遍历文件夹中的所有文件
File[] files = inputDirectory.listFiles((dir, name) -> name.toLowerCase().endsWith(".xlsx"));
if (files != null) {
for (File file : files) {
// 检查文件的最后修改时间
if (file.lastModified() > thresholdDate.getTime()) {
try (FileInputStream fis = new FileInputStream(file);
Workbook workbook = new XSSFWorkbook(fis)) {
// 尝试获取 sheet6如果没有则获取 sheet1
Sheet sheet = workbook.getSheet("sheet6");
if (sheet == null) {
sheet = workbook.getSheet("sheet1");
}
if (sheet != null) {
// 遍历选定的 sheet 的数据并汇总
for (Row row : sheet) {
Row newRow = newSheet.createRow(newSheet.getPhysicalNumberOfRows());
for (Cell cell : row) {
Cell newCell = newRow.createCell(cell.getColumnIndex());
switch (cell.getCellType()) {
case STRING:
newCell.setCellValue(cell.getStringCellValue());
break;
case NUMERIC:
newCell.setCellValue(cell.getNumericCellValue());
break;
case BOOLEAN:
newCell.setCellValue(cell.getBooleanCellValue());
break;
default:
newCell.setCellValue(cell.toString());
}
}
}
}
} catch (IOException e) {
throw new RuntimeException("处理 Excel 文件时出错", e);
}
}
}
}
// 写入新的 Excel 文件
try (FileOutputStream fos = new FileOutputStream(outputFilePath)) {
newWorkbook.write(fos);
} catch (IOException e) {
throw new RuntimeException("写入汇总 Excel 文件时出错", e);
}
}
}

View File

@ -0,0 +1,14 @@
package com.ruoyi.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

View File

@ -0,0 +1,170 @@
package com.ruoyi.common.utils;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.model.dto.WorkCenterResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
@Component
public class HttpRequestUtil {
private final RestTemplate restTemplate;
private static final Logger log = LoggerFactory.getLogger(HttpRequestUtil.class);
private static String currentSessionId; // 添加静态的 sessionId
public HttpRequestUtil(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
/**
* post请求
* <p>
* 返回对象处理 responseEntity 注意返回状态码
* 请求成功HttpStatus.OK.equals(responseEntity.getStatusCodeValue())
* <p>
* 1. 接口返回 list 对象
* JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(responseEntity.getBody()));
* List<T> result = JSONObject.parseArray(jsonObject.toString(), T.class);
* <p>
* 2. 接口直接返回单个对象
* JSONObject jsonObject1 = JSONObject.parseObject(JSONObject.toJSONString(responseEntity.getBody()));
* T result = JSONObject.parseObject(jsonObject1.toString(), T.class);
*
* @param url 地址
* @param data 数据
* @return java.lang.Object
* @author liuhao
* @date 2022/3/6 13:38
**/
public ResponseEntity<Object> doPost(String url, Object data) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<JSONObject> httpEntity = new HttpEntity(data, headers);
return restTemplate.postForEntity(url, httpEntity, Object.class);
}
public ResponseEntity<Object> doUploadFile(String url, File file) {
// 1封装请求头
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("multipart/form-data");
headers.setContentType(type);
headers.setContentLength(file.length());
headers.setContentDispositionFormData("media", file.getName());
// 2封装请求体
MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
FileSystemResource resource = new FileSystemResource(file);
param.add("file", resource);
// 3封装整个请求报文
HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(param, headers);
return restTemplate.postForEntity(url, formEntity, Object.class);
}
/**
* 金蝶系统登录
* @return 登录响应
*/
public ResponseEntity<String> kingdeeLogin() {
String url = "http://192.168.5.8/K3cloud/Kingdee.BOS.WebApi.ServicesStub.AuthService.LoginByAppSecret.common.kdsvc";
// 构建登录参数
Map<String, Object> loginParams = new HashMap<>();
loginParams.put("acctID", "670768a85463de"); // 数据中心ID
loginParams.put("Username", "Administrator"); // 用户名
loginParams.put("appId", "288012_Rc0C0zCG2lga0/Vs2Y4pzYSL6hQcWOko"); // 用户名
loginParams.put("appSecret", "8a76cd746fa24636b2c65ef9f313c640");
loginParams.put("lcid", "2052"); // 语言标识
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 创建请求实体
HttpEntity<Map<String, Object>> entity = new HttpEntity<>(loginParams, headers);
// 发送请求并返回响应
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
// 保存 sessionId
if (response.getBody() != null) {
JSONObject loginResult = JSONObject.parseObject(response.getBody());
currentSessionId = loginResult.getString("KDSVCSessionId");
log.info("保存新的会话ID: {}", currentSessionId);
}
return response;
}
/**
* 查询金蝶工段数据
*/
public ResponseEntity<WorkCenterResponse> queryWorkCenterData(String sessionId, String workCenterName) {
// 优先使用已保存的会话ID
String useSessionId = currentSessionId != null ? currentSessionId : sessionId;
String url = "http://192.168.5.8/K3Cloud/Ljint.Kingdee.YiTe.KanBan.WebApi.ProduceWebApi.ExecuteService,Ljint.Kingdee.YiTe.KanBan.WebApi.common.kdsvc";
try {
log.info("发送工段数据查询请求使用会话ID: {}, WorkCenterName: {}", useSessionId, workCenterName);
// 直接构建JSON字符串
String jsonBody = String.format(
"{ \"parameter\": { \"FWorkCenterName\": \"%s\" } }",
workCenterName
);
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("KDSVCSessionId", useSessionId);
// 使用字符串作为请求体
HttpEntity<String> httpEntity = new HttpEntity<>(jsonBody, headers);
log.info("发送工段数据查询请求httpEntity: {}", httpEntity);
log.info("请求体: {}", jsonBody);
// 获取响应
ResponseEntity<String> stringResponse = restTemplate.postForEntity(url, httpEntity, String.class);
String responseBody = stringResponse.getBody();
log.info("工段数据查询原始响应: {}", responseBody);
// 检查是否包含错误信息
if (responseBody != null && responseBody.startsWith("response_error:")) {
String errorMsg = responseBody.substring("response_error:".length()).trim();
log.error("金蝶接口返回错误: {}", errorMsg);
throw new RuntimeException("金蝶接口错误: " + errorMsg);
}
// 尝试解析JSON响应
WorkCenterResponse workCenterResponse = null;
if (responseBody != null) {
try {
workCenterResponse = JSONObject.parseObject(responseBody, WorkCenterResponse.class);
} catch (Exception e) {
log.error("解析工段数据响应失败: {}", responseBody, e);
throw new RuntimeException("解析工段数据响应失败: " + e.getMessage());
}
}
return new ResponseEntity<>(workCenterResponse, stringResponse.getHeaders(), stringResponse.getStatusCode());
} catch (Exception e) {
log.error("工段数据查询失败", e);
throw e;
}
}
}

View File

@ -4,11 +4,13 @@ import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.google.gson.*;
import com.kingdee.bos.webapi.entity.RepoRet;
import com.kingdee.bos.webapi.entity.SuccessEntity;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@ -22,8 +24,6 @@ public class JdUtils {
* @return
*/
public static String HBshenhe(String huiBNum) {
K3CloudApi client = new K3CloudApi();
JsonObject jsonObject = new JsonObject();
JsonArray numbers = new JsonArray();
@ -1553,5 +1553,57 @@ public class JdUtils {
}
return jsonArray;
}
public static ArrayList<SuccessEntity> jinyong(String FNumber) {
K3CloudApi client = new K3CloudApi();
// 创建一个空的JsonObject
JsonObject json = new JsonObject();
json.addProperty("CreateOrgId", 0);
// 创建 Numbers 数组并添加物料编码
JsonArray numbersArray = new JsonArray();
if (FNumber != null && !FNumber.isEmpty()) {
numbersArray.add(FNumber);
}
json.add("Numbers", numbersArray);
json.addProperty("Ids", "");
json.add("PkEntryIds", new JsonArray());
json.addProperty("UseOrgId", 0);
json.addProperty("NetworkCtrl", "");
json.addProperty("IgnoreInterationFlag", "");
String jsonData = json.toString();
try {
// 业务对象标识
String formId = "BD_MATERIAL";
// 操作接口编码
String operateNumber = "Forbid";
// 调用接口
String resultJson = client.excuteOperation(formId, operateNumber, jsonData);
// 用于记录结果
Gson gson = new Gson();
// 对返回结果进行解析和校验
RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
// 检查接口返回的状态
if (repoRet.getResult().getResponseStatus().isIsSuccess()) {
System.out.printf("接口返回结果: %s%n", gson.toJson(repoRet.getResult()));
return repoRet.getResult().getResponseStatus().getSuccessEntitys(); // 返回成功的实体
} else {
// 处理错误信息
String errorMessage = "接口返回结果: " + gson.toJson(repoRet.getResult().getResponseStatus());
log.error(errorMessage);
return null; // 或者根据需要返回一个空的 JSONArray
}
} catch (Exception e) {
log.error("调用接口时发生异常: " + e.getMessage());
return null; // 或者根据需要返回一个空的 JSONArray
}
}
}

View File

@ -0,0 +1,154 @@
package com.ruoyi.common.utils;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.File;
import java.util.*;
@Slf4j
@Component
public class WxRobotUtil {
@Resource
private HttpRequestUtil httpRequestUtil;
/** 企业微信群上传文件url */
public static final String UPLOAD_FILE_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media";
/** 发送群消息url */
public static final String SEND_MESSAGE_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send";
/**
* 上传文件并推送到企业微信群
* @param file
* @param robotId 机器人Id
* @throws ServiceException
*/
public void sendFileToWeChatGroup(File file, String robotId) {
// 上传文件
String urlString = UPLOAD_FILE_URL + "?key=" + robotId + "&type=file";
ResponseEntity<Object> result = httpRequestUtil.doUploadFile(urlString, file);
JSONObject dataObject = JSONObject.parseObject(JSONObject.toJSONString(result.getBody()));
Integer errcode = Integer.valueOf(dataObject.get("errcode").toString());
if (errcode.equals(0)) {
// 推送消息
String mediaid = (String) dataObject.get("media_id");
String sendUrl = SEND_MESSAGE_URL + "?key=" + robotId;
Map<String, Object> mediaMap = new HashMap<>();
mediaMap.put("media_id", mediaid);
Map<String, Object> msgMap = new HashMap<>();
msgMap.put("msgtype", "file");
msgMap.put("file", mediaMap);
httpRequestUtil.doPost(sendUrl, msgMap);
log.info("企业微信推送报表成功,时间:" + new Date());
} else {
log.error("企业微信推送报表失败,时间:" + new Date());
}
}
/**
* 推送信息给企业微信机器人
* @param msg 消息内容
* @param robotId 机器人ID
* @param mentionAll 是否@所有人
*/
public void sendMsgToWeChatGroup(String msg, String robotId, boolean mentionAll) {
HashMap<String, Object> paramMap = new HashMap<>();
HashMap<String, Object> textMap = new HashMap<>();
textMap.put("content", msg);
// 添加@所有人的配置
if (mentionAll) {
textMap.put("mentioned_list", Collections.singletonList("@all"));
}
paramMap.put("msgtype", "text");
paramMap.put("text", textMap);
String sendUrl = SEND_MESSAGE_URL + "?key=" + robotId;
ResponseEntity<Object> result = httpRequestUtil.doPost(sendUrl, paramMap);
JSONObject dataObject = JSONObject.parseObject(JSONObject.toJSONString(result.getBody()));
Integer errcode = Integer.valueOf(dataObject.get("errcode").toString());
if (errcode.equals(0)) {
log.info("企业微信推送消息成功,时间:" + new Date());
} else {
log.error("企业微信推送消息失败,时间:" + new Date());
}
}
// 保留原有方法默认不@所有人
public void sendMsgToWeChatGroup(String msg, String robotId) {
sendMsgToWeChatGroup(msg, robotId, false);
}
/**
* 推送Markdown格式信息给企业微信机器人
* @param markdownMsg Markdown格式的消息内容
* @param robotId 机器人ID
*/
public void sendMarkdownMsgToWeChatGroup(String markdownMsg, String robotId) {
HashMap<String, Object> paramMap = new HashMap<>();
HashMap<String, Object> markdownMap = new HashMap<>();
markdownMap.put("content", markdownMsg);
paramMap.put("msgtype", "markdown");
paramMap.put("markdown", markdownMap);
String sendUrl = SEND_MESSAGE_URL + "?key=" + robotId;
ResponseEntity<Object> result = httpRequestUtil.doPost(sendUrl, paramMap);
JSONObject dataObject = JSONObject.parseObject(JSONObject.toJSONString(result.getBody()));
Integer errcode = Integer.valueOf(dataObject.get("errcode").toString());
if (errcode.equals(0)) {
log.info("企业微信推送Markdown消息成功时间" + new Date());
} else {
log.error("企业微信推送Markdown消息失败时间" + new Date());
}
}
/**
* 推送图文类型信息给企业微信机器人
* @param title 标题
* @param description 描述
* @param url 点击跳转链接
* @param picUrl 图片链接
* @param robotId 机器人ID
*/
public void sendNewsToWeChatGroup(String title, String description, String url, String picUrl, String robotId) {
HashMap<String, Object> paramMap = new HashMap<>();
// 创建文章对象
HashMap<String, Object> article = new HashMap<>();
article.put("title", title);
article.put("description", description);
article.put("url", url);
article.put("picurl", picUrl);
// 创建文章列表
List<HashMap<String, Object>> articles = new ArrayList<>();
articles.add(article);
// 创建news对象
HashMap<String, Object> newsMap = new HashMap<>();
newsMap.put("articles", articles);
// 设置消息类型和内容
paramMap.put("msgtype", "news");
paramMap.put("news", newsMap);
String sendUrl = SEND_MESSAGE_URL + "?key=" + robotId;
ResponseEntity<Object> result = httpRequestUtil.doPost(sendUrl, paramMap);
JSONObject dataObject = JSONObject.parseObject(JSONObject.toJSONString(result.getBody()));
Integer errcode = Integer.valueOf(dataObject.get("errcode").toString());
if (errcode.equals(0)) {
log.info("企业微信推送图文消息成功,时间:" + new Date());
} else {
log.error("企业微信推送图文消息失败,时间:" + new Date());
}
}
}

View File

@ -1,13 +1,23 @@
package com.ruoyi.common.utils.file;
import cn.hutool.core.io.FileUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
/**
* 文件处理工具类
@ -49,4 +59,59 @@ public class FileUtils extends FileUtil {
String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
return encode.replaceAll("\\+", "%20");
}
/**
*
* @param data 数据
* @param clazz 导出DTO类
* @param fileName 文件名
* @param extension 文件后缀
* @return
* @param <T>
* @throws IOException
*/
public <T> File exportReturnToFile(List<T> data, Class<T> clazz, String fileName, String extension) throws IOException {
File file = File.createTempFile(fileName, extension);
HorizontalCellStyleStrategy horizontalCellStyleStrategy = defaultStylePolicyPolicy();
//导出
EasyExcel.write(file, clazz)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.registerWriteHandler(horizontalCellStyleStrategy)
.sheet()
.doWrite(data);
return file;
}
/**
* 默认样式策略策略
*
* @return
*/
private static HorizontalCellStyleStrategy defaultStylePolicyPolicy() {
// 头的策略
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
// 背景设置为浅蓝色
headWriteCellStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
//设置水平对齐方式
headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
//设置字体为微软雅黑
WriteFont headWriteFont = new WriteFont();
headWriteFont.setFontName("宋体");
headWriteCellStyle.setWriteFont(headWriteFont);
// 内容的策略
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
//设置字体为微软雅黑
WriteFont contentWriteFont = new WriteFont();
contentWriteFont.setFontName("宋体");
contentWriteCellStyle.setWriteFont(contentWriteFont);
// 这个策略是 头是头的样式 内容是内容的样式
return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
}
}

View File

@ -5,6 +5,10 @@ import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.CellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;

View File

@ -27,6 +27,10 @@
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
</dependency>
</dependencies>

View File

@ -280,8 +280,9 @@ public class BomDetailsController extends BaseController {
log.info("开始新增不存在的电气物料==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName());
result = loadMaterialToDQ(material, state);
} else {
Double a = 0.0;
log.info("开始新增不存在的物料==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName());
result = loadMaterialPreservation(material, state);
result = loadMaterialPreservation(material, state, a);
}
if (result == 1) {
log.info("新增物料成功==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName());
@ -372,6 +373,7 @@ public class BomDetailsController extends BaseController {
@PostMapping("/updateFBMaterial")
public R updateFBMaterial(@RequestBody List<Map<String, String>> bomDetailParams) {
List<BomDetails> bomDetailsList = new ArrayList<>();
Set<String> processedMaterials = new HashSet<>(); // 用于跟踪已处理的物料编码
// 遍历前端传来的数据
for (Map<String, String> param : bomDetailParams) {
@ -380,12 +382,45 @@ public class BomDetailsController extends BaseController {
// 根据物料编码和生产令号查询
List<BomDetails> bomDetails = iBomDetailsService.selectByFNumberAndTotalWeight(fnumber, totalWeight);
System.out.println("处理物料编码:" + fnumber + ", 生产令号:" + totalWeight);
log.info("处理物料编码: {}, 生产令号: {}", fnumber, totalWeight);
if (bomDetails != null && !bomDetails.isEmpty()) {
// 检查金蝶中是否存在该物料的BOM
// JsonArray existingBom = checkBomExists(fnumber);
for (BomDetails material : bomDetails) {
// 只在第一次遇到该物料时新增父级物料
if (!processedMaterials.contains(material.getFNumber())) {
try { log.info("开始新增不存在的物料 ==> 物料图号: {}, 物料名称: {}", material.getPartNumber(), material.getName());
JdUtil.loadChengPinMaterialPreservation(material);
processedMaterials.add(material.getFNumber()); // 标记为已处理
} catch (Exception e) {
log.error("新增父级物料失败: {}", e.getMessage());
}
}
// 获取工艺表中的非委外工时
Double fbWorkTime = iProcessRouteService.getFbWorkTime(material);
if (material.getPartNumber() != null && material.getName() != null&& material.getUnitWeight().equals("")) {
String state = determineState(material);
log.info("开始新增不存在的物料 ==> 物料图号: {}, 物料名称: {}", material.getPartNumber(), material.getName());
try {
int result = loadMaterialPreservation(material, state, fbWorkTime);
if (result == 1) {
log.info("新增物料成功 ==> 物料图号: {}, 物料名称: {}", material.getPartNumber(), material.getName());
material.setUnitWeight("新增成功");
} else {
log.error("新增物料失败 ==> 物料图号: {}, 物料名称: {}", material.getPartNumber(),
material.getName());
}
// 更新物料状态
iBomDetailsService.updateByBo(BeanUtil.toBean(material, BomDetailsBo.class));
} catch (Exception e) {
log.error("处理物料时发生异常: {}", e.getMessage());
}
} else {
log.error("物料信息不完整,无法新增物料");
}
}
// 物料清单保存方法
FBloadBillOfMaterialsPreservation(bomDetails);
bomDetailsList.addAll(bomDetails);
@ -816,6 +851,8 @@ public class BomDetailsController extends BaseController {
subHeadEntity6.addProperty("FCheckProduct", true);
subHeadEntity6.addProperty("FCheckSubRtnMtrl", true);
}
// 库存检验
subHeadEntity6.addProperty("FCheckStock", true);
// 创建SubHeadEntity5对象并加入Model
JsonObject subHeadEntity5 = new JsonObject();
model.add("SubHeadEntity5", subHeadEntity5);
@ -990,10 +1027,12 @@ public class BomDetailsController extends BaseController {
if (bomDetail.getStats().equals("1")) {
// 外购
subHeadEntity6.addProperty("FCheckIncoming", true);
subHeadEntity6.addProperty("FCheckStock", true);
}
if (bomDetail.getStats().equals("2")) {
// 自制
subHeadEntity6.addProperty("FCheckProduct", true);
subHeadEntity6.addProperty("FCheckStock", true);
subHeadEntity6.addProperty("FCheckReturnMtrl", true);
}
if (bomDetail.getStats().equals("3")) {
@ -1002,6 +1041,8 @@ public class BomDetailsController extends BaseController {
subHeadEntity6.addProperty("FCheckProduct", true);
subHeadEntity6.addProperty("FCheckSubRtnMtrl", true);
}
// 库存检验
subHeadEntity6.addProperty("FCheckStock", true);
// 创建SubHeadEntity5对象并加入Model
JsonObject subHeadEntity5 = new JsonObject();
model.add("SubHeadEntity5", subHeadEntity5);
@ -1283,7 +1324,7 @@ public class BomDetailsController extends BaseController {
}
}
public int loadMaterialPreservation(BomDetails bomDetails1, String states) {
public int loadMaterialPreservation(BomDetails bomDetails1, String states, Double fbWorkTime) {
K3CloudApi client = new K3CloudApi();
// 创建一个空的JsonObject
JsonObject json = new JsonObject();
@ -1402,10 +1443,12 @@ public class BomDetailsController extends BaseController {
if (states.equals("1")) {
// 外购
subHeadEntity6.addProperty("FCheckIncoming", true);
subHeadEntity6.addProperty("FCheckStock", true);
}
if (states.equals("2")) {
// 自制
subHeadEntity6.addProperty("FCheckProduct", true);
subHeadEntity6.addProperty("FCheckStock", true);
subHeadEntity6.addProperty("FCheckReturnMtrl", true);
}
if (states.equals("3")) {
@ -1414,7 +1457,8 @@ public class BomDetailsController extends BaseController {
subHeadEntity6.addProperty("FCheckProduct", true);
subHeadEntity6.addProperty("FCheckReturnMtrl", true);
}
// 库存检验
subHeadEntity6.addProperty("FCheckStock", true);
// 创建SubHeadEntity5对象并加入Model
JsonObject subHeadEntity5 = new JsonObject();
model.add("SubHeadEntity5", subHeadEntity5);
@ -1423,6 +1467,7 @@ public class BomDetailsController extends BaseController {
JsonObject fProduceUnitId = new JsonObject();
fProduceUnitId.addProperty("FNumber", "jian");
subHeadEntity5.add("FProduceUnitId", fProduceUnitId);
// 实际作工时并加入SubHeadEntity5
// 创建FProduceBillType对象并加入SubHeadEntity5
JsonObject fProduceBillType = new JsonObject();
@ -1446,7 +1491,9 @@ public class BomDetailsController extends BaseController {
subHeadEntity1.add("FPickStockId", fPickStockId);
subHeadEntity5.addProperty("FOverControlMode", "1");
subHeadEntity5.addProperty("FStandHourUnitId", "3600");
// 标准人员实作工时
subHeadEntity5.addProperty("FStdLaborProcessTime", fbWorkTime);
subHeadEntity5.addProperty("FStandHourUnitId", "60");
subHeadEntity5.addProperty("FBackFlushType", "1");
String jsonData = json.toString();
System.out.println(jsonData);
@ -1742,10 +1789,12 @@ public class BomDetailsController extends BaseController {
if (states.equals("1")) {
// 外购
subHeadEntity6.addProperty("FCheckIncoming", true);
subHeadEntity6.addProperty("FCheckStock", true);
}
if (states.equals("2")) {
// 自制
subHeadEntity6.addProperty("FCheckProduct", true);
subHeadEntity6.addProperty("FCheckStock", true);
subHeadEntity6.addProperty("FCheckReturnMtrl", true);
}
if (states.equals("3")) {
@ -1754,7 +1803,7 @@ public class BomDetailsController extends BaseController {
subHeadEntity6.addProperty("FCheckProduct", true);
subHeadEntity6.addProperty("FCheckReturnMtrl", true);
}
subHeadEntity6.addProperty("FCheckStock", true);
// 创建SubHeadEntity5对象并加入Model
JsonObject subHeadEntity5 = new JsonObject();
model.add("SubHeadEntity5", subHeadEntity5);

View File

@ -1,12 +1,28 @@
package com.ruoyi.system.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import com.alibaba.fastjson.JSONObject;
import com.kingdee.bos.webapi.entity.SuccessEntity;
import com.ruoyi.common.excel.ExcelResult;
import com.ruoyi.common.utils.JdUtils;
import com.ruoyi.system.domain.EleMaterials;
import com.ruoyi.system.domain.dto.JdEntry;
import com.ruoyi.system.domain.dto.JinYongDTO;
import com.ruoyi.system.domain.vo.ExcelVo;
import com.ruoyi.system.runner.JdUtil;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.ruoyi.common.annotation.RepeatSubmit;
@ -22,6 +38,7 @@ import com.ruoyi.system.domain.vo.EleMaterialsVo;
import com.ruoyi.system.domain.bo.EleMaterialsBo;
import com.ruoyi.system.service.IEleMaterialsService;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;
/**
* 电器物料管理
@ -36,7 +53,7 @@ import com.ruoyi.common.core.page.TableDataInfo;
public class EleMaterialsController extends BaseController {
private final IEleMaterialsService iEleMaterialsService;
private static final Logger log = LoggerFactory.getLogger(EleMaterialsController.class);
/**
* 查询电器物料管理列表
*/
@ -104,4 +121,155 @@ public class EleMaterialsController extends BaseController {
@PathVariable Long[] ids) {
return toAjax(iEleMaterialsService.deleteWithValidByIds(Arrays.asList(ids), true));
}
/**
* 将物料上传至金蝶
*/
@SaCheckPermission("system:materials:addToK3")
@Log(title = "将物料上传至金蝶", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping("/addToK3")
public R<List<EleMaterials>> addToK3() {
List<EleMaterials> eleMaterialsVos = iEleMaterialsService.addToJindie();
return R.ok(eleMaterialsVos);
}
@Log(title = "电器物料导入", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:materials:import")
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ExcelVo importData(@RequestParam("file") MultipartFile file, HttpServletResponse response) throws Exception {
String originalFilename = file.getOriginalFilename();
log.info("读取文件名: " + originalFilename);
// 确保文件不为空
if (file.isEmpty()) {
throw new RuntimeException("上传的文件为空");
}
// 导入 Excel 数据
ExcelResult<EleMaterialsVo> eleMaterialsVoExcelResult = ExcelUtil.importExcelSheet1(file.getInputStream(), EleMaterialsVo.class, true);
// 检查导入结果
if (eleMaterialsVoExcelResult.getList() == null || eleMaterialsVoExcelResult.getList().isEmpty()) {
throw new RuntimeException("导入的 Excel 文件没有有效数据");
}
// 返回导入结果
ExcelVo jsonObject = new ExcelVo();
jsonObject.setList(eleMaterialsVoExcelResult.getList());
return jsonObject;
}
@SaCheckPermission("system:materials:export")
@Log(title = "电器物料导出", businessType = BusinessType.EXPORT)
@PostMapping(value = "/importData1")
public void importData1(@RequestBody ExcelVo excelVo, HttpServletResponse response) throws Exception {
// result 返回
try {
// 保存数据并导出 Excel
if (iEleMaterialsService.saveData(excelVo.getList(), response)) {
log.info("上传物料成功");
} else {
log.error("导入失败");
}
} catch (Exception e) {
log.error("导出 Excel 文件时发生错误: ", e);
// 这里可以选择记录日志或处理其他逻辑但不要发送错误响应
}
}
@Log(title = "禁用物料", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:route:importDataTime")
@PostMapping(value = "/importMA", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> importMA(@RequestParam("file") MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename();
log.info("读取文件名: " + originalFilename);
ExcelResult<EleMaterialsVo> result = ExcelUtil.importExcelSheet1(file.getInputStream(), EleMaterialsVo.class,
true);
List<EleMaterialsVo> list = result.getList();
for (EleMaterialsVo processRouteVo : list) {
ArrayList<SuccessEntity> jinyong = JdUtils.jinyong(processRouteVo.getMaterialCode());
}
return R.ok("更新成功");
}
@Log(title = "禁用子项中包含的物料", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:route:importDataTime")
@PostMapping(value = "/importMA1", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> importMA1(@RequestParam("file") MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename();
log.info("读取文件名: " + originalFilename);
ExcelResult<EleMaterialsVo> result = ExcelUtil.importExcelSheet1(file.getInputStream(), EleMaterialsVo.class, true);
List<EleMaterialsVo> list = result.getList();
// 创建一个固定大小的线程池
ExecutorService executorService = Executors.newFixedThreadPool(10); // 可以根据需要调整线程数
for (EleMaterialsVo processRouteVo : list) {
executorService.submit(() -> {
log.info("查询对应的bom中包含的子项物料=====>: " + processRouteVo.getMaterialCode());
List<JinYongDTO> jinyong = JdUtil.getFuji(processRouteVo.getMaterialCode());
log.info("查询对应的父级物料清单bom: " + jinyong);
for (JinYongDTO jinYongDTO : jinyong) {
String fNumber = jinYongDTO.getFNumber(); // 确保使用正确的字段名
// 调用金蝶接口用料订单禁用
try {
JdUtil.jtestForbidMaterial(fNumber);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
}
// 关闭线程池并等待所有任务完成
executorService.shutdown();
try {
if (!executorService.awaitTermination(60, TimeUnit.MINUTES)) {
executorService.shutdownNow(); // 超时后强制关闭
}
} catch (InterruptedException e) {
executorService.shutdownNow();
Thread.currentThread().interrupt(); // 保留中断状态
}
return R.ok("更新成功");
}
@Log(title = "更新工时", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:route:updaDateGongshi")
@PostMapping(value = "/updaDateGongshi", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> updaDateGongshi(@RequestParam("file") MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename();
log.info("读取文件名: " + originalFilename);
ExcelResult<EleMaterialsVo> result = ExcelUtil.importExcelSheet1(file.getInputStream(), EleMaterialsVo.class, true);
List<EleMaterialsVo> list = result.getList();
// 创建固定大小的线程池
ExecutorService executor = Executors.newFixedThreadPool(10); // 可以根据需要调整线程数
for (EleMaterialsVo processRouteVo : list) {
executor.submit(() -> {
List<JdEntry> entryID = JdUtil.getEntryID(processRouteVo.getMaterialCode());
for (JdEntry jdEntry : entryID) {
int FMATERIALID = jdEntry.getFMATERIALID();
int fEntryId = jdEntry.getFEntryId();
log.info("FMATERIALID: " + FMATERIALID);
log.info("fEntryId: " + fEntryId);
log.info("物料编码: " + processRouteVo.getMaterialValue());
log.info("工时: " + processRouteVo.getMaterialCode());
try {
JdUtil.atestSaveMaterial(FMATERIALID, fEntryId, processRouteVo.getMaterialCode(), Double.parseDouble(processRouteVo.getMaterialValue()));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
}
// 关闭线程池
executor.shutdown();
while (!executor.isTerminated()) {
// 等待所有任务完成
}
return R.ok("更新成功");
}
}

View File

@ -0,0 +1,559 @@
package com.ruoyi.system.controller;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Arrays;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.CellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ruoyi.common.utils.HttpRequestUtil;
import com.ruoyi.common.utils.WxRobotUtil;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollUtil;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.vo.KingdeeWorkCenterDataVo;
import com.ruoyi.system.domain.bo.KingdeeWorkCenterDataBo;
import com.ruoyi.system.service.IKingdeeWorkCenterDataService;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.util.StringUtils;
/**
* 金蝶工段数据
*
* @author 田志阳
* @date 2025-01-18
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/workCenterData")
public class KingdeeWorkCenterDataController extends BaseController {
@Resource
private WxRobotUtil wxRobotUtil;
private final IKingdeeWorkCenterDataService iKingdeeWorkCenterDataService;
private final HttpRequestUtil httpRequestUtil;
private static final Logger log = LoggerFactory.getLogger(KingdeeWorkCenterDataController.class);
/**
* 查询金蝶工段数据列表
*/
@SaCheckPermission("system:workCenterData:list")
@GetMapping("/list")
public TableDataInfo<KingdeeWorkCenterDataVo> list(KingdeeWorkCenterDataBo bo, PageQuery pageQuery) {
return iKingdeeWorkCenterDataService.queryPageList(bo, pageQuery);
}
/**
* 导出金蝶工段数据列表
*/
@SaCheckPermission("system:workCenterData:export")
@Log(title = "金蝶工段数据", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(KingdeeWorkCenterDataBo bo, HttpServletResponse response) {
List<KingdeeWorkCenterDataVo> list = iKingdeeWorkCenterDataService.queryList(bo);
ExcelUtil.exportExcel(list, "金蝶工段数据", KingdeeWorkCenterDataVo.class, response);
}
/**
* 获取金蝶工段数据详细信息
*
* @param id 主键
*/
@SaCheckPermission("system:workCenterData:query")
@GetMapping("/{id}")
public R<KingdeeWorkCenterDataVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
return R.ok(iKingdeeWorkCenterDataService.queryById(id));
}
/**
* 新增金蝶工段数据
*/
@SaCheckPermission("system:workCenterData:add")
@Log(title = "金蝶工段数据", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody KingdeeWorkCenterDataBo bo) {
return toAjax(iKingdeeWorkCenterDataService.insertByBo(bo));
}
/**
* 修改金蝶工段数据
*/
@SaCheckPermission("system:workCenterData:edit")
@Log(title = "金蝶工段数据", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody KingdeeWorkCenterDataBo bo) {
return toAjax(iKingdeeWorkCenterDataService.updateByBo(bo));
}
/**
* 删除金蝶工段数据
*
* @param ids 主键串
*/
@SaCheckPermission("system:workCenterData:remove")
@Log(title = "金蝶工段数据", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
return toAjax(iKingdeeWorkCenterDataService.deleteWithValidByIds(Arrays.asList(ids), true));
}
/**
* 获取金蝶相关工段数据
*/
@SaCheckPermission("system:workCenterData:remove")
@Log(title = "金蝶工段数据提前2天", businessType = BusinessType.DELETE)
@PostMapping("/getKingdeeWorkCenterData")
public R<List<KingdeeWorkCenterDataBo>> getKingdeeWorkCenterData(@RequestParam(value="workCenter") String workCenter) {
try {
K3CloudApi client = new K3CloudApi();
JsonObject parameter = new JsonObject();
List<KingdeeWorkCenterDataBo> kingdeeWorkCenterDataVos = new ArrayList<>();
parameter.addProperty("FWorkCenterName", workCenter);
Object[] parameters = new Object[] { parameter.toString() };
String execute = client.execute(
"Ljint.Kingdee.YiTe.KanBan.WebApi.ProduceWebApi.ExecuteService,Ljint.Kingdee.YiTe.KanBan.WebApi",
parameters);
log.info("金蝶接口返回数据: {}", execute);
// 解析响应
JSONObject response = JSONObject.parseObject(execute);
if (!"true".equals(response.getString("IsSuccess"))) {
String errorMsg = response.getString("Message");
return R.fail("获取工段数据失败:" + errorMsg);
}
// 获取明天的日期字符串 (格式: yyyy-MM-dd)
String tomorrow = DateUtil.format(DateUtil.tomorrow().toLocalDateTime().plusDays(1), "yyyy-MM-dd");
// 获取数据数组
JSONArray dataArray = response.getJSONArray("data");
if (dataArray == null || dataArray.isEmpty()) {
return R.ok("无数据");
}
for (int i = 0; i < dataArray.size(); i++) {
JSONArray queryList = dataArray.getJSONObject(i).getJSONArray("QueryList");
for (int j = 0; j < queryList.size(); j++) {
JSONObject item = queryList.getJSONObject(j);
// 获取计划结束时间并转换为日期格式进行比较
String planFinishTime = item.getString("FOperPlanFinishTime2");
if (StringUtils.hasText(planFinishTime)) {
// 提取日期部分进行比较 (去掉时间部分)
String finishDate = planFinishTime.split(" ")[0];
// 只处理明天结束的工单
if (tomorrow.equals(finishDate)) {
// 转换为实体对象
KingdeeWorkCenterDataBo data = new KingdeeWorkCenterDataBo();
data.setWorkCenter(workCenter);
data.setMoBillNo(item.getString("MoBillNo"));
data.setMoOrderNo(item.getString("MoOrderNo"));
data.setMaterialNumber(item.getString("FMaterialNumber"));
data.setMaterialName(item.getString("FMaterialName"));
data.setOperQty(item.getLong("FOperQty"));
data.setTransInQty(item.getLong("FTransInQty"));
data.setTransOutQty(item.getLong("FTransOutQty"));
data.setMaterialStatus(item.getString("FMaterialStatus"));
data.setOperNumber(item.getString("FOperNumber"));
data.setProcessName(item.getString("FProcessName"));
data.setOperPlanStartTime(item.getString("FOperPlanStartTime2"));
data.setOperPlanFinishTime(planFinishTime);
data.setDelayDays(item.getString("FDelayDays"));
kingdeeWorkCenterDataVos.add(data);
Boolean b = iKingdeeWorkCenterDataService.insertByBo(data);
if (!b) {
return R.fail("保存工段数据失败");
}
}
}
}
}
if (kingdeeWorkCenterDataVos.isEmpty()) {
return R.ok("明天没有计划结束的工单");
}
return R.ok(kingdeeWorkCenterDataVos);
} catch (Exception e) {
log.error("获取金蝶工段数据失败", e);
return R.fail("获取金蝶工段数据失败:" + e.getMessage());
}
}
@Log(title = "获取金蝶工段数据模板2")
@SaCheckPermission("system:route:sendMsg")
@PostMapping("/sendMsg")
public R<Void> getMassage(@RequestParam String workCenter) {
String robotId = "4d2f037d-0cee-493a-a4ff-1758f67b8069";
R<List<KingdeeWorkCenterDataBo>> kingdeeWorkCenterData = getKingdeeWorkCenterData(workCenter);
if (R.isError(kingdeeWorkCenterData)) {
return R.fail("获取工段数据失败");
}
List<KingdeeWorkCenterDataBo> data = kingdeeWorkCenterData.getData();
for (KingdeeWorkCenterDataBo kingdeeWorkCenterDataBo : data) {
String msg = "## 🚨 生产延期预警通知\n\n" +
"<font color=\"warning\">当前工单延期生产</font>\n\n" +
"### 📋 工单明细:\n\n" +
"#### 1. " + kingdeeWorkCenterDataBo.getWorkCenter() + " (延期"
+ kingdeeWorkCenterDataBo.getDelayDays() + "天)\n" +
"> 工单号:<font color=\"comment\">" + kingdeeWorkCenterDataBo.getMoBillNo();
}
String markdownMsg = "## 🚨 生产延期预警通知\n\n" +
"<font color=\"warning\">当前工单延期生产</font>\n\n" +
"### 📋 工单明细:\n\n" +
"#### 1. AGV电气部分 (延期23天)\n" +
"> 工单号:<font color=\"comment\">MO006380</font>\n" +
"> 订单号:<font color=\"comment\">XM-QX-024-0230-01</font>\n" +
"> 计划时间:<font color=\"comment\">12-28 ~ 12-28</font>\n" +
"> 生产状态:<font color=\"warning\">未转出</font>\n" +
"> 数量信息:计划<font color=\"comment\">4.00</font>,已转入<font color=\"comment\">4.00</font>,已转出<font color=\"comment\">0.00</font>\n\n"
+
"#### 2. 轻卡全自动滑板底盘换电站 (延期22天)\n" +
"> 工单号:<font color=\"comment\">MO007925</font>\n" +
"> 订单号:<font color=\"comment\">XM-KC-024-0271</font>\n" +
"> 计划时间:<font color=\"comment\">12-19 ~ 12-29</font>\n" +
"> 生产状态:<font color=\"info\">已转出</font>\n" +
"> 数量信息:计划<font color=\"comment\">30.00</font>,已转入<font color=\"comment\">30.00</font>,已转出<font color=\"comment\">17.00</font>\n\n"
+
"#### 3. 配线盘 (延期10天)\n" +
"> 工单号:<font color=\"comment\">MO007930</font>\n" +
"> 订单号:<font color=\"comment\">XM-KC-024-0320</font>\n" +
"> 计划时间:<font color=\"comment\">01-07 ~ 01-10</font>\n" +
"> 生产状态:<font color=\"warning\">未转出</font>\n" +
"> 数量信息:计划<font color=\"comment\">1.00</font>,已转入<font color=\"comment\">1.00</font>,已转出<font color=\"comment\">0.00</font>\n\n"
+
"请相关部门负责人关注并及时处理!";
wxRobotUtil.sendMarkdownMsgToWeChatGroup(markdownMsg, robotId);
return R.ok();
}
@Log(title = "获取金蝶工段数据模板")
@SaCheckPermission("system:route:getMassage1")
@PostMapping("/getMassage1")
public R<Void> getMassage1() {
try {
String robotId = "4d2f037d-0cee-493a-a4ff-1758f67b8069";
// 获取数据
K3CloudApi client = new K3CloudApi();
JsonObject parameter = new JsonObject();
parameter.addProperty("FWorkCenterName", "委外中心");
Object[] parameters = new Object[] { parameter.toString() };
String execute = client.execute(
"Ljint.Kingdee.YiTe.KanBan.WebApi.ProduceWebApi.ExecuteService,Ljint.Kingdee.YiTe.KanBan.WebApi",
parameters);
// 解析响应
JSONObject response = JSONObject.parseObject(execute);
if (!"true".equals(response.getString("IsSuccess"))) {
return R.fail("获取工段数据失败:" + response.getString("Message"));
}
// 构建markdown消息
StringBuilder markdownMsg = new StringBuilder();
markdownMsg.append("## 🚨 生产延期预警通知\n\n")
.append("<font color=\"warning\">当前工单延期生产</font>\n\n")
.append("### 📋 工单明细:\n\n");
// 获取数据数组
JSONArray dataArray = response.getJSONArray("data");
if (dataArray != null && !dataArray.isEmpty()) {
int index = 1;
for (int i = 0; i < dataArray.size(); i++) {
JSONArray queryList = dataArray.getJSONObject(i).getJSONArray("QueryList");
if (queryList != null) {
for (int j = 0; j < queryList.size(); j++) {
JSONObject item = queryList.getJSONObject(j);
// 获取状态颜色
String statusColor = "已转出".equals(item.getString("FMaterialStatus")) ? "info" : "warning";
// 添加每个工单的详细信息
markdownMsg.append(String.format("#### %d. %s (延期%s天)\n",
index++,
item.getString("FMaterialName"),
item.getString("FDelayDays")))
.append(String.format("> 工单号:<font color=\"comment\">%s</font>\n",
item.getString("MoBillNo")))
.append(String.format("> 订单号:<font color=\"comment\">%s</font>\n",
item.getString("MoOrderNo")))
.append(String.format("> 计划时间:<font color=\"comment\">%s ~ %s</font>\n",
item.getString("FOperPlanStartTime"),
item.getString("FOperPlanFinishTime")))
.append(String.format("> 生产状态:<font color=\"%s\">%s</font>\n",
statusColor,
item.getString("FMaterialStatus")))
.append(String.format(
"> 数量信息:计划<font color=\"comment\">%.2f</font>,已转入<font color=\"comment\">%.2f</font>,已转出<font color=\"comment\">%.2f</font>\n\n",
item.getDoubleValue("FOperQty"),
item.getDoubleValue("FTransInQty"),
item.getDoubleValue("FTransOutQty")));
}
}
}
}
// 添加结束语
markdownMsg.append("请相关部门负责人关注并及时处理!");
// 发送消息
wxRobotUtil.sendMarkdownMsgToWeChatGroup(markdownMsg.toString(), robotId);
return R.ok();
} catch (Exception e) {
log.error("发送工段数据失败", e);
return R.fail("发送工段数据失败:" + e.getMessage());
}
}
@Log(title = "预警企业机器人")
@XxlJob("getMassageForMultipleWorkCenters")
public R<Void> getMassageForMultipleWorkCenters() {
try {
String robotId = "4d2f037d-0cee-493a-a4ff-1758f67b8069";
List<String> workCenters = Arrays.asList("机一工段", "机二工段", "机三工段", "装一工段", "装二工段", "委外中心", "电钳工段", "铆焊工段");
String currentTime = DateUtil.format(new Date(), "yyyy年MM月dd日 HH:mm:ss");
StringBuilder msg = new StringBuilder();
msg.append("🏭 生产数据更新提醒(提前两天)\n\n")
.append("更新时间:").append(currentTime).append("\n\n")
.append("🔧 工作中心数据统计:\n");
// 获取并统计每个工段的数据
for (String workCenter : workCenters) {
try {
R<List<KingdeeWorkCenterDataBo>> result = getKingdeeWorkCenterData(workCenter);
if (R.isError(result) || CollUtil.isEmpty(result.getData())) {
msg.append("- ").append(workCenter).append(" (无数据)\n");
continue;
}
List<KingdeeWorkCenterDataBo> dataList = result.getData();
msg.append("- ").append(workCenter).append(" (共").append(dataList.size()).append("条数据)\n");
// 生成Excel文件
String fileName = String.format("%s生产预警数据_%s.xlsx", workCenter,
DateUtil.format(new Date(), "yyyyMMddHHmmss"));
String filePath = FileUtils.getTempDirectoryPath() + File.separator + fileName;
// 使用EasyExcel写入数据
EasyExcel.write(filePath, KingdeeWorkCenterDataVo.class)
.sheet("工段数据")
.doWrite(BeanUtil.copyToList(dataList, KingdeeWorkCenterDataVo.class));
// 发送Excel文件
File excelFile = new File(filePath);
wxRobotUtil.sendFileToWeChatGroup(excelFile, robotId);
// 删除临时文件
FileUtils.deleteQuietly(excelFile);
} catch (Exception e) {
log.error("获取工段{}数据失败", workCenter, e);
msg.append("- ").append(workCenter).append(" (获取失败: ").append(e.getMessage()).append(")\n");
}
}
msg.append("\n详细数据请查看发送的Excel文件");
wxRobotUtil.sendMsgToWeChatGroup(msg.toString(), robotId, true); // @所有人
return R.ok();
} catch (Exception e) {
log.error("发送工段数据失败", e);
return R.fail("发送工段数据失败:" + e.getMessage());
}
}
/**
* 金蝶工段数据延期数据
*/
@SaCheckPermission("system:workCenterData:remove")
@Log(title = "金蝶工段数据延期数据", businessType = BusinessType.DELETE)
@PostMapping("/getKingdeeDelayData")
public R<List<KingdeeWorkCenterDataBo>> getKingdeeDelayData(@RequestParam(value="workCenter") String workCenter) {
try {
K3CloudApi client = new K3CloudApi();
JsonObject parameter = new JsonObject();
List<KingdeeWorkCenterDataBo> kingdeeWorkCenterDataVos = new ArrayList<>();
parameter.addProperty("FWorkCenterName", workCenter);
Object[] parameters = new Object[] { parameter.toString() };
String execute = client.execute(
"Ljint.Kingdee.YiTe.KanBan.WebApi.ProduceWebApi.ExecuteService,Ljint.Kingdee.YiTe.KanBan.WebApi",
parameters);
log.info("金蝶接口返回数据: {}", execute);
// 解析响应
JSONObject response = JSONObject.parseObject(execute);
if (!"true".equals(response.getString("IsSuccess"))) {
String errorMsg = response.getString("Message");
return R.fail("获取工段数据失败:" + errorMsg);
}
// 获取明天的日期字符串 (格式: yyyy-MM-dd)
String yesterday = DateUtil.format(DateUtil.yesterday(), "yyyy-MM-dd");
// 获取数据数组
JSONArray dataArray = response.getJSONArray("data");
if (dataArray == null || dataArray.isEmpty()) {
return R.ok("无数据");
}
for (int i = 0; i < dataArray.size(); i++) {
JSONArray queryList = dataArray.getJSONObject(i).getJSONArray("QueryList");
for (int j = 0; j < queryList.size(); j++) {
JSONObject item = queryList.getJSONObject(j);
// 获取计划结束时间并转换为日期格式进行比较
String planFinishTime = item.getString("FOperPlanFinishTime2");
if (StringUtils.hasText(planFinishTime)) {
// 提取日期部分进行比较 (去掉时间部分)
String finishDate = planFinishTime.split(" ")[0];
// 只处理明天结束的工单
if (yesterday.equals(finishDate)) {
// 计算延期条件转出数减转入数大于0
//转出
long transOutQty = item.getLong("FTransOutQty");
//转入
long transInQty = item.getLong("FTransInQty");
if (transInQty - transOutQty > 0) {
// 转换为实体对象
KingdeeWorkCenterDataBo data = new KingdeeWorkCenterDataBo();
data.setWorkCenter(workCenter);
data.setMoBillNo(item.getString("MoBillNo"));
data.setMoOrderNo(item.getString("MoOrderNo"));
data.setMaterialNumber(item.getString("FMaterialNumber"));
data.setMaterialName(item.getString("FMaterialName"));
data.setOperQty(item.getLong("FOperQty"));
data.setTransInQty(transInQty);
data.setTransOutQty(transOutQty);
data.setOperNumber(item.getString("FOperNumber"));
data.setProcessName(item.getString("FProcessName"));
data.setOperPlanStartTime(item.getString("FOperPlanStartTime2"));
data.setOperPlanFinishTime(planFinishTime);
data.setDelayDays(item.getString("FDelayDays"));
kingdeeWorkCenterDataVos.add(data);
Boolean b = iKingdeeWorkCenterDataService.insertByBo(data);
if (!b) {
return R.fail("保存工段数据失败");
}
}
}
}
}
}
if (kingdeeWorkCenterDataVos.isEmpty()) {
return R.ok("明天没有计划结束的工单");
}
return R.ok(kingdeeWorkCenterDataVos);
} catch (Exception e) {
log.error("获取金蝶工段数据失败", e);
return R.fail("获取金蝶工段数据失败:" + e.getMessage());
}
}
@Log(title = "延期警告企业机器人")
@XxlJob("getMassageDelayDate")
public R<Void> getMassageDelayDate() {
try {
// String robotId = "4d2f037d-0cee-493a-a4ff-1758f67b8069";
String robotId = "483489b2-b219-468c-851f-f56a34a62d91";
List<String> workCenters = Arrays.asList("机一工段", "机二工段", "机三工段", "装一工段", "装二工段", "委外中心", "电钳工段", "铆焊工段");
String currentTime = DateUtil.format(new Date(), "yyyy年MM月dd日 HH:mm:ss");
StringBuilder msg = new StringBuilder();
msg.append("🏭 延期数据更新提醒\n\n")
.append("更新时间:").append(currentTime).append("\n\n")
.append("🔧 工作中心数据统计:\n");
// 获取并统计每个工段的数据
for (String workCenter : workCenters) {
try {
R<List<KingdeeWorkCenterDataBo>> result = getKingdeeDelayData(workCenter);
if (R.isError(result) || CollUtil.isEmpty(result.getData())) {
msg.append("- ").append(workCenter).append(" (无数据)\n");
continue;
}
List<KingdeeWorkCenterDataBo> dataList = result.getData();
msg.append("- ").append(workCenter).append(" (共").append(dataList.size()).append("条数据)\n");
// 生成Excel文件
String fileName = String.format("%s生产延期数据_%s.xlsx", workCenter,
DateUtil.format(new Date(), "yyyyMMddHHmmss"));
String filePath = FileUtils.getTempDirectoryPath() + File.separator + fileName;
// 使用EasyExcel写入数据
EasyExcel.write(filePath, KingdeeWorkCenterDataVo.class)
.sheet("工段数据")
.doWrite(BeanUtil.copyToList(dataList, KingdeeWorkCenterDataVo.class));
// 发送Excel文件
File excelFile = new File(filePath);
wxRobotUtil.sendFileToWeChatGroup(excelFile, robotId);
// 删除临时文件
FileUtils.deleteQuietly(excelFile);
} catch (Exception e) {
log.error("获取工段{}数据失败", workCenter, e);
msg.append("- ").append(workCenter).append(" (获取失败: ").append(e.getMessage()).append(")\n");
}
}
msg.append("\n详细数据请查看发送的Excel文件");
wxRobotUtil.sendMsgToWeChatGroup(msg.toString(), robotId, true); // @所有人
return R.ok();
} catch (Exception e) {
log.error("发送工段数据失败", e);
return R.fail("发送工段数据失败:" + e.getMessage());
}
}
}

View File

@ -118,11 +118,11 @@ public class NewMaterialsController extends BaseController {
@Log(title = "金蝶物料管理", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping("/addToK3")
public R<Void> addToK3() {
public R<List<NewMaterialsVo>> addToK3() {
List<NewMaterialsVo> newMaterialsVos = iNewMaterialsService.addToJindie();
return R.ok();
return R.ok(newMaterialsVos);
}
@Log(title = "物料导入", businessType = BusinessType.IMPORT)
@Log(title = "电器物料导入", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:newMaterials:import")
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> importData(@RequestParam("file") MultipartFile file) throws Exception {

View File

@ -30,7 +30,6 @@ import com.ruoyi.common.core.page.TableDataInfo;
/**
* 项目令号
*
* @author ruoyi
* @date 2024-10-22
*/
@ -71,7 +70,6 @@ public class ProcessOrderProController extends BaseController {
/**
* 获取项目令号详细信息
*
* @param id 主键
*/
@SaCheckPermission("system:orderPro:query")
@ -113,6 +111,7 @@ public class ProcessOrderProController extends BaseController {
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iProcessOrderProService.deleteWithValidByIds(Arrays.asList(ids), true));
return iProcessOrderProService.deleteWithValidByIds(Arrays.asList(ids), true);
}
}

View File

@ -1,6 +1,9 @@
package com.ruoyi.system.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.controller.BaseController;
@ -11,15 +14,15 @@ import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.excel.ExcelResult;
import com.ruoyi.common.utils.HttpRequestUtil;
import com.ruoyi.common.utils.WxRobotUtil;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.MaterialBom;
import com.ruoyi.system.domain.ProcessRoute;
import com.ruoyi.system.domain.ProductionRouteTwo;
import com.ruoyi.system.domain.bo.ProcessRouteBo;
import com.ruoyi.system.domain.dto.CombinedDTO;
import com.ruoyi.system.domain.dto.ProcessRoutePushResultDTO;
import com.ruoyi.system.domain.dto.ProcessRouteSelectDTO;
import com.ruoyi.system.domain.dto.*;
import com.ruoyi.system.jdmain.rouplan.Model;
import com.ruoyi.system.domain.dto.ProcessRouteXuDTO;
import com.ruoyi.system.domain.vo.ProcessRouteVo;
import com.ruoyi.system.domain.vo.ProductionOrderVo;
import com.ruoyi.system.service.IProcessRouteService;
@ -34,6 +37,8 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@ -202,7 +207,6 @@ public class ProcessRouteController extends BaseController {
child.setXuEndTime(processRouteVo.getXuEndTime());
return child;
}
/**
* 导出工艺路线列表
*/
@ -265,8 +269,10 @@ public class ProcessRouteController extends BaseController {
public R<Void> importData(@RequestParam("file") MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename();
log.info("读取文件名: " + originalFilename);
//读取工艺部分sheet
ExcelResult<ProcessRouteVo> result = ExcelUtil.importExcelSheet6(file.getInputStream(), ProcessRouteVo.class,
true);
//读取总装部分sheet
ExcelResult<ProductionOrderVo> result1 = ExcelUtil.importExcelSheet1(file.getInputStream(),
ProductionOrderVo.class, true);
List<ProductionOrderVo> list = result1.getList();
@ -403,14 +409,24 @@ public class ProcessRouteController extends BaseController {
@Log(title = "获取材料bom列表")
@SaCheckPermission("system:route:getRawBom")
@PostMapping("/getBomInfo")
public ResponseEntity<List<MaterialBom>> getProcessMaterialList(@RequestParam String materialCode,
@RequestParam String materialName,
@RequestParam String productionOrderNo) {
public ResponseEntity<List<MaterialBom>> getProcessMaterialList(@RequestParam(value = "materialCode") String materialCode,
@RequestParam(value = "materialName") String materialName,
@RequestParam(value = "productionOrderNo") String productionOrderNo) {
return ResponseEntity
.ok(iProcessRouteService.getProcessMaterialList(materialCode, materialName, productionOrderNo));
return ResponseEntity.ok(iProcessRouteService.getProcessMaterialList(materialCode, materialName, productionOrderNo));
}
@Log(title = "获取金蝶列表")
@SaCheckPermission("system:route:getProcessRouteList")
@GetMapping("/getProcessRouteList")
public ResponseEntity<List<ProcessRouteJdDTO> >getProcessRouteList(@RequestParam(value = "materialCode") String materialCode,
@RequestParam(value = "materialName") String materialName,
@RequestParam(value = "productionOrderNo") String productionOrderNo) {
return ResponseEntity.ok(iProcessRouteService.getProcessRouteList(materialCode, materialName, productionOrderNo));
}
@Log(title = "导入时间", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:route:importDataTime")
@PostMapping(value = "/importDataTime", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ -428,8 +444,7 @@ public class ProcessRouteController extends BaseController {
@SaCheckPermission("system:route:getSelectProcessRoute")
@PostMapping("/getSelectProcessRoute")
public List<ProcessRouteSelectDTO> getSelectProcessRoute(@RequestParam String materilCode) {
List<ProcessRouteSelectDTO> list = iProcessRouteService.getSelectProcessRoute(materilCode);
return list;
return iProcessRouteService.getSelectProcessRoute(materilCode);
}
}

View File

@ -22,7 +22,7 @@ public class EleMaterials extends BaseEntity {
/**
*
*/
@TableId(value = "id")
@TableId(value = "ID",type = IdType.AUTO)
private Long id;
/**
* 序号
@ -56,5 +56,8 @@ public class EleMaterials extends BaseEntity {
* 备注
*/
private String remarks;
/**
* 物料值
*/
private String materialValue;
}

View File

@ -0,0 +1,96 @@
package com.ruoyi.system.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 金蝶工段数据对象
*
* @author ruoyi
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("kingdee_work_center_data")
public class KingdeeWorkCenterData extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id",type = IdType.AUTO)
private Long id;
/**
* 生产订单号
*/
private String moBillNo;
/**
* 生产令号
*/
private String moOrderNo;
/**
* 产品编码
*/
private String materialNumber;
/**
* 产品名称
*/
private String materialName;
/**
* 生产数量
*/
private Long operQty;
/**
* 转入数量
*/
private Long transInQty;
/**
* 转出数量
*/
private Long transOutQty;
/**
* 物料状态
*/
private String materialStatus;
/**
* 工序号
*/
private String operNumber;
/**
* 工序名称
*/
private String processName;
/**
* 计划开始时间
*/
private String operPlanStartTime;
/**
* 计划完成时间
*/
private String operPlanFinishTime;
/**
* 延迟天数
*/
private String delayDays;
/**
* 工作中心
*/
private String workCenter;
}

View File

@ -39,7 +39,7 @@ public class ProductionOrder extends BaseEntity {
/**
* 生产数量
*/
private Long quantity;
private Double quantity;
/**
* 生产材料
*/

View File

@ -111,7 +111,7 @@ public class ProductionRouteTwo extends BaseEntity {
/**
* 活动时长
*/
private Long activityLengh;
private Double activityLengh;
/**
* bom材质
*/

View File

@ -22,19 +22,16 @@ public class EleMaterialsBo extends BaseEntity {
/**
*
*/
@NotNull(message = "不能为空", groups = { EditGroup.class })
private Long id;
/**
* 序号
*/
@NotNull(message = "序号不能为空", groups = { AddGroup.class, EditGroup.class })
private Long serialNumber;
/**
* 物料编码
*/
@NotBlank(message = "物料编码不能为空", groups = { AddGroup.class, EditGroup.class })
private String materialCode;
/**
@ -52,13 +49,11 @@ public class EleMaterialsBo extends BaseEntity {
/**
* 材质
*/
@NotBlank(message = "材质不能为空", groups = { AddGroup.class, EditGroup.class })
private String materialType;
/**
* 单位
*/
@NotBlank(message = "单位不能为空", groups = { AddGroup.class, EditGroup.class })
private String unit;
/**
@ -70,8 +65,10 @@ public class EleMaterialsBo extends BaseEntity {
/**
* 备注
*/
@NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
private String remarks;
/**
* 物料值
*/
private String materialValue;
}

View File

@ -0,0 +1,113 @@
package com.ruoyi.system.domain.bo;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.*;
/**
* 金蝶工段数据业务对象 kingdee_work_center_data
*
* @author 田志阳
* @date 2025-01-18
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class KingdeeWorkCenterDataBo extends BaseEntity {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
private Long id;
/**
* 生产订单号
*/
@NotBlank(message = "生产订单号不能为空", groups = { AddGroup.class, EditGroup.class })
private String moBillNo;
/**
* 生产令号
*/
@NotBlank(message = "生产令号不能为空", groups = { AddGroup.class, EditGroup.class })
private String moOrderNo;
/**
* 产品编码
*/
@NotBlank(message = "产品编码不能为空", groups = { AddGroup.class, EditGroup.class })
private String materialNumber;
/**
* 产品名称
*/
@NotBlank(message = "产品名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String materialName;
/**
* 生产数量
*/
@NotNull(message = "生产数量不能为空", groups = { AddGroup.class, EditGroup.class })
private Long operQty;
/**
* 转入数量
*/
@NotNull(message = "转入数量不能为空", groups = { AddGroup.class, EditGroup.class })
private Long transInQty;
/**
* 转出数量
*/
@NotNull(message = "转出数量不能为空", groups = { AddGroup.class, EditGroup.class })
private Long transOutQty;
/**
* 物料状态
*/
@NotBlank(message = "物料状态不能为空", groups = { AddGroup.class, EditGroup.class })
private String materialStatus;
/**
* 工序号
*/
@NotBlank(message = "工序号不能为空", groups = { AddGroup.class, EditGroup.class })
private String operNumber;
/**
* 工序名称
*/
@NotBlank(message = "工序名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String processName;
/**
* 计划开始时间
*/
@NotBlank(message = "计划开始时间不能为空", groups = { AddGroup.class, EditGroup.class })
private String operPlanStartTime;
/**
* 计划完成时间
*/
@NotBlank(message = "计划完成时间不能为空", groups = { AddGroup.class, EditGroup.class })
private String operPlanFinishTime;
/**
* 延迟天数
*/
@NotBlank(message = "延迟天数不能为空", groups = { AddGroup.class, EditGroup.class })
private String delayDays;
/**
* 工作中心
*/
@NotBlank(message = "工作中心不能为空", groups = { AddGroup.class, EditGroup.class })
private String workCenter;
}

View File

@ -34,7 +34,7 @@ public class ProductionOrderBo extends BaseEntity {
/**
* 生产数量
*/
private Long quantity;
private Double quantity;
/**
* 生产材料
*/

View File

@ -155,7 +155,7 @@ public class ProductionRouteTwoBo extends BaseEntity {
* 活动时长
*/
@NotNull(message = "活动时长不能为空", groups = { AddGroup.class, EditGroup.class })
private Long activityLengh;
private Double activityLengh;
/**
* bom材质

View File

@ -0,0 +1,13 @@
package com.ruoyi.system.domain.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class JdEntry {
@JsonProperty("FMATERIALID")
private int FMATERIALID;
@JsonProperty("SubHeadEntity5_FEntryId")
private int FEntryId;
}

View File

@ -0,0 +1,10 @@
package com.ruoyi.system.domain.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class JinYongDTO {
@JsonProperty("FNumber")
private String FNumber;
}

View File

@ -33,4 +33,8 @@ public class ProcessRouteDTO {
* 活动单位
*/
private String activityUnit;
/**
* 工序名称描述
*/
private String processNameDescription;
}

View File

@ -0,0 +1,30 @@
package com.ruoyi.system.domain.dto;
import lombok.Data;
import java.util.List;
@Data
public class ProcessRouteJdDTO {
private Long id;
/**
* 生产令号
*/
private String project_code;
/**
* 工艺编码
*/
private String fnumber;
/**
* 物料编码
*/
private String materialCode;
/**
* 物料名称
*/
private String materialName;
/**
* 工艺路线
*/
private List<ProcessRouteDTO> processRouteDT;
}

View File

@ -15,6 +15,10 @@ public class ProcessRouteXuDTO {
* 物料名称
*/
private String materialName;
/**
* 工序路线描述
*/
private String processDescription;
/**
* 工艺路线
*/

View File

@ -0,0 +1,37 @@
package com.ruoyi.system.domain.dto;
import com.ruoyi.system.domain.KingdeeWorkCenterData;
import java.util.List;
public class WorkCenterResponse {
private Boolean isSuccess;
private String message;
private List<KingdeeWorkCenterData> data;
// Getter Setter 方法
public Boolean getIsSuccess() {
return isSuccess;
}
public void setIsSuccess(Boolean isSuccess) {
this.isSuccess = isSuccess;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<KingdeeWorkCenterData> getData() {
return data;
}
public void setData(List<KingdeeWorkCenterData> data) {
this.data = data;
}
}

View File

@ -72,7 +72,9 @@ public class BomDetailsVo {
*子项数量
*/
@ExcelProperty(value = "子项分子")
private Double quantity;
@ExcelProperty(value = "子项分母")
private Double denominator;
/**

View File

@ -22,56 +22,59 @@ public class EleMaterialsVo {
/**
*
*/
@ExcelProperty(value = "id")
private Long id;
/**
* 序号
*/
@ExcelProperty(value = "序号")
private Long serialNumber;
/**
* 物料编码
*/
@ExcelProperty(value = "物料编码")
@ExcelProperty(value = "产品编码")
private String materialCode;
/**
* 物料名称
*/
@ExcelProperty(value = "物料名称")
// @ExcelProperty(value = "物料名称")
private String materialName;
/**
* 型号
*/
@ExcelProperty(value = "型号")
// @ExcelProperty(value = "型号")
private String model;
/**
* 材质
*/
@ExcelProperty(value = "材质")
// @ExcelProperty(value = "类别")
private String materialType;
/**
* 单位
*/
@ExcelProperty(value = "单位")
// @ExcelProperty(value = "单位")
private String unit;
/**
* 品牌
*/
@ExcelProperty(value = "品牌")
// @ExcelProperty(value = "品牌")
private String brand;
/**
* 备注
*/
@ExcelProperty(value = "备注")
// @ExcelProperty(value = "备注")
private String remarks;
/**
* 物料值
*/
@ExcelProperty(value = "标准人员实作工时")
private String materialValue;
}

View File

@ -0,0 +1,10 @@
package com.ruoyi.system.domain.vo;
import lombok.Data;
import java.util.List;
@Data
public class ExcelVo {
private List<EleMaterialsVo> list;
}

View File

@ -0,0 +1,112 @@
package com.ruoyi.system.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.common.convert.ExcelDictConvert;
import lombok.Data;
/**
* 金蝶工段数据视图对象 kingdee_work_center_data
*
* @author 田志阳
* @date 2025-01-18
*/
@Data
@ExcelIgnoreUnannotated
public class KingdeeWorkCenterDataVo {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 生产订单号
*/
@ExcelProperty(value = "生产订单号")
private String moBillNo;
/**
* 生产令号
*/
@ExcelProperty(value = "生产令号")
private String moOrderNo;
/**
* 产品编码
*/
@ExcelProperty(value = "产品编码")
private String materialNumber;
/**
* 产品名称
*/
@ExcelProperty(value = "产品名称")
private String materialName;
/**
* 生产数量
*/
@ExcelProperty(value = "生产数量")
private Long operQty;
/**
* 转入数量
*/
@ExcelProperty(value = "转入数量")
private Long transInQty;
/**
* 转出数量
*/
@ExcelProperty(value = "转出数量")
private Long transOutQty;
/**
* 物料状态
*/
@ExcelProperty(value = "转出数量")
private String materialStatus;
/**
* 工序号
*/
@ExcelProperty(value = "工序号")
private String operNumber;
/**
* 工序名称
*/
@ExcelProperty(value = "工序名称")
private String processName;
/**
* 计划开始时间
*/
@ExcelProperty(value = "计划开始时间")
private String operPlanStartTime;
/**
* 计划完成时间
*/
@ExcelProperty(value = "计划完成时间")
private String operPlanFinishTime;
/**
* 延迟天数
*/
@ExcelProperty(value = "延迟天数")
private String delayDays;
/**
* 工作中心
*/
@ExcelProperty(value = "工作中心")
private String workCenter;
}

View File

@ -3,6 +3,7 @@ package com.ruoyi.system.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.NumberFormat;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.convert.ExcelDictConvert;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
@ -167,14 +168,14 @@ public class ProcessRouteVo {
* 序开始时间
*/
@ExcelProperty(value = {"计划完成时间","起始日期"},index = 19)
@DateTimeFormat(pattern = "yyyy/MM/dd")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date xuStartTime;
/**
* 序结束时间
*/
@ExcelProperty(value = {"计划完成时间","完成日期"},index = 21)
@DateTimeFormat(pattern = "yyyy/MM/dd")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date xuEndTime;
}

View File

@ -47,7 +47,7 @@ public class ProductionOrderVo {
* 生产数量
*/
@ExcelProperty(value = "数量")
private Long quantity;
private Double quantity;
/**
* 生产材料

View File

@ -157,7 +157,7 @@ public class ProductionRouteTwoVo {
* 活动时长
*/
@ExcelProperty(value = "活动时长")
private Long activityLengh;
private Double activityLengh;
/**
* bom材质

View File

@ -3,6 +3,7 @@ package com.ruoyi.system.mapper;
import com.ruoyi.system.domain.EleMaterials;
import com.ruoyi.system.domain.vo.EleMaterialsVo;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Select;
/**
* 电器物料管理Mapper接口
@ -11,5 +12,6 @@ import com.ruoyi.common.core.mapper.BaseMapperPlus;
* @date 2024-12-28
*/
public interface EleMaterialsMapper extends BaseMapperPlus<EleMaterialsMapper, EleMaterials, EleMaterialsVo> {
@Select("SELECT material_code FROM ele_materials WHERE material_code LIKE CONCAT(#{category}, '%') ORDER BY material_code DESC LIMIT 1")
String getLastMaterialCode(String category);
}

View File

@ -0,0 +1,15 @@
package com.ruoyi.system.mapper;
import com.ruoyi.system.domain.KingdeeWorkCenterData;
import com.ruoyi.system.domain.vo.KingdeeWorkCenterDataVo;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
/**
* 金蝶工段数据Mapper接口
*
* @author 田志阳
* @date 2025-01-18
*/
public interface KingdeeWorkCenterDataMapper extends BaseMapperPlus<KingdeeWorkCenterDataMapper, KingdeeWorkCenterData, KingdeeWorkCenterDataVo> {
}

View File

@ -3,6 +3,7 @@ package com.ruoyi.system.mapper;
import com.ruoyi.system.domain.ProcessRoute;
import com.ruoyi.system.domain.vo.ProcessRouteVo;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
@ -22,7 +23,11 @@ public interface ProcessRouteMapper extends BaseMapperPlus<ProcessRouteMapper, P
// 查询工艺序号是否已经存在根据 materialCode
@Select("SELECT COUNT(1) FROM process_route WHERE process_no = #{processNo} AND material_code = #{materialCode} AND route_description = #{routeDescription}")
boolean existsByProcessNoAndMaterialCode(@Param("processNo") Long processNo, @Param("materialCode") String materialCode,@Param("route_description") String routeDescription);
boolean existsByProcessNoAndMaterialCode(@Param("processNo") Long processNo, @Param("materialCode") String materialCode);
@Delete("DELETE FROM process_route where route_description = #{productionOrderNo}")
Boolean deleteByProCode(@Param("routeDescription") String productionOrderNo);
// 检查工序号是否存在排除自身
@Select("SELECT COUNT(1) FROM process_route WHERE process_no = #{processNo} " +
@ -56,4 +61,6 @@ public interface ProcessRouteMapper extends BaseMapperPlus<ProcessRouteMapper, P
@Param("endNo") Long endNo,
@Param("materialCode") String materialCode,
@Param("routeDescription") String routeDescription);
}

View File

@ -0,0 +1,21 @@
package com.ruoyi.system.runner;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import java.util.Map;
public class CustomMapConverter implements Converter<Map<String, Object>> {
@Override
public Class<?> supportJavaTypeKey() {
return Map.class;
}
@Override
public WriteCellData<?> convertToExcelData(Map<String, Object> value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
// 实现转换逻辑
// 例如 Map 转换为 Excel 单元格数据
return new WriteCellData<>(value.toString());
}
}

View File

@ -9,6 +9,7 @@ import com.google.gson.JsonObject;
import com.kingdee.bos.webapi.entity.RepoRet;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ruoyi.common.utils.JdUtils;
import com.ruoyi.system.controller.EleMaterialsController;
import com.ruoyi.system.domain.BomDetails;
import com.ruoyi.system.domain.MaterialProperties;
import com.ruoyi.system.domain.dto.*;
@ -22,6 +23,8 @@ import com.ruoyi.system.service.IImProductionPlanProService;
import com.ruoyi.system.service.IProcessRouteService;
import org.aspectj.bridge.MessageUtil;
import org.checkerframework.checker.units.qual.A;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Resource;
@ -40,6 +43,8 @@ public class JdUtil {
@Resource
private IImProductionPlanProService imProductionPlanProService;
private static final Logger log = LoggerFactory.getLogger(JdUtil.class);
// 入库状态
public static JsonArray storageProduce(String number, String FMaterialIdCode) {
K3CloudApi client = new K3CloudApi();
@ -729,15 +734,341 @@ public class JdUtil {
for (JsonElement jsonElement : jsonArray) {
String FNumber = jsonElement.getAsJsonObject().get("FNumber").getAsString();
String FName = jsonElement.getAsJsonObject().get("FName").getAsString();
String Funit = jsonElement.getAsJsonObject().get("FBaseUnitId.FNumber").getAsString();
// 检查名称是否一致
if (FNumber.equals(DrawingNumber) && !FName.equals(name)) {
return 3; // 编码相同但名称不同
if (FNumber.equals(DrawingNumber)) {
if (!FName.equals(name)) {
log.warn("编码相同但名称不同: 编码 = {}, 名称 = {}, 查询到的名称 = {}", DrawingNumber, name, FName);
return 3; // 编码相同但名称不同
}
return 1; // 编码和名称都一致
}
}
return 1;
return 1; // 编码未找到返回1表示正常
}
}
/*本接口用于实现物料清单 的禁用功能*/
public static void jtestForbidMaterial(String FNumber) throws Exception {
K3CloudApi api = new K3CloudApi();
String data = "{\"CreateOrgId\": 0,\"Numbers\": ["+"\""+FNumber+"\""+"],\"Ids\": \"\",\"PkEntryIds\":[],\"NetworkCtrl\": \"\",\"IgnoreInterationFlag\": \"\"}";
String result = api.excuteOperation("ENG_BOM", "Forbid", data);
Gson gson = new Gson();
RepoRet repoRet = gson.fromJson(result, RepoRet.class);
if (repoRet.getResult().getResponseStatus().isIsSuccess()) {
System.out.printf("物料禁用接口: %s%n", gson.toJson(repoRet.getResult()));
} else {
fail("物料提交接口: " + gson.toJson(repoRet.getResult()));
}
}
//用料清单查询接口腹肌无聊
public static List<JinYongDTO> getFuji(String materialCode) {
List<JinYongDTO> jinYongDTOS = new ArrayList<>();
K3CloudApi client = new K3CloudApi();
JsonObject json = new JsonObject();
json.addProperty("FormId", "ENG_BOM");
json.addProperty("FieldKeys", "FNumber");
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FMATERIALIDCHILD.FNumber");
filterObject.addProperty("Compare", "=");
filterObject.addProperty("Value", materialCode);
filterObject.addProperty("Left", "");
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);
filterString.add(filterObject);
json.add("FilterString", filterString);
json.addProperty("OrderString", "");
json.addProperty("TopRowCount", 0);
json.addProperty("StartRow", 0);
json.addProperty("Limit", 2000);
json.addProperty("SubSystemId", "");
String jsonData = json.toString();
try {
String resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
if (jsonArray != null && jsonArray.size() > 0) {
ObjectMapper objectMapper = new ObjectMapper();
List<JinYongDTO> JinYongDTOList = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<JinYongDTO>>() {});
if (JinYongDTOList != null && !JinYongDTOList.isEmpty()) {
jinYongDTOS.addAll(JinYongDTOList);
}
} else {
log.warn("未找到与bom版本号 " + materialCode + " 相关的记录");
}
} catch (Exception e) {
log.error("调用接口时发生异常: " + e.getMessage(), e);
}
return jinYongDTOS;
}
//查询物料 FMATERIALID SubHeadEntity5FEntryId
public static List<JdEntry> getEntryID(String materialCode) {
List<JdEntry> jinYongDTOS = new ArrayList<>();
K3CloudApi client = new K3CloudApi();
JsonObject json = new JsonObject();
json.addProperty("FormId", "BD_MATERIAL");
json.addProperty("FieldKeys", "FMATERIALID,SubHeadEntity5_FEntryId");
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FNumber");
filterObject.addProperty("Compare", "=");
filterObject.addProperty("Value", materialCode);
filterObject.addProperty("Left", "");
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);
filterString.add(filterObject);
json.add("FilterString", filterString);
json.addProperty("OrderString", "");
json.addProperty("TopRowCount", 0);
json.addProperty("StartRow", 0);
json.addProperty("Limit", 2000);
json.addProperty("SubSystemId", "");
String jsonData = json.toString();
try {
String resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
if (jsonArray != null && jsonArray.size() > 0) {
ObjectMapper objectMapper = new ObjectMapper();
List<JdEntry> JinYongDTOList = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<JdEntry>>() {});
if (JinYongDTOList != null && !JinYongDTOList.isEmpty()) {
jinYongDTOS.addAll(JinYongDTOList);
}
} else {
log.warn("未找到与bom版本号 " + materialCode + " 相关的记录");
}
} catch (Exception e) {
log.error("调用接口时发生异常: " + e.getMessage(), e);
}
return jinYongDTOS;
}
//修改物料工时,固定单位=
public static void atestSaveMaterial(int FMATERIALID,int fEntryId,String materialCode ,double laborTime) throws Exception {
K3CloudApi api = new K3CloudApi(false);
// 创建主 JSON 对象
JsonObject mainObject = new JsonObject();
// 创建 NeedUpDateFields 数组
JsonArray needUpdateFields = new JsonArray();
needUpdateFields.add("SubHeadEntity5");
needUpdateFields.add("FStdLaborProcessTime");
needUpdateFields.add("FMATERIALID");
needUpdateFields.add("FStandHourUnitId");
// 创建 NeedReturnFields 数组
JsonArray needReturnFields = new JsonArray();
needReturnFields.add("SubHeadEntity5_FEntryId");
needReturnFields.add("FStdLaborProcessTime");
needReturnFields.add("FNumber");
// 设置 IsDeleteEntry 字段
mainObject.addProperty("IsDeleteEntry", "false");
// 创建 Model 对象
JsonObject modelObject = new JsonObject();
modelObject.addProperty("FMATERIALID", FMATERIALID);
modelObject.addProperty("FNumber", materialCode);
// 创建 SubHeadEntity5 对象
JsonObject subHeadEntity5 = new JsonObject();
subHeadEntity5.addProperty("FEntryId", fEntryId);
subHeadEntity5.addProperty("FStdLaborProcessTime", laborTime);
subHeadEntity5.addProperty("FStandHourUnitId", "60");
// SubHeadEntity5 添加到 Model 对象
modelObject.add("SubHeadEntity5", subHeadEntity5);
// NeedUpDateFields NeedReturnFields 添加到主对象
mainObject.add("NeedUpDateFields", needUpdateFields);
mainObject.add("NeedReturnFields", needReturnFields);
// Model 添加到主对象
mainObject.add("Model", modelObject);
String data = mainObject.toString();
String result = api.save("BD_Material", data);
Gson gson = new Gson();
RepoRet sRet = gson.fromJson(result, RepoRet.class);
if (sRet.isSuccessfully()) {
System.out.printf("物料保存接口: %s%n", gson.toJson(sRet.getResult()));
} else {
fail("物料保存接口: " + gson.toJson(sRet.getResult()));
}
}
//新增父级物料
public static int loadChengPinMaterialPreservation(BomDetails bomDetail) {
K3CloudApi client = new K3CloudApi();
// 创建一个空的JsonObject
JsonObject json = new JsonObject();
// 添加IsAutoSubmitAndAudit字段
json.addProperty("IsAutoSubmitAndAudit", "true");
// 创建Model对象并加入JsonObject
JsonObject model = new JsonObject();
json.add("Model", model);
// 添加Model字段
model.addProperty("FMATERIALID", 0);
model.addProperty("FNumber", bomDetail.getFNumber());
model.addProperty("FName", bomDetail.getFName());
// 创建FMaterialGroup对象并加入Model
JsonObject fMaterialGroup = new JsonObject();
fMaterialGroup.addProperty("FNumber", "A000106");
model.add("FMaterialGroup", fMaterialGroup);
model.addProperty("FIsHandleReserve", true);
// 创建SubHeadEntity对象并加入Model
JsonObject subHeadEntity = new JsonObject();
model.add("SubHeadEntity", subHeadEntity);
subHeadEntity.addProperty("FErpClsID", "2");
subHeadEntity.addProperty("FFeatureItem", "1");
// 创建FCategoryID对象并加入SubHeadEntity
JsonObject fCategoryID = new JsonObject();
fCategoryID.addProperty("FNumber", "CHLB05_SYS");// 产成品
subHeadEntity.add("FCategoryID", fCategoryID);
// 创建FTaxRateId对象并加入SubHeadEntity
JsonObject fTaxRateId = new JsonObject();
fTaxRateId.addProperty("FNUMBER", "SL02_SYS");
subHeadEntity.add("FTaxRateId", fTaxRateId);
// 创建FBaseUnitId对象并加入SubHeadEntity
JsonObject fBaseUnitId = new JsonObject();
fBaseUnitId.addProperty("FNumber", "008");
subHeadEntity.add("FBaseUnitId", fBaseUnitId);
subHeadEntity.addProperty("FIsPurchase", true);
subHeadEntity.addProperty("FIsInventory", true);
// 成品不允许委外
// subHeadEntity.addProperty("FIsSubContract", true);
subHeadEntity.addProperty("FIsSale", true);
subHeadEntity.addProperty("FIsProduce", true);
// 创建SubHeadEntity1对象并加入Model
JsonObject subHeadEntity1 = new JsonObject();
model.add("SubHeadEntity1", subHeadEntity1);
JsonObject fStoreUnitId = new JsonObject();
fStoreUnitId.addProperty("FNumber", "008");
subHeadEntity1.add("FStoreUnitID", fStoreUnitId);
subHeadEntity1.addProperty("FUnitConvertDir", "1");
// 创建FStockId对象并加入SubHeadEntity1
JsonObject fStockId = new JsonObject();
// 判断是产成品还是企标
String cangKu = "CK011";
fStockId.addProperty("FNumber", cangKu);
subHeadEntity1.add("FStockId", fStockId);
// 创建FCurrencyId对象并加入SubHeadEntity1
JsonObject fCurrencyId = new JsonObject();
fCurrencyId.addProperty("FNumber", "PRE001");
subHeadEntity1.add("FCurrencyId", fCurrencyId);
subHeadEntity1.addProperty("FIsSNPRDTracy", false);
subHeadEntity1.addProperty("FSNManageType", "1");
subHeadEntity1.addProperty("FSNGenerateTime", "1");
subHeadEntity1.addProperty("FBoxStandardQty", 0.0);
// 创建FPurchaseUnitId对象并加入SubHeadEntity1
JsonObject fPurchaseUnitId = new JsonObject();
fPurchaseUnitId.addProperty("FNumber", "008");
subHeadEntity1.add("FPurchaseUnitId", fPurchaseUnitId);
// 创建SubHeadEntity3对象并加入Model
JsonObject subHeadEntity3 = new JsonObject();
model.add("SubHeadEntity3", subHeadEntity3);
/*
* // 创建FPurchaseUnitId对象并加入SubHeadEntity3
* JsonObject fPurchaseUnitId = new JsonObject();
* fPurchaseUnitId.addProperty("FNumber", "008");
* subHeadEntity3.add("FPurchaseUnitId", fPurchaseUnitId);
*/
// 创建FPurchasePriceUnitId对象并加入SubHeadEntity3
JsonObject fPurchasePriceUnitId = new JsonObject();
fPurchasePriceUnitId.addProperty("FNumber", "008");
subHeadEntity3.add("FPurchasePriceUnitId", fPurchasePriceUnitId);
subHeadEntity3.addProperty("FIsQuota", false);
subHeadEntity3.addProperty("FQuotaType", "1");
// 创建SubHeadEntity6对象并加入Model 检验项
JsonObject subHeadEntity6 = new JsonObject();
model.add("SubHeadEntity6", subHeadEntity6);
subHeadEntity6.addProperty("FCheckProduct", true);
subHeadEntity6.addProperty("FCheckReturn", true);
// 创建SubHeadEntity5对象并加入Model
JsonObject subHeadEntity5 = new JsonObject();
model.add("SubHeadEntity5", subHeadEntity5);
// 创建FProduceUnitId对象并加入SubHeadEntity5
JsonObject fProduceUnitId = new JsonObject();
fProduceUnitId.addProperty("FNumber", "008");
subHeadEntity5.add("FProduceUnitId", fProduceUnitId);
// 创建FProduceBillType对象并加入SubHeadEntity5
JsonObject fProduceBillType = new JsonObject();
fProduceBillType.addProperty("FNUMBER", "SCDD05_SYS");
subHeadEntity5.add("FProduceBillType", fProduceBillType);
// 创建FBOMUnitId对象并加入SubHeadEntity5
JsonObject fBOMUnitId = new JsonObject();
fBOMUnitId.addProperty("FNumber", "008");
subHeadEntity5.add("FBOMUnitId", fBOMUnitId);
subHeadEntity5.addProperty("FIsMainPrd", true);
subHeadEntity5.addProperty("FIssueType", "1");
// 创建FPickStockId对象并加入SubHeadEntity5
JsonObject fPickStockId = new JsonObject();
fPickStockId.addProperty("FNumber", "CK012");
subHeadEntity1.add("FPickStockId", fPickStockId);
subHeadEntity5.addProperty("FOverControlMode", "1");
subHeadEntity5.addProperty("FStandHourUnitId", "3600");
subHeadEntity5.addProperty("FBackFlushType", "1");
String jsonData = json.toString();
System.out.println(jsonData);
try {
// 业务对象标识
String formId = "BD_MATERIAL";
// 调用接口
String resultJson = client.save(formId, jsonData);
// 用于记录结果
Gson gson = new Gson();
// 对返回结果进行解析和校验
RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
if (repoRet.getResult().getResponseStatus().isIsSuccess()) {
System.out.printf("接口返回结果: %s%n", gson.toJson(repoRet.getResult()));
log.debug("接口返回结果: %s%n" + gson.toJson(repoRet.getResult()));
return 1;
} else {
MessageUtil.fail("接口返回结果: " + gson.toJson(repoRet.getResult().getResponseStatus()));
log.error("接口返回结果: " + gson.toJson(repoRet.getResult().getResponseStatus()));
return 0;
}
} catch (Exception e) {
MessageUtil.fail(e.getMessage());
return 0;
}
}
}

View File

@ -97,7 +97,7 @@ public class PDFGenerator {
}
public static String writeToPdf(List<CombinedDTO> combinedVoList, String rooteProdet) {
String fontPath = "C:\\Windows\\Fonts\\arial unicode ms.ttf";
String fontPath = "C:\\Users\\Administrator\\Desktop\\arial unicode ms.ttf";
List<String> pdfPaths = new ArrayList<>();
String directoryPath = "D:\\上传BOM\\" + rooteProdet;
// 检查目录是否存在如果不存在则创建

View File

@ -6,6 +6,7 @@ import com.ruoyi.system.domain.bo.EleMaterialsBo;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.List;
@ -46,4 +47,8 @@ public interface IEleMaterialsService {
* 校验并批量删除电器物料管理信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
List<EleMaterials> addToJindie();
boolean saveData(List<EleMaterialsVo> list, HttpServletResponse response);
}

View File

@ -0,0 +1,49 @@
package com.ruoyi.system.service;
import com.ruoyi.system.domain.KingdeeWorkCenterData;
import com.ruoyi.system.domain.vo.KingdeeWorkCenterDataVo;
import com.ruoyi.system.domain.bo.KingdeeWorkCenterDataBo;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 金蝶工段数据Service接口
*
* @author 田志阳
* @date 2025-01-18
*/
public interface IKingdeeWorkCenterDataService {
/**
* 查询金蝶工段数据
*/
KingdeeWorkCenterDataVo queryById(Long id);
/**
* 查询金蝶工段数据列表
*/
TableDataInfo<KingdeeWorkCenterDataVo> queryPageList(KingdeeWorkCenterDataBo bo, PageQuery pageQuery);
/**
* 查询金蝶工段数据列表
*/
List<KingdeeWorkCenterDataVo> queryList(KingdeeWorkCenterDataBo bo);
/**
* 新增金蝶工段数据
*/
Boolean insertByBo(KingdeeWorkCenterDataBo bo);
/**
* 修改金蝶工段数据
*/
Boolean updateByBo(KingdeeWorkCenterDataBo bo);
/**
* 校验并批量删除金蝶工段数据信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@ -1,6 +1,6 @@
package com.ruoyi.system.service;
import com.ruoyi.system.domain.ProcessOrderPro;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.system.domain.ProcessRoute;
import com.ruoyi.system.domain.vo.ProcessOrderProVo;
import com.ruoyi.system.domain.bo.ProcessOrderProBo;
@ -46,7 +46,7 @@ public interface IProcessOrderProService {
/**
* 校验并批量删除项目令号信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
R<Void> deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
List<ProcessRoute> selectProList(ProcessOrderProBo bo);
}

View File

@ -3,19 +3,18 @@ package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.domain.BomDetails;
import com.ruoyi.system.domain.MaterialBom;
import com.ruoyi.system.domain.ProcessRoute;
import com.ruoyi.system.domain.bo.ProcessRouteBo;
import com.ruoyi.system.domain.dto.CombinedDTO;
import com.ruoyi.system.domain.dto.ProcessRoutePushResultDTO;
import com.ruoyi.system.domain.dto.ProcessRouteSelectDTO;
import com.ruoyi.system.domain.dto.*;
import com.ruoyi.system.jdmain.rouplan.Model;
import com.ruoyi.system.domain.dto.ProcessRouteXuDTO;
import com.ruoyi.system.domain.vo.ProcessRouteVo;
import com.ruoyi.system.domain.vo.ProductionOrderVo;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 工艺路线Service接口
@ -34,6 +33,7 @@ public interface IProcessRouteService {
* 查询工艺路线列表
*/
TableDataInfo<ProcessRouteVo> queryPageList(ProcessRouteBo bo, PageQuery pageQuery);
TableDataInfo<ProcessRouteVo> queryPageList2(ProcessRouteBo bo, PageQuery pageQuery);
/**
@ -97,4 +97,12 @@ public interface IProcessRouteService {
boolean isAnTuDingGou(String materialCode);
List<ProcessRouteSelectDTO> getSelectProcessRoute(String materilCode);
//根据项目令号删除 材料bom 总装bom 工艺路线
R<Void> selectByProjectCode(String productionOrderNo);
List<ProcessRouteJdDTO> getProcessRouteList(String materialCode, String materialName, String productionOrderNo);
//获取物料的非委外的工作时长
Double getFbWorkTime(BomDetails material);
//根据令号和物料编码 查询工艺路线
List<ProcessRoute> getProcessRoutesByOrder(String productionOrderNo, String materialCode);
}

View File

@ -96,7 +96,7 @@ public class BomDetailsServiceImpl implements IBomDetailsService {
lqw.like(StringUtils.isNotBlank(bo.getFNumber()), BomDetails::getFNumber, bo.getFNumber());
lqw.eq(StringUtils.isNotBlank(bo.getMaterial()), BomDetails::getMaterial, bo.getMaterial());
lqw.eq(StringUtils.isNotBlank(bo.getUnitWeight()), BomDetails::getUnitWeight, bo.getUnitWeight());
lqw.like(StringUtils.isNotBlank(bo.getTotalWeight()), BomDetails::getTotalWeight, bo.getTotalWeight());
lqw.eq(StringUtils.isNotBlank(bo.getTotalWeight()), BomDetails::getTotalWeight, bo.getTotalWeight());
lqw.eq(StringUtils.isNotBlank(bo.getRemarks()), BomDetails::getRemarks, bo.getRemarks());
lqw.like(StringUtils.isNotBlank(bo.getFName()), BomDetails::getFName, bo.getFName());
lqw.eq(StringUtils.isNotBlank(bo.getStats()), BomDetails::getStats, bo.getStats());
@ -189,7 +189,7 @@ public class BomDetailsServiceImpl implements IBomDetailsService {
@Override
public List<BomDetails> selectByFNumberAndTotalWeight(String fnumber, String totalWeight) {
LambdaQueryWrapper<BomDetails> bomDetailsLambdaQueryWrapper = new LambdaQueryWrapper<>();
bomDetailsLambdaQueryWrapper.eq(BomDetails::getTotalWeight,totalWeight)
bomDetailsLambdaQueryWrapper.eq(BomDetails::getTotalWeight,totalWeight)
.eq(BomDetails::getFNumber,fnumber);
return baseMapper.selectList(bomDetailsLambdaQueryWrapper);
}

View File

@ -1,12 +1,24 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.kingdee.bos.webapi.entity.RepoRet;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.MaterialProperties;
import com.ruoyi.system.runner.JdUtil;
import com.ruoyi.system.service.IMaterialPropertiesService;
import com.ruoyi.system.service.ISysDictDataService;
import lombok.RequiredArgsConstructor;
import org.aspectj.bridge.MessageUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.ruoyi.system.domain.bo.EleMaterialsBo;
import com.ruoyi.system.domain.vo.EleMaterialsVo;
@ -14,9 +26,12 @@ import com.ruoyi.system.domain.EleMaterials;
import com.ruoyi.system.mapper.EleMaterialsMapper;
import com.ruoyi.system.service.IEleMaterialsService;
import com.ruoyi.common.utils.StringUtils;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import com.alibaba.excel.EasyExcel;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;
/**
* 电器物料管理Service业务层处理
@ -29,7 +44,9 @@ import java.util.Collection;
public class EleMaterialsServiceImpl implements IEleMaterialsService {
private final EleMaterialsMapper baseMapper;
private final IMaterialPropertiesService iMaterialPropertiesService;
private static final Logger log = LoggerFactory.getLogger(IEleMaterialsService.class);
private final ISysDictDataService dictDataService;
/**
* 查询电器物料管理
*/
@ -61,26 +78,40 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<EleMaterials> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getSerialNumber() != null, EleMaterials::getSerialNumber, bo.getSerialNumber());
lqw.eq(StringUtils.isNotBlank(bo.getMaterialCode()), EleMaterials::getMaterialCode, bo.getMaterialCode());
lqw.like(StringUtils.isNotBlank(bo.getMaterialCode()), EleMaterials::getMaterialCode, bo.getMaterialCode());
lqw.like(StringUtils.isNotBlank(bo.getMaterialName()), EleMaterials::getMaterialName, bo.getMaterialName());
lqw.eq(StringUtils.isNotBlank(bo.getModel()), EleMaterials::getModel, bo.getModel());
lqw.like(StringUtils.isNotBlank(bo.getModel()), EleMaterials::getModel, bo.getModel());
lqw.eq(StringUtils.isNotBlank(bo.getMaterialType()), EleMaterials::getMaterialType, bo.getMaterialType());
lqw.eq(StringUtils.isNotBlank(bo.getUnit()), EleMaterials::getUnit, bo.getUnit());
lqw.eq(StringUtils.isNotBlank(bo.getBrand()), EleMaterials::getBrand, bo.getBrand());
lqw.like(StringUtils.isNotBlank(bo.getBrand()), EleMaterials::getBrand, bo.getBrand());
lqw.eq(StringUtils.isNotBlank(bo.getRemarks()), EleMaterials::getRemarks, bo.getRemarks());
lqw.eq(bo.getMaterialValue() != null, EleMaterials::getMaterialValue, bo.getMaterialValue());
return lqw;
}
/**
* 新增电器物料管理
*/
@Override
public Boolean insertByBo(EleMaterialsBo bo) {
EleMaterials add = BeanUtil.toBean(bo, EleMaterials.class);
//物料编码自动新增
//查询 是否有相同的物料编码 规格 品牌
// 查询是否有相同的物料编码
String category = add.getMaterialType(); // 获取类别
String lastCode = baseMapper.getLastMaterialCode(category); // 查询数据库中最后的编码
// 生成新的物料编码
if (lastCode != null) {
String newCode = generateNextMaterialCode(lastCode, category);
add.setMaterialCode(newCode);
} else {
add.setMaterialCode(category + "0000000001"); // 如果没有设置为第一个编码
}
int verification = JdUtil.isMaterialVerification(add.getMaterialCode(), add.getMaterialName());
if (verification == 1) {
add.setMaterialValue("1");
} else if (verification == 3) {
add.setMaterialValue("3");
log.warn("物料编码相同但名称不同: 编码 = {}, 名称 = {}", add.getMaterialCode(), add.getMaterialName());
} else if (verification == 0) {
add.setMaterialValue("0");
}
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
@ -89,6 +120,24 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
return flag;
}
private String generateNextMaterialCode(String lastCode, String category) {
// 提取数字部分
String numberPart = lastCode.substring(2); // 获取数字部分
long nextNumber;
try {
// 只提取数字部分并转换为 long
nextNumber = Long.parseLong(numberPart) + 1; // 生成下一个数字
} catch (NumberFormatException e) {
// 处理无法解析的情况
log.error("物料编码格式错误: " + lastCode, e);
throw new IllegalArgumentException("物料编码格式错误: " + lastCode);
}
// 确保后面的数字部分总共为 12
String formattedNumber = String.format("%010d", nextNumber); // 10位数字 + 1 位前缀
return category + formattedNumber; // 拼接 category 和格式化后的数字
}
/**
* 修改电器物料管理
*/
@ -102,8 +151,27 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(EleMaterials entity){
//TODO 做一些数据校验,如唯一约束
private void validEntityBeforeSave(EleMaterials entity) {
// 检查名称型号品牌和备注是否为空
if (StringUtils.isBlank(entity.getMaterialName()) ||
StringUtils.isBlank(entity.getModel()) ||
StringUtils.isBlank(entity.getBrand())) {
throw new IllegalArgumentException("名称、型号、品牌不能为空");
}
// 查询数据库中是否存在相同的记录
LambdaQueryWrapper<EleMaterials> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(EleMaterials::getMaterialName, entity.getMaterialName())
.eq(EleMaterials::getModel, entity.getModel())
.eq(EleMaterials::getMaterialType, entity.getMaterialType())
.eq(EleMaterials::getBrand, entity.getBrand());
// 如果存在相同的记录则抛出异常
Long count = baseMapper.selectCount(queryWrapper);
if (count > 0) {
log.warn("尝试新增物料失败,已存在相同的物料记录: {}", entity);
throw new IllegalArgumentException("已存在相同的物料记录,无法新增");
}
}
/**
@ -116,4 +184,554 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
}
return baseMapper.deleteBatchIds(ids) > 0;
}
/**
* @return
*/
@Override
public List<EleMaterials> addToJindie() {
LambdaQueryWrapper<EleMaterials> wra = new LambdaQueryWrapper<>();
wra.eq(EleMaterials::getMaterialValue, "0");
List<EleMaterials> newMaterials = baseMapper.selectList(wra);
List<EleMaterials> newMaterialsVos = new ArrayList<>();
if (!newMaterials.isEmpty()) {
for (EleMaterials eleMaterials : newMaterials) {
// 确保 materialValue 不为 null
if ("0".equals(eleMaterials.getMaterialValue()) || "1".equals(eleMaterials.getMaterialValue())) {
// 属性判断
String states;
// 判断品牌
if (StringUtils.isBlank(eleMaterials.getBrand())) {
// 品牌为空时默认状态为1
states = "1";
} else if (eleMaterials.getBrand().contains("伊特")) {
// 品牌为伊特时状态为2
states = "2";
} else {
// 其他品牌状态为1
states = "1";
}
int result = loadMaterialToDQ(eleMaterials, states);
if (result == 1) {
// 直接更新数据库
EleMaterials updateMaterial = new EleMaterials();
updateMaterial.setId(eleMaterials.getId());
updateMaterial.setMaterialValue("1");
updateMaterial.setRemarks("已推送");
// 更新数据库并检查更新结果
if (baseMapper.updateById(updateMaterial) > 0) {
// 更新对象状态并添加到返回列表
eleMaterials.setMaterialValue("1");
eleMaterials.setRemarks("已推送");
newMaterialsVos.add(eleMaterials);
} else {
log.error("更新物料失败物料ID: " + eleMaterials.getId());
}
}
}
}
} else {
log.warn("未找到符合条件的物料");
}
return newMaterialsVos;
}
/**
* @param list
* @param response
* @return
*/
@Override
public boolean saveData(List<EleMaterialsVo> list, HttpServletResponse response) {
Collection<EleMaterials> eleMaterialsList = new ArrayList<>();
List<EleMaterialsVo> allMaterialsList = new ArrayList<>(); // 用于导出所有物料
// 获取表中的已有的数据
log.info("开始获取表中的已有的数据");
for (EleMaterialsVo newMaterialsVo : list) {
// 根据名称型号类别和品牌查询数据库
LambdaQueryWrapper<EleMaterials> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(EleMaterials::getMaterialName, newMaterialsVo.getMaterialName())
.eq(EleMaterials::getModel, newMaterialsVo.getModel())
.eq(EleMaterials::getMaterialType, newMaterialsVo.getMaterialType())
.eq(EleMaterials::getBrand, newMaterialsVo.getBrand());
// 查询是否存在相同的物料
EleMaterials existingMaterial = baseMapper.selectOne(queryWrapper);
EleMaterialsVo eleMaterialsVo = BeanUtil.copyProperties(existingMaterial, EleMaterialsVo.class);
// 处理物料逻辑
if (eleMaterialsVo != null) {
// 如果存在将已有的物料编码加入列表
log.info("查询是否存在的物料: {}", eleMaterialsVo.getMaterialCode());
newMaterialsVo.setMaterialCode(eleMaterialsVo.getMaterialCode());
// 仅添加已存在的物料到导出列表
allMaterialsList.add(eleMaterialsVo); // 添加到导出列表
} else {
// 如果不存在生成新的物料编码
String lastCode = baseMapper.getLastMaterialCode(newMaterialsVo.getMaterialType()); // 查询数据库中最后的编码
String newCode = generateNextMaterialCode(lastCode, newMaterialsVo.getMaterialType());
newMaterialsVo.setMaterialCode(newCode);
EleMaterials eleMaterials = BeanUtil.copyProperties(newMaterialsVo, EleMaterials.class);
// 仅在有编码的情况下添加到插入列表和导出列表
eleMaterialsList.add(eleMaterials); // 添加到插入列表
allMaterialsList.add(newMaterialsVo); // 添加到导出列表
}
}
// 批量插入物料数据
log.info("开始批量插入物料数据");
boolean flag = baseMapper.insertBatch(eleMaterialsList);
// 导出数据为 Excel 文件
log.info("开始导出数据为 Excel 文件");
ExcelUtil.exportExcel(allMaterialsList, "电气物料BOM", EleMaterialsVo.class, response);
// exportToExcel(allMaterialsList, response, "副本电气库房库存整理V3(1)"); // 导出所有物料
return flag;
}
// 导出数据为 Excel 文件的方法
private void exportToExcel(List<EleMaterialsVo> materials, HttpServletResponse response, String fileName) {
// 设置响应头
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + ".xlsx\"");
try (OutputStream outputStream = response.getOutputStream()) {
// 使用 EasyExcel 进行写入
EasyExcel.write(outputStream, EleMaterials.class)
.sheet("电气物料BOM")
.doWrite(materials);
} catch (IOException e) {
log.error("导出 Excel 文件时发生错误: ", e);
throw new RuntimeException("导出 Excel 文件失败", e);
} catch (Exception e) {
log.error("导出 Excel 发生未知错误: ", e);
throw new RuntimeException("导出 Excel 发生未知错误", e);
}
}
public int loadMaterialToDQ(EleMaterials newMaterial, String states) {
K3CloudApi client = new K3CloudApi();
// 创建一个空的JsonObject
JsonObject json = new JsonObject();
// 添加IsAutoSubmitAndAudit字段
json.addProperty("IsAutoSubmitAndAudit", "true");
// 创建Model对象并加入JsonObject
JsonObject model = new JsonObject();
json.add("Model", model);
// 添加Model字段
model.addProperty("FMATERIALID", 0);
model.addProperty("F_HBYT_PP", newMaterial.getBrand());//品牌
model.addProperty("FSpecification", newMaterial.getModel());// 备注仓库
model.addProperty("FNumber", newMaterial.getMaterialCode());
model.addProperty("FName", newMaterial.getMaterialName());
MaterialProperties materialProperties = iMaterialPropertiesService.selectByAttribute(newMaterial.getMaterialType());
if (materialProperties != null) {
JsonObject FSVRIAssistant = new JsonObject();
FSVRIAssistant.addProperty("FNumber", materialProperties.getMaterialAttributeId());
model.add("F_SVRI_Assistant", FSVRIAssistant);
} else {
// 没写材料为默认为空
JsonObject FSVRIAssistant = new JsonObject();
FSVRIAssistant.addProperty("FNumber", "17");
model.add("F_SVRI_Assistant", FSVRIAssistant);
}
// 创建FMaterialGroup对象并加入Model
JsonObject fMaterialGroup = new JsonObject();
fMaterialGroup.addProperty("FNumber", "YT100.01");
model.add("FMaterialGroup", fMaterialGroup);
model.addProperty("FIsHandleReserve", true);
// 创建SubHeadEntity对象并加入Model
JsonObject subHeadEntity = new JsonObject();
model.add("SubHeadEntity", subHeadEntity);
subHeadEntity.addProperty("FErpClsID", states);
subHeadEntity.addProperty("FFeatureItem", "1");
// 创建FCategoryID对象并加入SubHeadEntity
JsonObject fCategoryID = new JsonObject();
if (states.equals("2") || states.equals("3")) {
fCategoryID.addProperty("FNumber", "007");
} else {
fCategoryID.addProperty("FNumber", "006");
}
subHeadEntity.add("FCategoryID", fCategoryID);
// 创建FTaxRateId对象并加入SubHeadEntity
JsonObject fTaxRateId = new JsonObject();
fTaxRateId.addProperty("FNUMBER", "SL02_SYS");
subHeadEntity.add("FTaxRateId", fTaxRateId);
// 创建FBaseUnitId对象并加入SubHeadEntity
JsonObject fBaseUnitId = new JsonObject();
switch (newMaterial.getUnit()) {// 单位
case "":
fBaseUnitId.addProperty("FNumber", "002");
break;
case "":
fBaseUnitId.addProperty("FNumber", "012");
break;
case "":
fBaseUnitId.addProperty("FNumber", "001");
break;
case "":
fBaseUnitId.addProperty("FNumber", "003");
break;
case "":
fBaseUnitId.addProperty("FNumber", "005");
break;
case "":
fBaseUnitId.addProperty("FNumber", "020");
break;
case "":
fBaseUnitId.addProperty("FNumber", "014");
break;
case "":
fBaseUnitId.addProperty("FNumber", "jian");
break;
case "":
fBaseUnitId.addProperty("FNumber", "011");
break;
case "":
fBaseUnitId.addProperty("FNumber", "016");
break;
case "":
fBaseUnitId.addProperty("FNumber", "017");
break;
case "":
fBaseUnitId.addProperty("FNumber", "007");
break;
}
subHeadEntity.add("FBaseUnitId", fBaseUnitId);
if (states.equals("1")) {
subHeadEntity.addProperty("FIsPurchase", true);
subHeadEntity.addProperty("FIsSale", true);
subHeadEntity.addProperty("FIsInventory", true);
} else {
subHeadEntity.addProperty("FIsPurchase", true);
subHeadEntity.addProperty("FIsInventory", true);
subHeadEntity.addProperty("FIsSubContract", true);
subHeadEntity.addProperty("FIsSale", true);
subHeadEntity.addProperty("FIsProduce", true);
}
// 创建SubHeadEntity1对象并加入Model
JsonObject subHeadEntity1 = new JsonObject();
model.add("SubHeadEntity1", subHeadEntity1);
JsonObject fStoreUnitId = new JsonObject();
switch (newMaterial.getUnit()) {
case "":
fBaseUnitId.addProperty("FNumber", "002");
break;
case "":
fBaseUnitId.addProperty("FNumber", "012");
break;
case "":
fBaseUnitId.addProperty("FNumber", "001");
break;
case "":
fBaseUnitId.addProperty("FNumber", "003");
break;
case "":
fBaseUnitId.addProperty("FNumber", "005");
break;
case "":
fBaseUnitId.addProperty("FNumber", "020");
break;
case "":
fBaseUnitId.addProperty("FNumber", "014");
break;
case "":
fBaseUnitId.addProperty("FNumber", "jian");
break;
case "":
fBaseUnitId.addProperty("FNumber", "011");
break;
case "":
fBaseUnitId.addProperty("FNumber", "016");
break;
case "":
fBaseUnitId.addProperty("FNumber", "017");
break;
case "":
fBaseUnitId.addProperty("FNumber", "007");
break;
}
subHeadEntity1.add("FStoreUnitID", fStoreUnitId);
subHeadEntity1.addProperty("FUnitConvertDir", "1");
// 创建FStockId对象并加入SubHeadEntity1
// 仓库代码为 半成品库007
JsonObject fStockId = new JsonObject();
fStockId.addProperty("FNumber", "007");
subHeadEntity1.add("FStockId", fStockId);
// 创建FCurrencyId对象并加入SubHeadEntity1
JsonObject fCurrencyId = new JsonObject();
fCurrencyId.addProperty("FNumber", "PRE001");
subHeadEntity1.add("FCurrencyId", fCurrencyId);
subHeadEntity1.addProperty("FIsSNPRDTracy", false);
subHeadEntity1.addProperty("FSNManageType", "1");
subHeadEntity1.addProperty("FSNGenerateTime", "1");
subHeadEntity1.addProperty("FBoxStandardQty", 0.0);
// 创建FPurchaseUnitId对象并加入SubHeadEntity1
JsonObject fPurchaseUnitId = new JsonObject();
switch (newMaterial.getUnit()) {
case "":
fBaseUnitId.addProperty("FNumber", "002");
break;
case "":
fBaseUnitId.addProperty("FNumber", "012");
break;
case "":
fBaseUnitId.addProperty("FNumber", "001");
break;
case "":
fBaseUnitId.addProperty("FNumber", "003");
break;
case "":
fBaseUnitId.addProperty("FNumber", "005");
break;
case "":
fBaseUnitId.addProperty("FNumber", "020");
break;
case "":
fBaseUnitId.addProperty("FNumber", "014");
break;
case "":
fBaseUnitId.addProperty("FNumber", "jian");
break;
case "":
fBaseUnitId.addProperty("FNumber", "011");
break;
case "":
fBaseUnitId.addProperty("FNumber", "016");
break;
case "":
fBaseUnitId.addProperty("FNumber", "017");
break;
case "":
fBaseUnitId.addProperty("FNumber", "007");
break;
}
subHeadEntity1.add("FPurchaseUnitId", fPurchaseUnitId);
// 创建SubHeadEntity3对象并加入Model
JsonObject subHeadEntity3 = new JsonObject();
model.add("SubHeadEntity3", subHeadEntity3);
// 创建FPurchasePriceUnitId对象并加入SubHeadEntity3
JsonObject fPurchasePriceUnitId = new JsonObject();
switch (newMaterial.getUnit()) {
case "":
fBaseUnitId.addProperty("FNumber", "002");
break;
case "":
fBaseUnitId.addProperty("FNumber", "012");
break;
case "":
fBaseUnitId.addProperty("FNumber", "001");
break;
case "":
fBaseUnitId.addProperty("FNumber", "003");
break;
case "":
fBaseUnitId.addProperty("FNumber", "005");
break;
case "":
fBaseUnitId.addProperty("FNumber", "020");
break;
case "":
fBaseUnitId.addProperty("FNumber", "014");
break;
case "":
fBaseUnitId.addProperty("FNumber", "jian");
break;
case "":
fBaseUnitId.addProperty("FNumber", "011");
break;
case "":
fBaseUnitId.addProperty("FNumber", "016");
break;
case "":
fBaseUnitId.addProperty("FNumber", "017");
break;
case "":
fBaseUnitId.addProperty("FNumber", "007");
break;
}
subHeadEntity3.add("FPurchasePriceUnitId", fPurchasePriceUnitId);
subHeadEntity3.addProperty("FIsQuota", false);
subHeadEntity3.addProperty("FQuotaType", "1");
JsonObject subHeadEntity6 = new JsonObject();
model.add("SubHeadEntity6", subHeadEntity6);
// 不同的属性不同的检验方案
if (states.equals("1")) {
// 外购
subHeadEntity6.addProperty("FCheckIncoming", true);
subHeadEntity6.addProperty("FCheckStock", true);
}
if (states.equals("2")) {
// 自制
subHeadEntity6.addProperty("FCheckProduct", true);
subHeadEntity6.addProperty("FCheckStock", true);
subHeadEntity6.addProperty("FCheckReturnMtrl", true);
}
if (states.equals("3")) {
// 委外
subHeadEntity6.addProperty("FCheckIncoming", true);
subHeadEntity6.addProperty("FCheckProduct", true);
subHeadEntity6.addProperty("FCheckReturnMtrl", true);
}
subHeadEntity6.addProperty("FCheckStock", true);
// 创建SubHeadEntity5对象并加入Model
JsonObject subHeadEntity5 = new JsonObject();
model.add("SubHeadEntity5", subHeadEntity5);
// 创建FProduceUnitId对象并加入SubHeadEntity5
JsonObject fProduceUnitId = new JsonObject();
switch (newMaterial.getUnit()) {
case "":
fBaseUnitId.addProperty("FNumber", "002");
break;
case "":
fBaseUnitId.addProperty("FNumber", "012");
break;
case "":
fBaseUnitId.addProperty("FNumber", "001");
break;
case "":
fBaseUnitId.addProperty("FNumber", "003");
break;
case "":
fBaseUnitId.addProperty("FNumber", "005");
break;
case "":
fBaseUnitId.addProperty("FNumber", "020");
break;
case "":
fBaseUnitId.addProperty("FNumber", "014");
break;
case "":
fBaseUnitId.addProperty("FNumber", "jian");
break;
case "":
fBaseUnitId.addProperty("FNumber", "011");
break;
case "":
fBaseUnitId.addProperty("FNumber", "016");
break;
case "":
fBaseUnitId.addProperty("FNumber", "017");
break;
case "":
fBaseUnitId.addProperty("FNumber", "007");
break;
}
subHeadEntity5.add("FProduceUnitId", fProduceUnitId);
// 创建FProduceBillType对象并加入SubHeadEntity5
JsonObject fProduceBillType = new JsonObject();
fProduceBillType.addProperty("FNUMBER", "SCDD05_SYS");
subHeadEntity5.add("FProduceBillType", fProduceBillType);
// 创建FBOMUnitId对象并加入SubHeadEntity5
JsonObject fBOMUnitId = new JsonObject();
switch (newMaterial.getUnit()) {
case "":
fBaseUnitId.addProperty("FNumber", "002");
break;
case "":
fBaseUnitId.addProperty("FNumber", "012");
break;
case "":
fBaseUnitId.addProperty("FNumber", "001");
break;
case "":
fBaseUnitId.addProperty("FNumber", "003");
break;
case "":
fBaseUnitId.addProperty("FNumber", "005");
break;
case "":
fBaseUnitId.addProperty("FNumber", "020");
break;
case "":
fBaseUnitId.addProperty("FNumber", "014");
break;
case "":
fBaseUnitId.addProperty("FNumber", "jian");
break;
case "":
fBaseUnitId.addProperty("FNumber", "011");
break;
case "":
fBaseUnitId.addProperty("FNumber", "016");
break;
case "":
fBaseUnitId.addProperty("FNumber", "017");
break;
case "":
fBaseUnitId.addProperty("FNumber", "007");
break;
}
subHeadEntity5.add("FBOMUnitId", fBOMUnitId);
if (states.equals("1")) {
subHeadEntity5.addProperty("FIsMainPrd", false);
} else {
subHeadEntity5.addProperty("FIsMainPrd", true);
}
subHeadEntity5.addProperty("FIssueType", "1");
// 创建FPickStockId对象并加入SubHeadEntity5
JsonObject fPickStockId = new JsonObject();
fPickStockId.addProperty("FNumber", "CK010");
subHeadEntity1.add("FPickStockId", fPickStockId);
subHeadEntity5.addProperty("FOverControlMode", "1");
subHeadEntity5.addProperty("FStandHourUnitId", "3600");
subHeadEntity5.addProperty("FBackFlushType", "1");
String jsonData = json.toString();
System.out.println(jsonData);
try {
// 业务对象标识
String formId = "BD_MATERIAL";
// 调用接口
String resultJson = client.save(formId, jsonData);
// 用于记录结果
Gson gson = new Gson();
// 对返回结果进行解析和校验
RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
if (repoRet.getResult().getResponseStatus().isIsSuccess()) {
System.out.printf("接口返回结果: %s%n", gson.toJson(repoRet.getResult()));
log.info("接口返回结果: %s%n" + gson.toJson(repoRet.getResult()));
return 1;
} else {
MessageUtil.fail("接口返回结果: " + gson.toJson(repoRet.getResult().getResponseStatus()));
log.error("接口返回结果: 失败 " + gson.toJson(repoRet.getResult().getResponseStatus()));
return 0;
}
} catch (Exception e) {
MessageUtil.fail(e.getMessage());
}
return 1;
}
}

View File

@ -0,0 +1,122 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.system.domain.bo.KingdeeWorkCenterDataBo;
import com.ruoyi.system.domain.vo.KingdeeWorkCenterDataVo;
import com.ruoyi.system.domain.KingdeeWorkCenterData;
import com.ruoyi.system.mapper.KingdeeWorkCenterDataMapper;
import com.ruoyi.system.service.IKingdeeWorkCenterDataService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 金蝶工段数据Service业务层处理
*
* @author 田志阳
* @date 2025-01-18
*/
@RequiredArgsConstructor
@Service
public class KingdeeWorkCenterDataServiceImpl implements IKingdeeWorkCenterDataService {
private final KingdeeWorkCenterDataMapper baseMapper;
/**
* 查询金蝶工段数据
*/
@Override
public KingdeeWorkCenterDataVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 查询金蝶工段数据列表
*/
@Override
public TableDataInfo<KingdeeWorkCenterDataVo> queryPageList(KingdeeWorkCenterDataBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<KingdeeWorkCenterData> lqw = buildQueryWrapper(bo);
Page<KingdeeWorkCenterDataVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询金蝶工段数据列表
*/
@Override
public List<KingdeeWorkCenterDataVo> queryList(KingdeeWorkCenterDataBo bo) {
LambdaQueryWrapper<KingdeeWorkCenterData> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<KingdeeWorkCenterData> buildQueryWrapper(KingdeeWorkCenterDataBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<KingdeeWorkCenterData> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getMoBillNo()), KingdeeWorkCenterData::getMoBillNo, bo.getMoBillNo());
lqw.eq(StringUtils.isNotBlank(bo.getMoOrderNo()), KingdeeWorkCenterData::getMoOrderNo, bo.getMoOrderNo());
lqw.eq(StringUtils.isNotBlank(bo.getMaterialNumber()), KingdeeWorkCenterData::getMaterialNumber, bo.getMaterialNumber());
lqw.like(StringUtils.isNotBlank(bo.getMaterialName()), KingdeeWorkCenterData::getMaterialName, bo.getMaterialName());
lqw.eq(bo.getOperQty() != null, KingdeeWorkCenterData::getOperQty, bo.getOperQty());
lqw.eq(bo.getTransInQty() != null, KingdeeWorkCenterData::getTransInQty, bo.getTransInQty());
lqw.eq(bo.getTransOutQty() != null, KingdeeWorkCenterData::getTransOutQty, bo.getTransOutQty());
lqw.eq(StringUtils.isNotBlank(bo.getMaterialStatus()), KingdeeWorkCenterData::getMaterialStatus, bo.getMaterialStatus());
lqw.eq(StringUtils.isNotBlank(bo.getOperNumber()), KingdeeWorkCenterData::getOperNumber, bo.getOperNumber());
lqw.like(StringUtils.isNotBlank(bo.getProcessName()), KingdeeWorkCenterData::getProcessName, bo.getProcessName());
lqw.eq(StringUtils.isNotBlank(bo.getOperPlanStartTime()), KingdeeWorkCenterData::getOperPlanStartTime, bo.getOperPlanStartTime());
lqw.eq(StringUtils.isNotBlank(bo.getOperPlanFinishTime()), KingdeeWorkCenterData::getOperPlanFinishTime, bo.getOperPlanFinishTime());
lqw.eq(StringUtils.isNotBlank(bo.getDelayDays()), KingdeeWorkCenterData::getDelayDays, bo.getDelayDays());
lqw.eq(StringUtils.isNotBlank(bo.getWorkCenter()), KingdeeWorkCenterData::getWorkCenter, bo.getWorkCenter());
return lqw;
}
/**
* 新增金蝶工段数据
*/
@Override
public Boolean insertByBo(KingdeeWorkCenterDataBo bo) {
KingdeeWorkCenterData add = BeanUtil.toBean(bo, KingdeeWorkCenterData.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改金蝶工段数据
*/
@Override
public Boolean updateByBo(KingdeeWorkCenterDataBo bo) {
KingdeeWorkCenterData update = BeanUtil.toBean(bo, KingdeeWorkCenterData.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(KingdeeWorkCenterData entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除金蝶工段数据
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}

View File

@ -52,6 +52,7 @@ public class NewMaterialsServiceImpl implements INewMaterialsService {
/**
* 查询金蝶物料管理
*/
@Override
public NewMaterialsVo queryById(Long id){
return baseMapper.selectVoById(id);
@ -121,6 +122,7 @@ public class NewMaterialsServiceImpl implements INewMaterialsService {
* 保存前的数据校验
*/
private void validEntityBeforeSave(NewMaterials entity){
//TODO 做一些数据校验,如唯一约束
}
@ -187,6 +189,7 @@ public class NewMaterialsServiceImpl implements INewMaterialsService {
}
}
}
return newMaterialsVos;
}
public int loadMaterialToDQ(NewMaterials newMaterial, String states) {
@ -202,6 +205,7 @@ public class NewMaterialsServiceImpl implements INewMaterialsService {
// 添加Model字段
model.addProperty("FMATERIALID", 0);
model.addProperty("F_HBYT_PP", newMaterial.getMaterialBrand());//品牌
model.addProperty("FSpecification", newMaterial.getRemarks());// 备注仓库
model.addProperty("FNumber", newMaterial.getMaterialCode());
model.addProperty("FName", newMaterial.getMaterialName());
@ -468,7 +472,7 @@ public class NewMaterialsServiceImpl implements INewMaterialsService {
subHeadEntity6.addProperty("FCheckProduct", true);
subHeadEntity6.addProperty("FCheckReturnMtrl", true);
}
subHeadEntity6.addProperty("FCheckStock", true);
// 创建SubHeadEntity5对象并加入Model
JsonObject subHeadEntity5 = new JsonObject();
model.add("SubHeadEntity5", subHeadEntity5);

View File

@ -1,13 +1,16 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.system.domain.EleMaterials;
import com.ruoyi.system.domain.ProcessRoute;
import com.ruoyi.system.mapper.ProcessRouteMapper;
import com.ruoyi.system.service.IProcessRouteService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -17,6 +20,8 @@ import com.ruoyi.system.domain.ProcessOrderPro;
import com.ruoyi.system.mapper.ProcessOrderProMapper;
import com.ruoyi.system.service.IProcessOrderProService;
import com.ruoyi.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Map;
@ -32,10 +37,12 @@ import java.util.Collection;
@Service
public class ProcessOrderProServiceImpl implements IProcessOrderProService {
private static final Logger log = LoggerFactory.getLogger(ProcessOrderProServiceImpl.class);
private final ProcessOrderProMapper baseMapper;
@Autowired
private ProcessRouteMapper processRouteMapper;
private final IProcessRouteService iProcessRouteService;
/**
* 查询项目令号
*/
@ -81,6 +88,7 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
@Override
public Boolean insertByBo(ProcessOrderProBo bo) {
ProcessOrderPro add = BeanUtil.toBean(bo, ProcessOrderPro.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
@ -104,23 +112,47 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
*/
private void validEntityBeforeSave(ProcessOrderPro entity){
//TODO 做一些数据校验,如唯一约束
if (StringUtils.isBlank(entity.getProductionOrderNo()) ){
throw new IllegalArgumentException("生产令号不能为空");
}
LambdaQueryWrapper<ProcessOrderPro> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ProcessOrderPro::getProductionOrderNo, entity.getProductionOrderNo());
if (baseMapper.selectCount(queryWrapper) > 0) {
throw new IllegalArgumentException("生产令号已存在");
}
}
/**
* 批量删除项目令号
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
public R<Void> deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
for (Long id : ids) {
ProcessOrderProVo processOrderProVo = baseMapper.selectVoById(id);
if (processOrderProVo == null) {
log.warn("未找到对应的 ProcessOrderProVoID: {}", id);
continue;
}
String productionOrderNo = processOrderProVo.getProductionOrderNo();
String materialCode = processOrderProVo.getDrawingNo();
// 调用 selectByProjectCode 方法并检查结果
return iProcessRouteService.selectByProjectCode(productionOrderNo);
}
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
if (isValid) {
// TODO: 执行业务校验逻辑
// 例如检查是否有未完成的订单等
}
return baseMapper.deleteBatchIds(ids) > 0;
// 执行批量删除操作
boolean deleteResult = baseMapper.deleteBatchIds(ids) > 0;
if (deleteResult) {
log.info("成功删除 ID 列表: {}", ids);
} else {
log.error("删除 ID 列表失败: {}", ids);
}
return R.fail();
}
@Override

View File

@ -3,9 +3,9 @@ package com.ruoyi.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.cell.CellSetter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.type.TypeReference;
@ -20,10 +20,8 @@ import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.redis.RedisUtils;
import com.ruoyi.system.controller.ProcessRouteController;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.bo.BomDetailsBo;
import com.ruoyi.system.domain.bo.MaterialBomBo;
import com.ruoyi.system.domain.bo.ProcessRouteBo;
import com.ruoyi.system.domain.dto.*;
@ -48,7 +46,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
@ -82,7 +79,12 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
MaterialBomMapper materialBomMapper;
@Autowired
ProcessInfoMapper processInfoMapper;
private final ProductionRouteTwoMapper productionRouteTwoMapper;
private final IBomDetailsService bomDetailsService;
private static final Logger log = LoggerFactory.getLogger(ProcessRouteController.class);
private static final Logger logger = LoggerFactory.getLogger(IProcessRouteService.class);
/**
@ -102,6 +104,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
Page<ProcessRouteVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
@Override
public TableDataInfo<ProcessRouteVo> queryPageList2(ProcessRouteBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<ProcessRoute> lqw = buildQueryWrapper(bo);
@ -118,23 +121,72 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
}
return TableDataInfo.build(result);
}
/**
* 查询工艺路线列表
*/
@Override
public List<ProcessRouteVo> queryList(ProcessRouteBo bo) {
LambdaQueryWrapper<ProcessRoute> lqw = buildQueryWrapper(bo);
List<ProcessRouteVo> routeVoList = baseMapper.selectVoList(lqw);
// 对这个集合进行重新排序按照物料编码排序
routeVoList.sort(Comparator.comparing(ProcessRouteVo::getMaterialCode));
return routeVoList;
List<ProcessRouteVo> sortedList = new ArrayList<>();
// 获取工艺表中材质为总装部件的物料编码和名称
LambdaQueryWrapper<ProcessRoute> lqwRoute = buildQueryWrapper(bo);
lqwRoute.eq(ProcessRoute::getMaterial, "总装部件")
.eq(ProcessRoute::getRouteDescription, bo.getRouteDescription());
List<ProcessRoute> processRoutes = baseMapper.selectList(lqwRoute);
// 装配工艺路线
for (ProcessRoute processRoute : processRoutes) {
List<ProcessRoute> routes1 = getProcessRoutesByOrder(processRoute.getRouteDescription(), processRoute.getMaterialCode());
for (ProcessRoute route : routes1) {
ProcessRouteVo processRouteVo1 = BeanUtil.copyProperties(route, ProcessRouteVo.class);
sortedList.add(processRouteVo1);
}
// 查询 BOM 详情
List<BomDetails> bomDetails1 = bomDetailsService.selectByFNumberAndTotalWeight(processRoute.getMaterialCode(), processRoute.getRouteDescription());
List<BomDetails> filteredBomDetails = filterBomDetails(bomDetails1);
log.info("过滤后的 BOM 详情数量: {}", filteredBomDetails.size());
// 将对应的工艺路线加入到 sortedList
for (BomDetails bomDetail : filteredBomDetails) {
addProcessRoutesFromBomDetail(bomDetail, sortedList);
// 将组焊件写入工艺
if ("组焊件".equals(bomDetail.getMaterial())) {
List<BomDetails> bomDetails = bomDetailsService.selectByFNumberAndTotalWeight(bomDetail.getPartNumber(), bomDetail.getTotalWeight());
for (BomDetails detail : bomDetails) {
addProcessRoutesFromBomDetail(detail, sortedList);
}
}
}
}
return sortedList;
}
private List<BomDetails> filterBomDetails(List<BomDetails> bomDetails) {
return bomDetails.stream()
.filter(bom -> bom != null &&
bom.getPartNumber() != null &&
!bom.getPartNumber().startsWith("009") &&
!bom.getPartNumber().startsWith(" ") &&
(bom.getRemarks() == null || !bom.getRemarks().contains("伊特")))
.collect(Collectors.toList());
}
private void addProcessRoutesFromBomDetail(BomDetails bomDetail, List<ProcessRouteVo> sortedList) {
List<ProcessRoute> routes = getProcessRoutesByOrder(bomDetail.getTotalWeight(), bomDetail.getPartNumber());
for (ProcessRoute route : routes) {
ProcessRouteVo processRouteVo1 = BeanUtil.copyProperties(route, ProcessRouteVo.class);
sortedList.add(processRouteVo1);
}
}
private LambdaQueryWrapper<ProcessRoute> buildQueryWrapper(ProcessRouteBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<ProcessRoute> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getRouteDescription()), ProcessRoute::getRouteDescription,
lqw.eq(StringUtils.isNotBlank(bo.getRouteDescription()), ProcessRoute::getRouteDescription,
bo.getRouteDescription());
lqw.eq(StringUtils.isNotBlank(bo.getMaterialCode()), ProcessRoute::getMaterialCode, bo.getMaterialCode());
lqw.like(StringUtils.isNotBlank(bo.getMaterialName()), ProcessRoute::getMaterialName, bo.getMaterialName());
@ -170,39 +222,52 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
*/
@Override
public Boolean insertByBo(ProcessRouteBo bo) {
try {
ProcessRoute add = BeanUtil.toBean(bo, ProcessRoute.class);
// 查询是否存在重复序号
if (baseMapper.existsByProcessNoAndMaterialCode(
add.getProcessNo(),
add.getMaterialCode())) {
throw new ServiceException("序号重复,请重新输入");
}
ProcessRoute add = BeanUtil.toBean(bo, ProcessRoute.class);
// 查询最大序为多少
if (baseMapper.existsByProcessNoAndMaterialCode(add.getProcessNo(), add.getMaterialCode(),
add.getProcessDescription())) {
throw new ServiceException("序号重复,请重新输入");
}
// 1.查询当前物料的所有工序关系
LambdaQueryWrapper<ProcessRoute> route = new LambdaQueryWrapper<>();
route.eq(ProcessRoute::getMaterialCode, add.getMaterialCode())
.eq(ProcessRoute::getMaterialName, add.getMaterialName())
.eq(ProcessRoute::getRouteDescription, add.getRouteDescription());
List<ProcessRoute> routeList = baseMapper.selectList(route);
// 2. 校验连续工序中相同工作中心的工序控制码
if (!routeList.isEmpty()) {
setoProcessControl(routeList);
}
// 1.查询当前物料的所有工序关系
LambdaQueryWrapper<ProcessRoute> route = new LambdaQueryWrapper<>();
route.eq(ProcessRoute::getMaterialCode, add.getMaterialCode())
.eq(ProcessRoute::getMaterialName, add.getMaterialName())
.eq(ProcessRoute::getRouteDescription, add.getRouteDescription());
List<ProcessRoute> routeList = baseMapper.selectList(route);
// 2. 更新所有比新序号大的工艺路线将它们的 processNo
baseMapper.updateProcessNoAfterInsert(add.getProcessNo(), add.getMaterialCode(), add.getProcessDescription());
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
// 2. 校验连续工序中相同工作中心的工序控制码
if (!routeList.isEmpty()) {
setoProcessControl(routeList);
}
// 3. 更新所有比新序号大的工艺路线
baseMapper.updateProcessNoAfterInsert(
add.getProcessNo(),
add.getMaterialCode(),
add.getRouteDescription());
// 4. 保存前的实体校验
validEntityBeforeSave(add);
// 5. 插入数据
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
} catch (Exception e) {
log.error("新增工艺路线失败", e);
throw new ServiceException("新增工艺路线失败:" + e.getMessage());
}
return flag;
}
private void setoProcessControl(List<ProcessRoute> routeList) {
if (routeList == null || routeList.size() < 2) {
return;
}
// 按工序号排序
routeList.sort(Comparator.comparing(ProcessRoute::getProcessNo));
@ -215,14 +280,12 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
current.setProcessControl("委外+汇报");
continue;
}
// 查找连续相同工作中心的最后一个工序
int j = i;
while (j + 1 < routeList.size() &&
routeList.get(j + 1).getWorkCenter().equals(current.getWorkCenter())) {
j++;
}
// 设置工序控制码
if (i == j) {
// 单个工序设置为"汇报+质量"
@ -316,9 +379,12 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
List<ProcessRoute> cunList = new ArrayList<>();
for (Long id : ids) {
ProcessRoute processRoute = baseMapper.selectById(id);
if (processRoute.getProcessNo() == 10) {
throw new ServiceException("最少保留首序");
}
LambdaQueryWrapper<ProcessRoute> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ProcessRoute::getMaterialCode, processRoute.getMaterialCode())
.eq(ProcessRoute::getProcessDescription, processRoute.getProcessDescription());
List<ProcessRoute> routeList = baseMapper.selectList(wrapper);
// 判断当前集合里的元素是不是只剩一个只剩下一个就不能删除
}
// 这里你到时候改成通过ids查询出来 这个ids是你传过来要删除的,你不能通过去排序和查询en
for (Long id : ids) {
@ -365,16 +431,19 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
}
public boolean saveData(List<ProcessRouteVo> routeVoList, List<ProductionOrderVo> productionOrderVos) {
// ProcessRouteVo 转换为 ProcessRoute
// ProcessRouteVo 转换为 ProcessRoute 工艺集合 材料bom 集合
List<ProcessRoute> processRoutes = BeanUtil.copyToList(routeVoList, ProcessRoute.class);
// 1. 处理材料 BOM
// 1. 处理材料 BOM 存入材料bom
processMaterialBom(processRoutes);
// 2. 处理 BOM 详情
List<BomDetailsVo> bomDetailsVos = processBomDetails(processRoutes, productionOrderVos);
// 2. 处理 BOM 详情 工艺 总装的
List<BomDetailsVo> bomDetailsVos = processBomDetails(routeVoList, productionOrderVos);
// 3. 保存 BOM 详情
Map<String, Double> inventoryCache = new HashMap<>(); // 缓存可用库存
saveBomDetails(bomDetailsVos);
List<ProcessRoute> routeArrayList = new ArrayList<>();
boolean allEmpty = processRoutes.stream()
.allMatch(route -> route.getProcessNo() == null && route.getProcessName() == null);
@ -415,55 +484,71 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
List<ProcessRouteSelectDTO> selectProcessRoute = getSelectProcessRoute(processRoute.getMaterialCode());
if (!selectProcessRoute.isEmpty()) {
List<ProductionRouteTwo> productionRouteTwos = new ArrayList<>();
for (ProcessRouteSelectDTO processRouteSelectDTO : selectProcessRoute) {
ProcessRoute processRoute1 = new ProcessRoute();
// 复制基本信息
processRoute1.setMaterialCode(processRoute.getMaterialCode());
processRoute1.setMaterialName(processRoute.getMaterialName());
processRoute1.setRouteDescription(processRoute.getRouteDescription());
processRoute1.setMaterial(processRoute.getMaterial());
processRoute1.setDiscWeight(processRoute.getDiscWeight());
// 复制工艺信息
processRoute1.setProcessNo(processRouteSelectDTO.getProcessNo());
processRoute1.setProcessName(processRouteSelectDTO.getProcessName());
processRoute1.setProcessDescription(processRouteSelectDTO.getProcessDescription());
processRoute1.setWorkCenter(processRouteSelectDTO.getWorkCenter());
processRoute1.setProcessControl(processRouteSelectDTO.getProcessControl());
processRoute1.setActivityDuration(processRouteSelectDTO.getActivityDuration());
processRoute1.setActivityUnit("");
log.info("开始查询可用库存:" + processRoute.getMaterialCode());
processRoute1.setFirstBatchQuantity(kucun);
// 设置时间
processRoute1.setCreateTime(new Date());
processRoute1.setUpdateTime(new Date());
routeArrayList.add(processRoute1);
ProductionRouteTwo productionRouteTwo = new ProductionRouteTwo();
productionRouteTwo.setFHbytSclh(processRoute.getRouteDescription());
productionRouteTwo.setFproductidFnumber(processRouteSelectDTO.getMatericalCode());
productionRouteTwo.setFProductName(processRouteSelectDTO.getMatericalName());
productionRouteTwo.setFprocessidFname(processRouteSelectDTO.getProcessName());
productionRouteTwo.setFworkcenteridFname(processRouteSelectDTO.getWorkCenter());
productionRouteTwo.setFOperNumber(String.valueOf(processRouteSelectDTO.getProcessNo()));
productionRouteTwo.setFOptCtrlCodeidFname(processRouteSelectDTO.getProcessControl());
productionRouteTwo.setActivityLengh(processRouteSelectDTO.getActivityDuration());
productionRouteTwo.setFOperDescription(processRouteSelectDTO.getProcessDescription());
productionRouteTwo.setFOperQty(processRouteSelectDTO.getActivityDuration().longValue());
productionRouteTwo.setFmaterialidFnumber(processRouteSelectDTO.getFNumber());
productionRouteTwos.add(productionRouteTwo);
}
} else {
// 1. 保存金蝶工艺路线
productionRouteTwoMapper.insertOrUpdateBatch(productionRouteTwos);
// 2. 同时创建默认工序
ProcessRoute defaultRoute = new ProcessRoute();
BeanUtil.copyProperties(processRoute, defaultRoute);
// 设置工序号 (10, 20, 30, 40)
defaultRoute.setProcessNo((long) (10));
// 清空工序相关信息
// 设置默认工序信息
defaultRoute.setProcessNo(10L); // 默认工序号为10
defaultRoute.setWorkCenter(null);
defaultRoute.setProcessName(null);
defaultRoute.setProcessDescription(null);
defaultRoute.setProcessControl(null);
defaultRoute.setActivityDuration(null);
defaultRoute.setActivityUnit("");
defaultRoute.setFirstBatchQuantity(kucun);
// 设置创建时间和更新时间
// 设置库存信息
kucun = inventoryCache.getOrDefault(processRoute.getMaterialCode(), 0.0);
defaultRoute.setFirstBatchQuantity(kucun);
// 设置时间戳
defaultRoute.setCreateTime(new Date());
defaultRoute.setUpdateTime(new Date());
routeArrayList.add(defaultRoute);
log.info("为物料 {} 生成了默认工序,因为在金蝶中未找到对应工艺路线", processRoute.getMaterialCode());
log.info("为物料 {} 同时生成了金蝶工艺路线和默认工序", processRoute.getMaterialCode());
} else {
// 如果没有金蝶工艺路线只生成默认工序
ProcessRoute defaultRoute = new ProcessRoute();
BeanUtil.copyProperties(processRoute, defaultRoute);
defaultRoute.setProcessNo(10L);
defaultRoute.setWorkCenter(null);
defaultRoute.setProcessName(null);
defaultRoute.setProcessDescription(null);
defaultRoute.setProcessControl(null);
defaultRoute.setActivityDuration(null);
defaultRoute.setActivityUnit("");
kucun = inventoryCache.getOrDefault(processRoute.getMaterialCode(), 0.0);
defaultRoute.setFirstBatchQuantity(kucun);
defaultRoute.setCreateTime(new Date());
defaultRoute.setUpdateTime(new Date());
routeArrayList.add(defaultRoute);
log.info("为物料 {} 仅生成默认工序,因为在金蝶中未找到对应工艺路线", processRoute.getMaterialCode());
}
// 如果是重复的组焊件标记为已处理
@ -478,12 +563,13 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
// 处理非空工序的情况
for (ProcessRoute processRoute : processRoutes) {
if (processRoute.getProcessNo() != null || processRoute.getProcessName() != null) {
processRoute.setActivityUnit("");
processRoute.setCreateTime(new Date());
processRoute.setUpdateTime(new Date());
Double kucun = JdUtil.getKeyong(processRoute.getMaterialCode());
processRoute.setFirstBatchQuantity(kucun);
Double kucun = JdUtil.getKeyong(processRoute.getMaterialCode());
processRoute.setFirstBatchQuantity(kucun);
routeArrayList.add(processRoute);
routeArrayList.add(processRoute);
}
}
}
@ -521,35 +607,74 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
}
}
private List<BomDetailsVo> processBomDetails(List<ProcessRoute> processRoutes,
/*
* @productionOrderVos 总装
*
* @routeVoList 工艺路线
*/
private List<BomDetailsVo> processBomDetails(List<ProcessRouteVo> routeVoList,
List<ProductionOrderVo> productionOrderVos) {
List<BomDetailsVo> bomDetailsVos = new ArrayList<>();
// 是否已处理过总装部件
boolean hasProcessedAssemblyPart = false;
// 1. 处理总装部件
for (ProcessRoute processRoute : processRoutes) {
if (processRoute != null) {
String zFlinghao = processRoute.getRouteDescription();
if ("总装部件".equals(processRoute.getMaterial()) && !hasProcessedAssemblyPart) {
String zFnumber = processRoute.getMaterialCode();
String zFname = processRoute.getMaterialName();
// 将装配 BOM 详情填充进 BOM 详情列表
createAssemblyBomDetails(zFlinghao, zFnumber, zFname, productionOrderVos);
// 设置标志为已处理
hasProcessedAssemblyPart = true;
continue;
if (productionOrderVos != null && !productionOrderVos.isEmpty()) {
List<ProductionOrder> productionOrderList = productionOrderVos.stream().map(productionOrderVo -> {
ProductionOrder productionOrder = new ProductionOrder();
BeanUtil.copyProperties(productionOrderVo, productionOrder);
return productionOrder;
}).collect(Collectors.toList());
// 批量插入到数据库中
boolean b = productionOrderMapper.insertBatch(productionOrderList);
log.info("插入到装备BOM清单中: {}", b);
// 获取主产品图号
for (ProductionOrderVo productionOrderVo : productionOrderVos) {
BomDetailsVo bomDetails = new BomDetailsVo();
bomDetails.setTotalWeight(productionOrderVo.getProductionOrderNo());
bomDetails.setFNumber(productionOrderVo.getMainProducts());
bomDetails.setFName(productionOrderVo.getMainProductsName());
bomDetails.setPartdiagramCode(productionOrderVo.getParentDrawingNo());
bomDetails.setPartdiagramName(productionOrderVo.getParentPart());
bomDetails.setPartNumber(productionOrderVo.getDrawingNo());
bomDetails.setName(productionOrderVo.getDrawingName());
Double quantity = productionOrderVo.getQuantity();
bomDetails.setQuantity(quantity != null ? quantity : 0.0);
bomDetails.setMaterial(productionOrderVo.getMaterial());
bomDetails.setRemarks(productionOrderVo.getRemark());
// 判断外购或自制
String drawingNo = productionOrderVo.getDrawingNo();
String remark = productionOrderVo.getRemark();
if (drawingNo != null) {
if (isOutsourced(drawingNo) || (remark != null && remark.contains("外购件"))
|| drawingNo.startsWith(" ") || drawingNo.startsWith("009")) {
bomDetails.setStats("外购");
} else {
bomDetails.setStats("自制");
}
}
if (processRoute.getRawMaterialCode() != null || processRoute.getRawMaterialName() != null
|| processRoute.getBomMaterial() != null || processRoute.getBomUnit() != null) {
BomDetailsVo bomDetails = createBomDetails(processRoute);
bomDetailsVos.add(bomDetails);
// 只在这里添加 bomDetails
bomDetailsVos.add(bomDetails);
}
}
if (routeVoList != null && !routeVoList.isEmpty()) {
for (ProcessRouteVo processRouteVo : routeVoList) {
if (processRouteVo.getRawMaterialCode() != null && processRouteVo.getRawMaterialName() != null) {
// 处理表中的材料bom
bomDetailsVos.add(createBomDetails(processRouteVo));
}
}
}
return bomDetailsVos;
return bomDetailsVos; // 如果需要返回结果
}
private BomDetailsVo createBomDetails(ProcessRoute processRoute) {
/**
* 为工艺列表中材料bom 生成bomdetial 对象
*
* @param processRoute
* @return
*/
private BomDetailsVo createBomDetails(ProcessRouteVo processRoute) {
BomDetailsVo bomDetails = new BomDetailsVo();
bomDetails.setTotalWeight(processRoute.getRouteDescription());
bomDetails.setFNumber(processRoute.getMaterialCode());
@ -582,7 +707,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
private void createAssemblyBomDetails(String zFlinghao, String zFnumber, String zFname,
List<ProductionOrderVo> productionOrderVos) {
ArrayList<BomDetailsVo> bomDetailsVos = new ArrayList<>();
List<BomDetailsVo> bomDetailsVos = new ArrayList<>();
for (ProductionOrderVo productionOrderVo : productionOrderVos) {
if (productionOrderVo != null) {
BomDetailsVo bomDetails = new BomDetailsVo();
@ -593,14 +718,15 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
bomDetails.setPartdiagramName(productionOrderVo.getParentPart());
bomDetails.setPartNumber(productionOrderVo.getDrawingNo());
bomDetails.setName(productionOrderVo.getDrawingName());
bomDetails.setQuantity(Double.valueOf(productionOrderVo.getQuantity()));
bomDetails.setQuantity(productionOrderVo.getQuantity());
bomDetails.setMaterial(productionOrderVo.getMaterial());
bomDetails.setRemarks(productionOrderVo.getRemark());
// 判断外购或自制
String drawingNo = productionOrderVo.getDrawingNo();
String remark = productionOrderVo.getRemark();
if (drawingNo != null) {
if ((isOutsourced(drawingNo) || (remark != null && remark.contains("外购件"))
if ((isOutsourced(drawingNo)
|| (remark != null && (remark.contains("外购件") || remark.contains("伊特")))
|| drawingNo.startsWith(" ")) || drawingNo.startsWith("009")) {
bomDetails.setStats("外购");
} else {
@ -737,10 +863,12 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
if (states.equals("1")) {
// 外购
subHeadEntity6.addProperty("FCheckIncoming", true);
subHeadEntity6.addProperty("FCheckStock", true);
}
if (states.equals("2")) {
// 自制
subHeadEntity6.addProperty("FCheckProduct", true);
subHeadEntity6.addProperty("FCheckStock", true);
subHeadEntity6.addProperty("FCheckReturnMtrl", true);
}
if (states.equals("3")) {
@ -832,58 +960,36 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
iBomDetailsService.insertByVo(BeanUtil.toBean(bomDetails, BomDetailsVo.class));
}
// 新增不存在的物料
for (BomDetails material : materialsToAdd) {
String state = determineState(material);
log.info("开始新增不存在的物料 ==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName());
int result = loadMaterialPreservation(material, state);
if (result == 1) {
log.info("新增物料成功 ==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName());
material.setUnitWeight("新增成功");
} else {
log.error("新增物料失败 ==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName());
}
// 更新物料状态
iBomDetailsService.updateByBo(BeanUtil.toBean(material, BomDetailsBo.class));
}
}
private void saveBomDetails1(List<BomDetailsVo> bomDetailsVos) {
List<BomDetails> materialsToAdd = new ArrayList<>();
for (BomDetailsVo bomDetailsVo : bomDetailsVos) {
BomDetails bomDetails = BeanUtil.toBean(bomDetailsVo, BomDetails.class);
// 验证物料是否存在
if (isMaterialVerification(bomDetails.getPartNumber(), bomDetails.getName()) == 1) {
bomDetails.setUnitWeight("");
} else {
bomDetails.setUnitWeight("");
materialsToAdd.add(bomDetails);
}
}
// 新增不存在的物料
for (BomDetails material : materialsToAdd) {
String state = determineState(material);
log.info("开始新增不存在的物料 ==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName());
int result = loadMaterialPreservation(material, state);
if (result == 1) {
log.info("新增物料成功 ==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName());
material.setUnitWeight("新增成功");
} else {
log.error("新增物料失败 ==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName());
}
// 更新物料状态
// iBomDetailsService.updateByBo(BeanUtil.toBean(material, BomDetailsBo.class));
}
/*
* // 新增不存在的物料
* for (BomDetails material : materialsToAdd) {
* if (material != null && material.getPartNumber() != null &&
* material.getName() != null) {
* String state = determineState(material);
* log.info("开始新增不存在的物料 ==> 物料图号: " + material.getPartNumber() + " 物料名称: " +
* material.getName());
*
* int result = loadMaterialPreservation(material, state);
* if (result == 1) {
* log.info("新增物料成功 ==> 物料图号: " + material.getPartNumber() + " 物料名称: " +
* material.getName());
* material.setUnitWeight("新增成功");
* } else {
* log.error("新增物料失败 ==> 物料图号: " + material.getPartNumber() + " 物料名称: " +
* material.getName());
* }
*
* // 更新物料状态
* iBomDetailsService.updateByBo(BeanUtil.toBean(material, BomDetailsBo.class));
* } else {
* log.error("物料信息不完整,无法新增物料");
* }
* }
*/
}
@Override
// 获取这个项目中材质为组焊件 和这个物料为组焊件的图号
public List<ProcessRoute> pushGroupWeldments(ProcessRoute Bo) {
// 获取这个项目中材质为组焊件 和这个物料为组焊件的图号
List<ProcessRoute> processRoutes = baseMapper.selectList();
@ -982,6 +1088,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
routeDTO.setProcessControl(processRoute.getProcessControl());
routeDTO.setActivityDuration(processRoute.getActivityDuration());
routeDTO.setActivityUnit(processRoute.getActivityUnit());
routeDTO.setProcessNameDescription(processRoute.getMaterial());
// 将该工序信息添加到 xuDTO
xuDTO.getProcessRouteDT().add(routeDTO);
@ -1039,6 +1146,47 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
return resultDTO;
}
public ProcessRoutePushResultDTO pushRouteQBBom(String rooteProdet) {
List<ProcessRouteXuDTO> rawBomList = getProcessRoute(rooteProdet);
List<ProcessRouteXuDTO> successfulRoutes = new ArrayList<>();
List<ProcessRouteXuDTO> failedRoutes = new ArrayList<>();
List<String> duplicateRoutes = new ArrayList<>();
for (ProcessRouteXuDTO processRouteXuDTO : rawBomList) {
// 获取金蝶中的此物料工艺路线,在金蝶查询可能有多条工艺路线
List<ProcessRouteSelectDTO> jdProcessRoute = getSelectProcessRoute(processRouteXuDTO.getMaterialCode());
Map<String, List<ProcessRouteSelectDTO>> groupedByFNumber = jdProcessRoute.stream()
.collect(Collectors.groupingBy(ProcessRouteSelectDTO::getFNumber));
// 当前物料的工艺路线
List<ProcessRouteDTO> processRouteDT = processRouteXuDTO.getProcessRouteDT();
// 比较工艺路线
boolean isDifferent = compareProcessRoutes(processRouteDT, groupedByFNumber);
if (isDifferent) {
log.info("工艺路线不同,进行更新: " + processRouteXuDTO.getMaterialCode());
// 保存工艺路线
LoadBomResult result = loadBillOfMaterialsPreservation(processRouteXuDTO);
// 处理返回结果
if (result.isSuccess()) {
log.info("工艺路线保存成功: " + processRouteXuDTO.getMaterialCode() + result.getResultData());
successfulRoutes.add(processRouteXuDTO);
} else {
log.info("工艺路线保存失败: " + processRouteXuDTO.getMaterialCode() + result.getMessage());
failedRoutes.add(processRouteXuDTO);
}
} else {
log.info("工艺路线相同,无需更新: " + processRouteXuDTO.getMaterialCode());
duplicateRoutes.add(processRouteXuDTO.getMaterialCode());
}
}
// 封装结果
ProcessRoutePushResultDTO resultDTO = new ProcessRoutePushResultDTO();
resultDTO.setSuccessfulRoutes(successfulRoutes);
resultDTO.setFailedRoutes(failedRoutes);
resultDTO.setDuplicateRoutes(duplicateRoutes);
return resultDTO;
}
private boolean compareProcessRoutes(List<ProcessRouteDTO> processRouteDT,
Map<String, List<ProcessRouteSelectDTO>> groupedByFNumber) {
// 对当前物料的工艺路线进行排序
@ -1514,6 +1662,17 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
return materialBomMapper.selectList(wrapper);
}
/**
* 查询组焊件集合
*/
public List<MaterialBom> getZuHanList(ProcessRoute processRoute) {
LambdaQueryWrapper<MaterialBom> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(MaterialBom::getParentMaterialCode, processRoute.getMaterialCode())
.eq(MaterialBom::getParentMaterialName, processRoute.getMaterialName())
.eq(MaterialBom::getProjectNumber, processRoute.getRouteDescription());
return materialBomMapper.selectList(wrapper);
}
// 是否是按图定制的物料
public Boolean insertByBoToBom(MaterialBomBo bo) {
@ -1879,4 +2038,172 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
}
}
/**
* 根据项目令号删除 材料bom 总装bom 工艺路线
*
* @param productionOrderNo
* @return
*/
@Override
public R<Void> selectByProjectCode(String productionOrderNo) {
boolean allDeleted = true;
// 查询并删除工艺路线
List<ProcessRoute> selectList = baseMapper.selectList(
new QueryWrapper<ProcessRoute>().eq("route_description", productionOrderNo));
if (!selectList.isEmpty()) {
boolean result = baseMapper.deleteBatchIds(
selectList.stream().map(ProcessRoute::getId).collect(Collectors.toList())) > 0;
if (!result) {
log.error("删工艺数据发生意外: {}", productionOrderNo);
allDeleted = false;
}
}
// 查询并删除材料BOM
List<MaterialBom> selectMaterList = materialBomMapper.selectList(
new QueryWrapper<MaterialBom>().eq("project_number", productionOrderNo));
if (!selectMaterList.isEmpty()) {
boolean result = materialBomMapper.deleteBatchIds(
selectMaterList.stream().map(MaterialBom::getId).collect(Collectors.toList())) > 0;
if (!result) {
log.error("删材料发生意外: {}", productionOrderNo);
allDeleted = false;
}
}
// 查询并删除BOM详情
List<BomDetails> selectBomdetailList = bomDetailsMapper.selectList(
new QueryWrapper<BomDetails>().eq("total_weight", productionOrderNo));
if (!selectBomdetailList.isEmpty()) {
boolean result = bomDetailsMapper.deleteBatchIds(
selectBomdetailList.stream().map(BomDetails::getId).collect(Collectors.toList())) > 0;
if (!result) {
log.error("删BOM数据发生意外: {}", productionOrderNo);
allDeleted = false;
}
}
// 返回结果
if (allDeleted) {
return R.ok();
} else {
return R.fail("删除操作未完全成功");
}
}
/**
* @param materialCode
* @param materialName
* @param productionOrderNo
* @return
*/
@Override
public List<ProcessRouteJdDTO> getProcessRouteList(String materialCode, String materialName,
String productionOrderNo) {
QueryWrapper<ProductionRouteTwo> wrapper = new QueryWrapper<>();
wrapper.eq("FProductId_FNumber", materialCode)
.eq("f_product_name", materialName)
.eq("F_HBYT_SCLH", productionOrderNo)
.orderByAsc("FMATERIALID_FNumber"); // 按工序号排序
List<ProductionRouteTwo> productionRouteTwos = productionRouteTwoMapper.selectList(wrapper);
if (CollectionUtils.isEmpty(productionRouteTwos)) {
return Collections.emptyList();
}
// 按生产令号分组
Map<String, List<ProductionRouteTwo>> groupedByProjectCode = productionRouteTwos.stream()
.collect(Collectors.groupingBy(ProductionRouteTwo::getFmaterialidFnumber));
// 将结果转换到DTO中
List<ProcessRouteJdDTO> processRouteJdDTOs = new ArrayList<>();
groupedByProjectCode.forEach((projectCode, routes) -> {
ProcessRouteJdDTO processRouteJdDTO = new ProcessRouteJdDTO();
ProductionRouteTwo firstRoute = routes.get(0);
// 设置基本信息
processRouteJdDTO.setId(firstRoute.getId());
processRouteJdDTO.setProject_code(firstRoute.getFHbytSclh());
processRouteJdDTO.setFnumber(firstRoute.getFmaterialidFnumber());
processRouteJdDTO.setMaterialCode(firstRoute.getFproductidFnumber());
processRouteJdDTO.setMaterialName(firstRoute.getFProductName());
// 按工序号分组并转换为ProcessRouteDTO
List<ProcessRouteDTO> processRouteDTList = routes.stream()
.map(route -> {
ProcessRouteDTO routeDTO = new ProcessRouteDTO();
// 设置工序信息
routeDTO.setProcessNo(
StringUtils.isNotEmpty(route.getFOperNumber()) ? Long.parseLong(route.getFOperNumber())
: null);
routeDTO.setWorkCenter(route.getFworkcenteridFname());
routeDTO.setProcessName(route.getFprocessidFname());
routeDTO.setProcessDescription(route.getFOperDescription());
routeDTO.setProcessControl(route.getFOptCtrlCodeidFname());
routeDTO.setActivityDuration(route.getActivityLengh());
// 如果需要设置活动单位可以在这里添加
routeDTO.setActivityUnit("小时"); // 或从其他字段获取
return routeDTO;
})
.sorted(Comparator.comparing(ProcessRouteDTO::getProcessNo,
Comparator.nullsLast(Comparator.naturalOrder())))
.collect(Collectors.toList());
// 设置工艺路线列表
processRouteJdDTO.setProcessRouteDT(processRouteDTList);
processRouteJdDTOs.add(processRouteJdDTO);
});
// 记录日志
log.info("查询到{}条工艺路线数据", processRouteJdDTOs.size());
return processRouteJdDTOs;
}
/**
* @param material
* @return
*/
@Override
public Double getFbWorkTime(BomDetails material) {
if (material == null) {
log.error("传入的物料对象为 null");
return 0.0; // 或者抛出异常
}
LambdaQueryWrapper<ProcessRoute> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ProcessRoute::getMaterialCode, material.getPartNumber())
.eq(ProcessRoute::getMaterialName, material.getName())
.eq(ProcessRoute::getRouteDescription, material.getTotalWeight())
.ne(ProcessRoute::getWorkCenter, "委外中心");
// 不包含工作中心是委外中心的工艺路线
List<ProcessRoute> processRoutes = baseMapper.selectList(wrapper);
if (!CollectionUtils.isEmpty(processRoutes)) {
// 获取所有活动时长并求和处理可能为 null 的情况
double totalActivityDuration = processRoutes.stream()
.mapToDouble(route -> Optional.ofNullable(route.getActivityDuration()).orElse(0.0))
.sum();
return totalActivityDuration;
}
return 0.0;
}
/**
* @param productionOrderNo
* @param materialCode
* @return
*/
@Override
public List<ProcessRoute> getProcessRoutesByOrder(String productionOrderNo, String materialCode) {
LambdaQueryWrapper<ProcessRoute> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ProcessRoute::getRouteDescription, productionOrderNo)
.eq(ProcessRoute::getMaterialCode, materialCode);
if (baseMapper.selectList(wrapper) != null) {
return baseMapper.selectList(wrapper);
}
return Collections.emptyList();
}
}

View File

@ -182,7 +182,7 @@ public class ProductionRouteTwoServiceImpl implements IProductionRouteTwoService
productionRouteTwo.setFworkcenteridFname(plannedProcess.getFWorkCenterName()); // 工作中心
productionRouteTwo.setFprocessidFname(plannedProcess.getFProcessName()); // 工艺名称
productionRouteTwo.setFOptCtrlCodeidFname(plannedProcess.getFOptCtrlCodeIFName());
productionRouteTwo.setActivityLengh(plannedProcess.getFActivity1BaseQty().longValue());
productionRouteTwo.setActivityLengh((double) plannedProcess.getFActivity1BaseQty().longValue());
// 填充物料相关数据
productionRouteTwo.setFMaterialid2ChildFnumber(materialUsageDTO.getMaterialCode()); // 物料编码
productionRouteTwo.setFMaterialName1(materialUsageDTO.getMaterialName()); // 物料名称

View File

@ -3,6 +3,7 @@ package com.ruoyi.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.Gson;
@ -11,7 +12,9 @@ import com.google.gson.JsonObject;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.controller.ProcessRouteController;
import com.ruoyi.system.domain.SafetyStock;
import com.ruoyi.system.domain.WlStockData;
import com.ruoyi.system.domain.bo.WlStockDataBo;
@ -48,6 +51,11 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
private final StandardPartsMapper standardPartsMapper;
private final SafetyStockMapper safetyStockMapper;
private static final int MAX_RETRIES = 3;
private static final long RETRY_DELAY = 2000L; // 2秒
private static final int THREAD_POOL_SIZE = 10;
/**
* 查询安全库存单据
*/
@ -256,7 +264,7 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
// 检查是否已经存在相同物料编码的单据
if (existingMaterialCodes.contains(materialCode)) {
logger.info("已存在相同物料编码的单据: {}", materialCode);
logger.debug("已存在相同物料编码的单据: {}", materialCode);
continue;
}
@ -280,104 +288,162 @@ public class WlStockDataServiceImpl implements IWlStockDataService {
@Override
public List<WlStockData> generateDoc() {
List<SafetyStock> safetyStocks = safetyStockMapper.selectList();
List<WlStockData> wlStockDataList = new ArrayList<>();
// 使用 CachedThreadPool
ExecutorService executor = Executors.newCachedThreadPool();
List<CompletableFuture<WlStockData>> futures = new ArrayList<>();
for (SafetyStock safetyStock : safetyStocks) {
// 提交任务到线程池
CompletableFuture<WlStockData> future = CompletableFuture.supplyAsync(() -> processMaterialCode(safetyStock), executor);
futures.add(future);
if (CollectionUtils.isEmpty(safetyStocks)) {
logger.warn("没有找到安全库存数据");
return Collections.emptyList();
}
// 收集结果
for (CompletableFuture<WlStockData> future : futures) {
future.thenAccept(wlStockData -> {
if (wlStockData != null) {
wlStockDataList.add(wlStockData);
// 使用固定大小的线程池而不是CachedThreadPool避免创建过多线程
ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
List<WlStockData> wlStockDataList = Collections.synchronizedList(new ArrayList<>());
try {
// 创建所有任务的Future列表
List<CompletableFuture<Void>> futures = safetyStocks.stream()
.map(safetyStock -> CompletableFuture
.supplyAsync(() -> processWithRetry(safetyStock), executor)
.thenAccept(wlStockData -> {
if (wlStockData != null) {
wlStockDataList.add(wlStockData);
}
})
.exceptionally(e -> {
logger.error("处理安全库存数据失败: {}", safetyStock.getMaterialCode(), e);
return null;
}))
.collect(Collectors.toList());
// 等待所有任务完成
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.get(5, TimeUnit.MINUTES); // 设置整体超时时间
// 批量保存数据
if (!wlStockDataList.isEmpty()) {
boolean success = baseMapper.insertBatch(wlStockDataList);
logger.info("批量插入{}条数据: {}", wlStockDataList.size(), success);
}
return wlStockDataList;
} catch (TimeoutException e) {
logger.error("生成文档操作超时", e);
throw new ServiceException("操作超时,请稍后重试");
} catch (Exception e) {
logger.error("生成文档时发生错误", e);
throw new ServiceException("生成文档失败:" + e.getMessage());
} finally {
executor.shutdown();
try {
if (!executor.awaitTermination(30, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
}).exceptionally(e -> {
e.printStackTrace();
return null;
});
} catch (InterruptedException e) {
executor.shutdownNow();
Thread.currentThread().interrupt();
}
}
}
// 等待所有任务完成
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
executor.shutdown();
baseMapper.insertBatch(wlStockDataList);
return wlStockDataList;
private WlStockData processWithRetry(SafetyStock safetyStock) {
int retryCount = 0;
while (retryCount < MAX_RETRIES) {
try {
return processMaterialCode(safetyStock);
} catch (Exception e) {
retryCount++;
if (retryCount == MAX_RETRIES) {
logger.error("处理物料{}失败,已重试{}次", safetyStock.getMaterialCode(), MAX_RETRIES, e);
return null;
}
logger.warn("处理物料{}失败,正在进行第{}次重试", safetyStock.getMaterialCode(), retryCount);
try {
Thread.sleep(RETRY_DELAY * retryCount);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
return null;
}
}
}
return null;
}
private WlStockData processMaterialCode(SafetyStock safetyStock) {
if (safetyStock == null) {
logger.error("SafetyStock is null");
if (safetyStock == null || StringUtils.isEmpty(safetyStock.getMaterialCode())) {
logger.error("无效的安全库存数据");
return null;
}
String materialCode = safetyStock.getMaterialCode();
if (materialCode == null) {
logger.error("Material code is null for SafetyStock: {}", safetyStock);
return null;
try {
// 获取库存分析报告
List<InvReserveAnalyzeRptDTO> analyzeRpt = JdUtil.getInvReserveAnalyzeRpt(materialCode);
double fSecAVBQty = 0.0;
double fSecQty = 0.0;
if (!CollectionUtils.isEmpty(analyzeRpt)) {
fSecAVBQty = analyzeRpt.get(0).getFSecAVBQty();
fSecQty = analyzeRpt.stream()
.mapToDouble(dto -> dto.getFSecQty() != null ? dto.getFSecQty() : 0.0)
.sum();
}
// 获取生产订单数量
double productionQty = Optional.ofNullable(JdUtil.getProMoList(materialCode))
.map(list -> list.stream()
.mapToDouble(ProMoDTO::getFQty)
.sum())
.orElse(0.0);
// 获取采购订单数量
double purchaseQty = Optional.ofNullable(JdUtil.getPurchaseOrderList(materialCode))
.map(list -> list.stream()
.mapToDouble(PurchaseOrderDTO::getFQty)
.sum())
.orElse(0.0);
// 计算可用库存
double availableStock = fSecAVBQty + productionQty + purchaseQty - fSecQty;
double minSafetyStock = safetyStock.getMinSafetyStock();
double maxSafetyStock = safetyStock.getMaxSafetyStock();
logger.debug("物料编码:{},生产订单数量: {}, 采购订单数量: {}, 可用库存: {}",materialCode,productionQty, purchaseQty, availableStock);
// 如果可用库存低于最小安全库存创建库存数据记录
if (availableStock < minSafetyStock) {
return createWlStockData(safetyStock, availableStock, fSecAVBQty,
productionQty, purchaseQty, fSecQty, minSafetyStock, maxSafetyStock);
}
} catch (Exception e) {
logger.error("处理物料编码时出错: {}", materialCode, e);
throw e; // 抛出异常以触发重试机制
}
return null;
}
List<InvReserveAnalyzeRptDTO> analyzeRpt = JdUtil.getInvReserveAnalyzeRpt(materialCode);
double fSecAVBQty = 0.0; // 默认值
double fSecQty = 0.0; // 默认值
private WlStockData createWlStockData(SafetyStock safetyStock, double availableStock,
double fSecAVBQty, double productionQty, double purchaseQty,
double fSecQty, double minSafetyStock, double maxSafetyStock) {
WlStockData wlStockData = new WlStockData();
wlStockData.setMaterialCode(safetyStock.getMaterialCode());
wlStockData.setMaterialName(safetyStock.getMaterialName());
wlStockData.setRequiredStock(maxSafetyStock);
wlStockData.setCurrentStock(availableStock);
wlStockData.setTriggerTime(new Date());
wlStockData.setAvailableStock(BigDecimal.valueOf(availableStock));
wlStockData.setProductionQty(BigDecimal.valueOf(productionQty));
wlStockData.setPurchaseQty(BigDecimal.valueOf(purchaseQty));
wlStockData.setSecQty(BigDecimal.valueOf(fSecQty));
wlStockData.setMinsafetyStock(BigDecimal.valueOf(minSafetyStock));
wlStockData.setMaxsafetyStock(BigDecimal.valueOf(maxSafetyStock));
wlStockData.setSecAvbqty(BigDecimal.valueOf(fSecAVBQty));
// 检查 analyzeRpt 是否为 null 或空
if (analyzeRpt != null && !analyzeRpt.isEmpty()) {
fSecAVBQty = analyzeRpt.get(0).getFSecAVBQty();
fSecQty = analyzeRpt.stream().mapToDouble(dto -> dto.getFSecQty() != null ? dto.getFSecQty() : 0.0).sum();
} else {
logger.warn("No inventory report found for material code: {}", materialCode);
// 如果没有库存数据fSecAVBQty fSecQty 保持为 0
}
double productionQty = 0.0;
double purchaseQty = 0.0;
productionQty = JdUtil.getProMoList(materialCode).stream().mapToDouble(ProMoDTO::getFQty).sum();
purchaseQty = JdUtil.getPurchaseOrderList(materialCode).stream().mapToDouble(PurchaseOrderDTO::getFQty).sum();
//可用库存
double availableStock = fSecAVBQty + productionQty + purchaseQty - fSecQty;
//最小安全库存
double minSafetyStock = safetyStock.getMinSafetyStock();
//最大安全库存
double maxSafetyStock = safetyStock.getMaxSafetyStock();
if (availableStock < minSafetyStock) {
WlStockData wlStockData = new WlStockData();
wlStockData.setMaterialCode(safetyStock.getMaterialCode());
wlStockData.setMaterialName(safetyStock.getMaterialName());
wlStockData.setRequiredStock(maxSafetyStock);
wlStockData.setCurrentStock(availableStock);
wlStockData.setTriggerTime(new Date());
wlStockData.setAvailableStock(BigDecimal.valueOf(availableStock));
wlStockData.setProductionQty(BigDecimal.valueOf(productionQty));
wlStockData.setPurchaseQty(BigDecimal.valueOf(purchaseQty));
wlStockData.setSecQty(BigDecimal.valueOf(fSecQty));
wlStockData.setMinsafetyStock(BigDecimal.valueOf(minSafetyStock));
wlStockData.setMaxsafetyStock(BigDecimal.valueOf(maxSafetyStock));
wlStockData.setSecAvbqty(BigDecimal.valueOf(fSecAVBQty));
wlStockData.setDocumentType("物料编码:" + materialCode + "||" + "可用库存:" + availableStock + "||" + "库存量:"
+ fSecAVBQty + "||" + "生产订单:" + productionQty + "||" + "采购订单:" + purchaseQty + "||" + "预留量:"
+ fSecQty + "||" + "最大库存:" + maxSafetyStock + "||" + "最低库存:" + minSafetyStock);
//创建生产订单
return wlStockData;
}else {
System.err.println("未找到物料编码的库相关信息: " + materialCode+ "可用库存:" + availableStock + "||" + "库存量:"
+ fSecAVBQty + "||" + "生产订单:" + productionQty + "||" + "采购订单:" + purchaseQty + "||" + "预留量:"
+ fSecQty + "||" + "最大库存:" + maxSafetyStock + "||" + "最低库存:" + minSafetyStock);
return null;
}
wlStockData.setDocumentType(String.format("物料编码:%s||可用库存:%.2f||库存量:%.2f||生产订单:%.2f||" +
"采购订单:%.2f||预留量:%.2f||最大库存:%.2f||最低库存:%.2f",
safetyStock.getMaterialCode(), availableStock, fSecAVBQty, productionQty,
purchaseQty, fSecQty, maxSafetyStock, minSafetyStock));
return wlStockData;
}
/**

View File

@ -18,6 +18,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateTime" column="update_time"/>
<result property="createBy" column="create_by"/>
<result property="updateBy" column="update_by"/>
<result property="materialValue" column="material_value"/>
</resultMap>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.KingdeeWorkCenterDataMapper">
<resultMap type="com.ruoyi.system.domain.KingdeeWorkCenterData" id="KingdeeWorkCenterDataResult">
<result property="id" column="id"/>
<result property="moBillNo" column="mo_bill_no"/>
<result property="moOrderNo" column="mo_order_no"/>
<result property="materialNumber" column="material_number"/>
<result property="materialName" column="material_name"/>
<result property="operQty" column="oper_qty"/>
<result property="transInQty" column="trans_in_qty"/>
<result property="transOutQty" column="trans_out_qty"/>
<result property="materialStatus" column="material_status"/>
<result property="operNumber" column="oper_number"/>
<result property="processName" column="process_name"/>
<result property="operPlanStartTime" column="oper_plan_start_time"/>
<result property="operPlanFinishTime" column="oper_plan_finish_time"/>
<result property="delayDays" column="delay_days"/>
<result property="workCenter" column="work_center"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
</resultMap>
</mapper>

View File

@ -35,5 +35,12 @@
<result property="xuEndTime" column="xu_end_time"/>
</resultMap>
<select id="existsByProcessNoAndMaterialCode" resultType="boolean">
SELECT COUNT(1) > 0
FROM process_route
WHERE process_no = #{processNo}
AND material_code = #{materialCode}
AND route_description = #{routeDescription}
</select>
</mapper>