电器物料管理
物料禁用等等 0125
This commit is contained in:
parent
f936d78407
commit
8684667167
1670
logs/sys-error.2025-01-16.log
Normal file
1670
logs/sys-error.2025-01-16.log
Normal file
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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 "切割库存问题已解决!";
|
||||
}
|
||||
}
|
||||
@ -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";
|
||||
}
|
||||
}
|
||||
@ -72,7 +72,7 @@ spring:
|
||||
# 国际化资源文件路径
|
||||
basename: i18n/messages
|
||||
profiles:
|
||||
active: @profiles.active@
|
||||
active: '@profiles.active@'
|
||||
# 文件上传
|
||||
servlet:
|
||||
multipart:
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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("更新成功");
|
||||
}
|
||||
}
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -39,7 +39,7 @@ public class ProductionOrder extends BaseEntity {
|
||||
/**
|
||||
* 生产数量
|
||||
*/
|
||||
private Long quantity;
|
||||
private Double quantity;
|
||||
/**
|
||||
* 生产材料
|
||||
*/
|
||||
|
||||
@ -111,7 +111,7 @@ public class ProductionRouteTwo extends BaseEntity {
|
||||
/**
|
||||
* 活动时长
|
||||
*/
|
||||
private Long activityLengh;
|
||||
private Double activityLengh;
|
||||
/**
|
||||
* bom材质
|
||||
*/
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -34,7 +34,7 @@ public class ProductionOrderBo extends BaseEntity {
|
||||
/**
|
||||
* 生产数量
|
||||
*/
|
||||
private Long quantity;
|
||||
private Double quantity;
|
||||
/**
|
||||
* 生产材料
|
||||
*/
|
||||
|
||||
@ -155,7 +155,7 @@ public class ProductionRouteTwoBo extends BaseEntity {
|
||||
* 活动时长
|
||||
*/
|
||||
@NotNull(message = "活动时长不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private Long activityLengh;
|
||||
private Double activityLengh;
|
||||
|
||||
/**
|
||||
* bom材质
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -33,4 +33,8 @@ public class ProcessRouteDTO {
|
||||
* 活动单位
|
||||
*/
|
||||
private String activityUnit;
|
||||
/**
|
||||
* 工序名称描述
|
||||
*/
|
||||
private String processNameDescription;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -15,6 +15,10 @@ public class ProcessRouteXuDTO {
|
||||
* 物料名称
|
||||
*/
|
||||
private String materialName;
|
||||
/**
|
||||
* 工序路线描述
|
||||
*/
|
||||
private String processDescription;
|
||||
/**
|
||||
* 工艺路线
|
||||
*/
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -72,7 +72,9 @@ public class BomDetailsVo {
|
||||
*子项数量
|
||||
*/
|
||||
@ExcelProperty(value = "子项分子")
|
||||
|
||||
private Double quantity;
|
||||
|
||||
@ExcelProperty(value = "子项分母")
|
||||
private Double denominator;
|
||||
/**
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
|
||||
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ public class ProductionOrderVo {
|
||||
* 生产数量
|
||||
*/
|
||||
@ExcelProperty(value = "数量")
|
||||
private Long quantity;
|
||||
private Double quantity;
|
||||
|
||||
/**
|
||||
* 生产材料
|
||||
|
||||
@ -157,7 +157,7 @@ public class ProductionRouteTwoVo {
|
||||
* 活动时长
|
||||
*/
|
||||
@ExcelProperty(value = "活动时长")
|
||||
private Long activityLengh;
|
||||
private Double activityLengh;
|
||||
|
||||
/**
|
||||
* bom材质
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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> {
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
// 检查目录是否存在,如果不存在则创建
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
|
||||
@ -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("未找到对应的 ProcessOrderProVo,ID: {}", 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
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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()); // 物料名称
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
|
||||
@ -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>
|
||||
@ -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>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user