feat(common): 优化PDF水印与Excel导出功能,新增分数转换工具

- PDFDocHelper优化图片水印处理逻辑,分离图纸章与文字水印步骤,增加临时文件处理机制
- ExcelUtil调整EasyExcel sheet索引,修复导出逻辑,增强多Sheet导出稳定性
- 新增FractionUtil工具类,支持字符串分数(如"1/21")与数字(如"0.0476")转换为保留3位小数的BigDecimal
- JdUtils扩展物料查询字段,增加修改日期查询,并修复物料禁用接口的变量引用问题
- SecurityConfig开放系统计划、MRP、订单等相关API的匿名访问权限
- BomDetailsController重构物料导入与验证逻辑,优化日志输出,新增工艺与图纸关联查询,修复BOM校验与保存流程
- EleMaterialsController移除冗余日志
- ImMaterialController新增基于日期的物料同步方法,集成K3Cloud API查询与数据处理
This commit is contained in:
tzy 2025-09-04 09:15:53 +08:00
parent 43a4b7a756
commit bdeba059ff
80 changed files with 3841 additions and 488 deletions

View File

@ -0,0 +1,50 @@
package com.ruoyi.common.utils;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class FractionUtil {
/**
* 将字符串数值支持分数形式如 "1/21" 或普通数字如 "0.0476"转为 BigDecimal保留 3 位小数四舍五入
* 允许出现空格 " 1 / 21 "
* @param val 原始字符串
* @return 三位小数的 BigDecimal若为空或非法返回 null也可改成 BigDecimal.ZERO
*/
public static BigDecimal toDecimal3(String val) {
if (val == null) return null;
String s = val.trim();
if (s.isEmpty()) return null;
// 兼容中文全角斜杠或奇怪字符
s = s.replace('', '/');
try {
if (s.contains("/")) {
// 分数形式
String[] parts = s.split("/");
if (parts.length != 2) return null;
String numStr = parts[0].trim();
String denStr = parts[1].trim();
if (numStr.isEmpty() || denStr.isEmpty()) return null;
BigDecimal numerator = new BigDecimal(numStr);
BigDecimal denominator = new BigDecimal(denStr);
if (denominator.compareTo(BigDecimal.ZERO) == 0) {
// 分母为 0视为非法
return null;
}
// 先用较高精度做除法避免中间精度丢失再统一 setScale(3)
BigDecimal valBD = numerator.divide(denominator, 10, RoundingMode.HALF_UP);
return valBD.setScale(3, RoundingMode.HALF_UP);
} else {
// 普通数字也支持 "0.047619""8.736841" 这类
BigDecimal valBD = new BigDecimal(s);
return valBD.setScale(3, RoundingMode.HALF_UP);
}
} catch (NumberFormatException ex) {
// 包含非数字内容时返回 null也可抛异常或返回 0
return null;
}
}
}

View File

@ -1463,7 +1463,7 @@ public class JdUtils {
//请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "BD_MATERIAL");
json.addProperty("FieldKeys", "FNumber,FName,FCategoryID.FNumber,F_SVRI_Assistant.FNumber,FErpClsID,FBaseUnitId.FName");
json.addProperty("FieldKeys", "FMATERIALID,FNumber,FName,FCategoryID.FNumber,F_SVRI_Assistant.FNumber,FErpClsID,FBaseUnitId.FName,FModifyDate");
JsonArray filterString = new JsonArray();
log.debug("构建查询条件...");
json.add("FilterString", filterString);
@ -1476,6 +1476,7 @@ public class JdUtils {
json.addProperty("StartRow", pageNo);
// 通过无限循环来持续查询数据直到没有更多数据为止
JSONArray list = new JSONArray();
JSONArray objects1;
while (true) {
// 将当前的JSON对象转换为字符串以符合查询接口的参数要求
String jsonData = json.toString();
@ -1483,7 +1484,7 @@ public class JdUtils {
// 调用客户端的billQuery方法传入JSON字符串作为查询参数
String input = String.valueOf(client.billQuery(jsonData));
// 将返回的JSON字符串转换为JSONArray对象
JSONArray objects1 = new JSONArray(input);
objects1 = new JSONArray(input);
/// 如果返回的数组为空则表示没有更多数据退出循环
if (objects1.size() == 0) {
break;
@ -1500,7 +1501,7 @@ public class JdUtils {
}
}
// 循环结束后返回总的查询结果数组
return list;
return objects1;
}
/*
物料属性查询
@ -1553,30 +1554,30 @@ 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";
@ -1584,12 +1585,12 @@ public class JdUtils {
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()));

View File

@ -183,55 +183,65 @@ public class PDFDocHelper {
return true;
}
public static boolean imageWatermark(String inputPath, String outputPath,String name,String images,List<Map<String, ?>> reviews,float[] pswX,float[] pswY) throws IOException, DocumentException {
//打图纸章水印
public static boolean imageWatermark(String inputPath, String outputPath, String name, String images,
List<Map<String, ?>> reviews, float[] pswX, float[] pswY) throws IOException, DocumentException {
PdfReader reader = new PdfReader(inputPath);
FileOutputStream foc = new FileOutputStream(outputPath+"/bom/"+ name);
// 临时输出文件名防止冲突
String tempName = name.replace(".pdf", "_temp.pdf");
String tempPath = outputPath + "/" + tempName;
FileOutputStream foc = new FileOutputStream(tempPath);
PdfStamper stamper = new PdfStamper(reader, foc);
PdfGState gs1 = new PdfGState();
float height = 0.0f;
try{
try {
gs1.setFillOpacity(1f);
Image image = Image.getInstance(images);
int n = reader.getNumberOfPages();
PdfContentByte under;
// 获取pdf的宽和高
Rectangle pageSize = reader.getPageSize(1);
height = pageSize.getHeight();
PdfContentByte pdfContentByte = stamper.getOverContent(1);
PdfContentByte pdunder = stamper.getUnderContent(1);
// 获得PDF最顶层
under = stamper.getOverContent(1);
pdfContentByte.setGState(gs1);
pdunder.setGState(gs1);
// 水印文字成45度角倾斜
image.setRotation(30);// 旋转 弧度
// 设置旋转角度
image.setRotationDegrees(0);// 旋转 角度
// 设置等比缩放
under.setColorFill(BaseColor.RED);
//设置水印的大小同比缩小
image.scaleToFit(100,190);
image.setRotation(45);
image.setAbsolutePosition(0, height-190); // set the first background image of the absolute
pdfContentByte.addImage(image);
}catch (Exception e){
// 获取每页打图章
for (int i = 1; i <= n; i++) {
PdfContentByte over = stamper.getOverContent(i);
Rectangle pageSize = reader.getPageSize(i);
float height = pageSize.getHeight();
// 设置图章样式
image.setRotationDegrees(0);
image.scaleToFit(100, 190);
image.setRotation(45);
image.setAbsolutePosition(0, height - 190);
over.setGState(gs1);
over.addImage(image);
}
} catch (Exception e) {
e.printStackTrace();
return false;
}finally{
} finally {
stamper.close();
foc.close();
reader.close();
}
//打文字水印
// 第二次处理 添加文字水印
try {
signSinglePsw(outputPath,name,reviews,pswX,pswY);
signSinglePsw(outputPath, tempName, outputPath, name, reviews, pswX, pswY);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
// 删除临时文件
File tempFile = new File(tempPath);
if (tempFile.exists()) {
tempFile.delete();
}
return true;
}
/**
* pdf合并
* @param files
@ -255,27 +265,31 @@ public class PDFDocHelper {
return new File(targetPath);
}
private static String signSinglePsw(String oldPswFilePath,String name,List<Map<String, ?>> reviews,float[] pswX,float[] pswY) throws IOException, DocumentException {
private static String signSinglePsw(String inputDir, String inputName, String outputDir, String outputName,
List<Map<String, ?>> reviews, float[] pswX, float[] pswY)
throws IOException, DocumentException {
PdfReader reader = new PdfReader(oldPswFilePath + "/bom/" + name);
FileOutputStream foc = new FileOutputStream(oldPswFilePath + "/zip/" + name);
PdfReader reader = new PdfReader(inputDir + "/" + inputName);
FileOutputStream foc = new FileOutputStream(outputDir + "/" + outputName);
PdfStamper stp = new PdfStamper(reader, foc);
for (int i = 0; i < reader.getNumberOfPages(); ) {
i++;
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
PdfContentByte content = stp.getOverContent(i);
content.beginText();
// 设置字体及字号
content.setFontAndSize(getBaseFont(), 10);
Map<String, Object> review = (Map<String, Object>) reviews.get(0);
addDeptReview(content, review,pswX[0],pswY[0]);
addDeptReview(content, review, pswX[0], pswY[0]);
content.endText();
}
stp.close();
foc.close();
reader.close();
return oldPswFilePath + "/zip/" + name;
return outputDir + "/" + outputName;
}
/**
* 合并打印文字水印和图纸章水印
* inputPath 原始图路径

View File

@ -68,7 +68,7 @@ public class ExcelUtil {
}
public static <T> ExcelResult<T> importExcelSheet6(InputStream is, Class<T> clazz, boolean isValidate) {
DefaultExcelListener<T> listener = new DefaultExcelListener<>(isValidate);
EasyExcel.read(is, clazz, listener).sheet(5).doRead();
EasyExcel.read(is, clazz, listener).sheet(6).doRead();
return listener.getExcelResult();
}
public static <T> ExcelResult<T> importExcelSheet1(InputStream is, Class<T> clazz, boolean isValidate) {
@ -159,26 +159,26 @@ public class ExcelUtil {
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode(sheetName1, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
os = response.getOutputStream();
// 创建ExcelWriter
excelWriter = EasyExcel.write(os)
.autoCloseStream(false) // 防止自动关闭流
.build();
// 写入第一个sheet
WriteSheet writeSheet1 = EasyExcel.writerSheet(0, sheetName1)
.head(clazz1)
.build();
excelWriter.write(list1, writeSheet1);
// 写入第二个sheet
WriteSheet writeSheet2 = EasyExcel.writerSheet(1, sheetName2)
.head(clazz2)
.build();
excelWriter.write(list2, writeSheet2);
} catch (Exception e) {
throw new RuntimeException("导出Excel异常: " + e.getMessage(), e);
} finally {
@ -440,10 +440,10 @@ public class ExcelUtil {
if (CollUtil.isEmpty(list) || CollUtil.isEmpty(sheetNames) || list.size() != sheetNames.size()) {
throw new IllegalArgumentException("数据列表或sheet名称列表不能为空且两者长度必须相等");
}
resetResponse(sheetNames.get(0), response);
ServletOutputStream os = response.getOutputStream();
// 创建ExcelWriter
ExcelWriter excelWriter = EasyExcel.write(os)
.autoCloseStream(false)
@ -452,7 +452,7 @@ public class ExcelUtil {
// 大数值自动转换 防止失真
.registerConverter(new ExcelBigNumberConvert())
.build();
try {
// 循环写入每个sheet
for (int i = 0; i < list.size(); i++) {
@ -487,14 +487,14 @@ public class ExcelUtil {
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("导出数据", "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
os = response.getOutputStream();
// 创建ExcelWriter
excelWriter = EasyExcel.write(os)
.autoCloseStream(false) // 防止自动关闭流
.build();
// 循环写入每个sheet
for (int i = 0; i < sheetDataList.size(); i++) {
SheetData<?> sheetData = sheetDataList.get(i);
@ -503,7 +503,7 @@ public class ExcelUtil {
.build();
excelWriter.write(sheetData.getData(), writeSheet);
}
} catch (Exception e) {
throw new RuntimeException("导出Excel异常: " + e.getMessage(), e);
} finally {

View File

@ -31,7 +31,13 @@ public class SecurityConfig {
.headers().frameOptions().disable()
.and().authorizeRequests()
.antMatchers("/system/proPlan/**").anonymous()
.antMatchers("/system/mrp/**").anonymous()
.antMatchers("/system/orderPro/**").anonymous()
// .antMatchers("/dev-api/system/proPlan/overdue").anonymous()
// .antMatchers("/dev-api/system/proPlan/expiryProjects").anonymous()
.antMatchers("/dev-api/system/material/list/").anonymous()
.antMatchers("/dev-api/system/dict/data/type/**").anonymous()
.antMatchers("/dev-api/index/list/").anonymous()
.antMatchers("/jmreport/**").anonymous()
.antMatchers(adminContextPath + "/assets/**"

View File

@ -21,16 +21,16 @@ import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.JdUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.BomDetails;
import com.ruoyi.system.domain.FigureSave;
import com.ruoyi.system.domain.MaterialProperties;
import com.ruoyi.system.domain.bo.BomDetailsBo;
import com.ruoyi.system.domain.bo.ProcessOrderProBo;
import com.ruoyi.system.domain.dto.JdValidateBomDTO;
import com.ruoyi.system.domain.dto.JdChildDTO;
import com.ruoyi.system.domain.vo.BomDetailsVo;
import com.ruoyi.system.mapper.FigureSaveMapper;
import com.ruoyi.system.runner.JdUtil;
import com.ruoyi.system.service.IBomDetailsService;
import com.ruoyi.system.service.IMaterialPropertiesService;
import com.ruoyi.system.service.IMaterialTotalService;
import com.ruoyi.system.service.IProcessRouteService;
import com.ruoyi.system.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
@ -73,7 +73,9 @@ public class BomDetailsController extends BaseController {
private final IMaterialTotalService iMaterialTotalService;
private final IProcessOrderProService iProcessOrderProService;
private final IFigureSaveService iFigureSaveService;
/**
* 查询bom明细列表
@ -200,6 +202,7 @@ public class BomDetailsController extends BaseController {
/**
* 导入BOM
* daorubaon
*
* @param file 导入文件
*/
@ -214,7 +217,7 @@ public class BomDetailsController extends BaseController {
HashMap<String, String> bomFinishedProduct = getBomFinishedProduct(file);
// 新增成品父级物流
if (loadChengPinMaterialPreservation(bomFinishedProduct) == 1) {
log.info("新增成品父级物成功");
log.info("新增成品父级物成功");
}
for (BomDetailsVo bomDetailsvo : bomDetailsVos) {
BomDetails bomDetails = BeanUtil.toBean(bomDetailsvo, BomDetails.class);
@ -226,35 +229,19 @@ public class BomDetailsController extends BaseController {
}
// 验证物料是否存在
if (bomDetails.getFNumber() != null && bomDetails.getFName() != null && bomDetails.getPartNumber() != null && bomDetails.getName() != null) {
int verification = isMaterialVerification(bomDetails.getPartNumber(), bomDetails.getName());
if (verification == 1) {
bomDetails.setUnitWeight("");
} else if (verification == 3) {
if (bomDetails.getStats() == null || bomDetails.getStats().equals("外购") || bomDetails.getFName().startsWith("009") || bomDetails.getFName().startsWith("AA") || bomDetails.getFName().startsWith("AB") || bomDetails.getFName().startsWith("AC") || bomDetails.getFName().startsWith("015")) {
materialsToAdd.add(bomDetails);
} else if (bomDetails.getStats().equals("自制")) {
materialsToAdd.add(bomDetails);
} else if (bomDetails.getStats().equals("委外")) {
materialsToAdd.add(bomDetails);
}
bomDetails.setUnitWeight("编码名称不符");
} else {
if (bomDetails.getStats() == null || bomDetails.getStats().equals("外购") || bomDetails.getFName().startsWith("009") || bomDetails.getFName().startsWith("AA") || bomDetails.getFName().startsWith("AB") || bomDetails.getFName().startsWith("AC") || bomDetails.getFName().startsWith("015")) {
materialsToAdd.add(bomDetails);
} else if (bomDetails.getStats().equals("自制")) {
materialsToAdd.add(bomDetails);
} else if (bomDetails.getStats().equals("委外")) {
materialsToAdd.add(bomDetails);
}
bomDetails.setUnitWeight("");
//TODO 验证物料是否存在 这里存在问题
if (bomDetailsvo.getUnitWeight().equals("")) {
continue;
} else if (bomDetailsvo.getUnitWeight().equals("")) {
materialsToAdd.add(bomDetails);
} else if (bomDetailsvo.getUnitWeight().equals("编码名称不符")) {
materialsToAdd.add(bomDetails);
}
}
// 保存当前记录
BomDetailsVo bean = BeanUtil.toBean(bomDetails, BomDetailsVo.class);
iBomDetailsService.insertByVo(bean);
}
// 记录缺失字段的警告信息
if (!missingFieldsWarnings.isEmpty()) {
log.warn("导入时发现以下记录缺少必要字段: \n" + String.join("\n", missingFieldsWarnings));
@ -266,28 +253,23 @@ public class BomDetailsController extends BaseController {
if (material == null) {
continue; // 如果 material 为空则跳过当前循环
}
String state = determineState(material);
log.info("开始新增不存在的物料==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName());
System.out.println("state:=======================>" + state);
// 判断是否是电器物料
int result;
if (material.getTotalWeight().contains("DQ")) {
log.info("开始新增不存在的电气物料==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName());
log.info("项目号,物料图号,物料名称, {},{},{}", material.getTotalWeight(), material.getPartNumber(), material.getName());
result = loadMaterialToDQ(material, state);
} else {
Double a = 0.0;
log.info("开始新增不存在的物料==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName());
log.info("项目号,物料图号,物料名称, {},{},{}", material.getTotalWeight(), material.getPartNumber(), material.getName());
result = loadMaterialPreservation(material, state, a);
}
if (result == 1) {
log.info("新增物料成功==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName());
log.info("项目号,物料图号,物料名称新增成功, {},{},{}", material.getTotalWeight(), material.getPartNumber(), material.getName());
material.setUnitWeight("新增成功");
bomDetails.add(material);
} else {
log.error("新增物料失败==> 物料图号: " + material.getPartNumber() + " 物料名称: " + material.getName());
log.info("项目号,物料图号,物料名称新增失败, {},{},{}", material.getTotalWeight(), material.getPartNumber(), material.getName());
material.setUnitWeight("新增成功");
bomDetails.add(material);
}
@ -382,25 +364,21 @@ public class BomDetailsController extends BaseController {
// 根据物料编码和生产令号查询
List<BomDetails> bomDetails = iBomDetailsService.selectByFNumberAndTotalWeight(fnumber, totalWeight);
log.info("处理物料编码: {}, 生产令号: {}", fnumber, totalWeight);
if (bomDetails != null && !bomDetails.isEmpty()) {
// 检查金蝶中是否存在该物料的BOM
for (BomDetails material : bomDetails) {
// 只在第一次遇到该物料时新增父级物料
if (!processedMaterials.contains(material.getFNumber())) {
try {
log.info("开始新增不存在的物料 ==> 物料图号: {}, 物料名称: {}", material.getPartNumber(), material.getName());
Double fbWorkTime = iProcessRouteService.getFaWorkTime(material);
JdUtil.loadChengPinMaterialPreservation(material, fbWorkTime);
processedMaterials.add(material.getFNumber()); // 标记为已处理
} catch (Exception e) {
log.error("新增父级物料失败: {}", e.getMessage());
failedMaterials.add(material.getPartNumber());
}
}
//TODO 处理父级物料
ProcessOrderProBo bo = iProcessOrderProService.selectByProjectNumber(totalWeight);
List<FigureSave> list = iFigureSaveService.selectByProCode(totalWeight);
if (list.size() > 0) {
for (FigureSave figureSave : list) {
String figureNumber = figureSave.getFigureNumber();
List<BomDetails> bomDetails1 = iBomDetailsService.selectByFNumberAndTotalWeight(figureNumber, totalWeight);
}
}
for (BomDetails material : bomDetails) {
// 获取工艺表中的非委外工时
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());
@ -427,14 +405,12 @@ public class BomDetailsController extends BaseController {
}
// 保存物料清单之前进行BOM校验
if (validateBOM(fnumber, bomDetails)) {
log.error("BOM校验失败物料编码: {}", fnumber);
if (validateBOM(fnumber, bomDetails)) {
failedMaterials.add(fnumber);
continue; // 跳过保存
}
// 物料清单保存方法
FBloadBillOfMaterialsPreservation(bomDetails);
FBloadBillOfMaterialsPreservation(bomDetails, bo);
bomDetailsList.addAll(bomDetails);
}
}
@ -527,10 +503,7 @@ public class BomDetailsController extends BaseController {
JsonObject fGroupType = new JsonObject();
model.add("FGroup", fGroupType);
fGroupType.addProperty("FNumber", "X007");
/*
* model.addProperty("FCfgBomId", 0);
* model.addProperty("FYIELDRATE", 100.0);
*/
// 创建FMATERIALID对象并加入Model
JsonObject fMaterialId = new JsonObject();
model.add("FMATERIALID", fMaterialId);
@ -612,12 +585,12 @@ public class BomDetailsController extends BaseController {
}
// FBOM物料清单保存
public void FBloadBillOfMaterialsPreservation(List<BomDetails> bomlist) {
public void FBloadBillOfMaterialsPreservation(List<BomDetails> bomlist, ProcessOrderProBo bo) {
BomDetails bomDetails1 = bomlist.get(0);
int verification = isMaterialVerification(bomDetails1.getFNumber(), bomDetails1.getFName());
// 验证父级物料是否存在
if (verification == 0) {
if (verification == 2) {
log.debug("父级物料物料不存在");
// 父级物料不存在,即调用物料新增接口
int materialVerificationResult = loadFBMaterialPreservation(bomDetails1);
@ -647,10 +620,6 @@ public class BomDetailsController extends BaseController {
JsonObject fGroupType = new JsonObject();
model.add("FGroup", fGroupType);
fGroupType.addProperty("FNumber", "TT001");
/*
* model.addProperty("FCfgBomId", 0);
* model.addProperty("FYIELDRATE", 100.0);
*/
// 创建FMATERIALID对象并加入Model
JsonObject fMaterialId = new JsonObject();
model.add("FMATERIALID", fMaterialId);
@ -751,7 +720,6 @@ public class BomDetailsController extends BaseController {
// 对返回结果进行解析和校验
RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
if (repoRet.getResult().getResponseStatus().isIsSuccess()) {
System.out.printf("接口返回结果: %s%n", gson.toJson(repoRet.getResult()));
log.debug("物料清单bom 保存成功===================>" + "图号:" + bomDetails1.getFNumber());
} else {
log.error("物料清单bom 保存失败===================>" + "图号:" + bomDetails1.getFNumber());
@ -1315,7 +1283,7 @@ public class BomDetailsController extends BaseController {
}
JsonArray jsonArray = JdUtils.loadMaterialQuery(DrawingNumber, name);
if (jsonArray == null) {
return 0;
return 2;
} else {
for (JsonElement jsonElement : jsonArray) {
String FNumber = jsonElement.getAsJsonObject().get("FNumber").getAsString();
@ -1335,16 +1303,17 @@ public class BomDetailsController extends BaseController {
}
/**
* x
* 物料验证
* 获取单位
*/
public static String isMaterialVerification2(String DrawingNumber) {
if (DrawingNumber == null || DrawingNumber.isEmpty()) {
return "不存在";
return "jian";
}
JsonArray jsonArray = JdUtils.loadMaterialQueryDrawingNumber(DrawingNumber);
if (jsonArray == null) {
return "不存在";
return "jian";
} else {
String Funit = null;
for (JsonElement jsonElement : jsonArray) {
@ -1371,7 +1340,7 @@ public class BomDetailsController extends BaseController {
//单重
if (!(bomDetails1.getDanZhong() == null) && !(bomDetails1.getSingleWeghit() == null)) {
model.addProperty("F_HBYT_DZ", bomDetails1.getSingleWeghit());
}else {
} else {
model.addProperty("F_HBYT_DZ", bomDetails1.getDanZhong());
}
model.addProperty("FSpecification", bomDetails1.getRemarks());

View File

@ -240,7 +240,6 @@ public class EleMaterialsController extends BaseController {
@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();
@ -295,8 +294,6 @@ public class EleMaterialsController extends BaseController {
for (JdHuoZhu jdEntryVmi : entryID) {
int fmaterialid = jdEntryVmi.getFID();
int fEntryId1 = jdEntryVmi.getFTreeEntityFENTRYID();
log.info("物料" + vmi.getMaterialCode() + "的FId: " + fmaterialid);
log.info("物料" + vmi.getMaterialCode() + "fEntryId: " + fEntryId1);
try {
JdUtil.updateHuozhu(fmaterialid, fEntryId1, vmi.getMaterialCode());
} catch (Exception e) {

View File

@ -3,8 +3,13 @@ package com.ruoyi.system.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONArray;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.controller.BaseController;
@ -37,8 +42,11 @@ import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import static com.ruoyi.common.core.mapper.BaseMapperPlus.log;
/**
* 物料检索
*
@ -261,23 +269,153 @@ public class ImMaterialController extends BaseController {
@XxlJob("updateMaterials")
public void updateMaterials() {
JSONArray jsonArray = JdUtils.loadMaterial();
JsonArray jsonArray1 = null;
if (jsonArray != null) {
jsonArray1 = new Gson().fromJson(jsonArray.toString(), JsonArray.class);
}
iImMaterialService.updateMaterials(jsonArray1);
public Boolean updateMaterials() throws Exception {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
List<ImMaterial> imMaterials = updateJdMaterial(sdf.format(date));
Boolean result = iImMaterialService.updateByFMid(imMaterials);
return result;
}
public List<ImMaterial> updateJdMaterial(String date) throws Exception {
K3CloudApi client = new K3CloudApi();
//请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "BD_MATERIAL");
json.addProperty("FieldKeys", "FMATERIALID,FNumber,FName,FCategoryID.FNumber,F_HBYT_DZ,F_SVRI_Assistant.FNumber,FErpClsID,FBaseUnitId.FName,FModifyDate,FForbidStatus");
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FForbidStatus"); // 使用传入的 fieldName
filterObject.addProperty("Compare", "105");
filterObject.addProperty("Value", "A");
filterObject.addProperty("Left", "");
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);
filterString.add(filterObject);
JsonObject filterObject1 = new JsonObject();
filterObject1.addProperty("FieldName", "FCreateDate"); // 使用传入的 fieldName
filterObject1.addProperty("Compare", "93");
filterObject1.addProperty("Value", date);
filterObject1.addProperty("Left", "");
filterObject1.addProperty("Right", "");
filterObject1.addProperty("Logic", 0);
filterString.add(filterObject1);
JsonObject filterObject2 = new JsonObject();
filterObject2.addProperty("FieldName", "FCreateDate"); // 使用传入的 fieldName
filterObject2.addProperty("Compare", "93");
filterObject2.addProperty("Value", date);
filterObject2.addProperty("Left", "");
filterObject2.addProperty("Right", "");
filterObject2.addProperty("Logic", 0);
filterString.add(filterObject2);
log.debug("构建查询条件...");
json.add("FilterString", filterString);
json.addProperty("OrderString", "");
json.addProperty("TopRowCount", 0);
json.addProperty("Limit", 10000);
json.addProperty("SubSystemId", "");
int pageNo = 0;
json.addProperty("StartRow", pageNo);
// 通过无限循环来持续查询数据直到没有更多数据为止
JSONArray list = new JSONArray();
JSONArray objects1;
while (true) {
// 将当前的JSON对象转换为字符串以符合查询接口的参数要求
String jsonData = json.toString();
try {
// 调用客户端的billQuery方法传入JSON字符串作为查询参数
String input = String.valueOf(client.billQuery(jsonData));
// 将返回的JSON字符串转换为JSONArray对象
objects1 = new JSONArray(input);
/// 如果返回的数组为空则表示没有更多数据退出循环
if (objects1.size() == 0) {
break;
}
// 将本次查询到的数据添加到总的查询结果数组中
list.addAll(objects1);
// 更新页码为下一次查询准备
pageNo++;
// 更新JSON对象中的StartRow属性用于下一次查询的分页
json.addProperty("StartRow", pageNo * 10000);
} catch (Exception e) {
e.printStackTrace();
}
}
ObjectMapper objectMapper = new ObjectMapper();
List<ImMaterial> materialList = objectMapper.readValue(
list.toString(),
new TypeReference<List<ImMaterial>>() {
});
return materialList;
}
public List<ImMaterial> loadMaterial() throws JsonProcessingException {
K3CloudApi client = new K3CloudApi();
//请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "BD_MATERIAL");
json.addProperty("FieldKeys", "FMATERIALID,FNumber,FName,FCategoryID.FNumber,F_HBYT_DZ,F_SVRI_Assistant.FNumber,FErpClsID,FBaseUnitId.FName,FModifyDate,FForbidStatus");
JsonArray filterString = new JsonArray();
log.debug("构建查询条件...");
json.add("FilterString", filterString);
json.addProperty("OrderString", "");
json.addProperty("TopRowCount", 0);
json.addProperty("Limit", 10000);
json.addProperty("SubSystemId", "");
int pageNo = 0;
json.addProperty("StartRow", pageNo);
// 通过无限循环来持续查询数据直到没有更多数据为止
JSONArray list = new JSONArray();
JSONArray objects1;
while (true) {
// 将当前的JSON对象转换为字符串以符合查询接口的参数要求
String jsonData = json.toString();
try {
// 调用客户端的billQuery方法传入JSON字符串作为查询参数
String input = String.valueOf(client.billQuery(jsonData));
// 将返回的JSON字符串转换为JSONArray对象
objects1 = new JSONArray(input);
/// 如果返回的数组为空则表示没有更多数据退出循环
if (objects1.size() == 0) {
break;
}
// 将本次查询到的数据添加到总的查询结果数组中
list.addAll(objects1);
// 更新页码为下一次查询准备
pageNo++;
// 更新JSON对象中的StartRow属性用于下一次查询的分页
json.addProperty("StartRow", pageNo * 10000);
} catch (Exception e) {
e.printStackTrace();
}
}
ObjectMapper objectMapper = new ObjectMapper();
List<ImMaterial> materialList = objectMapper.readValue(
list.toString(),
new TypeReference<List<ImMaterial>>() {
});
return materialList;
}
/**
* 更新库存
* @return
* 保存所有的物料编码
* @return List<ImMaterial>
*/
@GetMapping("/insertJDMaterial")
public List<ImMaterial> insertJDMaterial() throws Exception {
List<ImMaterial> materialList = loadMaterial();
iImMaterialService.insertJDMaterial(materialList);
return materialList;
}
@GetMapping("/updateInventory")
@PostMapping("/updateInventory")
public String updateInventory() {
List<ImMaterial> imMaterialCodeList = imMaterialMapper.selectList();
iImMaterialService.updateInventory(imMaterialCodeList);
return "string";

View File

@ -61,7 +61,7 @@ public class IndexController {
try {
// 并行执行多个查询任务
CompletableFuture<Double> inventoryFuture = CompletableFuture.supplyAsync(() -> {
log.info("开始查询库存数量: {}", materialCode);
log.info("开始查询即时库存数量: {}", materialCode);
return Optional.ofNullable(JdUtil.getKuCun(materialCode))
.map(list -> list.stream()
.mapToDouble(JDInventoryDTO::getFBaseQty)
@ -70,7 +70,7 @@ public class IndexController {
}, executorService);
CompletableFuture<Double> noPickedFuture = CompletableFuture.supplyAsync(() -> {
log.info("开始查询未领料数量: {}", materialCode);
log.info("开始查询生产用料清单子项未领料数量: {}", materialCode);
return Optional.ofNullable(JdUtil.getWeiLingliao(materialCode))
.map(list -> list.stream()
.mapToDouble(JDProductionDTO::getFNoPickedQty)
@ -105,7 +105,7 @@ public class IndexController {
double productionQty = productionFuture.get();
double purchaseQty = purchaseFuture.get();
// 计算预计可用库存
// 计算预计可用库存 即时库存+生产未入库+(采购申请-采购未入库)-子项未领料
double keyong = inventoryQty + productionQty + purchaseQty - fNoPickedQty;
InventoryInfoVO inventoryInfoVO = new InventoryInfoVO();
inventoryInfoVO.setMaterialCode(materialCode);

View File

@ -0,0 +1,106 @@
package com.ruoyi.system.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
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.KingdeeAssetCardVo;
import com.ruoyi.system.domain.bo.KingdeeAssetCardBo;
import com.ruoyi.system.service.IKingdeeAssetCardService;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* 金蝶资产卡片
*
* @author ruoyi
* @date 2025-09-04
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/assetCard")
public class KingdeeAssetCardController extends BaseController {
private final IKingdeeAssetCardService iKingdeeAssetCardService;
/**
* 查询金蝶资产卡片列表
*/
@SaCheckPermission("system:assetCard:list")
@GetMapping("/list")
public TableDataInfo<KingdeeAssetCardVo> list(KingdeeAssetCardBo bo, PageQuery pageQuery) {
return iKingdeeAssetCardService.queryPageList(bo, pageQuery);
}
/**
* 导出金蝶资产卡片列表
*/
@SaCheckPermission("system:assetCard:export")
@Log(title = "金蝶资产卡片", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(KingdeeAssetCardBo bo, HttpServletResponse response) {
List<KingdeeAssetCardVo> list = iKingdeeAssetCardService.queryList(bo);
ExcelUtil.exportExcel(list, "金蝶资产卡片", KingdeeAssetCardVo.class, response);
}
/**
* 获取金蝶资产卡片详细信息
*
* @param id 主键
*/
@SaCheckPermission("system:assetCard:query")
@GetMapping("/{id}")
public R<KingdeeAssetCardVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iKingdeeAssetCardService.queryById(id));
}
/**
* 新增金蝶资产卡片
*/
@SaCheckPermission("system:assetCard:add")
@Log(title = "金蝶资产卡片", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody KingdeeAssetCardBo bo) {
return toAjax(iKingdeeAssetCardService.insertByBo(bo));
}
/**
* 修改金蝶资产卡片
*/
@SaCheckPermission("system:assetCard:edit")
@Log(title = "金蝶资产卡片", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody KingdeeAssetCardBo bo) {
return toAjax(iKingdeeAssetCardService.updateByBo(bo));
}
/**
* 删除金蝶资产卡片
*
* @param ids 主键串
*/
@SaCheckPermission("system:assetCard:remove")
@Log(title = "金蝶资产卡片", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iKingdeeAssetCardService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

View File

@ -485,27 +485,29 @@ public class KingdeeWorkCenterDataController extends BaseController {
long transOutQty = item.getLong("FTransOutQty");
// 转入
long transInQty = item.getLong("FTransInQty");
// 转换为实体对象
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 (transOutQty<transInQty){
// 转换为实体对象
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("保存工段数据失败");
}
}
}
}
}

View File

@ -0,0 +1,133 @@
package com.ruoyi.system.controller;
import java.sql.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.springframework.beans.BeanUtils;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.MrpResultCheck;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
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.MrpResultCheckVo;
import com.ruoyi.system.domain.bo.MrpResultCheckBo;
import com.ruoyi.system.service.IMrpResultCheckService;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* MRP运算结果复查
*
* @author tzy
* @date 2025-08-22
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/mrp")
public class MrpResultCheckController extends BaseController {
private final IMrpResultCheckService iMrpResultCheckService;
/**
* 查询MRP运算结果复查列表
*/
@SaCheckPermission("system:mrp:list")
@GetMapping("/list")
public TableDataInfo<MrpResultCheckVo> list(MrpResultCheckBo bo, PageQuery pageQuery) {
return iMrpResultCheckService.queryPageList(bo, pageQuery);
}
/**
* 导出MRP运算结果复查列表
*/
@SaCheckPermission("system:mrp:export")
@Log(title = "MRP运算结果复查", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(@RequestBody MrpResultCheckBo bo, HttpServletResponse response) {
// 1. 验证必填参数
if (bo.getOrderProId() == null) {
throw new ServiceException("生产令号ID不能为空");
}
List<MrpResultCheck> list = iMrpResultCheckService.queryListByOrderProId(bo);
if (StringUtils.isNotEmpty(bo.getMaterialCode())) {
list = list.stream()
.filter(item -> item.getMaterialCode().contains(bo.getMaterialCode()))
.collect(Collectors.toList());
}
List<MrpResultCheckVo> mrpResultCheckVos = list.stream()
.map(item -> {
MrpResultCheckVo vo = new MrpResultCheckVo();
BeanUtils.copyProperties(item, vo);
return vo;
})
.collect(Collectors.toList());
ExcelUtil.exportExcel(mrpResultCheckVos, "MRP运算结果复查", MrpResultCheckVo.class, response);
}
/**
* 获取MRP运算结果复查详细信息
*
* @param id 主键
*/
@SaCheckPermission("system:mrp:query")
@GetMapping("/{id}")
public R<MrpResultCheckVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iMrpResultCheckService.queryById(id));
}
/**
* 新增MRP运算结果复查
*/
@SaCheckPermission("system:mrp:add")
@Log(title = "MRP运算结果复查", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody MrpResultCheckBo bo) {
return toAjax(iMrpResultCheckService.insertByBo(bo));
}
/**
* 修改MRP运算结果复查
*/
@SaCheckPermission("system:mrp:edit")
@Log(title = "MRP运算结果复查", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody MrpResultCheckBo bo) {
return toAjax(iMrpResultCheckService.updateByBo(bo));
}
/**
* 删除MRP运算结果复查
*
* @param ids 主键串
*/
@SaCheckPermission("system:mrp:remove")
@Log(title = "MRP运算结果复查", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iMrpResultCheckService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

View File

@ -1,12 +1,23 @@
package com.ruoyi.system.controller;
import java.util.List;
import java.util.Arrays;
import java.io.ByteArrayInputStream;
import java.util.*;
import java.util.stream.Collectors;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.ruoyi.common.excel.DefaultExcelListener;
import com.ruoyi.system.domain.PcRigidChain;
import com.ruoyi.system.mapper.PcRigidChainMapper;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.ruoyi.common.annotation.RepeatSubmit;
@ -22,6 +33,7 @@ import com.ruoyi.system.domain.vo.PcRigidChainVo;
import com.ruoyi.system.domain.bo.PcRigidChainBo;
import com.ruoyi.system.service.IPcRigidChainService;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;
/**
* 销齿链型号管理
@ -33,10 +45,12 @@ import com.ruoyi.common.core.page.TableDataInfo;
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/pcRigidChain")
@Slf4j
public class PcRigidChainController extends BaseController {
private final IPcRigidChainService iPcRigidChainService;
@Autowired
private PcRigidChainMapper pcRigidChainMapper;
/**
* 查询销齿链型号管理列表
*/
@ -103,4 +117,110 @@ public class PcRigidChainController extends BaseController {
@PathVariable Long[] ids) {
return toAjax(iPcRigidChainService.deleteWithValidByIds(Arrays.asList(ids), true));
}
@SaCheckPermission("system:pcRigidChain:importVariableData')")
@PostMapping("/importVariableData")
public R<List<PcRigidChain>> importVariableData(@RequestParam("file") MultipartFile file) throws Exception {
if (file == null || file.isEmpty()) {
return R.fail("上传文件不能为空");
}
byte[] fileBytes = file.getBytes();
String originalFilename = file.getOriginalFilename();
if (originalFilename == null || originalFilename.isEmpty()) {
return R.fail("文件名不能为空");
}
String type = "";
if (originalFilename.contains("30D")) {
type = "30D";
} else if (originalFilename.contains("30S")) {
type = "30S";
} else if (originalFilename.contains("35E_R")) {
type = "35E";
} else if (originalFilename.contains("40R")) {
type = "40R";
} else if (originalFilename.contains("40S")) {
type = "40S";
} else if (originalFilename.contains("60R")) {
type = "60R";
} else if (originalFilename.contains("80R")) {
type = "80R";
} else if (originalFilename.contains("100R")) {
type = "100R";
} else if (originalFilename.contains("125R")) {
type = "125R";
}
//每个产品都会有 ,,+
List<String> AxialDirection = Arrays.asList("R", "L", "L+R");
ExcelReaderBuilder read = EasyExcel.read(new ByteArrayInputStream(fileBytes));
List<PcRigidChain> pcRigidChainsToUpdate = null;
for (ReadSheet readSheet : read.build().excelExecutor().sheetList()) {
DefaultExcelListener<PcRigidChainVo> excelListener = new DefaultExcelListener<>(true);
EasyExcel.read(new ByteArrayInputStream(fileBytes), PcRigidChainVo.class, excelListener)
.excelType(ExcelTypeEnum.XLS)
.sheet(readSheet.getSheetNo())
.headRowNumber(3)
.doRead();
List<PcRigidChainVo> list = excelListener.getExcelResult().getList();
pcRigidChainsToUpdate = new ArrayList<>();
// 批量查询数据库中的记录
List<PcRigidChain> chains = iPcRigidChainService.selectPcRigidChainByType(type);
Map<String, PcRigidChain> chainMap = chains.stream()
.collect(Collectors.toMap(c -> c.getTypeName() + "_" + c.getAxialDirection(), c -> c));
for (String s : AxialDirection) {
for (PcRigidChainVo pcRigidChainVO : list) {
Long vOne = pcRigidChainVO.getVOne();
String sheetName = readSheet.getSheetName();
String box = "";
if (sheetName != null && sheetName.contains("单层")) {
box = "S";
} else if (sheetName != null && sheetName.contains("双层")) {
box = "D";
} else if (sheetName != null && sheetName.contains("三层")) {
box = "T";
}
String typeName = type + "/" + s + "-" + vOne + "/" + box;
log.debug("此物料的完整图号:=====================>{}", typeName);
// 从缓存中查找
PcRigidChain dbChain = chainMap.get(typeName + "_" + s);
if (dbChain != null) {
BeanUtil.copyProperties(pcRigidChainVO, dbChain, "id");
dbChain.setJourney(vOne);
dbChain.setTypeName(typeName);
dbChain.setType(type);
dbChain.setBox(box);
dbChain.setAxialDirection(s);
// dbChain.setUpdateBy(SecurityUtils.getUsername());
dbChain.setCreateTime(new Date());
pcRigidChainsToUpdate.add(dbChain);
}
}
}
if (!pcRigidChainsToUpdate.isEmpty()) {
for (PcRigidChain pcRigidChain : pcRigidChainsToUpdate) {
int i = pcRigidChainMapper.updateById(pcRigidChain);
if (i > 0) {
log.debug("物料:{}更新成功!!", pcRigidChain.getTypeName());
} else {
log.debug("物料:{}更新失败!!", pcRigidChain.getTypeName());
}
}
} else {
return R.fail("没有找到要更新的数据");
}
}
return R.ok("导入成功", pcRigidChainsToUpdate);
}
}

View File

@ -9,8 +9,13 @@ import com.ruoyi.common.excel.DefaultExcelListener;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.SmbUtil;
import com.ruoyi.system.domain.MrpResultCheck;
import com.ruoyi.system.domain.ProcessRoute;
import com.ruoyi.system.domain.bo.FigureSaveBo;
import com.ruoyi.system.domain.vo.MrpResultCheckVo;
import com.ruoyi.system.domain.vo.OverdueProjectVo;
import com.ruoyi.system.service.IBomDetailsService;
import com.ruoyi.system.service.IMrpResultCheckService;
import com.ruoyi.system.service.impl.ProductionOrderServiceImpl;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
@ -51,7 +56,8 @@ public class ProcessOrderProController extends BaseController {
private final IProcessOrderProService iProcessOrderProService;
@Autowired
private final ProductionOrderServiceImpl productionOrderService;
private final IMrpResultCheckService iMrpResultCheckService;
private final IBomDetailsService iBomDetailsService;
/**
* 查询项目令号列表
*/
@ -156,9 +162,6 @@ public class ProcessOrderProController extends BaseController {
}
//读取excel文件sheet
return toAjax(iProcessOrderProService.insertByBo(bo));
}
/**
@ -189,7 +192,7 @@ public class ProcessOrderProController extends BaseController {
}
/**
* 上传dwg图纸
* @param code
* @param id
* @param filePath
* @return
*/
@ -222,7 +225,6 @@ public class ProcessOrderProController extends BaseController {
try {
// 调用service方法获取文件路径
R<String> result = iProcessOrderProService.uploadPDF(id);
if (result.getCode() != 200) {
response.setStatus(HttpStatus.BAD_REQUEST.value());
response.setContentType("application/json;charset=UTF-8");
@ -318,4 +320,14 @@ public class ProcessOrderProController extends BaseController {
}
}
}
@GetMapping("/overdue")
public List<OverdueProjectVo> getOverdueProjects() {
return iProcessOrderProService.getOverdueProjects();
}
@PostMapping("/getMRPResults/{id}")
public R<List<MrpResultCheck>> geMRPResults(@PathVariable Long id) {
return iMrpResultCheckService.getMRPResults(id);
}
}

View File

@ -0,0 +1,132 @@
package com.ruoyi.system.controller;
import java.util.List;
import java.util.Arrays;
import com.ruoyi.system.domain.vo.ExpiryProjectVo;
import com.ruoyi.system.domain.vo.OverdueProjectVo;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
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.ProcessPlanVo;
import com.ruoyi.system.domain.bo.ProcessPlanBo;
import com.ruoyi.system.service.IProcessPlanService;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* 方案管理
*
* @author 田志阳
* @date 2025-08-20
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/proPlan")
public class ProcessPlanController extends BaseController {
private final IProcessPlanService iProcessPlanService;
/**
* 查询方案管理列表
*/
@SaCheckPermission("system:proPlan:list")
@GetMapping("/list")
public TableDataInfo<ProcessPlanVo> list(ProcessPlanBo bo, PageQuery pageQuery) {
return iProcessPlanService.queryPageList(bo, pageQuery);
} /**
* 查询方案管理列表
*/
@SaCheckPermission("system:proPlan:list2")
@GetMapping("/list2")
public TableDataInfo<ProcessPlanVo> list2(ProcessPlanBo bo, PageQuery pageQuery) {
return iProcessPlanService.queryPageList2(bo, pageQuery);
}
/**
* 导出方案管理列表
*/
@SaCheckPermission("system:proPlan:export")
@Log(title = "方案管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(ProcessPlanBo bo, HttpServletResponse response) {
List<ProcessPlanVo> list = iProcessPlanService.queryList(bo);
ExcelUtil.exportExcel(list, "方案管理", ProcessPlanVo.class, response);
}
/**
* 获取方案管理详细信息
*
* @param id 主键
*/
@SaCheckPermission("system:proPlan:query")
@GetMapping("/{id}")
public R<ProcessPlanVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iProcessPlanService.queryById(id));
}
/**
* 新增方案管理
*/
@SaCheckPermission("system:proPlan:add")
@Log(title = "方案管理", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody ProcessPlanBo bo) {
return toAjax(iProcessPlanService.insertByBo(bo));
}
/**
* 修改方案管理
*/
@SaCheckPermission("system:proPlan:edit")
@Log(title = "方案管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody ProcessPlanBo bo) {
return toAjax(iProcessPlanService.updateByBo(bo));
}
/**
* 删除方案管理
*
* @param ids 主键串
*/
@SaCheckPermission("system:proPlan:remove")
@Log(title = "方案管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iProcessPlanService.deleteWithValidByIds(Arrays.asList(ids), true));
}
/**
* 超期项目
* @param
*/
@GetMapping("/overdue")
public List<OverdueProjectVo> getOverdueProjects() {
return iProcessPlanService.getOverdueProjects();
}
/**
* 超期项目
* @param
*/
@GetMapping("/expiryProjects")
public List<ExpiryProjectVo> getExpiryProjects() {
return iProcessPlanService.getExpiryProjects();
}
}

View File

@ -1,6 +1,7 @@
package com.ruoyi.system.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
@ -28,6 +29,7 @@ import com.ruoyi.system.mapper.BomDetailsMapper;
import com.ruoyi.system.mapper.MaterialBomMapper;
import com.ruoyi.system.mapper.ProcessRouteMapper;
import com.ruoyi.system.runner.JdUtil;
import com.ruoyi.system.service.IBomDetailsService;
import com.ruoyi.system.service.IProcessRouteService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -67,7 +69,7 @@ public class ProcessRouteController extends BaseController {
private final IProcessRouteService iProcessRouteService;
@Autowired
MaterialBomMapper materialBomMapper;
private final IBomDetailsService iBomDetailsService;
private Long generateUniqueParentId(Long originalId) {
return originalId + 1000;
}
@ -80,8 +82,7 @@ public class ProcessRouteController extends BaseController {
public TableDataInfo<ProcessRouteVo> list2(ProcessRouteBo bo, PageQuery pageQuery) {
try {
// 查询工艺路线数据
TableDataInfo<ProcessRouteVo> processRouteVoTableDataInfo = iProcessRouteService.queryPageList2(bo,
pageQuery);
TableDataInfo<ProcessRouteVo> processRouteVoTableDataInfo = iProcessRouteService.queryPageList2(bo, pageQuery);
// 用于存储父子关系的Mapkey为"物料编码_物料名称"值为父级ProcessRouteVo
Map<String, ProcessRouteVo> routeMap = new HashMap<>();
// 存储顶级列表
@ -114,14 +115,11 @@ public class ProcessRouteController extends BaseController {
topLevelList.add(parent);
}
// 创建子节点并将其添加到父节点的子集
ProcessRouteVo child = createChildVo(processRouteVo, parent.getId(), parent.getMaterialCode(),
parent.getMaterialName());
ProcessRouteVo child = createChildVo(processRouteVo, parent.getId(), parent.getMaterialCode(), parent.getMaterialName());
parent.getChildren().add(child);
}
// 设置返回的rows为顶级节点列表
processRouteVoTableDataInfo.setRows(topLevelList);
// 返回构建后的数据
return processRouteVoTableDataInfo;
} catch (Exception e) {
@ -138,8 +136,7 @@ public class ProcessRouteController extends BaseController {
public TableDataInfo<ProcessRouteVo> list(ProcessRouteBo bo, PageQuery pageQuery) {
try {
// 查询工艺路线数据
TableDataInfo<ProcessRouteVo> processRouteVoTableDataInfo = iProcessRouteService.queryPageList(bo,
pageQuery);
TableDataInfo<ProcessRouteVo> processRouteVoTableDataInfo = iProcessRouteService.queryPageList(bo, pageQuery);
// 用于存储父子关系的Mapkey为"物料编码_物料名称"值为父级ProcessRouteVo
Map<String, ProcessRouteVo> routeMap = new HashMap<>();
// 存储顶级列表
@ -196,12 +193,10 @@ public class ProcessRouteController extends BaseController {
* @param processRouteVo 原始数据
* @return ProcessRouteVo 子节点
*/
private ProcessRouteVo createChildVo(ProcessRouteVo processRouteVo, Long parentId, String materialCode,
String materialName) {
private ProcessRouteVo createChildVo(ProcessRouteVo processRouteVo, Long parentId, String materialCode, String materialName) {
ProcessRouteVo child = new ProcessRouteVo();
child.setId(processRouteVo.getId());
child.setParentId(parentId);
child.setProcessNo(processRouteVo.getProcessNo());
child.setWorkCenter(processRouteVo.getWorkCenter());
child.setProcessName(processRouteVo.getProcessName());
@ -376,16 +371,28 @@ public class ProcessRouteController extends BaseController {
@Log(title = "明细导入", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:route:import")
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> importData(@RequestParam("file") MultipartFile file) throws Exception {
public R 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);
ExcelResult<ProcessRouteVo> result = ExcelUtil.importExcelSheet6(file.getInputStream(), ProcessRouteVo.class, true);
List<ProcessRouteVo> list1 = result.getList();
// 读取总装部分sheet
ExcelResult<ProductionOrderVo> result1 = ExcelUtil.importExcelSheet1(file.getInputStream(),
ProductionOrderVo.class, true);
ExcelResult<ProductionOrderVo> result1 = ExcelUtil.importExcelSheet1(file.getInputStream(), ProductionOrderVo.class, true);
List<ProductionOrderVo> list = result1.getList();
String productionOrderNo = list1.get(0).getRouteDescription();
List<BomDetails> bomDetails = iBomDetailsService.selectByProjectNumber(list1.get(0).getRouteDescription());
List<ProcessRoute> route = iProcessRouteService.selectByProjectNumber(list1.get(0).getRouteDescription());
if (list1.isEmpty()){
return R.fail("项目 "+productionOrderNo+"工艺生产计划表为空,请检查此表或将sheet移动至第七个!");
}
if (!bomDetails.isEmpty()){
return R.fail("项目 "+productionOrderNo+"已导入过BOM,请先清空再上传");
}
if (!route.isEmpty()){
return R.fail("项目 "+productionOrderNo+"已导入过工艺 ,请先清空再上传");
}
if (iProcessRouteService.saveData(result.getList(), list)) {
return R.ok("上传物料成功");
} else {
@ -652,12 +659,6 @@ public class ProcessRouteController extends BaseController {
//子项分母
bomDetails.setDenominator(Double.valueOf(materialUsageDTO.getFenmu()));
bomDetails.setName(materialUsageDTO.getMaterialName());
/* if (materialUsageDTO.getItemType().equals("1")){
bomDetails.setStats("外购");
}else{
bomDetails.setStats("自制");
}*/
bomDetails.setMaterial(materialUsageDTO.getCaizhi());
return bomDetails;
}

View File

@ -8,7 +8,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 外购件临时对象 figure_save
* 项目产品对象 figure_save
*
* @author tzy
* @date 2024-05-28

View File

@ -3,11 +3,15 @@ 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.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 物料检索对象 im_material
@ -27,21 +31,30 @@ public class ImMaterial extends BaseEntity {
*/
@TableId(value = "id",type = IdType.AUTO)
private Long id;
/**
* 物料内码
*/
@JsonProperty("FMATERIALID")
private String materialId;
/**
* 物料编号
*/
@JsonProperty("FNumber")
private String materialCode;
/**
* 物料名称
*/
@JsonProperty("FName")
private String materialName;
/**
* 材质
*/
@JsonProperty("F_SVRI_Assistant.FNumber")
private String materialQuality;
/*
分类名称
*/
@JsonProperty("FCategoryID.FNumber")
private String imCategory;
/*
所属名称:danwei
@ -50,11 +63,10 @@ public class ImMaterial extends BaseEntity {
/*
所属编号
*/
@JsonProperty("FErpClsID")
private String classificationNumber;
/**
* 单重:暂存可用库存
*/
@JsonProperty("F_HBYT_DZ")
private BigDecimal singleWeight;
/**
* 单价
@ -63,6 +75,7 @@ public class ImMaterial extends BaseEntity {
/**
* 单位
*/
@JsonProperty("FBaseUnitId.FName")
private String unit;
/**
* 标记: 0为未使用, 1为使用
@ -73,5 +86,18 @@ public class ImMaterial extends BaseEntity {
* 搜索次数
*/
private Long searchCount;
/**
* 金蝶修改时间当日
*/
@JsonProperty("FModifyDate")
private String modifyDate;
/**
* 金蝶禁用状态
*/
@JsonProperty("FForbidStatus")
private String forbidStatus;
/**
* jishikucun
*/
private String inInventory;
}

View File

@ -0,0 +1,61 @@
package com.ruoyi.system.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
/**
* 金蝶资产卡片对象 kingdee_asset_card
*
* @author ruoyi
* @date 2025-09-04
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("kingdee_asset_card")
public class KingdeeAssetCard extends BaseEntity {
private static final long serialVersionUID=1L;
/**
* ID
*/
@TableId(value = "id")
private Long id;
/**
* 资产类别
*/
private String assetCategory;
/**
* 卡片编码
*/
private String cardCode;
/**
* 计量单位
*/
private String assetUnit;
/**
* 资产编码
*/
private String assetCode;
/**
* 资产位置
*/
private String assetLocation;
/**
* 资产数量
*/
private BigDecimal assetQuantity;
/**
* 资产名称
*/
private String assetName;
/**
* 制造商
*/
private String assetManufacturer;
}

View File

@ -0,0 +1,64 @@
package com.ruoyi.system.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
/**
* MRP运算结果复查对象 mrp_result_check
*
* @author tzy
* @date 2025-08-22
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("mrp_result_check")
public class MrpResultCheck extends BaseEntity {
private static final long serialVersionUID=1L;
/**
* 主键ID
*/
@TableId(value = "id")
private Long id;
/**
* 物料名称
*/
private String materialName;
/**
* 物料编码
*/
private String materialCode;
/**
* 本项目可用库存
*/
private BigDecimal availableStock;
/**
* 当前可用库存
*/
private BigDecimal realTimeStock;
/**
* 生产未入库数量
*/
private BigDecimal prodNotInStock;
/**
* 采购申请单数量
*/
private BigDecimal purchaseRequestQty;
/**
* 采购未入库数量
*/
private String purchaseNotInStock;
/**
* 子项未领料数量
*/
private BigDecimal childNotPickedQty;
/**
* 关联项目id
*/
private Long orderProId;
}

View File

@ -78,4 +78,13 @@ public class ProcessOrderPro extends BaseEntity {
*/
@Translation(type = TransConstant.OSS_ID_TO_URL)
private String drawingPath;
/**
* bom状态(0,未完成 1,完成 2已上传)
*/
private Long bomStatus;
/**
* 工艺状态(0,未完成 1,完成 2已上传)
*/
private Long routeStatus;
}

View File

@ -0,0 +1,58 @@
package com.ruoyi.system.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 方案管理对象 process_plan
*
* @author 田志阳
* @date 2025-08-20
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("process_plan")
public class ProcessPlan extends BaseEntity {
private static final long serialVersionUID=1L;
/**
* 序号
*/
@TableId(value = "id")
private Long id;
/**
* 方案编码
*/
private String projectCode;
/**
* 设计人
*/
private String designer;
/**
* 逾期天数
*/
private String overdueDays;
/**
* 方案备注
*/
private String remark;
/**
* 预计开始时间
*/
private Date startDate;
/**
* 预计完成时间
*/
private Date endDate;
/**
* 方案状态
*/
private Long processStatus;
}

View File

@ -5,6 +5,8 @@ import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
/**
* 生产订单对象 production_order
@ -64,5 +66,8 @@ public class ProductionOrder extends BaseEntity {
* 部件图号
*/
private String parentDrawingNo;
/**
* 批次数量
*/
private String batchQuantity;
}

View File

@ -1,5 +1,6 @@
package com.ruoyi.system.domain.bo;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import lombok.Data;
@ -24,7 +25,10 @@ public class ImMaterialBo extends BaseEntity {
* ID
*/
private Long id;
/**
* 物料内码
*/
private String materialId;
/**
* 物料编号
*/
@ -77,4 +81,16 @@ public class ImMaterialBo extends BaseEntity {
* 搜索次数
*/
private Long searchCount;
/**
* 金蝶修改时间当日
*/
private String modifyDate;
/**
* 金蝶禁用状态
*/
private String forbidStatus;
/**
* jishikucun
*/
private String inInventory;
}

View File

@ -0,0 +1,78 @@
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.*;
import java.math.BigDecimal;
/**
* 金蝶资产卡片业务对象 kingdee_asset_card
*
* @author ruoyi
* @date 2025-09-04
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class KingdeeAssetCardBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "ID不能为空", groups = { EditGroup.class })
private Long id;
/**
* 资产类别
*/
@NotBlank(message = "资产类别不能为空", groups = { AddGroup.class, EditGroup.class })
private String assetCategory;
/**
* 卡片编码
*/
@NotBlank(message = "卡片编码不能为空", groups = { AddGroup.class, EditGroup.class })
private String cardCode;
/**
* 计量单位
*/
@NotBlank(message = "计量单位不能为空", groups = { AddGroup.class, EditGroup.class })
private String assetUnit;
/**
* 资产编码
*/
@NotBlank(message = "资产编码不能为空", groups = { AddGroup.class, EditGroup.class })
private String assetCode;
/**
* 资产位置
*/
@NotBlank(message = "资产位置不能为空", groups = { AddGroup.class, EditGroup.class })
private String assetLocation;
/**
* 资产数量
*/
@NotNull(message = "资产数量不能为空", groups = { AddGroup.class, EditGroup.class })
private BigDecimal assetQuantity;
/**
* 资产名称
*/
@NotBlank(message = "资产名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String assetName;
/**
* 制造商
*/
@NotBlank(message = "制造商不能为空", groups = { AddGroup.class, EditGroup.class })
private String assetManufacturer;
}

View File

@ -0,0 +1,82 @@
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.*;
import java.math.BigDecimal;
/**
* MRP运算结果复查业务对象 mrp_result_check
*
* @author tzy
* @date 2025-08-22
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class MrpResultCheckBo extends BaseEntity {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
private Long id;
/**
* 物料名称
*/
@NotBlank(message = "物料名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String materialName;
/**
* 物料编码
*/
@NotBlank(message = "物料编码不能为空", groups = { AddGroup.class, EditGroup.class })
private String materialCode;
/**
* 可用库存
*/
@NotNull(message = "可用库存不能为空", groups = { AddGroup.class, EditGroup.class })
private BigDecimal availableStock;
/**
* 即时库存
*/
@NotNull(message = "即时库存不能为空", groups = { AddGroup.class, EditGroup.class })
private BigDecimal realTimeStock;
/**
* 生产未入库数量
*/
@NotNull(message = "生产未入库数量不能为空", groups = { AddGroup.class, EditGroup.class })
private BigDecimal prodNotInStock;
/**
* 采购申请单数量
*/
@NotNull(message = "采购申请单数量不能为空", groups = { AddGroup.class, EditGroup.class })
private BigDecimal purchaseRequestQty;
/**
* 采购未入库数量
*/
@NotNull(message = "采购未入库数量不能为空", groups = { AddGroup.class, EditGroup.class })
private String purchaseNotInStock;
/**
* 子项未领料数量
*/
@NotNull(message = "子项未领料数量不能为空", groups = { AddGroup.class, EditGroup.class })
private BigDecimal childNotPickedQty;
/**
* 关联项目id
*/
@NotNull(message = "关联项目id不能为空", groups = { AddGroup.class, EditGroup.class })
private Long orderProId;
}

View File

@ -29,16 +29,24 @@ public class ProcessOrderProBo extends BaseEntity {
*/
@NotNull(message = "主键ID自动递增不能为空", groups = { EditGroup.class })
private Long id;
/**
* 项目令号
*/
private String productionOrderNo;
/**
* 项目名称
*/
private String productionName;
/**
* 项目图号
*/
private String drawingNo;
/**
* 产品名称
*/
private String drawingName;
/**
* 计划结束时间
@ -46,7 +54,7 @@ public class ProcessOrderProBo extends BaseEntity {
private Date planEndTime;
/**
* 计划开始时间
* 方案开始时间
*/
private Date planStartTime;
/**
@ -55,7 +63,7 @@ public class ProcessOrderProBo extends BaseEntity {
private String drawingType;
/**
* 项目完成时间
* 方案完成时间
*/
private Date projectEndTime;
@ -81,4 +89,22 @@ public class ProcessOrderProBo extends BaseEntity {
*/
@Translation(mapper = "drawingPath", type = TransConstant.OSS_ID_TO_URL)
private String drawingPathUrl;
/**
* 方案设计人
*/
private String programDesigner;
/**
* 项目备注
*/
private String proRemark;
/**
* bom状态(0,未完成 1,完成 2已上传)
*/
private Long bomStatus;
/**
* 工艺状态(0,未完成 1,完成 2已上传)
*/
private Long routeStatus;
}

View File

@ -0,0 +1,73 @@
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.*;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 方案管理业务对象 process_plan
*
* @author 田志阳
* @date 2025-08-20
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class ProcessPlanBo extends BaseEntity {
/**
* 序号
*/
@NotNull(message = "序号不能为空", groups = { EditGroup.class })
private Long id;
/**
* 方案编码
*/
@NotBlank(message = "方案编码不能为空", groups = { AddGroup.class, EditGroup.class })
private String projectCode;
/**
* 设计人
*/
@NotBlank(message = "设计人不能为空", groups = { AddGroup.class, EditGroup.class })
private String designer;
/**
* 逾期天数
*/
//@NotBlank(message = "逾期天数不能为空", groups = { AddGroup.class, EditGroup.class })
private String overdueDays;
/**
* 方案备注
*/
@NotBlank(message = "方案备注不能为空", groups = { AddGroup.class, EditGroup.class })
private String remark;
/**
* 预计开始时间
*/
@NotNull(message = "预计开始时间不能为空", groups = { AddGroup.class, EditGroup.class })
private Date startDate;
/**
* 预计完成时间
*/
@NotNull(message = "预计完成时间不能为空", groups = { AddGroup.class, EditGroup.class })
private Date endDate;
/**
* 方案状态
*/
@NotNull(message = "方案状态不能为空", groups = { AddGroup.class, EditGroup.class })
private Long processStatus;
}

View File

@ -6,6 +6,7 @@ import com.ruoyi.common.core.validate.EditGroup;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.*;
import java.math.BigDecimal;
/**
@ -59,5 +60,8 @@ public class ProductionOrderBo extends BaseEntity {
* 部件图号
*/
private String parentDrawingNo;
/**
* 批次数量
*/
private String batchQuantity;
}

View File

@ -0,0 +1,15 @@
package com.ruoyi.system.domain.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CodeInfo {
/** 名称 */
private String name;
/** 数量 */
private String qty;
}

View File

@ -13,18 +13,18 @@ public class JdVMIVo {
/**
* 名称
*/
@ExcelProperty(value = "名称")
// @ExcelProperty(value = "名称")
private String materialName;
/**
* 仓库编码
*/
@ExcelProperty(value = "仓库编码")
//@ExcelProperty(value = "仓库编码")
private String FStockId;
/**
* 仓位编码
*/
@ExcelProperty(value = "仓位编码")
// @ExcelProperty(value = "仓位编码")
private String FStockPlaceId;
}

View File

@ -0,0 +1,14 @@
package com.ruoyi.system.domain.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class PurchaseRequestDTO {
@JsonProperty("FMaterialId.FNumber")
private String FMaterialIdFNumber;
@JsonProperty("FMaterialName")
private String FMaterialName;
@JsonProperty("FReqQty")
private Double FReqQty;
}

View File

@ -20,7 +20,7 @@ public class EleMaterialsVo {
private static final long serialVersionUID = 1L;
/**
*
*
*/
private Long id;
@ -44,36 +44,36 @@ public class EleMaterialsVo {
/**
* 型号
*/
@ExcelProperty(value = "型号")
//@ExcelProperty(value = "型号")
private String model;
/**
* 材质
*/
@ExcelProperty(value = "类别")
//@ExcelProperty(value = "类别")
private String materialType;
/**
* 单位
*/
@ExcelProperty(value = "单位")
// @ExcelProperty(value = "单位")
private String unit;
/**
* 品牌
*/
@ExcelProperty(value = "品牌")
//@ExcelProperty(value = "品牌")
private String brand;
/**
* 备注
*/
@ExcelProperty(value = "备注")
// @ExcelProperty(value = "备注")
private String remarks;
/**
* 物料值
*/
@ExcelProperty(value = "总工时")
private String materialValue;

View File

@ -0,0 +1,31 @@
package com.ruoyi.system.domain.vo;
import lombok.Data;
@Data
public class ExpiryProjectVo {
/**
* 项目令号
*/
private String projectCode;
/**
*方案设计人
*/
private String designer;
/**
*方案描述
*/
private String description;
/**
*开始时间
*/
private String startDate;
/**
*计划结束时间
*/
private String planDate;
/**
*临期天数
*/
private long overdueDays;
}

View File

@ -84,4 +84,8 @@ public class ImMaterialVo {
* 搜索次数
*/
private Long searchCount;
/**
* jishikucun
*/
private String inInventory;
}

View File

@ -0,0 +1,78 @@
package com.ruoyi.system.domain.vo;
import java.math.BigDecimal;
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_asset_card
*
* @author ruoyi
* @date 2025-09-04
*/
@Data
@ExcelIgnoreUnannotated
public class KingdeeAssetCardVo {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "ID")
private Long id;
/**
* 资产类别
*/
@ExcelProperty(value = "资产类别")
private String assetCategory;
/**
* 卡片编码
*/
@ExcelProperty(value = "卡片编码")
private String cardCode;
/**
* 计量单位
*/
@ExcelProperty(value = "计量单位")
private String assetUnit;
/**
* 资产编码
*/
@ExcelProperty(value = "资产编码")
private String assetCode;
/**
* 资产位置
*/
@ExcelProperty(value = "资产位置")
private String assetLocation;
/**
* 资产数量
*/
@ExcelProperty(value = "资产数量")
private BigDecimal assetQuantity;
/**
* 资产名称
*/
@ExcelProperty(value = "资产名称")
private String assetName;
/**
* 制造商
*/
@ExcelProperty(value = "制造商")
private String assetManufacturer;
}

View File

@ -0,0 +1,92 @@
package com.ruoyi.system.domain.vo;
import java.math.BigDecimal;
import java.util.Date;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.common.convert.ExcelDictConvert;
import lombok.Data;
/**
* MRP运算结果复查视图对象 mrp_result_check
*
* @author tzy
* @date 2025-08-22
*/
@Data
@ExcelIgnoreUnannotated
public class MrpResultCheckVo {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
private Long id;
/**
* 物料名称
*/
@ExcelProperty(value = "物料名称")
private String materialName;
/**
* 物料编码
*/
@ExcelProperty(value = "物料编码")
private String materialCode;
/**
* 可用库存
*/
@ExcelProperty(value = "本项目可用库存")
private BigDecimal availableStock;
/**
* 即时库存
*/
@ExcelProperty(value = "即时库存")
private BigDecimal realTimeStock;
/**
* 生产未入库数量
*/
@ExcelProperty(value = "本次生产未入库")
private BigDecimal prodNotInStock;
/**
/**
* 采购申请单数量
*/
@ExcelProperty(value = "本项目采购申请")
private BigDecimal purchaseRequestQty;
/**
* 采购未入库数量
*/
@ExcelProperty(value = "项目本批数")
private String purchaseNotInStock;
/**
* 子项未领料数量
*/
@ExcelProperty(value = "子项未领料数量")
private BigDecimal childNotPickedQty;
/**
* 关联项目id
*/
private Long orderProId;
/**
* 创建时间
*/
private Date createTime;
/* 创建时间
*/
private Date updateTime;
}

View File

@ -0,0 +1,36 @@
package com.ruoyi.system.domain.vo;
import lombok.Data;
/**
* 设计超期项目
* @author tzy
* @date 2025-08-20
*/
@Data
public class OverdueProjectVo {
/**
* 项目令号
*/
private String projectCode;
/**
*方案设计人
*/
private String designer;
/**
*方案描述
*/
private String description;
/**
*开始时间
*/
private String startDate;
/**
*计划结束时间
*/
private String planDate;
/**
*超期天数
*/
private long overdueDays;
}

View File

@ -341,7 +341,7 @@ public class PcRigidChainVo extends BaseEntity
private Long vFortySix;
/** X7 */
@ExcelProperty( "{V48}")
@ExcelProperty( "{V47}")
private Long vFortySeven;
/** X8 */

View File

@ -1,7 +1,10 @@
package com.ruoyi.system.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.common.annotation.Translation;
import com.ruoyi.common.constant.TransConstant;
@ -26,7 +29,7 @@ public class ProcessOrderProVo {
/**
* 主键ID自动递增
*/
@ExcelProperty(value = "主键ID自动递增")
@ExcelProperty(value = "序号")
private Long id;
/**
@ -92,7 +95,17 @@ public class ProcessOrderProVo {
*/
@ExcelProperty(value = "是否企标 (0-否, 1-是)")
private Integer isEnterpriseStandard;
/**
* bom状态(0,未完成 1,完成 2已上传)
*/
@ExcelProperty(value = "bom状态(0,未完成 1,完成 2已上传)")
private Long bomStatus;
/**
* 工艺状态(0,未完成 1,完成 2已上传)
*/
@ExcelProperty(value = "工艺状态(0,未完成 1,完成 2已上传)")
private Long routeStatus;
/**
* 图纸路径
*/
@ -101,4 +114,7 @@ public class ProcessOrderProVo {
@Translation(mapper = "drawingPath", type = TransConstant.OSS_ID_TO_URL)
private String drawingPathUrl;
private Date createTime;
}

View File

@ -0,0 +1,74 @@
package com.ruoyi.system.domain.vo;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
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;
/**
* 方案管理视图对象 process_plan
*
* @author 田志阳
* @date 2025-08-20
*/
@Data
@ExcelIgnoreUnannotated
public class ProcessPlanVo {
private static final long serialVersionUID = 1L;
/**
* 序号
*/
@ExcelProperty(value = "序号")
private Long id;
/**
* 方案编码
*/
@ExcelProperty(value = "方案编码")
private String projectCode;
/**
* 设计人
*/
@ExcelProperty(value = "设计人", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "plan_proer")
private String designer;
/**
* 逾期天数
*/
@ExcelProperty(value = "逾期天数")
private String overdueDays;
/**
* 方案备注
*/
@ExcelProperty(value = "方案备注")
private String remark;
/**
* 预计开始时间
*/
@ExcelProperty(value = "预计开始时间")
private Date startDate;
/**
* 预计完成时间
*/
@ExcelProperty(value = "预计完成时间")
private Date endDate;
/**
* 方案状态
*/
@ExcelProperty(value = "方案状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "pro_status")
private Long processStatus;
}

View File

@ -27,7 +27,7 @@ import java.util.List;
@ContentRowHeight(15)
@HeadRowHeight(20)
@ColumnWidth(15)
public class ProcessRouteVo {
public class ProcessRouteVo {
private static final long serialVersionUID = 1L;
private List<ProcessRouteVo> children;

View File

@ -6,6 +6,8 @@ import com.ruoyi.common.annotation.ExcelDictFormat;
import com.ruoyi.common.convert.ExcelDictConvert;
import lombok.Data;
import java.math.BigDecimal;
/**
* 生产订单视图对象 production_order
@ -49,6 +51,9 @@ public class ProductionOrderVo {
@ExcelProperty(value = "数量")
private Double quantity;
@ExcelProperty(value = "批次数量")
private String batchQuantity;
/**
* 生产材料
*/

View File

@ -37,6 +37,7 @@ public class WlStockDataVo {
@ExcelProperty(value = "物料名称")
private String materialName;
@ExcelProperty(value = "材质")
private String documentType;
/**

View File

@ -7,7 +7,6 @@ public class LoadBomResult {
private boolean isSuccess;
private String message; // 成功或者失败的消息
private String resultData; // 保存接口返回的结果数据
public LoadBomResult(boolean isSuccess, String message, String resultData) {
this.isSuccess = isSuccess;
this.message = message;

View File

@ -24,4 +24,12 @@ public interface ImMaterialMapper extends BaseMapperPlus<ImMaterialMapper, ImMat
// 自定义批量查询方法
List<ImMaterial> getMaterialsByCodes(@Param("codes") List<String> codes);
void updateByMaterid(ImMaterial imMaterial);
//根据金蝶物料内码更新 批量更新
Boolean updateBatchByMaterid(@Param("list") List<ImMaterial> imMaterials);
/**
* 根据 materialId 查询物料
*/
ImMaterial selectByMid(@Param("materialId") String materialId);
}

View File

@ -0,0 +1,15 @@
package com.ruoyi.system.mapper;
import com.ruoyi.system.domain.KingdeeAssetCard;
import com.ruoyi.system.domain.vo.KingdeeAssetCardVo;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
/**
* 金蝶资产卡片Mapper接口
*
* @author ruoyi
* @date 2025-09-04
*/
public interface KingdeeAssetCardMapper extends BaseMapperPlus<KingdeeAssetCardMapper, KingdeeAssetCard, KingdeeAssetCardVo> {
}

View File

@ -0,0 +1,15 @@
package com.ruoyi.system.mapper;
import com.ruoyi.system.domain.MrpResultCheck;
import com.ruoyi.system.domain.vo.MrpResultCheckVo;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
/**
* MRP运算结果复查Mapper接口
*
* @author tzy
* @date 2025-08-22
*/
public interface MrpResultCheckMapper extends BaseMapperPlus<MrpResultCheckMapper, MrpResultCheck, MrpResultCheckVo> {
}

View File

@ -0,0 +1,15 @@
package com.ruoyi.system.mapper;
import com.ruoyi.system.domain.ProcessPlan;
import com.ruoyi.system.domain.vo.ProcessPlanVo;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
/**
* 方案管理Mapper接口
*
* @author 田志阳
* @date 2025-08-20
*/
public interface ProcessPlanMapper extends BaseMapperPlus<ProcessPlanMapper, ProcessPlan, ProcessPlanVo> {
}

View File

@ -621,7 +621,186 @@ public class JdUtil {
return promoList; // 返回结果
}
/**
* 查询生产订单未入库 本项目除外
*查询
* @param materialCode
* @return
*/
public static List<ProMoDTO> getProMoListLimitByProCode(String materialCode,String proCode) {
K3CloudApi client = new K3CloudApi();
// 请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "PRD_MO");
json.addProperty("FieldKeys",
"FMaterialId.FNumber,FMaterialName,FNoStockInQty");
// 创建过滤条件
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FMaterialId.FNumber");
filterObject.addProperty("Compare", "="); // 改为等号运算符
filterObject.addProperty("Value", materialCode);
filterObject.addProperty("Left", "");
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);// PlanOrderVo 获取生产令号
filterString.add(filterObject);
JsonObject filterObject1 = new JsonObject();
filterObject1.addProperty("FieldName", "FStatus");
filterObject1.addProperty("Compare", "106"); // 改为等号运算符
filterObject1.addProperty("Value", 5);
filterObject1.addProperty("Left", "");
filterObject1.addProperty("Right", "");
filterObject1.addProperty("Logic", 0);// PlanOrderVo 获取生产令号
filterString.add(filterObject1);
JsonObject filterObject2 = new JsonObject();
filterObject2.addProperty("FieldName", "FStatus");
filterObject2.addProperty("Compare", "106"); // 改为等号运算符
filterObject2.addProperty("Value", 6);
filterObject2.addProperty("Left", "");
filterObject2.addProperty("Right", "");
filterObject2.addProperty("Logic", 0);// PlanOrderVo 获取生产令号
filterString.add(filterObject2);
JsonObject filterObject3 = new JsonObject();
filterObject3.addProperty("FieldName", "FStatus");
filterObject3.addProperty("Compare", "106"); // 改为等号运算符
filterObject3.addProperty("Value", 7);
filterObject3.addProperty("Left", "");
filterObject3.addProperty("Right", "");
filterObject3.addProperty("Logic", 0);
filterString.add(filterObject3);
JsonObject filterObject4 = new JsonObject();
filterObject4.addProperty("FieldName", "FNoStockInQty");
filterObject4.addProperty("Compare", "21"); // 改为等号运算符
filterObject4.addProperty("Value", 0);
filterObject4.addProperty("Left", "");
filterObject4.addProperty("Right", "");
filterObject4.addProperty("Logic", 0);
filterString.add(filterObject4);
JsonObject filterObject5 = new JsonObject();
filterObject5.addProperty("FieldName", "F_HBYT_SCLH");
filterObject5.addProperty("Compare", "83");
filterObject5.addProperty("Value", proCode);//筛选条件 生产令号
filterObject5.addProperty("Left", "");
filterObject5.addProperty("Right", "");
filterObject5.addProperty("Logic", 0);
filterString.add(filterObject5);
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();
List<ProMoDTO> promoList = null;
try {
// 调用接口
String resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
// 使用 ObjectMapper JsonArray 转换为 List<PlannedProcessVo>
ObjectMapper objectMapper = new ObjectMapper();
promoList = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<ProMoDTO>>() {
});
} catch (Exception e) {
e.printStackTrace(); // 输出异常日志
}
return promoList; // 返回结果
}
/**
* 查询生产订单未入库 本项目
*查询
* @param materialCode
* @return
*/
public static List<ProMoDTO> getProMoListByProCode(String materialCode,String proCode) {
K3CloudApi client = new K3CloudApi();
// 请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "PRD_MO");
json.addProperty("FieldKeys",
"FMaterialId.FNumber,FMaterialName,FNoStockInQty");
// 创建过滤条件
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FMaterialId.FNumber");
filterObject.addProperty("Compare", "="); // 改为等号运算符
filterObject.addProperty("Value", materialCode);
filterObject.addProperty("Left", "");
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);// PlanOrderVo 获取生产令号
filterString.add(filterObject);
JsonObject filterObject1 = new JsonObject();
filterObject1.addProperty("FieldName", "FStatus");
filterObject1.addProperty("Compare", "106"); // 改为等号运算符
filterObject1.addProperty("Value", 5);
filterObject1.addProperty("Left", "");
filterObject1.addProperty("Right", "");
filterObject1.addProperty("Logic", 0);// PlanOrderVo 获取生产令号
filterString.add(filterObject1);
JsonObject filterObject2 = new JsonObject();
filterObject2.addProperty("FieldName", "FStatus");
filterObject2.addProperty("Compare", "106"); // 改为等号运算符
filterObject2.addProperty("Value", 6);
filterObject2.addProperty("Left", "");
filterObject2.addProperty("Right", "");
filterObject2.addProperty("Logic", 0);// PlanOrderVo 获取生产令号
filterString.add(filterObject2);
JsonObject filterObject3 = new JsonObject();
filterObject3.addProperty("FieldName", "FStatus");
filterObject3.addProperty("Compare", "106"); // 改为等号运算符
filterObject3.addProperty("Value", 7);
filterObject3.addProperty("Left", "");
filterObject3.addProperty("Right", "");
filterObject3.addProperty("Logic", 0);
filterString.add(filterObject3);
JsonObject filterObject4 = new JsonObject();
filterObject4.addProperty("FieldName", "FNoStockInQty");
filterObject4.addProperty("Compare", "21"); // 改为等号运算符
filterObject4.addProperty("Value", 0);
filterObject4.addProperty("Left", "");
filterObject4.addProperty("Right", "");
filterObject4.addProperty("Logic", 0);
filterString.add(filterObject4);
JsonObject filterObject5 = new JsonObject();
filterObject5.addProperty("FieldName", "F_HBYT_SCLH");
filterObject5.addProperty("Compare", "=");
filterObject5.addProperty("Value", proCode);//筛选条件 生产令号
filterObject5.addProperty("Left", "");
filterObject5.addProperty("Right", "");
filterObject5.addProperty("Logic", 0);
filterString.add(filterObject5);
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();
List<ProMoDTO> promoList = null;
try {
// 调用接口
String resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
// 使用 ObjectMapper JsonArray 转换为 List<PlannedProcessVo>
ObjectMapper objectMapper = new ObjectMapper();
promoList = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<ProMoDTO>>() {
});
} catch (Exception e) {
e.printStackTrace(); // 输出异常日志
}
return promoList; // 返回结果
}
/**
* 查询采购订单 单据体
* 将预留量更改为 剩余未入库数量20250325
@ -656,14 +835,6 @@ public class JdUtil {
filterObject1.addProperty("Right", "");
filterObject1.addProperty("Logic", 0);// PlanOrderVo 获取生产令号
filterString.add(filterObject1);
/* JsonObject filterObject2 = new JsonObject();
filterObject2.addProperty("FieldName", "FCloseStatus");
filterObject2.addProperty("Compare", "106"); // 改为等号运算符
filterObject2.addProperty("Value", "A");
filterObject2.addProperty("Left", "");
filterObject2.addProperty("Right", "");
filterObject2.addProperty("Logic", 0);// PlanOrderVo 获取生产令号
filterString.add(filterObject2);*/
json.add("FilterString", filterString);
json.addProperty("OrderString", "");
json.addProperty("TopRowCount", 0);
@ -691,13 +862,282 @@ public class JdUtil {
return plannedProcessList; // 返回结果
}
/**
* 查询采购订单 单据体
* 将预留量更改为 剩余未入库数量20250325
* @param materialCode
* @return
*/
public static List<PurchaseOrderDTO> getPurchaseOrderListByProCode(String materialCode,String proCode) {
K3CloudApi client = new K3CloudApi();
// 请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "PUR_PurchaseOrder");
json.addProperty("FieldKeys",
"FMaterialId.FNumber,FMaterialName,FRemainStockINQty");
// 创建过滤条件
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FMaterialId.FNumber");
filterObject.addProperty("Compare", "=");
filterObject.addProperty("Value", materialCode);
filterObject.addProperty("Left", "");
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);
filterString.add(filterObject);
JsonObject filterObject1 = new JsonObject();
filterObject1.addProperty("FieldName", "FMRPCloseStatus");
filterObject1.addProperty("Compare", "105");
filterObject1.addProperty("Value", "A");
filterObject1.addProperty("Left", "");
filterObject1.addProperty("Right", "");
filterObject1.addProperty("Logic", 0);
filterString.add(filterObject1);
JsonObject filterObject2 = new JsonObject();
filterObject2.addProperty("FieldName", "F_UCHN_Text2");
filterObject2.addProperty("Compare", "83");
filterObject2.addProperty("Value", proCode);// 生产令号
filterObject2.addProperty("Left", "");
filterObject2.addProperty("Right", "");
filterObject2.addProperty("Logic", 0);
filterString.add(filterObject2);
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();
List<PurchaseOrderDTO> plannedProcessList = null;
try {
// 调用接口
String resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
// 使用 ObjectMapper JsonArray 转换为 List<PlannedProcessVo>
ObjectMapper objectMapper = new ObjectMapper();
plannedProcessList = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<PurchaseOrderDTO>>() {
});
} catch (Exception e) {
e.printStackTrace(); // 输出异常日志
}
return plannedProcessList; // 返回结果
}
public static List<PurchaseRequestDTO> getPurchaseRequestByProCode(String materialCode,String proCode) {
K3CloudApi client = new K3CloudApi();
// 请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "PUR_Requisition");
json.addProperty("FieldKeys",
"FMaterialId.FNumber,FMaterialName,FReqQty");
// 创建过滤条件
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FMaterialId.FNumber");
filterObject.addProperty("Compare", "=");
filterObject.addProperty("Value", materialCode);
filterObject.addProperty("Left", "");
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);
filterString.add(filterObject);
JsonObject filterObject1 = new JsonObject();
filterObject1.addProperty("FieldName", "F_UCHN_Text");
filterObject1.addProperty("Compare", "=");
filterObject1.addProperty("Value", proCode);
filterObject1.addProperty("Left", "");
filterObject1.addProperty("Right", "");
filterObject1.addProperty("Logic", 0);
filterString.add(filterObject1);
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();
List<PurchaseRequestDTO> plannedProcessList = null;
try {
// 调用接口
String resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
// 使用 ObjectMapper JsonArray 转换为 List<PlannedProcessVo>
ObjectMapper objectMapper = new ObjectMapper();
plannedProcessList = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<PurchaseRequestDTO>>() {
});
} catch (Exception e) {
e.printStackTrace(); // 输出异常日志
}
return plannedProcessList; // 返回结果
}
// 采购申请(本项目除外)
public static List<PurchaseRequestDTO> getPurchaseRequestByLimitProCode(String materialCode,String proCode) {
K3CloudApi client = new K3CloudApi();
// 请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "PUR_Requisition");
json.addProperty("FieldKeys",
"FMaterialId.FNumber,FMaterialName,FReqQty");
// 创建过滤条件
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FMaterialId.FNumber");
filterObject.addProperty("Compare", "=");
filterObject.addProperty("Value", materialCode);
filterObject.addProperty("Left", "");
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);
filterString.add(filterObject);
JsonObject filterObject1 = new JsonObject();
filterObject1.addProperty("FieldName", "F_UCHN_Text");
filterObject1.addProperty("Compare", "83");
filterObject1.addProperty("Value", proCode);
filterObject1.addProperty("Left", "");
filterObject1.addProperty("Right", "");
filterObject1.addProperty("Logic", 0);
filterString.add(filterObject1);
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();
List<PurchaseRequestDTO> plannedProcessList = null;
try {
// 调用接口
String resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
// 使用 ObjectMapper JsonArray 转换为 List<PlannedProcessVo>
ObjectMapper objectMapper = new ObjectMapper();
plannedProcessList = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<PurchaseRequestDTO>>() {
});
} catch (Exception e) {
e.printStackTrace(); // 输出异常日志
}
return plannedProcessList; // 返回结果
}
/**
* 查询生产用料清单单据体
* 查询子项物料的未领料量
* @param materialCode
* @return
*/
public static List<JDProductionDTO> getWeiLingliaoLimBen(String materialCode,String procode) {
K3CloudApi client = new K3CloudApi();
// 请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "PRD_PPBOM");
json.addProperty("FieldKeys",
"FMaterialID2.FNumber,FMaterialName1,FNoPickedQty");
// 创建过滤条件
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FMaterialID2.FNumber");
filterObject.addProperty("Compare", "67");
filterObject.addProperty("Value", materialCode);
filterObject.addProperty("Left", "");
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);
filterString.add(filterObject);
JsonObject filterObject1 = new JsonObject();
filterObject1.addProperty("FieldName", "FMoEntryStatus");
filterObject1.addProperty("Compare", "5");
filterObject1.addProperty("Value", "7");
filterObject1.addProperty("Left", "");
filterObject1.addProperty("Right", "");
filterObject1.addProperty("Logic", 0);
filterString.add(filterObject1);
JsonObject filterObject2 = new JsonObject();
filterObject2.addProperty("FieldName", "FMoEntryStatus");// 改为等号运算符
filterObject2.addProperty("Compare", "5");
filterObject2.addProperty("Value", "5");
filterObject2.addProperty("Left", "");
filterObject2.addProperty("Right", "");
filterObject2.addProperty("Logic", 0);
filterString.add(filterObject2);
JsonObject filterObject3 = new JsonObject();
filterObject3.addProperty("FieldName", "FMoEntryStatus");
filterObject3.addProperty("Compare", "5");
filterObject3.addProperty("Value", "6");
filterObject3.addProperty("Left", "");
filterObject3.addProperty("Right", "");
filterObject3.addProperty("Logic", 0);
filterString.add(filterObject3);
JsonObject filterObject4 = new JsonObject();
filterObject4.addProperty("FieldName", "FDocumentStatus");
filterObject4.addProperty("Compare", "105");
filterObject4.addProperty("Value", "C");//单据状态:已审核
filterObject4.addProperty("Left", "");
filterObject4.addProperty("Right", "");
filterObject4.addProperty("Logic", 0);
filterString.add(filterObject4);
JsonObject filterObject5 = new JsonObject();
filterObject5.addProperty("FieldName", "F_HBYT_SCLH");
filterObject5.addProperty("Compare", "=");
filterObject5.addProperty("Value", procode);//筛选条件 生产令号
filterObject5.addProperty("Left", "");
filterObject5.addProperty("Right", "");
filterObject5.addProperty("Logic", 0);
filterString.add(filterObject5);
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();
List<JDProductionDTO> plannedProcessList = null;
try {
// 调用接口
String resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
// 使用 ObjectMapper JsonArray 转换为 List<PlannedProcessVo>
ObjectMapper objectMapper = new ObjectMapper();
plannedProcessList = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<JDProductionDTO>>() {
});
} catch (Exception e) {
e.printStackTrace(); // 输出异常日志
}
return plannedProcessList; // 返回结果
}
/**
* 查询生产用料清单单据体
* 查询子项物料的未领料量
* @param materialCode
* @return
*/
public static List<JDProductionDTO> getWeiLingliao(String materialCode) {
K3CloudApi client = new K3CloudApi();
@ -749,6 +1189,100 @@ public class JdUtil {
filterObject4.addProperty("Right", "");
filterObject4.addProperty("Logic", 0);
filterString.add(filterObject4);
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();
List<JDProductionDTO> plannedProcessList = null;
try {
// 调用接口
String resultJson = String.valueOf(client.billQuery(jsonData));
JsonArray jsonArray = new Gson().fromJson(resultJson, JsonArray.class);
// 使用 ObjectMapper JsonArray 转换为 List<PlannedProcessVo>
ObjectMapper objectMapper = new ObjectMapper();
plannedProcessList = objectMapper.readValue(jsonArray.toString(),
new TypeReference<List<JDProductionDTO>>() {
});
} catch (Exception e) {
e.printStackTrace(); // 输出异常日志
}
return plannedProcessList; // 返回结果
}
/**
* 查询生产用料清单单据体
* 查询子项物料的未领料量限制生产令号
* @param materialCode
* @return
*/
public static List<JDProductionDTO> getWeiLingliaoByProcode(String materialCode,String procode) {
K3CloudApi client = new K3CloudApi();
// 请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "PRD_PPBOM");
json.addProperty("FieldKeys",
"FMaterialID2.FNumber,FMaterialName1,FNoPickedQty");
// 创建过滤条件
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "FMaterialID2.FNumber");
filterObject.addProperty("Compare", "67");
filterObject.addProperty("Value", materialCode);
filterObject.addProperty("Left", "");
filterObject.addProperty("Right", "");
filterObject.addProperty("Logic", 0);
filterString.add(filterObject);
JsonObject filterObject1 = new JsonObject();
filterObject1.addProperty("FieldName", "FMoEntryStatus");
filterObject1.addProperty("Compare", "5");
filterObject1.addProperty("Value", "7");
filterObject1.addProperty("Left", "");
filterObject1.addProperty("Right", "");
filterObject1.addProperty("Logic", 0);
filterString.add(filterObject1);
JsonObject filterObject2 = new JsonObject();
filterObject2.addProperty("FieldName", "FMoEntryStatus");// 改为等号运算符
filterObject2.addProperty("Compare", "5");
filterObject2.addProperty("Value", "5");
filterObject2.addProperty("Left", "");
filterObject2.addProperty("Right", "");
filterObject2.addProperty("Logic", 0);
filterString.add(filterObject2);
JsonObject filterObject3 = new JsonObject();
filterObject3.addProperty("FieldName", "FMoEntryStatus");
filterObject3.addProperty("Compare", "5");
filterObject3.addProperty("Value", "6");
filterObject3.addProperty("Left", "");
filterObject3.addProperty("Right", "");
filterObject3.addProperty("Logic", 0);
filterString.add(filterObject3);
JsonObject filterObject4 = new JsonObject();
filterObject4.addProperty("FieldName", "FDocumentStatus");
filterObject4.addProperty("Compare", "105");
filterObject4.addProperty("Value", "C");//单据状态:已审核
filterObject4.addProperty("Left", "");
filterObject4.addProperty("Right", "");
filterObject4.addProperty("Logic", 0);
filterString.add(filterObject4);
JsonObject filterObject5 = new JsonObject();
filterObject5.addProperty("FieldName", "F_HBYT_SCLH");
filterObject5.addProperty("Compare", "83");
filterObject5.addProperty("Value", procode);//筛选条件 生产令号
filterObject5.addProperty("Left", "");
filterObject5.addProperty("Right", "");
filterObject5.addProperty("Logic", 0);
filterString.add(filterObject5);
json.add("FilterString", filterString);
json.addProperty("OrderString", "");
json.addProperty("TopRowCount", 0);
@ -1182,7 +1716,6 @@ public class JdUtil {
// 对返回结果进行解析和校验
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 {
@ -1429,11 +1962,11 @@ public class JdUtil {
RepoRet sRet = gson.fromJson(result, RepoRet.class);
if (sRet.isSuccessfully()) {
String successMessage = String.format("物料清单 %s 保存成功", sRet.getResult().getResponseStatus());
log.info("物料编码"+code+"保存成功");
log.info("更新货主信息物料编码==>"+code+" 保存成功");
return successMessage;
} else {
String errorMessage = String.format("物料 %s 保存失败: %s", FENTRYID, gson.toJson(sRet.getResult()));
log.info("物料编码"+code+"保存失败"+"原因:"+gson.toJson(sRet.getResult()));
log.info("更新货主信息物料编码"+code+"保存失败"+"原因:"+gson.toJson(sRet.getResult()));
return errorMessage;
}
}

View File

@ -164,9 +164,10 @@ public class PDFGenerator {
departmentFolder.mkdirs();
}
// 3. 直接生成 PDF 到该文件夹
String pdfPath = departmentFolder.getAbsolutePath() + "\\" + fDepartmentName + "_" + materialCode1.replace("/", "_") + "_generated.pdf";
// 获取当前时间的毫秒时间戳
long timestamp = System.currentTimeMillis();
String pdfPath = departmentFolder.getAbsolutePath() + "\\" + fDepartmentName + "_"
+ materialCode1.replace("/", "_") + "_" + timestamp + ".pdf";
try {
// 创建 PDF 文件并写入内容
PDDocument document = new PDDocument();

View File

@ -56,4 +56,6 @@ public interface IBomDetailsService {
BomDetails selectBOMFNumber(String fnumbers);
List<BomDetails> selectByFNumberAndTotalWeight(String fnumber, String totalWeight);
List<BomDetails> selectByProjectNumber(String totalWeight);
}

View File

@ -53,4 +53,6 @@ public interface IFigureSaveService {
* @return
*/
List<FigureSave> selectByFid(Long id);
List<FigureSave> selectByProCode(String totalWeight);
}

View File

@ -62,4 +62,8 @@ public interface IImMaterialService {
TableDataInfo search(String query);
Boolean insertJDMaterial(List<ImMaterial> materialList);
Boolean updateByFMid(List<ImMaterial> imMaterials);
}

View File

@ -0,0 +1,49 @@
package com.ruoyi.system.service;
import com.ruoyi.system.domain.KingdeeAssetCard;
import com.ruoyi.system.domain.vo.KingdeeAssetCardVo;
import com.ruoyi.system.domain.bo.KingdeeAssetCardBo;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 金蝶资产卡片Service接口
*
* @author ruoyi
* @date 2025-09-04
*/
public interface IKingdeeAssetCardService {
/**
* 查询金蝶资产卡片
*/
KingdeeAssetCardVo queryById(Long id);
/**
* 查询金蝶资产卡片列表
*/
TableDataInfo<KingdeeAssetCardVo> queryPageList(KingdeeAssetCardBo bo, PageQuery pageQuery);
/**
* 查询金蝶资产卡片列表
*/
List<KingdeeAssetCardVo> queryList(KingdeeAssetCardBo bo);
/**
* 新增金蝶资产卡片
*/
Boolean insertByBo(KingdeeAssetCardBo bo);
/**
* 修改金蝶资产卡片
*/
Boolean updateByBo(KingdeeAssetCardBo bo);
/**
* 校验并批量删除金蝶资产卡片信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@ -1,5 +1,6 @@
package com.ruoyi.system.service;
import com.ruoyi.system.domain.MaterialBom;
import com.ruoyi.system.domain.ProcessRoute;
import com.ruoyi.system.domain.vo.MaterialBomVo;
import com.ruoyi.system.domain.bo.MaterialBomBo;
@ -50,4 +51,6 @@ public interface IMaterialBomService {
int addMaterialBom(ProcessRoute bo);
List<MaterialBomVo> getMaterialInfo(String processDescription, String materialCode);
List<MaterialBom> selectByProCode(String productionOrderNo);
}

View File

@ -0,0 +1,54 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.system.domain.MrpResultCheck;
import com.ruoyi.system.domain.vo.MrpResultCheckVo;
import com.ruoyi.system.domain.bo.MrpResultCheckBo;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* MRP运算结果复查Service接口
*
* @author tzy
* @date 2025-08-22
*/
public interface IMrpResultCheckService {
/**
* 查询MRP运算结果复查
*/
MrpResultCheckVo queryById(Long id);
/**
* 查询MRP运算结果复查列表
*/
TableDataInfo<MrpResultCheckVo> queryPageList(MrpResultCheckBo bo, PageQuery pageQuery);
/**
* 查询MRP运算结果复查列表
*/
List<MrpResultCheckVo> queryList(MrpResultCheckBo bo);
/**
* 新增MRP运算结果复查
*/
Boolean insertByBo(MrpResultCheckBo bo);
/**
* 修改MRP运算结果复查
*/
Boolean updateByBo(MrpResultCheckBo bo);
/**
* 校验并批量删除MRP运算结果复查信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
R<List<MrpResultCheck>> getMRPResults(Long id);
List<MrpResultCheck> queryListByOrderProId(MrpResultCheckBo bo);
}

View File

@ -57,4 +57,6 @@ public interface IPcRigidChainService {
* 根据型号名称集合批量查询销齿链型号管理
*/
List<PcRigidChain> selectByTypeNames(Set<String> typeNames);
List<PcRigidChain> selectPcRigidChainByType(String type);
}

View File

@ -4,6 +4,7 @@ import com.ruoyi.common.core.domain.R;
import com.ruoyi.system.domain.ProcessOrderPro;
import com.ruoyi.system.domain.ProcessRoute;
import com.ruoyi.system.domain.bo.FigureSaveBo;
import com.ruoyi.system.domain.vo.OverdueProjectVo;
import com.ruoyi.system.domain.vo.ProcessOrderProVo;
import com.ruoyi.system.domain.bo.ProcessOrderProBo;
import com.ruoyi.common.core.page.TableDataInfo;
@ -72,4 +73,6 @@ public interface IProcessOrderProService {
R<String> uploadPDF(Long id);
String uploadContractPDF(Integer id, String originalFilename, MultipartFile filePath);
List<OverdueProjectVo> getOverdueProjects();
}

View File

@ -0,0 +1,57 @@
package com.ruoyi.system.service;
import com.ruoyi.system.domain.ProcessPlan;
import com.ruoyi.system.domain.vo.ExpiryProjectVo;
import com.ruoyi.system.domain.vo.OverdueProjectVo;
import com.ruoyi.system.domain.vo.ProcessPlanVo;
import com.ruoyi.system.domain.bo.ProcessPlanBo;
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-08-20
*/
public interface IProcessPlanService {
/**
* 查询方案管理
*/
ProcessPlanVo queryById(Long id);
/**
* 查询方案管理列表
*/
TableDataInfo<ProcessPlanVo> queryPageList(ProcessPlanBo bo, PageQuery pageQuery);
/**
* 查询方案管理列表
*/
List<ProcessPlanVo> queryList(ProcessPlanBo bo);
/**
* 新增方案管理
*/
Boolean insertByBo(ProcessPlanBo bo);
/**
* 修改方案管理
*/
Boolean updateByBo(ProcessPlanBo bo);
/**
* 校验并批量删除方案管理信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
List<OverdueProjectVo> getOverdueProjects();
List<ExpiryProjectVo> getExpiryProjects();
TableDataInfo<ProcessPlanVo> queryPageList2(ProcessPlanBo bo, PageQuery pageQuery);
}

View File

@ -120,7 +120,7 @@ public interface IProcessRouteService {
List<ProcessRouteSelectDTO> getSelectProcessRoute(String materilCode);
List<ProcessRouteSelectDTO> getSelectStandProcessRoute(String materilCode);
//根据项目令号删除 材料bom 总装bom 工艺路线
R<Void> selectByProjectCode(String productionOrderNo);
R<Void> delByProjectCode(String productionOrderNo);
List<ProcessRouteJdDTO> getProcessRouteList(String materialCode, String materialName, String productionOrderNo);
//获取物料的非委外的工作时长
@ -141,4 +141,6 @@ public interface IProcessRouteService {
List<JDMaterialAndRoute> getProcessRouteGD(List<ProcessRouteVo> list);
//获取物料首个工序的工作中心
String getRouteCode(String materialCode,String code);
List<ProcessRoute> selectByProjectNumber(String productionOrderNo);
}

View File

@ -56,4 +56,6 @@ public interface IProductionOrderService {
List<ProductionOrder> getGroupWeldSubset(ProductionOrderVo productionOrderVo);
Boolean executDrawing(ProcessOrderProBo orderPro);
List<ProductionOrder> selectByProCode(String productionOrderNo);
}

View File

@ -27,6 +27,7 @@ import com.ruoyi.system.domain.BomDetails;
import com.ruoyi.system.mapper.BomDetailsMapper;
import com.ruoyi.system.service.IBomDetailsService;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Collection;
@ -169,7 +170,6 @@ public class BomDetailsServiceImpl implements IBomDetailsService {
public List<BomDetails> selectByFNumber(String fnumber) {
LambdaQueryWrapper<BomDetails> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(fnumber), BomDetails::getFNumber, fnumber);
lqw.eq(StringUtils.isNotBlank(fnumber), BomDetails::getFNumber, fnumber);
return baseMapper.selectList(lqw);
}
@ -222,8 +222,8 @@ public class BomDetailsServiceImpl implements IBomDetailsService {
MaterialBom matchedMaterialBom = materialBomMap.get(key);
if (matchedMaterialBom != null) {
if (matchedMaterialBom.getUnit().equals("")) {
bomDetail.setQuantity(1.0);
bomDetail.setDenominator(Double.valueOf(String.valueOf(matchedMaterialBom.getQuantity())));
bomDetail.setQuantity(Double.valueOf(String.valueOf(matchedMaterialBom.getQuantity()).split("/")[0]));
bomDetail.setDenominator(Double.valueOf(String.valueOf(matchedMaterialBom.getQuantity()).split("/")[1]));
} else {
bomDetail.setQuantity(Double.valueOf(String.valueOf(matchedMaterialBom.getQuantity())));
@ -235,6 +235,18 @@ public class BomDetailsServiceImpl implements IBomDetailsService {
return bomDetails;
}
/**
* @param totalWeight
* @return
*/
@Override
public List<BomDetails> selectByProjectNumber(String totalWeight) {
LambdaQueryWrapper<BomDetails> bomDetailsLambdaQueryWrapper = new LambdaQueryWrapper<>();
bomDetailsLambdaQueryWrapper.eq(BomDetails::getTotalWeight,totalWeight);
return baseMapper.selectList(bomDetailsLambdaQueryWrapper);
}
public int loadMaterialPreservation(BomDetails bomDetails1) {
K3CloudApi client = new K3CloudApi();

View File

@ -212,6 +212,7 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
// 处理物料并收集结果
List<ProcessResult> results = newMaterials.stream()
.filter(material -> isValidMaterialValue(material.getMaterialValue()))
//推送金蝶
.map(this::processMaterial)
.collect(Collectors.toList());
@ -386,11 +387,9 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
JsonObject json = new JsonObject();
// 添加IsAutoSubmitAndAudit字段
json.addProperty("IsAutoSubmitAndAudit", "false");
// 创建Model对象并加入JsonObject
JsonObject model = new JsonObject();
json.add("Model", model);
// 添加Model字段
model.addProperty("FMATERIALID", 0);
model.addProperty("F_HBYT_PP", newMaterial.getBrand());//品牌
@ -800,11 +799,9 @@ public class EleMaterialsServiceImpl implements IEleMaterialsService {
// 对返回结果进行解析和校验
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;
}

View File

@ -125,4 +125,16 @@ public class FigureSaveServiceImpl implements IFigureSaveService {
return baseMapper.selectList(wa);
}
/**
* @param totalWeight
* @return
*/
@Override
public List<FigureSave> selectByProCode(String totalWeight) {
LambdaQueryWrapper<FigureSave> wa = new LambdaQueryWrapper<>();
wa.eq(FigureSave::getProductionCode,totalWeight);
return baseMapper.selectList(wa);
}
}

View File

@ -16,6 +16,7 @@ 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.utils.BeanCopyUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.controller.ImMaterialController;
import com.ruoyi.system.domain.ImMaterial;
@ -40,6 +41,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
@ -175,25 +177,52 @@ public class ImMaterialServiceImpl implements IImMaterialService {
public TableDataInfo<ImMaterialVo> queryPageList(ImMaterialBo bo, PageQuery pageQuery) {
try {
System.out.println("查询开始"+System.currentTimeMillis());
LambdaQueryWrapper<ImMaterial> lqw = buildQueryWrapper(bo);
lqw.like(StringUtils.isNotBlank(bo.getMaterialCode()), ImMaterial::getMaterialCode, bo.getMaterialCode());
lqw.like(StringUtils.isNotBlank(bo.getMaterialName()), ImMaterial::getMaterialName, bo.getMaterialName());
lqw.like(StringUtils.isNotBlank(bo.getClassificationName()), ImMaterial::getClassificationName, bo.getClassificationName());
lqw.like(StringUtils.isNotBlank(bo.getImCategory()), ImMaterial::getImCategory, bo.getImCategory());
lqw.like(StringUtils.isNotBlank(bo.getMaterialQuality()), ImMaterial::getMaterialQuality, bo.getMaterialQuality());
lqw.eq(bo.getSingleWeight() != null, ImMaterial::getSingleWeight, bo.getSingleWeight());
lqw.eq( ImMaterial::getForbidStatus, "A");
lqw.like(StringUtils.isNotBlank(bo.getUnit()), ImMaterial::getUnit, bo.getUnit());
lqw.like(bo.getFlag() != null, ImMaterial::getFlag, bo.getFlag());
lqw.orderBy(true, false, ImMaterial::getModifyDate);
System.out.println("+++++++++++++++++++++++++++++++++++++++"+lqw.getSqlSegment());
// 执行查询
Page<ImMaterialVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
if (CollectionUtils.isEmpty(result.getRecords())) {
return TableDataInfo.build(result); // 如果结果为空直接返回
}
System.out.println("查询结束"+System.currentTimeMillis());
// 调用库存查询方法优化为批量查询而非逐个查询
Map<String, JsonObject> jsonMap = queryAllKuCun(result.getRecords());
System.out.println("组装结束"+System.currentTimeMillis());
// 更新库存信息
updateRecordsWithKuCunInfo(jsonMap, result.getRecords());
// 更新数量更新实体类
result.setRecords(result.getRecords()); // 更新结果集
List<ImMaterialVo> records = result.getRecords();
// 根据库存 in_inventory 降序排序
records.sort(Comparator.comparing(
r -> {
BigDecimal value = BigDecimal.ZERO;
if (r.getInInventory() != null) {
try {
value = new BigDecimal(r.getInInventory());
} catch (NumberFormatException e) {
// 如果 in_inventory 不是数字默认为 0
value = BigDecimal.ZERO;
}
}
// 保留三位小数四舍五入
return value.setScale(3, RoundingMode.HALF_UP);
},
Comparator.reverseOrder()
));
result.setRecords(records); // 更新结果集*/
return TableDataInfo.build(result);
} catch (Exception e) {
// 异常处理逻辑可根据实际情况调整
@ -224,8 +253,8 @@ public class ImMaterialServiceImpl implements IImMaterialService {
defaultJsonObject.addProperty("FMaterialId.FNumber", record.getMaterialCode());
defaultJsonObject.addProperty("FMaterialName", record.getMaterialName());
defaultJsonObject.addProperty("FStockName", "N/A");
defaultJsonObject.addProperty("FStockUnitId.FName", ""); // 假设单位是""
defaultJsonObject.addProperty("FBaseQty", 0.0); // 设置数量为 0
defaultJsonObject.addProperty("FStockUnitId.FName", "");
defaultJsonObject.addProperty("FBaseQty", 0.0);
jsonMap.put(record.getMaterialCode(), defaultJsonObject);
}
}else{
@ -296,25 +325,15 @@ public class ImMaterialServiceImpl implements IImMaterialService {
String materialCode = record.getMaterialCode();
JsonObject jsonObject = jsonMap.get(materialCode);
if (jsonObject != null) {
JsonElement unitElement = jsonObject.get("FBaseQty");
if (unitElement != null && !unitElement.isJsonNull()){
record.setUnit(unitElement.getAsString());
}
String unit = jsonObject.get("FStockUnitId.FName").getAsString();
if (unit != null && !unit.isEmpty()) {
record.setClassificationName(unit);
} else {
record.setClassificationName("");
}
JsonElement qualityElement = jsonObject.get("F_UCHN_BaseProperty");
JsonElement qualityElement = jsonObject.get("FBaseQty");
if (qualityElement != null && !qualityElement.isJsonNull()) {
record.setMaterialQuality(qualityElement.getAsString());
record.setInInventory(qualityElement.getAsString());
} else {
record.setMaterialQuality("");
record.setInInventory("0.0");
}
} else {
record.setMaterialQuality("");
record.setInInventory("0.0");
}
// 使用keYong方法计算可用库存
@ -395,6 +414,7 @@ public class ImMaterialServiceImpl implements IImMaterialService {
lqw.like(StringUtils.isNotBlank(bo.getImCategory()), ImMaterial::getImCategory, bo.getImCategory());
lqw.like(StringUtils.isNotBlank(bo.getMaterialQuality()), ImMaterial::getMaterialQuality, bo.getMaterialQuality());
lqw.eq(bo.getSingleWeight() != null, ImMaterial::getSingleWeight, bo.getSingleWeight());
lqw.eq(bo.getForbidStatus() != null, ImMaterial::getForbidStatus, "");
lqw.like(bo.getUnitPrice() != null, ImMaterial::getUnitPrice, bo.getUnitPrice());
lqw.like(StringUtils.isNotBlank(bo.getUnit()), ImMaterial::getUnit, bo.getUnit());
lqw.like(bo.getFlag() != null, ImMaterial::getFlag, bo.getFlag());
@ -699,6 +719,47 @@ public class ImMaterialServiceImpl implements IImMaterialService {
return null;
}
/**
* @param materialList
* @return
*/
@Override
public Boolean insertJDMaterial(List<ImMaterial> materialList) {
if (materialList.size()<0 || materialList.isEmpty()){
return false;
}
return baseMapper.insertBatch(materialList);
}
/**
* 更新当天创建的物料编码
* @param imMaterials
*/
@Override
public Boolean updateByFMid(List<ImMaterial> imMaterials) {
if (imMaterials == null || imMaterials.isEmpty()) {
return false;
}
for (ImMaterial imMaterial : imMaterials) {
// 根据 materialId 查询是否存在
ImMaterial existing = baseMapper.selectByMid(imMaterial.getMaterialId());
if (imMaterial.getForbidStatus().equals("A")){
imMaterial.setForbidStatus("");
}else {
imMaterial.setForbidStatus("");
}
if (existing != null) {
// 如果存在则更新
baseMapper.updateByMaterid(imMaterial);
} else {
// 如果不存在则插入
baseMapper.insert(imMaterial);
}
}
return true;
}
public ImMaterial findByMaterialCode(String materialCode) {
LambdaQueryWrapper<ImMaterial> queryWrapper = new LambdaQueryWrapper<>();

View File

@ -0,0 +1,116 @@
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.KingdeeAssetCardBo;
import com.ruoyi.system.domain.vo.KingdeeAssetCardVo;
import com.ruoyi.system.domain.KingdeeAssetCard;
import com.ruoyi.system.mapper.KingdeeAssetCardMapper;
import com.ruoyi.system.service.IKingdeeAssetCardService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 金蝶资产卡片Service业务层处理
*
* @author ruoyi
* @date 2025-09-04
*/
@RequiredArgsConstructor
@Service
public class KingdeeAssetCardServiceImpl implements IKingdeeAssetCardService {
private final KingdeeAssetCardMapper baseMapper;
/**
* 查询金蝶资产卡片
*/
@Override
public KingdeeAssetCardVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 查询金蝶资产卡片列表
*/
@Override
public TableDataInfo<KingdeeAssetCardVo> queryPageList(KingdeeAssetCardBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<KingdeeAssetCard> lqw = buildQueryWrapper(bo);
Page<KingdeeAssetCardVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询金蝶资产卡片列表
*/
@Override
public List<KingdeeAssetCardVo> queryList(KingdeeAssetCardBo bo) {
LambdaQueryWrapper<KingdeeAssetCard> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<KingdeeAssetCard> buildQueryWrapper(KingdeeAssetCardBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<KingdeeAssetCard> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getAssetCategory()), KingdeeAssetCard::getAssetCategory, bo.getAssetCategory());
lqw.eq(StringUtils.isNotBlank(bo.getCardCode()), KingdeeAssetCard::getCardCode, bo.getCardCode());
lqw.eq(StringUtils.isNotBlank(bo.getAssetUnit()), KingdeeAssetCard::getAssetUnit, bo.getAssetUnit());
lqw.eq(StringUtils.isNotBlank(bo.getAssetCode()), KingdeeAssetCard::getAssetCode, bo.getAssetCode());
lqw.eq(StringUtils.isNotBlank(bo.getAssetLocation()), KingdeeAssetCard::getAssetLocation, bo.getAssetLocation());
lqw.eq(bo.getAssetQuantity() != null, KingdeeAssetCard::getAssetQuantity, bo.getAssetQuantity());
lqw.like(StringUtils.isNotBlank(bo.getAssetName()), KingdeeAssetCard::getAssetName, bo.getAssetName());
lqw.eq(StringUtils.isNotBlank(bo.getAssetManufacturer()), KingdeeAssetCard::getAssetManufacturer, bo.getAssetManufacturer());
return lqw;
}
/**
* 新增金蝶资产卡片
*/
@Override
public Boolean insertByBo(KingdeeAssetCardBo bo) {
KingdeeAssetCard add = BeanUtil.toBean(bo, KingdeeAssetCard.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改金蝶资产卡片
*/
@Override
public Boolean updateByBo(KingdeeAssetCardBo bo) {
KingdeeAssetCard update = BeanUtil.toBean(bo, KingdeeAssetCard.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(KingdeeAssetCard entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除金蝶资产卡片
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}

View File

@ -24,6 +24,7 @@ import com.ruoyi.system.mapper.MaterialBomMapper;
import com.ruoyi.system.service.IMaterialBomService;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Collection;
@ -243,4 +244,16 @@ public class MaterialBomServiceImpl implements IMaterialBomService {
List<MaterialBomVo> materialBomVos = baseMapper.selectVoList(wrapper);
return materialBomVos;
}
/**
* @param productionOrderNo
* @return
*/
@Override
public List<MaterialBom> selectByProCode(String productionOrderNo) {
LambdaQueryWrapper<MaterialBom> lq = new LambdaQueryWrapper<>();
lq.eq(MaterialBom::getProjectNumber,productionOrderNo);
return baseMapper.selectList(lq);
}
}

View File

@ -0,0 +1,304 @@
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.common.utils.FractionUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.dto.*;
import com.ruoyi.system.mapper.FigureSaveMapper;
import com.ruoyi.system.mapper.ProcessOrderProMapper;
import com.ruoyi.system.runner.JdUtil;
import com.ruoyi.system.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.ruoyi.system.domain.bo.MrpResultCheckBo;
import com.ruoyi.system.domain.vo.MrpResultCheckVo;
import com.ruoyi.system.mapper.MrpResultCheckMapper;
import java.math.BigDecimal;
import java.util.*;
/**
* MRP运算结果复查Service业务层处理
*
* @author tzy
* @date 2025-08-22
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class MrpResultCheckServiceImpl implements IMrpResultCheckService {
private final MrpResultCheckMapper baseMapper;
private final FigureSaveMapper figureSaveMapper;
private final ProcessOrderProMapper processOrderProMapper;
private final IMaterialBomService iMaterialBomService;
private final IProductionOrderService iProductionOrderService;
private final IBomDetailsService iBomDetailsService;
private final IProcessRouteService iProcessRouteService;
/**
* 查询MRP运算结果复查
*/
@Override
public MrpResultCheckVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 查询MRP运算结果复查列表
*/
@Override
public TableDataInfo<MrpResultCheckVo> queryPageList(MrpResultCheckBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<MrpResultCheck> lqw = buildQueryWrapper(bo);
Page<MrpResultCheckVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询MRP运算结果复查列表
*/
@Override
public List<MrpResultCheckVo> queryList(MrpResultCheckBo bo) {
LambdaQueryWrapper<MrpResultCheck> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<MrpResultCheck> buildQueryWrapper(MrpResultCheckBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<MrpResultCheck> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getMaterialName()), MrpResultCheck::getMaterialName, bo.getMaterialName());
lqw.like(StringUtils.isNotBlank(bo.getMaterialCode()), MrpResultCheck::getMaterialCode, bo.getMaterialCode());
lqw.eq(bo.getAvailableStock() != null, MrpResultCheck::getAvailableStock, bo.getAvailableStock());
lqw.eq(bo.getRealTimeStock() != null, MrpResultCheck::getRealTimeStock, bo.getRealTimeStock());
lqw.eq(bo.getProdNotInStock() != null, MrpResultCheck::getProdNotInStock, bo.getProdNotInStock());
lqw.eq(bo.getPurchaseRequestQty() != null, MrpResultCheck::getPurchaseRequestQty, bo.getPurchaseRequestQty());
lqw.eq(bo.getPurchaseNotInStock() != null, MrpResultCheck::getPurchaseNotInStock, bo.getPurchaseNotInStock());
lqw.eq(bo.getChildNotPickedQty() != null, MrpResultCheck::getChildNotPickedQty, bo.getChildNotPickedQty());
lqw.eq(bo.getOrderProId() != null, MrpResultCheck::getOrderProId, bo.getOrderProId());
return lqw;
}
/**
* 新增MRP运算结果复查
*/
@Override
public Boolean insertByBo(MrpResultCheckBo bo) {
MrpResultCheck add = BeanUtil.toBean(bo, MrpResultCheck.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改MRP运算结果复查
*/
@Override
public Boolean updateByBo(MrpResultCheckBo bo) {
MrpResultCheck update = BeanUtil.toBean(bo, MrpResultCheck.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(MrpResultCheck entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除MRP运算结果复查
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
/**
* @param id
* @return
*/
@Override
public R<List<MrpResultCheck>> getMRPResults(Long id) {
// 根据Id查询生产令号
ProcessOrderPro processOrderPro = processOrderProMapper.selectById(id);
List<MaterialBom> materialBomList = iMaterialBomService.selectByProCode(processOrderPro.getProductionOrderNo());
List<ProductionOrder> productionOrderList = iProductionOrderService.selectByProCode(processOrderPro.getProductionOrderNo());
List<ProcessRouteXuDTO> processRoute = iProcessRouteService.getProcessRoute(processOrderPro.getProductionOrderNo());
// 使用 Map<String, CodeInfo>
Map<String, CodeInfo> codeMap = new LinkedHashMap<>();
if (!materialBomList.isEmpty() && !processRoute.isEmpty()) {
for (MaterialBom materialBom : materialBomList) {
String qty = materialBom.getQuantity() == null ? "0" : materialBom.getQuantity();
codeMap.putIfAbsent(
materialBom.getMaterialCode(),
new CodeInfo(materialBom.getMaterialName(), materialBom.getQuantity()) // 数量来自 BOM
);
}
} else {
return R.fail("未上传工艺和BOM");
}
if (!productionOrderList.isEmpty()) {
for (ProductionOrder productionOrder : productionOrderList) {
String qty = productionOrder.getBatchQuantity() == null ? "0" : productionOrder.getBatchQuantity();
codeMap.putIfAbsent(
productionOrder.getDrawingNo(),
new CodeInfo(productionOrder.getDrawingName(), productionOrder.getBatchQuantity()) // 数量来自生产令
);
codeMap.putIfAbsent(
productionOrder.getDrawingNo(),
new CodeInfo(productionOrder.getDrawingName(), productionOrder.getBatchQuantity()) // 数量来自生产令
);
}
}
List<MrpResultCheck> resultList = new ArrayList<>();
for (Map.Entry<String, CodeInfo> entry : codeMap.entrySet()) {
String materialCode = entry.getKey();
CodeInfo info = entry.getValue();
String materialName = info.getName();
//本批数量
String qty = info.getQty();
// 先查数据库是否已存在记录
MrpResultCheck exist = baseMapper.selectOne(
new LambdaQueryWrapper<MrpResultCheck>()
.eq(MrpResultCheck::getOrderProId, id)
.eq(MrpResultCheck::getMaterialCode, materialCode)
);
// 库存数量
double inventoryQty = Optional.ofNullable(JdUtil.getKuCun(materialCode))
.map(list -> list.stream()
.mapToDouble(JDInventoryDTO::getFBaseQty)
.sum())
.orElse(0.0);
// double realTimeStock =inventoryQty + productionQty + purchaseQty-fNoPickedQty;
//TODO:计算 当前可用库存 =即时库存 + 生产未入库数量(本项目除外) + 采购未入库项目(本项目除外) -子项未领料数量(本项目除外)
// 生产订单未入库数量(本项目除外)
double productionQty = Optional.ofNullable(JdUtil.getProMoListLimitByProCode(materialCode,processOrderPro.getProductionOrderNo()))
.map(list -> list.stream()
.mapToDouble(ProMoDTO::getFQty)
.sum())
.orElse(0.0);
// 采购订单未入库(本项目除外)
double reqQt1y = Optional.ofNullable(JdUtil.getPurchaseOrderListByProCode(materialCode,processOrderPro.getProductionOrderNo()))
.map(list -> list.stream()
.mapToDouble(PurchaseOrderDTO::getFRemainStockINQty)
.sum())
.orElse(0.0);
// 子项物料未领料量(本项目除外)
double fNoPickedQty1 = Optional.ofNullable(JdUtil.getWeiLingliaoByProcode(materialCode,processOrderPro.getProductionOrderNo()))
.map(list -> list.stream()
.mapToDouble(JDProductionDTO::getFNoPickedQty)
.sum())
.orElse(0.0);
//当前可用库存
double currentAvailableStock = inventoryQty + productionQty+reqQt1y-fNoPickedQty1;
log.debug(
"当前项目:{},物料编码:{}当前可用库存={} (即时库存:{} + 生产未入库数量:{} + 采购未入库数量:{} - 本项目除外子项未领料数量:{})",
processOrderPro.getProductionOrderNo(),
materialCode,
currentAvailableStock,
inventoryQty,
productionQty,
reqQt1y,
fNoPickedQty1
);
//TODO:本项目可用库存 = 当前可用库存 +本次生产未入库 + 本项目采购申请 -本项目子项未领料数量
//本次生产未入库
double benciscwrk = Optional.ofNullable(JdUtil.getProMoListByProCode(materialCode,processOrderPro.getProductionOrderNo()))
.map(list -> list.stream()
.mapToDouble(ProMoDTO::getFQty)
.sum())
.orElse(0.0);
//本项目采购申请
double reqQty = Optional.ofNullable(JdUtil.getPurchaseRequestByProCode(materialCode,processOrderPro.getProductionOrderNo()))
.map(list -> list.stream()
.mapToDouble(PurchaseRequestDTO::getFReqQty)
.sum())
.orElse(0.0);
//本项目子项未领料数量
double fNoPickedQtyAll = Optional.ofNullable(JdUtil.getWeiLingliaoLimBen(materialCode,processOrderPro.getProductionOrderNo()))
.map(list -> list.stream()
.mapToDouble(JDProductionDTO::getFNoPickedQty)
.sum())
.orElse(0.0);
//本项目可用库存
double bxmkykc = currentAvailableStock +benciscwrk +reqQty -fNoPickedQtyAll;
log.debug(
"当前项目:{},物料编码:{}+本项目可用库存={} (当前可用库存:{} + 本次生产未入库:{} + 本项目采购申请:{} - 子项未领料数量:{})",
processOrderPro.getProductionOrderNo(),
materialCode,
bxmkykc,
currentAvailableStock,
benciscwrk,
reqQty,
fNoPickedQtyAll
);
if (exist != null) {
// 更新
exist.setMaterialName(materialName);
exist.setAvailableStock(BigDecimal.valueOf(bxmkykc));
exist.setRealTimeStock(BigDecimal.valueOf(currentAvailableStock));
exist.setChildNotPickedQty(BigDecimal.valueOf(fNoPickedQtyAll));
exist.setProdNotInStock(BigDecimal.valueOf(benciscwrk));
exist.setPurchaseNotInStock(qty);
exist.setPurchaseRequestQty(BigDecimal.valueOf(reqQty));
baseMapper.updateById(exist);
} else {
// 插入
MrpResultCheck vo = new MrpResultCheck();
vo.setOrderProId(id);
vo.setMaterialCode(materialCode);
vo.setMaterialName(materialName);
vo.setAvailableStock(BigDecimal.valueOf(bxmkykc));
vo.setRealTimeStock(BigDecimal.valueOf(currentAvailableStock));
vo.setChildNotPickedQty(BigDecimal.valueOf(fNoPickedQtyAll));
vo.setProdNotInStock(BigDecimal.valueOf(benciscwrk));
//purchaseNotInStock项目本批数
vo.setPurchaseNotInStock(qty);
vo.setPurchaseRequestQty(BigDecimal.valueOf(reqQty));
baseMapper.insert(vo);
}
}
return R.ok(resultList);
}
/**
* @param bo
* @return
*/
@Override
public List<MrpResultCheck> queryListByOrderProId(MrpResultCheckBo bo) {
// 根据orderProId查询忽略分页参数
return baseMapper.selectList(
new LambdaQueryWrapper<MrpResultCheck>()
.eq(MrpResultCheck::getOrderProId, bo.getOrderProId())
.orderByDesc(MrpResultCheck::getCreateTime)
);
}
}

View File

@ -136,4 +136,12 @@ public class PcRigidChainServiceImpl implements IPcRigidChainService {
wrapper.in(PcRigidChain::getTypeName, typeNames);
return baseMapper.selectList(wrapper);
}
public List<PcRigidChain> selectPcRigidChainByType(String type) {
LambdaQueryWrapper<PcRigidChain> pcRigidChainLambdaQueryWrapper = new LambdaQueryWrapper<>();
pcRigidChainLambdaQueryWrapper.eq(PcRigidChain::getType, type)
.eq(PcRigidChain::getDelFlag, 0);
return baseMapper.selectList(pcRigidChainLambdaQueryWrapper);
}
}

View File

@ -14,7 +14,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.utils.FtpUtil;
import com.ruoyi.common.utils.HttpUtils;
import com.ruoyi.common.utils.WxRobotUtil;
import com.ruoyi.common.utils.file.DeleteFile;
import com.ruoyi.common.utils.file.PDFDocHelper;
@ -23,33 +22,36 @@ import com.ruoyi.system.domain.bo.FigureSaveBo;
import com.ruoyi.system.domain.dto.excuteDrawing.DataInfo;
import com.ruoyi.system.domain.dto.excuteDrawing.ProductInfo;
import com.ruoyi.system.domain.dto.excuteDrawing.PwProductionBill;
import com.ruoyi.system.domain.vo.OverdueProjectVo;
import com.ruoyi.system.listener.FileToZip;
import com.ruoyi.system.listener.SmbUtils;
import com.ruoyi.system.mapper.FigureSaveMapper;
import com.ruoyi.system.mapper.ProcessRouteMapper;
import com.ruoyi.system.service.IFigureSaveService;
import com.ruoyi.system.service.IPcRigidChainService;
import com.ruoyi.system.service.IProcessRouteService;
import com.ruoyi.system.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.domain.bo.ProcessOrderProBo;
import com.ruoyi.system.domain.vo.ProcessOrderProVo;
import com.ruoyi.system.mapper.ProcessOrderProMapper;
import com.ruoyi.system.service.IProcessOrderProService;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.*;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.function.Function;
import java.util.concurrent.CompletableFuture;
import java.time.LocalDate;
/**
* 项目令号Service业务层处理
@ -70,7 +72,7 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
@Autowired
private IPcRigidChainService pcRigidChainService;
private final IProcessRouteService iProcessRouteService;
private final IBomDetailsService iBomDetailsService;
private static final String FILE_EXTENSION = ".xlsx"; // 目标文件后缀
private static final String LOCAL_DIR = "D:/file/";
private static final String ROBOTID = "8af8abea-3f21-4ca7-ad0a-5b7a2cf4d78e";
@ -87,6 +89,8 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
@Value("${app.drawing.api-url:http://192.168.5.18:9000/generatedrawingscompatible}")
private String apiUrl;
@Value("${app.drawing.api-url:http://192.168.5.18:9000/getstate}")
private String status;
@Autowired
private IFigureSaveService iFigureSaveService;
@ -206,7 +210,7 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
String productionOrderNo = processOrderProVo.getProductionOrderNo();
// 调用 selectByProjectCode 方法并检查结果
return iProcessRouteService.selectByProjectCode(productionOrderNo);
return iProcessRouteService.delByProjectCode(productionOrderNo);
}
if (isValid) {
@ -232,10 +236,6 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
return processRouteMapper.selectList(wrapper);
}
/**
* @param routeDescription
* @return
*/
/**
* @param routeDescription
* @return
@ -328,6 +328,7 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
public void addProduct(FigureSaveBo bo, ProcessOrderProBo orderPro) {
FigureSave figureSave = new FigureSave();
BeanUtils.copyProperties(bo, figureSave);
//更新产品类型
figureSaveMapper.insert(figureSave);
}
@ -345,7 +346,6 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
// 3. 构建路径
String dirPath = buildDirectoryPath(orderPro.getProductionOrderNo());
createDirectoryIfNotExists(dirPath);
// 4. 构建生产单据
PwProductionBill pwProductionBill = buildProductionBill(orderPro, dirPath);
@ -355,7 +355,7 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
pwProductionBill.setProduct(productInfos);
// 6. 调用API
return callDrawingApi(pwProductionBill);
return callDrawingApi(pwProductionBill,orderPro);
}
@ -405,10 +405,12 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
}
private PwProductionBill buildProductionBill(ProcessOrderProBo orderPro, String dirPath) {
String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
PwProductionBill pwProductionBill = new PwProductionBill();
pwProductionBill.setDestpath(dirPath);
pwProductionBill.setProducitonorder(orderPro.getProductionOrderNo());
pwProductionBill.setReleasedate(String.valueOf(orderPro.getProjectEndTime()));
//出图时间 为啥当先执行出图时间
pwProductionBill.setReleasedate(format);
return pwProductionBill;
}
@ -427,7 +429,7 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
ProductInfo productInfo = new ProductInfo();
productInfo.setAssembledrawing(figureSave.getFigureNumber());
productInfo.setNumber(String.valueOf(figureSave.getFigureNum()));
productInfo.setSourcefile( figureSave.getDrawPath().replace("/","\\"));
productInfo.setSourcefile(figureSave.getDrawPath().replace("/", "\\"));
log.info("项目生产令号为:{}查询产品型号信息: {}+ 产品名称: {}", figureSave.getProductionCode(), figureSave.getFigureNumber(), figureSave.getFigureName());
@ -527,23 +529,63 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
datainfo.setG20(String.valueOf(rigidChain.getGTwenty()));
}
private String callDrawingApi(PwProductionBill pwProductionBill) {
private String callDrawingApi(PwProductionBill pwProductionBill,ProcessOrderProBo orderPro) {
try {
String drawingDate = JSONObject.toJSONString(pwProductionBill);
log.info("请求出图报文=====>{}", drawingDate);
return HttpUtils.sendPost(apiUrl, drawingDate);
// 1. 先发起生成请求
String response = HttpUtils.sendPost(apiUrl, drawingDate);
log.info("出图接口响应=====>{}", response);
// 2. 开始轮询状态接口直到完成
boolean finished = false;
int maxRetry = 60; // 最多轮询 60 根据需求调整比如 60*5s=5分钟
int count = 0;
while (!finished && count < maxRetry) {
String statusResp = HttpUtils.sendGet(status, "UTF-8");
JSONObject json = JSONObject.parseObject(statusResp);
String currentStatus = json.getString("status");
int processState = json.getIntValue("processstate");
log.info("进度状态=====>status={}, processstate={}", currentStatus, processState);
// 判断完成条件processstate=4 表示完成
if ("idle".equals(currentStatus) && processState == 4) {
ProcessOrderPro processOrderPro = new ProcessOrderPro();
BeanUtils.copyProperties(orderPro,processOrderPro);
//To do
processOrderPro.setBomStatus(1L);//
baseMapper.updateById(processOrderPro);
log.info("图纸处理完成!");
return response;
}
// 没完成就等待一会儿再查
Thread.sleep(1000); // 1 秒轮询一次
count++;
}
throw new RuntimeException("图纸生成超时未完成");
} catch (Exception e) {
log.error("调用图纸生成API失败", e);
throw new RuntimeException("图纸生成失败", e);
}
}
/**
* @param id
*/
@Override
public R<String> uploadPDF(Long id) {
try {
//下载之前查看是否有产品,mei有产品的话就不能进行下载
List<FigureSave> figureSaves = iFigureSaveService.selectByFid(id);
if (figureSaves == null || figureSaves.isEmpty()) {
return R.fail("项目下未添加产品相关信息");
}
// 2. 查询项目信息
ProcessOrderPro processOrderPro = baseMapper.selectById(id);
if (processOrderPro == null) {
@ -560,8 +602,22 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
}
// 4. 构建本地根目录
String localBaseDir = "F:/2025/";
// 5. 下载FTP文件到本地
String localBaseDir = "D:/2025/";
// 5. 清空本地目标文件夹
String targetDir = localBaseDir + code;
File targetDirectory = new File(targetDir);
if (targetDirectory.exists()) {
log.info("清空目标文件夹: {}", targetDir);
try {
deleteDirectory(targetDirectory);
log.info("目标文件夹清空完成: {}", targetDir);
} catch (Exception e) {
log.error("清空目标文件夹失败: {}", targetDir, e);
return R.fail("清空目标文件夹失败: " + e.getMessage());
}
}
// 6. 下载FTP文件到本地
log.info("开始从FTP下载文件...");
for (FigureSave figureSave : fiseList) {
try {
@ -610,20 +666,58 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
return R.fail("处理PDF文件失败");
}
// 8.1 分类PDF到工作中心文件夹
String pdfDir = arr + code + "/zip";
classifyPdfByWorkCenter(pdfDir, code);
// 8. 分类PDF到 zip/工作中心/ 文件夹
String watermarkedPdfDir = arr + code + "/zip";
classifyPdfByWorkCenterToTarget(watermarkedPdfDir, code, arr + code + "/zip");
// 9. 生成ZIP包
String zipDir = arr + code + "/zip";
String zipPath = arr + code + "/" + code + ".zip"; // 生成到外层目录
boolean zipSuccess = FileToZip.fileToZip(zipDir, arr + code, code); // 目标目录为外层
// 8.1 删除 zip/ 根目录中未分类的 PDF 文件只保留分类目录
File[] zipPdfFiles = new File(watermarkedPdfDir).listFiles((dir, name) -> name.toLowerCase().endsWith(".pdf"));
if (zipPdfFiles != null) {
for (File pdf : zipPdfFiles) {
if (pdf.isFile()) {
boolean deleted = pdf.delete();
if (deleted) {
log.info("已删除未分类PDF文件: {}", pdf.getName());
} else {
log.warn("删除未分类PDF失败: {}", pdf.getName());
}
}
}
}
// 9. 将所有分类后的PDF复制一份到 zip/allpdf 目录
File allPdfTarget = new File(arr + code + "/zip/allpdf");
if (!allPdfTarget.exists()) allPdfTarget.mkdirs();
// 遍历所有工作中心目录复制PDF文件到allpdf
File[] workCenterDirs = new File(watermarkedPdfDir).listFiles(File::isDirectory);
if (workCenterDirs != null) {
for (File workCenterDir : workCenterDirs) {
if ("allpdf".equals(workCenterDir.getName())) {
continue; // 跳过allpdf目录本身
}
File[] pdfFiles = workCenterDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".pdf"));
if (pdfFiles != null) {
for (File pdf : pdfFiles) {
try {
FileUtils.copyFileToDirectory(pdf, allPdfTarget);
log.info("已复制PDF至 allpdf 文件夹: {}", pdf.getName());
} catch (IOException e) {
log.warn("复制PDF到 allpdf 失败: {}", pdf.getName(), e);
}
}
}
}
}
// 10. 生成ZIP包
String zipPath = arr + code + "/" + code + ".zip";
boolean zipSuccess = FileToZip.fileToZip(arr + code + "/zip", arr + code, code);
if (!zipSuccess) {
return R.fail("生成ZIP包失败");
}
// 10. 验证ZIP文件是否存在
File zipFile = new File(zipPath);
if (!zipFile.exists()) {
return R.fail("ZIP文件生成失败文件不存在");
@ -638,15 +732,45 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
}
}
/**
* PDF 按工作中心分类复制到目标目录 zip/工作中心/
*/
private void classifyPdfByWorkCenterToTarget(String sourceDirPath, String code, String targetBaseDirPath) {
File sourceDir = new File(sourceDirPath);
if (!sourceDir.exists() || !sourceDir.isDirectory()) return;
File[] pdfFiles = sourceDir.listFiles((dir, name) -> name.endsWith(".pdf"));
if (pdfFiles == null || pdfFiles.length == 0) return;
for (File pdf : pdfFiles) {
String materialCode = extractMaterialCode(pdf.getName());
if (materialCode == null) continue;
String workCenter = iProcessRouteService.getRouteCode(materialCode, code);
if (workCenter == null || workCenter.isEmpty()) workCenter = "无工段";
File workCenterDir = new File(targetBaseDirPath, workCenter);
if (!workCenterDir.exists()) workCenterDir.mkdirs();
File targetFile = new File(workCenterDir, pdf.getName());
try {
FileUtils.copyFile(pdf, targetFile);
log.info("PDF {} 复制到 {}", pdf.getName(), workCenterDir.getAbsolutePath());
} catch (IOException e) {
log.warn("PDF {} 复制失败: {}", pdf.getName(), e.getMessage());
}
}
}
/**
* 构建工作目录路径
*/
private String buildWorkDirectory(String code) {
String arr = "";
if ("-".equals(code.substring(2, 3))) {
arr += "F:/20" + code.substring(3, 5);
arr += "D:/20" + code.substring(3, 5);
} else {
arr += "F:/20" + code.substring(2, 4);
arr += "D:/20" + code.substring(2, 4);
}
arr += "/";
return arr;
@ -657,6 +781,13 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
*/
private boolean createWorkDirectories(String arr, String code) {
try {
// 清理并创建zip目录
DeleteFile.deleteDirectory(arr + code + "/allpdf");
File filesZip1 = new File(arr + code + "/allpdf");
if (!filesZip1.exists() && !filesZip1.mkdirs()) {
log.error("无法创建zip目录: {}", filesZip1.getAbsolutePath());
return false;
}
// 清理并创建zip目录
DeleteFile.deleteDirectory(arr + code + "/zip");
File filesZip = new File(arr + code + "/zip");
@ -693,29 +824,74 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
*/
private boolean processPDFFiles(String arr, String code, List<FigureSave> fiseList) {
try {
// 获取第一个产品的图号作为处理目录
String replaceAll = fiseList.get(0).getFigureNumber().replaceAll("/", "-") + "-PDF";
File f = new File(arr + code + "/" + replaceAll);
//将fileList 中所有的文件复制到一个总的文件夹中
String allPdfDir = arr + code + "/allpdf";
if (!f.exists()) {
log.warn("PDF目录不存在: {}", f.getAbsolutePath());
return true; // 目录不存在不算错误可能没有PDF文件
// 创建allpdf文件夹,如果存在先删除 在创建
File allPdfFolder = new File(allPdfDir);
if (!allPdfFolder.exists()) {
if (!allPdfFolder.mkdirs()) {
log.error("无法创建allpdf文件夹: {}", allPdfDir);
return false;
}
}
File[] fa = f.listFiles();
if (fa == null || fa.length == 0) {
log.warn("PDF目录为空: {}", f.getAbsolutePath());
// 遍历所有产品将PDF文件复制到allpdf文件夹
for (FigureSave figureSave : fiseList) {
//获取文件路径
String filePDF = figureSave.getFigureNumber().replace("/", "-") + "-PDF";
String sourceDir = arr + code + "/" + filePDF;
File sourceFolder = new File(sourceDir);
if (!sourceFolder.exists()) {
log.warn("源PDF目录不存在: {}", sourceDir);
continue;
}
File[] pdfFiles = sourceFolder.listFiles((dir, name) -> name.toLowerCase().endsWith(".pdf"));
if (pdfFiles == null || pdfFiles.length == 0) {
log.warn("源PDF目录为空: {}", sourceDir);
continue;
}
// 复制所有PDF文件到allpdf文件夹
for (File pdfFile : pdfFiles) {
File targetFile = new File(allPdfDir, pdfFile.getName());
// 如果目标文件已存在先删除
if (targetFile.exists()) {
if (!targetFile.delete()) {
log.warn("无法删除已存在的目标文件: {}", targetFile.getAbsolutePath());
continue;
}
}
// 复制文件而不是移动
try {
copyFile(pdfFile, targetFile);
log.info("成功复制PDF文件: {} -> {}", pdfFile.getName(), targetFile.getAbsolutePath());
} catch (IOException e) {
log.error("复制PDF文件失败: {}", pdfFile.getName(), e);
return false;
}
}
}
// 检查allpdf文件夹是否有文件
File[] allPdfFiles = allPdfFolder.listFiles((dir, name) -> name.toLowerCase().endsWith(".pdf"));
if (allPdfFiles == null || allPdfFiles.length == 0) {
log.warn("allpdf文件夹为空没有PDF文件需要处理");
return true;
}
PDFDocHelper pd = new PDFDocHelper();
PdfReader reader = null;
for (File fs : fa) {
for (File fs : allPdfFiles) {
String name = fs.getName();
try {
// 读取PDF尺寸
reader = new PdfReader(arr + code + "/" + replaceAll + "/" + name);
reader = new PdfReader(fs.getAbsolutePath());
Rectangle pageSize = reader.getPageSize(1);
float height = pageSize.getHeight();
float width = pageSize.getWidth();
@ -729,12 +905,14 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
review.put("type", "1");
reviews.add(review);
// 处理PDF文件
PDFDocHelper.imageWatermark(arr + code + "/" + replaceAll + "/" + name, arr + code, name, "D:/java/tuzhizhang.png", reviews, pawX, pawY);
// 处理PDF文件 - 输出到zip目录
String zipDir = arr + code + "/zip";
log.info("处理PDF文件=====>输出到zip目录: {}", name);
PDFDocHelper.imageWatermark(fs.getAbsolutePath(), zipDir, name, "D:/java/tuzhizhang.png", reviews, pawX, pawY);
// 生成三维BOM版本
String threeDName = name.substring(name.indexOf("-") + 1);
PDFDocHelper.imageWatermark(arr + code + "/" + replaceAll + "/" + name, arr + code + "/bomThree/" + threeDName, "D:/java/tuzhizhang.png");
PDFDocHelper.imageWatermark(fs.getAbsolutePath(), arr + code + "/bomThree/" + threeDName, "D:/java/tuzhizhang.png");
log.info("PDF处理成功: {}", name);
@ -754,11 +932,26 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
return true;
} catch (Exception e) {
log.error("处理PDF文件过程中发生异常, e", e);
log.error("处理PDF文件过程中发生异常", e);
return false;
}
}
/**
* 复制文件
*/
private void copyFile(File source, File target) throws IOException {
try (FileInputStream fis = new FileInputStream(source); FileOutputStream fos = new FileOutputStream(target)) {
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
fos.flush();
}
}
private String extractMaterialCode(String fileName) {
int firstDash = fileName.indexOf("-");
int dotPdf = fileName.lastIndexOf(".pdf");
@ -769,137 +962,7 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
return null;
}
private void classifyPdfByWorkCenter(String pdfDir, String code) {
File dir = new File(pdfDir);
if (!dir.exists() || !dir.isDirectory()) return;
File[] pdfFiles = dir.listFiles((d, name) -> name.endsWith(".pdf"));
if (pdfFiles == null) return;
for (File pdf : pdfFiles) {
String materialCode = extractMaterialCode(pdf.getName());
if (materialCode == null) continue;
// 查询第一序工作中心
String workCenter = iProcessRouteService.getRouteCode(materialCode,code); // 你可能需要调整参数
if (workCenter == null || workCenter.isEmpty()) continue;
// 创建工作中心文件夹
File workCenterDir = new File(dir, workCenter);
if (!workCenterDir.exists()) workCenterDir.mkdirs();
// 移动PDF
File target = new File(workCenterDir, pdf.getName());
if (pdf.renameTo(target)) {
log.info("PDF {} 移动到 {}", pdf.getName(), workCenterDir.getAbsolutePath());
} else {
log.warn("PDF {} 移动失败", pdf.getName());
}
}
}
/**
* @param code
* @param originalFilename
* @return
*/
/* @Override
public String uploadContractPDF1(Integer id, String originalFilename, MultipartFile filePath) {
//获取路径
FigureSave figureSave1 = figureSaveMapper.selectById(id);
String code = figureSave1.getProductionCode();
String path = Constants.BASIC_URL;
if (code.contains("XCL") && !code.contains("(")) {
path += Constants.BASIC_URL_BZ + Constants.XCL_URL + code;
} else if (code.contains("ELS")) {
path += Constants.BASIC_URL_BZ + Constants.ELS_URL + code;
} else if (code.contains("EDS")) {
path += Constants.BASIC_URL_BZ + Constants.EDS_URL + code;
} else if (code.contains("WB")) {
path += Constants.BASIC_URL_BZ + Constants.WB_URL + code;
} else if (code.contains("QD")) {
path += Constants.BASIC_URL_BZ + Constants.QD_URL + code;
} else if (code.contains("ZHD")) {
path += Constants.BASIC_URL_BZ + Constants.ZHD_URL + code;
} else if (code.contains("ETK")) {
path += Constants.BASIC_URL_BZ + Constants.ETK_URL + code;
} else if (code.contains("ETT")) {
path += Constants.BASIC_URL_BZ + Constants.ETT_URL + code;
} else if (code.contains("ETP")) {
path += Constants.BASIC_URL_BZ + Constants.ETP_URL + code;
} else if (code.contains("ETH")) {
path += Constants.BASIC_URL_BZ + Constants.ETH_URL + code;
} else {
path += Constants.BASIC_URL_FB ;
}
//创建文件夹
File files = new File(path);
if (!files.exists()) {
files.mkdir();
}
path = path + "/" + originalFilename;
//上传到服务器
InputStream is = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try {
is = filePath.getInputStream();
fos = new FileOutputStream(path);
bos = new BufferedOutputStream(fos);
// 读取输入流并写入文件
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.flush();
} catch (Exception e) {
return "文件上传失败";
} finally {
try {
if (is != null) {
is.close();
}
if (bos != null) {
bos.close();
}
if (fos != null) {
fos.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 4. 上传到FTP
boolean ftpSuccess = false;
File localFile = new File(path);
try (FileInputStream fis = new FileInputStream(localFile)) {
ftpSuccess = FtpUtil.uploadWithAutoMkdir(
"192.168.5.18", "admin", "hbyt2025", 21,
path, originalFilename, fis
);
} catch (Exception e) {
e.printStackTrace();
return "上传到FTP失败";
}
if (!ftpSuccess) {
return "上传到FTP失败";
}
//反写图纸
figureSave1.setDrawPath(path);
int i = figureSaveMapper.updateById(figureSave1);
if (i == 1) {
return "上传成功";
} else {
return "上传失败";
}
}*/
@Override
public String uploadContractPDF(Integer id, String originalFilename, MultipartFile filePath) {
// 1. 获取数据
@ -946,7 +1009,7 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
ftpPath += Constants.BASIC_URL_BZ + Constants.ETH_URL + code;
} else {
localPath += Constants.BASIC_URL_FB + code;
ftpPath = Constants.BASIC_URL_FB+code;
ftpPath = Constants.BASIC_URL_FB + code;
}
// 3. 创建本地目录并保存文件
@ -955,10 +1018,8 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
localDir.mkdirs(); // 多级目录
}
String fullLocalPath = "/" + originalFilename;
try (InputStream is = filePath.getInputStream();
FileOutputStream fos = new FileOutputStream(fullLocalPath);
BufferedOutputStream bos = new BufferedOutputStream(fos)) {
String fullLocalPath = "/" + originalFilename;
try (InputStream is = filePath.getInputStream(); FileOutputStream fos = new FileOutputStream(fullLocalPath); BufferedOutputStream bos = new BufferedOutputStream(fos)) {
byte[] buffer = new byte[1024];
int bytesRead;
@ -974,9 +1035,7 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
// 4. 上传FTP
boolean ftpSuccess;
try (FileInputStream fis = new FileInputStream(fullLocalPath)) {
ftpSuccess = FtpUtil.uploadFile("192.168.5.18",8022,"admin","hbyt2025",
basePath,ftpPath,originalFilename, fis
);
ftpSuccess = FtpUtil.uploadFile("192.168.5.18", 8022, "admin", "hbyt2025", basePath, ftpPath, originalFilename, fis);
} catch (Exception e) {
e.printStackTrace();
return "上传到FTP失败";
@ -987,10 +1046,82 @@ public class ProcessOrderProServiceImpl implements IProcessOrderProService {
}
// 5. 反写FTP路径到数据库
figureSave.setDrawPath("E:"+basePath +ftpPath+ fullLocalPath);
figureSave.setDrawPath("E:" + basePath + ftpPath + fullLocalPath);
int updateCount = figureSaveMapper.updateById(figureSave);
return updateCount == 1 ? "上传成功" : "上传失败";
}
/**
* @return
*/
@Override
public List<OverdueProjectVo> getOverdueProjects() {
List<ProcessOrderPro> processOrderPros = baseMapper.selectList();
List<OverdueProjectVo> projects = new ArrayList<>();
// 获取当前日期
LocalDate currentDate = LocalDate.now();
if (!processOrderPros.isEmpty()) {
for (ProcessOrderPro processOrderPro : processOrderPros) {
OverdueProjectVo projectVo = new OverdueProjectVo();
projectVo.setProjectCode(processOrderPro.getProductionName());
// projectVo.setDesigner(processOrderPro.getProgramDesigner());
projectVo.setStartDate(processOrderPro.getPlanStartTime().toString());
projectVo.setPlanDate(processOrderPro.getPlanEndTime().toString());
LocalDate planStartDate = convertToLocalDate(processOrderPro.getPlanStartTime());
LocalDate planEndDate = convertToLocalDate(processOrderPro.getPlanEndTime());
// 判断是否超期
if (planEndDate.isAfter(planStartDate)) {
// 计算超期天数
long overdueDays = ChronoUnit.DAYS.between(planEndDate, currentDate);
// 如果超期天数为负数即计划时间在当前时间之后设置为0
projectVo.setOverdueDays(overdueDays);
}
projects.add(projectVo);
}
}
return projects;
}
// 辅助方法 java.util.Date 转换为 LocalDate
private LocalDate convertToLocalDate(Date date) {
if (date != null) {
return date.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate();
}
return null;
}
/**
* 递归删除目录及其内容
* @param directory 要删除的目录
* @throws IOException 删除失败时抛出异常
*/
private void deleteDirectory(File directory) throws IOException {
if (directory.exists()) {
File[] files = directory.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
deleteDirectory(file);
} else {
if (!file.delete()) {
throw new IOException("无法删除文件: " + file.getAbsolutePath());
}
}
}
}
if (!directory.delete()) {
throw new IOException("无法删除目录: " + directory.getAbsolutePath());
}
}
}
}

View File

@ -0,0 +1,234 @@
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 com.ruoyi.system.domain.ProcessOrderPro;
import com.ruoyi.system.domain.vo.ExpiryProjectVo;
import com.ruoyi.system.domain.vo.OverdueProjectVo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.system.domain.bo.ProcessPlanBo;
import com.ruoyi.system.domain.vo.ProcessPlanVo;
import com.ruoyi.system.domain.ProcessPlan;
import com.ruoyi.system.mapper.ProcessPlanMapper;
import com.ruoyi.system.service.IProcessPlanService;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
/**
* 方案管理Service业务层处理
*
* @author 田志阳
* @date 2025-08-20
*/
@RequiredArgsConstructor
@Service
public class ProcessPlanServiceImpl implements IProcessPlanService {
private final ProcessPlanMapper baseMapper;
/**
* 查询方案管理
*/
@Override
public ProcessPlanVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 查询方案管理列表
*/
@Override
public TableDataInfo<ProcessPlanVo> queryPageList(ProcessPlanBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<ProcessPlan> lqw = buildQueryWrapper(bo);
Page<ProcessPlanVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}/**
* 查询方案管理列表
*/@Override
public TableDataInfo<ProcessPlanVo> queryPageList2(ProcessPlanBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<ProcessPlan> lqw = buildQueryWrapper2(bo);
Page<ProcessPlanVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询方案管理列表
*/
@Override
public List<ProcessPlanVo> queryList(ProcessPlanBo bo) {
LambdaQueryWrapper<ProcessPlan> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
public List<ProcessPlanVo> queryList2(ProcessPlanBo bo) {
LambdaQueryWrapper<ProcessPlan> lqw = buildQueryWrapper2(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<ProcessPlan> buildQueryWrapper(ProcessPlanBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<ProcessPlan> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getProjectCode()), ProcessPlan::getProjectCode, bo.getProjectCode());
lqw.eq(StringUtils.isNotBlank(bo.getDesigner()), ProcessPlan::getDesigner, bo.getDesigner());
lqw.eq(StringUtils.isNotBlank(bo.getOverdueDays()), ProcessPlan::getOverdueDays, bo.getOverdueDays());
lqw.eq(bo.getStartDate() != null, ProcessPlan::getStartDate, bo.getStartDate());
lqw.eq(bo.getEndDate() != null, ProcessPlan::getEndDate, bo.getEndDate());
lqw.eq(bo.getProcessStatus() != null, ProcessPlan::getProcessStatus, bo.getProcessStatus());
return lqw;
} private LambdaQueryWrapper<ProcessPlan> buildQueryWrapper2(ProcessPlanBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<ProcessPlan> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getProjectCode()), ProcessPlan::getProjectCode, bo.getProjectCode());
lqw.eq(StringUtils.isNotBlank(bo.getDesigner()), ProcessPlan::getDesigner, bo.getDesigner());
lqw.eq(StringUtils.isNotBlank(bo.getOverdueDays()), ProcessPlan::getOverdueDays, bo.getOverdueDays());
lqw.eq(bo.getStartDate() != null, ProcessPlan::getStartDate, bo.getStartDate());
lqw.eq( ProcessPlan::getProcessStatus, 0);
lqw.eq(bo.getEndDate() != null, ProcessPlan::getEndDate, bo.getEndDate());
lqw.eq(bo.getProcessStatus() != null, ProcessPlan::getProcessStatus, bo.getProcessStatus());
return lqw;
}
/**
* 新增方案管理
*/
@Override
public Boolean insertByBo(ProcessPlanBo bo) {
ProcessPlan add = BeanUtil.toBean(bo, ProcessPlan.class);
validEntityBeforeSave(add);
add.setProcessStatus(0L);
// 3. 插入数据库
boolean flag = baseMapper.insert(add) > 0;
// 4. 回填ID
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改方案管理
*/
@Override
public Boolean updateByBo(ProcessPlanBo bo) {
ProcessPlan update = BeanUtil.toBean(bo, ProcessPlan.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(ProcessPlan entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除方案管理
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
/**
* @return
*/
@Override
public List<OverdueProjectVo> getOverdueProjects() {
LambdaQueryWrapper<ProcessPlan> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ProcessPlan::getProcessStatus,0);
List<ProcessPlan> processOrderPros = baseMapper.selectList(wrapper);
List<OverdueProjectVo> projects = new ArrayList<>();
// 获取当前日期
LocalDate currentDate = LocalDate.now();
SimpleDateFormat formatt = new SimpleDateFormat("yyyy-MM-dd");
if (!processOrderPros.isEmpty()) {
for (ProcessPlan processPlan : processOrderPros) {
OverdueProjectVo projectVo = new OverdueProjectVo();
projectVo.setProjectCode(processPlan.getProjectCode());
projectVo.setDesigner(processPlan.getDesigner());
projectVo.setStartDate(formatt.format(processPlan.getStartDate()));
projectVo.setPlanDate(formatt.format(processPlan.getEndDate()));
projectVo.setDescription(processPlan.getRemark());
LocalDate planStartDate = convertToLocalDate(processPlan.getStartDate());
LocalDate planEndDate = convertToLocalDate(processPlan.getEndDate());
// 判断是否超期
if (planEndDate.isAfter(planStartDate)) {
// 计算超期天数
long overdueDays = ChronoUnit.DAYS.between(planEndDate, currentDate);
// 如果超期天数为负数即计划时间在当前时间之后设置为0
if (overdueDays <= 0) {
continue;
}
projectVo.setOverdueDays(overdueDays);
}
projects.add(projectVo);
}
}
return projects;
}
/**
* @return
*/
@Override
public List<ExpiryProjectVo> getExpiryProjects() {
LambdaQueryWrapper<ProcessPlan> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ProcessPlan::getProcessStatus,0);
List<ProcessPlan> processOrderPros = baseMapper.selectList();
List<ExpiryProjectVo> projects = new ArrayList<>();
// 获取当前日期
LocalDate currentDate = LocalDate.now();
SimpleDateFormat formatt = new SimpleDateFormat("yyyy-MM-dd");
if (!processOrderPros.isEmpty()) {
for (ProcessPlan processPlan : processOrderPros) {
ExpiryProjectVo projectVo = new ExpiryProjectVo();
projectVo.setProjectCode(processPlan.getProjectCode());
projectVo.setDesigner(processPlan.getDesigner());
projectVo.setStartDate(formatt.format(processPlan.getStartDate()));
projectVo.setPlanDate(formatt.format(processPlan.getEndDate()));
projectVo.setDescription(processPlan.getRemark());
LocalDate planStartDate = convertToLocalDate(processPlan.getStartDate());
LocalDate planEndDate = convertToLocalDate(processPlan.getEndDate());
// 判断是否超期
if (planEndDate.isAfter(planStartDate)) {
// 计算超期天数
long overdueDays = ChronoUnit.DAYS.between(planEndDate, currentDate);
// 如果超期天数为负数即计划时间在当前时间之后设置为0
if (overdueDays > 0) {
continue;
}
projectVo.setOverdueDays(Math.abs(overdueDays));
}
projects.add(projectVo);
}
}
return projects;
}
// 辅助方法 java.util.Date 转换为 LocalDate
private LocalDate convertToLocalDate(Date date) {
if (date != null) {
return date.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate();
}
return null;
}
}

View File

@ -74,7 +74,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
private final MaterialBomMapper materialBomMapper;
private final ProcessInfoMapper processInfoMapper;
private final ProductionRouteTwoMapper productionRouteTwoMapper;
private final ProcessOrderProMapper iProcessOrderProService;
private final ProcessOrderProMapper processOrderProMapper;
private static final Logger log = LoggerFactory.getLogger(ProcessRouteController.class);
private static final Logger logger = LoggerFactory.getLogger(IProcessRouteService.class);
@ -272,6 +272,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
*/
@Override
public String getRouteCode(String materialCode, String code) {
LambdaQueryWrapper<ProcessRoute> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ProcessRoute::getMaterialCode, materialCode)
.eq(ProcessRoute::getRouteDescription, code)
@ -283,6 +284,17 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
return processRoute.getWorkCenter();
}
/**
* @param productionOrderNo
* @return
*/
@Override
public List<ProcessRoute> selectByProjectNumber(String productionOrderNo) {
LambdaQueryWrapper<ProcessRoute> war = new LambdaQueryWrapper<>();
war.eq(ProcessRoute::getRouteDescription,productionOrderNo);
return baseMapper.selectList(war);
}
private String generateKey1(BomDetails bomDetail, ProcessRoute processRoute) {
return String.format("%s:%s:%s", processRoute.getMaterialCode(), processRoute.getMaterialName(), bomDetail.getName(), bomDetail.getPartNumber());
@ -552,19 +564,13 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
public boolean saveData(List<ProcessRouteVo> routeVoList, List<ProductionOrderVo> productionOrderVos) {
List<ProcessRoute> processRoutes = BeanUtil.copyToList(routeVoList, ProcessRoute.class);
processMaterialBom(processRoutes);
List<BomDetailsVo> bomDetailsVos = processBomDetails(routeVoList, productionOrderVos);
saveBomDetails(bomDetailsVos);
List<ProcessRoute> routeArrayList = new ArrayList<>();
Map<String, Double> inventoryCache = new HashMap<>();
// 批量查询所有需要的库存信息
for (ProcessRoute processRoute : processRoutes) {
/* for (ProcessRoute processRoute : processRoutes) {
String materialCode = processRoute.getMaterialCode();
if (!inventoryCache.containsKey(materialCode)) {
try {
@ -575,10 +581,9 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
inventoryCache.put(materialCode, 0.0);
}
}
}
}*/
boolean allEmpty = processRoutes.stream()
.allMatch(route -> route.getProcessNo() == null && route.getProcessName() == null);
boolean allEmpty = processRoutes.stream().allMatch(route -> route.getProcessNo() == null && route.getProcessName() == null);
//获取工艺中所有的时间 挑选出最早的时间和最晚的时间
// 获取最早的开始时间
Date earliestStartTime = processRoutes.stream()
@ -594,12 +599,12 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
.orElse(null);
//更新至计划模块中
if (earliestStartTime != null && latestEndTime != null) {
ProcessOrderPro processOrderPro = iProcessOrderProService.selectByProjectNumber(processRoutes.get(0).getRouteDescription());
ProcessOrderPro processOrderPro = processOrderProMapper.selectByProjectNumber(processRoutes.get(0).getRouteDescription());
processOrderPro.setPlanStartTime(earliestStartTime);
processOrderPro.setPlanEndTime(latestEndTime);
processOrderPro.setUpdateTime(new Date());
log.info("更新计划生成令号为:{},计划开始时间:{},计划结束时间:{}",processRoutes.get(0).getRouteDescription(), earliestStartTime, latestEndTime);
iProcessOrderProService.updateByBo(processOrderPro);
processOrderProMapper.updateById(processOrderPro);
}
if (allEmpty && !processRoutes.isEmpty()) {
@ -695,14 +700,15 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
processRoute.setActivityUnit("");
processRoute.setCreateTime(new Date());
processRoute.setUpdateTime(new Date());
Double kucun = inventoryCache.get(processRoute.getMaterialCode());
processRoute.setFirstBatchQuantity(kucun);
processRoute.setFirstBatchQuantity(processRoute.getFirstBatchQuantity());
processRoute.setUnitQuantity(processRoute.getUnitQuantity());
routeArrayList.add(processRoute);
}
}
}
try {
return baseMapper.insertBatch(routeArrayList);
} catch (Exception e) {
log.error("批量插入工艺路线失败", e);
@ -738,7 +744,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
if ("mm".equals(unit)) {
// 将毫米转换为米并保留4位小数
materialBom.setQuantity(String.valueOf(new BigDecimal(quantity).divide(BigDecimal.valueOf(1000), 4, RoundingMode.HALF_UP)));
} else if("".equals(unit)){
} else if("".equals(unit) && quantity.contains("/")){
//写入工艺表时分数的体现 直接取分母 "/"为分割符,取第二个字符串
materialBom.setQuantity(quantity);
}else {
@ -1069,21 +1075,26 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
}
// 保存到 BomDetails 表中
//TODO: 使用本地库加速
private void saveBomDetails(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) {
int materialVerification = isMaterialVerification(bomDetails.getPartNumber(), bomDetails.getName());
if (materialVerification ==1) {
bomDetails.setUnitWeight("");
} else {
} else if(materialVerification ==2){
bomDetails.setUnitWeight("");
materialsToAdd.add(bomDetails);
}else if(materialVerification ==3){
bomDetails.setUnitWeight("编码名称不符");
}
// 保存 BomDetails 记录
iBomDetailsService.insertByVo(BeanUtil.toBean(bomDetails, BomDetailsVo.class));
Boolean b = iBomDetailsService.insertByVo(BeanUtil.toBean(bomDetails, BomDetailsVo.class));
}
@ -1214,15 +1225,13 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
for (ProcessRouteXuDTO processRouteXuDTO : rawBomList) {
// 获取金蝶中的此物料工艺路线,在金蝶查询可能有多条工艺路线
List<ProcessRouteSelectDTO> jdProcessRoute = getSelectProcessRoute(processRouteXuDTO.getMaterialCode());
Map<String, List<ProcessRouteSelectDTO>> groupedByFNumber = jdProcessRoute.stream()
.collect(Collectors.groupingBy(ProcessRouteSelectDTO::getFNumber));
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);
// 处理返回结果
@ -1244,6 +1253,10 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
resultDTO.setSuccessfulRoutes(successfulRoutes);
resultDTO.setFailedRoutes(failedRoutes);
resultDTO.setDuplicateRoutes(duplicateRoutes);
ProcessOrderPro processOrderPro = processOrderProMapper.selectByProjectNumber(rooteProdet);
//更新项目状态 推送工艺
processOrderPro.setBomStatus(3L);
processOrderProMapper.updateById(processOrderPro);
return resultDTO;
}
@ -1414,8 +1427,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
// 请求参数要求为json字符串
JsonObject json = new JsonObject();
json.addProperty("FormId", "PRD_MO");
json.addProperty("FieldKeys",
"F_HBYT_SCLH,FBillNo ,FMaterialId.FNumber,FMaterialName, F_UCHN_BaseProperty_qtr");
json.addProperty("FieldKeys", "F_HBYT_SCLH,FBillNo ,FMaterialId.FNumber,FMaterialName, F_UCHN_BaseProperty_qtr");
JsonArray filterString = new JsonArray();
JsonObject filterObject = new JsonObject();
filterObject.addProperty("FieldName", "F_HBYT_SCLH");
@ -1578,11 +1590,9 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
if (repoRet.getResult().getResponseStatus().isIsSuccess()) {
String result = gson.toJson(repoRet.getResult());
return new LoadBomResult(true, "工艺路线保存接口调用成功", result);
} else {
String errorMsg = gson.toJson(repoRet.getResult().getResponseStatus());
return new LoadBomResult(false, "工艺路线保存接口调用失败: " + errorMsg, null);
}
} catch (Exception e) {
return new LoadBomResult(false, "工艺路线保存异常信息: " + e.getMessage(), null);
@ -2210,7 +2220,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
* @return
*/
@Override
public R<Void> selectByProjectCode(String productionOrderNo) {
public R<Void> delByProjectCode(String productionOrderNo) {
boolean allDeleted = true;
// 查询并删除工艺路线
@ -2232,7 +2242,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
boolean result = materialBomMapper.deleteBatchIds(
selectMaterList.stream().map(MaterialBom::getId).collect(Collectors.toList())) > 0;
if (!result) {
log.error("材料发生意外: {}", productionOrderNo);
log.error("材料BOM发生意外: {}", productionOrderNo);
allDeleted = false;
}
}
@ -2248,6 +2258,17 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
allDeleted = false;
}
}
// 查询总装BOM详情
List<ProductionOrder> productionOrderList = productionOrderMapper.selectList(
new QueryWrapper<ProductionOrder>().eq("production_order_no", productionOrderNo));
if (!productionOrderList.isEmpty()) {
boolean result = productionOrderMapper.deleteBatchIds(
productionOrderList.stream().map(ProductionOrder::getId).collect(Collectors.toList())) > 0;
if (!result) {
log.error("删总装BOM数据发生意外: {}", productionOrderNo);
allDeleted = false;
}
}
// 返回结果
if (allDeleted) {
@ -2358,7 +2379,7 @@ public class ProcessRouteServiceImpl implements IProcessRouteService {
// 获取父级的物料的公式
public Double getFaWorkTime(BomDetails material) {
if (material == null) {
log.error("传入的物料对象为 null");
log.error("获取项目工时,传入的物料对象为 null");
return 0.0; // 或者抛出异常
}

View File

@ -309,5 +309,16 @@ public class ProductionOrderServiceImpl implements IProductionOrderService {
return null;
}
/**
* @param productionOrderNo
* @return
*/
@Override
public List<ProductionOrder> selectByProCode(String productionOrderNo) {
LambdaQueryWrapper<ProductionOrder> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ProductionOrder::getProductionOrderNo,productionOrderNo);
return baseMapper.selectList(wrapper);
}
}

View File

@ -7,6 +7,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<resultMap type="com.ruoyi.system.domain.ImMaterial" id="ImMaterialResult">
<result property="id" column="id"/>
<result property="materialCode" column="material_code"/>
<result property="materialId" column="material_id"/>
<result property="materialName" column="material_name"/>
<result property="materialQuality" column="material_quality"/>
<result property="singleWeight" column="single_weight"/>
@ -15,6 +16,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="flag" column="flag"/>
<result property="classificationName" column="classification_name"/>
<result property="classificationNumber" column="classification_number"/>
<result property="modifyDate" column="modify_date"/>
<result property="imCategory" column="im_category"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
@ -58,6 +60,46 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</foreach>
</select>
<!-- 根据 materid 更新物料 -->
<update id="updateByMaterid" parameterType="com.ruoyi.system.domain.ImMaterial">
UPDATE im_material
<set>
<if test="materialCode != null">material_code = #{materialCode},</if>
<if test="materialName != null">material_name = #{materialName},</if>
<if test="materialQuality != null">material_quality = #{materialQuality},</if>
<if test="singleWeight != null">single_weight = #{singleWeight},</if>
<if test="unitPrice != null">unit_price = #{unitPrice},</if>
<if test="unit != null">unit = #{unit},</if>
<if test="classificationName != null">classification_name = #{classificationName},</if>
<if test="classificationNumber != null">classification_number = #{classificationNumber},</if>
<if test="modifyDate != null">modify_date = #{modifyDate},</if>
<if test="forbidStatus != null">forbid_status = #{forbidStatus},</if>
</set>
WHERE material_id = #{materialId}
</update>
<update id="updateBatchByMaterid" parameterType="java.util.List">
<foreach collection="list" item="item" separator=";">
UPDATE im_material
<set>
<if test="item.materialCode != null">material_code = #{item.materialCode},</if>
<if test="item.materialName != null">material_name = #{item.materialName},</if>
<if test="item.materialQuality != null">material_quality = #{item.materialQuality},</if>
<if test="item.singleWeight != null">single_weight = #{item.singleWeight},</if>
<if test="item.unitPrice != null">unit_price = #{item.unitPrice},</if>
<if test="item.unit != null">unit = #{item.unit},</if>
<if test="item.classificationName != null">classification_name = #{item.classificationName},</if>
<if test="item.classificationNumber != null">classification_number = #{item.classificationNumber},</if>
<if test="item.modifyDate != null">modify_date = #{item.modifyDate},</if>
</set>
WHERE material_id = #{item.materialId}
</foreach>
</update>
<!-- 根据 materialId 查询物料 -->
<select id="selectByMid" resultType="com.ruoyi.system.domain.ImMaterial" parameterType="String">
SELECT *
FROM im_material
WHERE material_id = #{materialId}
</select>
</mapper>

View File

@ -0,0 +1,24 @@
<?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.KingdeeAssetCardMapper">
<resultMap type="com.ruoyi.system.domain.KingdeeAssetCard" id="KingdeeAssetCardResult">
<result property="id" column="id"/>
<result property="assetCategory" column="asset_category"/>
<result property="cardCode" column="card_code"/>
<result property="assetUnit" column="asset_unit"/>
<result property="assetCode" column="asset_code"/>
<result property="assetLocation" column="asset_location"/>
<result property="assetQuantity" column="asset_quantity"/>
<result property="assetName" column="asset_name"/>
<result property="assetManufacturer" column="asset_manufacturer"/>
<result property="createBy" column="create_by"/>
<result property="updateBy" column="update_by"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
</resultMap>
</mapper>

View File

@ -0,0 +1,25 @@
<?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.MrpResultCheckMapper">
<resultMap type="com.ruoyi.system.domain.MrpResultCheck" id="MrpResultCheckResult">
<result property="id" column="id"/>
<result property="materialName" column="material_name"/>
<result property="materialCode" column="material_code"/>
<result property="availableStock" column="available_stock"/>
<result property="realTimeStock" column="real_time_stock"/>
<result property="prodNotInStock" column="prod_not_in_stock"/>
<result property="purchaseRequestQty" column="purchase_request_qty"/>
<result property="purchaseNotInStock" column="purchase_not_in_stock"/>
<result property="childNotPickedQty" column="child_not_picked_qty"/>
<result property="createTime" column="create_time"/>
<result property="createBy" column="create_by"/>
<result property="updateTime" column="update_time"/>
<result property="updateBy" column="update_by"/>
<result property="orderProId" column="order_pro_id"/>
</resultMap>
</mapper>

View File

@ -22,6 +22,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="quantity" column="quantity"/>
<result property="isEnterpriseStandard" column="is_enterprise_standard"/>
<result property="drawingPath" column="drawing_path"/>
<result property="bomStatus" column="bom_status"/>
<result property="routeStatus" column="route_status"/>
</resultMap>
<!-- 根据项目编号查询 -->
<select id="selectByProjectNumber" resultType="com.ruoyi.system.domain.ProcessOrderPro">

View File

@ -0,0 +1,24 @@
<?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.ProcessPlanMapper">
<resultMap type="com.ruoyi.system.domain.ProcessPlan" id="ProcessPlanResult">
<result property="id" column="id"/>
<result property="projectCode" column="project_code"/>
<result property="proType" column="pro_type"/>
<result property="designer" column="designer"/>
<result property="overdueDays" column="overdue_days"/>
<result property="remark" column="remark"/>
<result property="startDate" column="start_date"/>
<result property="endDate" column="end_date"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="createBy" column="create_by"/>
<result property="updateBy" column="update_by"/>
<result property="processStatus" column="process_status"/>
</resultMap>
</mapper>

View File

@ -20,6 +20,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateBy" column="update_by"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="batchQuantity" column="batch_quantity"/>
</resultMap>