diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml
index a788a81..0238aea 100644
--- a/ruoyi-common/pom.xml
+++ b/ruoyi-common/pom.xml
@@ -167,6 +167,12 @@
org.bouncycastle
bcprov-jdk15to18
+
+ com.hierynomus
+ smbj
+ 0.14.0
+
+
com.itextpdf
diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/config/SecurityConfig.java b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/config/SecurityConfig.java
index e3bfa40..a27373e 100644
--- a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/config/SecurityConfig.java
+++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/config/SecurityConfig.java
@@ -34,6 +34,8 @@ public class SecurityConfig {
.antMatchers("/system/proPlan/**").anonymous()
.antMatchers("/system/mrp/**").anonymous()
.antMatchers("/system/orderPro/**").anonymous()
+ .antMatchers("/system/cost/**").anonymous()
+ .antMatchers("/dev-api/system/cost/**").anonymous()
// .antMatchers("/dev-api/system/proPlan/overdue").anonymous()
// .antMatchers("/dev-api/system/proPlan/expiryProjects").anonymous()
.antMatchers("/dev-api/system/material/list/").anonymous()
diff --git a/ruoyi-system/pom.xml b/ruoyi-system/pom.xml
index b5d9c14..fc2d270 100644
--- a/ruoyi-system/pom.xml
+++ b/ruoyi-system/pom.xml
@@ -6,7 +6,7 @@
ruoyi-vue-plus
com.ruoyi
4.7.0
-
+ org.apache.maven.pluginsmaven-compiler-plugin88
4.0.0
ruoyi-system
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/BomDetailsController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/BomDetailsController.java
index 57d44de..4b97a28 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/BomDetailsController.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/BomDetailsController.java
@@ -21,21 +21,20 @@ import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.enums.BusinessType;
-import com.ruoyi.common.result.BOMUploadResult;
+import com.ruoyi.system.domain.dto.BOMItem;
+import com.ruoyi.system.domain.dto.BOMUploadResult;
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.ProcessOrderPro;
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.dto.KindegeeLogDTO;
import com.ruoyi.system.domain.vo.BomDetailsVo;
import com.ruoyi.system.domain.vo.ElectricalMaterialBomVO;
-import com.ruoyi.system.mapper.FigureSaveMapper;
+import com.ruoyi.system.mapper.BomDetailsMapper;
import com.ruoyi.system.mapper.ProcessOrderProMapper;
import com.ruoyi.system.runner.JdUtil;
import com.ruoyi.system.service.*;
@@ -45,8 +44,6 @@ import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.WorkbookFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@@ -84,8 +81,10 @@ public class BomDetailsController extends BaseController {
private final IProcessOrderProService iProcessOrderProService;
- private final IFigureSaveService iFigureSaveService;
private final ProcessOrderProMapper processOrderProMapper;
+
+ private final BomDetailsMapper bomDetailsMapper;
+
/**
* 查询bom明细列表
*/
@@ -382,27 +381,38 @@ public class BomDetailsController extends BaseController {
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());
- try {
- int result = loadMaterialPreservation(material, state, fbWorkTime);
- if (result == 1) {
- log.info("新增物料成功 ==> 物料图号: {}, 物料名称: {}", material.getPartNumber(), material.getName());
- material.setUnitWeight("新增成功");
- } else {
- log.error("新增物料失败 ==> 物料图号: {}, 物料名称: {}", material.getPartNumber(), material.getName());
+ //判断bom类型是生产还是电气
+ if (material.getBomType().equals("0")) {
+ try {
+ int result = loadMaterialPreservation(material, state, fbWorkTime);
+ if (result == 1) {
+ material.setUnitWeight("新增成功");
+ } else {
+ failedMaterials.add(material.getPartNumber());
+ }
+ // 更新物料状态
+ iBomDetailsService.updateByBo(BeanUtil.toBean(material, BomDetailsBo.class));
+ } catch (Exception e) {
+ failedMaterials.add(material.getPartNumber());
+ }
+ } else {
+ try {
+ int result = loadMaterialToDQ(material, state);
+ if (result == 1) {
+ material.setUnitWeight("新增成功");
+ } else {
+ failedMaterials.add(material.getPartNumber());
+ }
+ // 更新物料状态
+ iBomDetailsService.updateByBo(BeanUtil.toBean(material, BomDetailsBo.class));
+ } catch (Exception e) {
failedMaterials.add(material.getPartNumber());
}
- // 更新物料状态
- iBomDetailsService.updateByBo(BeanUtil.toBean(material, BomDetailsBo.class));
- } catch (Exception e) {
- log.error("处理物料时发生异常: {}", e.getMessage());
- failedMaterials.add(material.getPartNumber());
}
+
} else {
- log.error("物料信息不完整,无法新增物料");
failedMaterials.add(material.getPartNumber());
}
}
@@ -411,22 +421,20 @@ public class BomDetailsController extends BaseController {
boolean needUpload = !validateBOM(fnumber, bomDetails);
if (needUpload) {
try {
- // 物料清单保存方法
+ // 物料清单保存方法,判断是电气还是生产
BOMUploadResult bomUploadResult = FBloadBillOfMaterialsPreservation(bomDetails, bo);
if (bomUploadResult.isSuccess()) {
KindegeeLogDTO logDTO = new KindegeeLogDTO();
logDTO.setProjectCode(bo.getProductionOrderNo());
logDTO.setMaterialCode(fnumber); // 使用物料编码而不是单个物料的编码
- logDTO.setMaterialName(fname);
- logDTO.setCode(bomUploadResult.getNumber());
- logDTO.setReason(bomUploadResult.getNumber()+"OK");
+ logDTO.setCode("200");
+ logDTO.setReason("成功上传"+"版本号:"+bomUploadResult.getNumber());
logDTOS.add(logDTO);
} else {
KindegeeLogDTO logDTO = new KindegeeLogDTO();
logDTO.setProjectCode(bo.getProductionOrderNo());
logDTO.setMaterialCode(fnumber);
- logDTO.setMaterialName(fname);
- logDTO.setCode(bomUploadResult.getNumber());
+ logDTO.setCode("300");
logDTO.setReason(bomUploadResult.getErrorMessage());
logDTOS.add(logDTO);
}
@@ -439,8 +447,7 @@ public class BomDetailsController extends BaseController {
KindegeeLogDTO logDTO = new KindegeeLogDTO();
logDTO.setProjectCode(bo.getProductionOrderNo());
logDTO.setMaterialCode(fnumber);
- logDTO.setMaterialName(fname);
- logDTO.setCode("200");
+ logDTO.setCode("100");
logDTO.setReason("BOM已存在且一致");
logDTOS.add(logDTO);
log.info("BOM已存在且一致,物料编码: {},跳过保存", fnumber);
@@ -450,13 +457,14 @@ public class BomDetailsController extends BaseController {
//更新项目进度
ProcessOrderPro processOrderProBo = iProcessOrderProService.selectByProjectNumber(totalWeight);
- processOrderProBo.setDrawingType( JSONUtil.toJsonStr(logDTOS));
+ processOrderProBo.setDrawingType(JSONUtil.toJsonStr(logDTOS));
processOrderProBo.setBomStatus(2L);
processOrderProMapper.updateById(processOrderProBo);
// 返回处理结果
return R.ok("成功", bomDetailsList);
}
+
private boolean validateBOM(String fnumber, List bomDetails) {
List JDBomList = JdUtil.getSelectBomList(fnumber);
@@ -701,7 +709,7 @@ public class BomDetailsController extends BaseController {
}
// FBOM物料清单保存
- public BOMUploadResult FBloadBillOfMaterialsPreservation(List bomlist, ProcessOrderPro bo) {
+ public BOMUploadResult FBloadBillOfMaterialsPreservation(List bomlist, ProcessOrderPro bo) {
BomDetails bomDetails1 = bomlist.get(0);
int verification = isMaterialVerification(bomDetails1.getFNumber(), bomDetails1.getFName());
@@ -805,9 +813,7 @@ public class BomDetailsController extends BaseController {
fTreeEntityItem.addProperty("F_HBYT_BJBM", details.getPartdiagramCode());
fTreeEntityItem.addProperty("F_HBYT_BJMC", details.getPartdiagramName());
fTreeEntityItem.addProperty("FDOSAGETYPE", "2");
- //判断这个在原材料表中单位如果是根,的话 那分子就是1 分母就是分子
-
- fTreeEntityItem.addProperty("FNUMERATOR", details.getQuantity());
+ fTreeEntityItem.addProperty("FNUMERATOR", details.getQuantity()); // 分子
fTreeEntityItem.addProperty("FDENOMINATOR", details.getDenominator());
// 添加货主信息 查看这个bom中是否符合货主信息
@@ -1724,7 +1730,10 @@ public class BomDetailsController extends BaseController {
return 1;
}
- // 创建电气物料
+ /**
+ * / 创建电气物料
+ */
+
public int loadMaterialToDQ(BomDetails bomDetails1, String states) {
K3CloudApi client = new K3CloudApi();
// 创建一个空的JsonObject
@@ -1738,7 +1747,8 @@ public class BomDetailsController extends BaseController {
// 添加Model字段
model.addProperty("FMATERIALID", 0);
- model.addProperty("FSpecification", bomDetails1.getRemarks());// 备注仓库
+ model.addProperty("FSpecification", bomDetails1.getMaterial());// 规格 为存入的材质字段
+ model.addProperty("F_HBYT_PP", bomDetails1.getWareHouse());// 品牌 为存入的仓库字段
model.addProperty("FNumber", bomDetails1.getPartNumber());
model.addProperty("FName", bomDetails1.getName());
MaterialProperties materialProperties = iMaterialPropertiesService.selectByAttribute(bomDetails1.getMaterial());
@@ -2108,10 +2118,9 @@ public class BomDetailsController extends BaseController {
subHeadEntity1.add("FPickStockId", fPickStockId);
subHeadEntity5.addProperty("FOverControlMode", "1");
- subHeadEntity5.addProperty("FStandHourUnitId", "3600");
+ subHeadEntity5.addProperty("FStandHourUnitId", "60");
subHeadEntity5.addProperty("FBackFlushType", "1");
String jsonData = json.toString();
- System.out.println(jsonData);
try {
// 业务对象标识
String formId = "BD_MATERIAL";
@@ -2135,6 +2144,7 @@ public class BomDetailsController extends BaseController {
}
return 1;
}
+
public BOMUploadResult parseK3Response(String jsonResponse) {
try {
ObjectMapper mapper = new ObjectMapper();
@@ -2166,20 +2176,61 @@ public class BomDetailsController extends BaseController {
* @param file 导入文件
*/
- @Log(title = "明细导入", businessType = BusinessType.IMPORT)
- @SaCheckPermission("system:details:import")
- @PostMapping(value = "/importData21", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
- public R importData21(@RequestPart("file") MultipartFile file) throws Exception {
+ @Log(title = "导入电气bom", businessType = BusinessType.IMPORT)
+ @SaCheckPermission("system:details:importElectricalBom")
+ @PostMapping(value = "/importElectricalBom", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+ public void importElectricalBom(@RequestPart("file") MultipartFile file) throws Exception {
List electricalMaterialBomVOS = ExcelUtil.importExcel(file.getInputStream(), ElectricalMaterialBomVO.class);
+ List list = new ArrayList<>();
for (ElectricalMaterialBomVO bomVO : electricalMaterialBomVOS) {
BomDetails bomDetails = new BomDetails();
bomDetails.setTotalWeight(bomVO.getProductionOrderNo());
- bomDetails.setFNumber(bomVO.getDrawingNo());
- bomDetails.setFName(bomVO.getDrawingName());
- bomDetails.setPartdiagramCode(bomVO.getParentDrawingNo());
- bomDetails.setPartdiagramName(bomVO.getParentPart());
+ bomDetails.setFNumber(bomVO.getParentDrawingNo());
+ bomDetails.setFName(bomVO.getParentPart());
+ bomDetails.setPartNumber(bomVO.getDrawingNo());
+ bomDetails.setName(bomVO.getDrawingName());
+ bomDetails.setMaterial(bomVO.getModel());//
+ bomDetails.setWareHouse(bomVO.getBrand());
+ bomDetails.setStats("外购");
+ String quantity = bomVO.getQuantity().toString();
+ bomDetails.setQuantity(quantity);
+ bomDetails.setRemarks(bomVO.getUnit());
+ bomDetails.setUpdateTime(new Date());
+ bomDetails.setBomType("1");//0 是生产bom 1 是电气bom
+ list.add(bomDetails);
}
- return null;
+ List bomDetailsVos1 = BeanUtil.copyToList(list, BomDetailsVo.class);
+ List bomDetails = saveBomDetails(bomDetailsVos1);
+ bomDetailsMapper.insertBatch(bomDetails);
+
+ }
+
+ // 保存到 BomDetails 表中
+ //TODO: 使用本地库加速
+ private List saveBomDetails(List bomDetailsVos) {
+ List materialsToAdd = new ArrayList<>();
+ for (BomDetailsVo bomDetailsVo : bomDetailsVos) {
+ BomDetails bomDetails = BeanUtil.toBean(bomDetailsVo, BomDetails.class);
+ // 验证物料是否存在
+ int materialVerification = isMaterialVerification(bomDetails.getPartNumber(), bomDetails.getName());
+ if (materialVerification == 1) {
+ bomDetails.setUnitWeight("是");
+ materialsToAdd.add(bomDetails);
+ } else if (materialVerification == 2) {
+ bomDetails.setUnitWeight("否");
+ materialsToAdd.add(bomDetails);
+ } else if (materialVerification == 3) {
+ bomDetails.setUnitWeight("编码名称不符");
+ materialsToAdd.add(bomDetails);
+ }
+ }
+ return materialsToAdd;
+ }
+ @Log(title = "推送工艺工序")
+ @SaCheckPermission("system:route:viewGetBomUploadStatus")
+ @PostMapping("/viewGetBomUploadStatus")
+ public R viewGetBomUploadStatus(@RequestParam String rooteProdet) {
+ return iProcessRouteService.viewGetBomUploadStatus(rooteProdet);
}
}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/BomVariableController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/BomVariableController.java
index d76f63a..bd3c1c0 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/BomVariableController.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/BomVariableController.java
@@ -267,7 +267,7 @@ public class BomVariableController extends BaseController {
if (decimalIndex != -1) {
quantityStr = quantityStr.substring(0, decimalIndex);
}
- bomDetails.setQuantity(Double.valueOf(quantityStr));
+ bomDetails.setQuantity(quantityStr);
}
// 检查并转换单重
if (!rowData.get(5).isEmpty()) {
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/ImMaterialController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/ImMaterialController.java
index 3707ac6..88bc4de 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/ImMaterialController.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/ImMaterialController.java
@@ -271,7 +271,7 @@ public class ImMaterialController extends BaseController {
@XxlJob("updateMaterials")
public Boolean updateMaterials() throws Exception {
Date date = new Date();
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
List imMaterials = updateJdMaterial(sdf.format(date));
Boolean result = iImMaterialService.updateByFMid(imMaterials);
return result;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/KingdeeWorkCenterDataController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/KingdeeWorkCenterDataController.java
index 3feff7d..7e529b9 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/KingdeeWorkCenterDataController.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/KingdeeWorkCenterDataController.java
@@ -2,8 +2,10 @@ package com.ruoyi.system.controller;
import java.io.File;
import java.time.LocalDate;
+import java.time.temporal.ChronoUnit;
import java.time.format.DateTimeFormatter;
import java.util.*;
+import java.util.stream.Collectors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
@@ -19,12 +21,14 @@ import com.ruoyi.common.utils.HttpRequestUtil;
import com.ruoyi.common.utils.WxRobotUtil;
import com.ruoyi.common.poi.ExcelTemplateProc;
import com.ruoyi.common.poi.DynamicDataMapping;
+import com.ruoyi.system.domain.ProcessRoute;
import com.ruoyi.system.domain.SafetyStock;
import com.ruoyi.system.domain.WlStockData;
import com.ruoyi.system.domain.dto.*;
import com.ruoyi.system.domain.vo.WlStockDataVo;
import com.ruoyi.system.mapper.WlStockDataMapper;
import com.ruoyi.system.runner.JdUtil;
+import com.ruoyi.system.service.IProcessRouteService;
import com.ruoyi.system.service.ISafetyStockService;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
@@ -39,6 +43,7 @@ import cn.hutool.core.collection.CollUtil;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+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;
@@ -74,7 +79,8 @@ public class KingdeeWorkCenterDataController extends BaseController {
private static final Logger log = LoggerFactory.getLogger(KingdeeWorkCenterDataController.class);
private final WlStockDataMapper baseMapper;
private final ISafetyStockService iSafetyStockService;
-
+ @Autowired
+ IProcessRouteService iProcessRouteService;
/**
* 查询金蝶工段数据列表
*/
@@ -381,8 +387,9 @@ public class KingdeeWorkCenterDataController extends BaseController {
msg.append("- ").append(workCenter).append(" (无数据)\n");
continue;
}
-
- List dataList = result.getData();
+ //加入暂停项目的过滤
+ List dataList = result.getData().stream().filter(item -> item.getMoOrderNo() != null && !item.getMoOrderNo().contains("暂停"))
+ .collect(Collectors.toList());
msg.append("- ").append(workCenter).append(" (共").append(dataList.size()).append("条数据)\n");
// 生成Excel文件
@@ -433,10 +440,8 @@ public class KingdeeWorkCenterDataController extends BaseController {
List kingdeeWorkCenterDataVos = new ArrayList<>();
parameter.addProperty("FWorkCenterName", workCenter);
Object[] parameters = new Object[]{parameter.toString()};
- String execute = client.execute(
- "Ljint.Kingdee.YiTe.KanBan.WebApi.ProduceWebApi.ExecuteService,Ljint.Kingdee.YiTe.KanBan.WebApi",
- parameters);
- log.info("金蝶接口返回数据: {}", execute);
+ String execute = client.execute("Ljint.Kingdee.YiTe.KanBan.WebApi.ProduceWebApi.ExecuteService,Ljint.Kingdee.YiTe.KanBan.WebApi121303", parameters);
+ log.info("金蝶接口:" + workCenter + "===> 返回数据: {}", execute);
// 解析响应
JSONObject response = JSONObject.parseObject(execute);
@@ -444,7 +449,6 @@ public class KingdeeWorkCenterDataController extends BaseController {
String errorMsg = response.getString("Message");
return R.fail("获取工段数据失败:" + errorMsg);
}
-
// 获取明天的日期字符串 (格式: yyyy-MM-dd)
String yesterday = DateUtil.format(DateUtil.yesterday(), "yyyy-MM-dd");
@@ -518,26 +522,30 @@ public class KingdeeWorkCenterDataController extends BaseController {
public R getMassageDelayDate() {
try {
// String robotId = "4d2f037d-0cee-493a-a4ff-1758f67b8069";
- String robotId = "483489b2-b219-468c-851f-f56a34a62d91";
+ String robotId = "483489b2-b219-468c-851f-f56a34a62d91";
+ // String robotId = "8af8abea-3f21-4ca7-ad0a-5b7a2cf4d78e";
List workCenters = Arrays.asList("机一工段", "机二工段", "机三工段", "装一工段", "装二工段", "委外中心", "电钳工段", "铆焊工段");
String currentTime = DateUtil.format(new Date(), "yyyy年MM月dd日 HH:mm:ss");
- StringBuilder msg = new StringBuilder();
- msg.append("🏭 延期数据更新提醒\n\n")
- .append("更新时间:").append(currentTime).append("\n\n")
- .append("🔧 工作中心数据统计:\n");
+ // 构建Markdown消息
+ StringBuilder markdownMsg = new StringBuilder();
+ markdownMsg.append("# 生产延期数据更新提醒\n\n")
+ .append("> **统计时间:** ").append(currentTime).append("\n\n")
+ .append("## 🔧 工作中心数据统计:\n");
// 获取并统计每个工段的数据
for (String workCenter : workCenters) {
try {
R> result = getKingdeeDelayData(workCenter);
+ List data = result.getData();
if (R.isError(result) || CollUtil.isEmpty(result.getData())) {
- msg.append("- ").append(workCenter).append(" (无数据)\n");
+ markdownMsg.append("- ").append(workCenter).append(":无数据\n");
continue;
}
+ List dataList = result.getData().stream().filter(item -> item.getMoOrderNo() != null && !item.getMoOrderNo().contains("暂停"))
+ .collect(Collectors.toList());
- List dataList = result.getData();
- msg.append("- ").append(workCenter).append(" (共").append(dataList.size()).append("条数据)\n");
+ markdownMsg.append("- ").append(workCenter).append(":共 ").append(dataList.size()).append(" 条\n");
// 生成Excel文件
String fileName = String.format("%s生产延期数据_%s.xlsx", workCenter,
@@ -558,12 +566,18 @@ public class KingdeeWorkCenterDataController extends BaseController {
} catch (Exception e) {
log.error("获取工段{}数据失败", workCenter, e);
- msg.append("- ").append(workCenter).append(" (获取失败: ").append(e.getMessage()).append(")\n");
+ markdownMsg.append("- ").append(workCenter).append(":获取失败: ").append(e.getMessage()).append("\n");
}
}
- msg.append("\n详细数据请查看发送的Excel文件!");
- wxRobotUtil.sendMsgToWeChatGroup(msg.toString(), robotId, true); // @所有人
+ // 结尾提示与分段发送
+ markdownMsg.append("\n> **📊 详细数据请查看发送的Excel文件!**");
+ String messageContent = markdownMsg.toString();
+ int maxLength = 4096;
+ for (int i = 0; i < messageContent.length(); i += maxLength) {
+ String part = messageContent.substring(i, Math.min(i + maxLength, messageContent.length()));
+ wxRobotUtil.sendMarkdownMsgToWeChatGroup(part, robotId);
+ }
return R.ok();
@@ -916,6 +930,7 @@ public class KingdeeWorkCenterDataController extends BaseController {
map.put("FDate", item.getFDate());
map.put("FDeliveryDate", item.getFDeliveryDate());
map.put("FUCHNText2", item.getFUCHNText2());
+ map.put("FCreateDate", item.getFCreateDate());
mapList.add(map);
index++;
}
@@ -944,6 +959,7 @@ public class KingdeeWorkCenterDataController extends BaseController {
map.put("FApplicationDate", item.getFApplicationDate());
map.put("FUCHNText", item.getFUCHNText());
map.put("FCreatorIdFName", item.getFCreatorIdFName());
+ map.put("FCreateDate", item.getFCreateDate());
mapList.add(map);
index++;
}
@@ -956,7 +972,6 @@ public class KingdeeWorkCenterDataController extends BaseController {
*/
private List filterPurchaseOrders(List allOrders) {
LocalDate today = LocalDate.now();
- DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
log.info("开始过滤采购订单,总数: {}, 当前日期: {}", allOrders.size(), today.format(outputFormatter));
@@ -966,30 +981,45 @@ public class KingdeeWorkCenterDataController extends BaseController {
String productionOrderNo = allOrder.getFUCHNText2();
String deliveryDate = allOrder.getFDeliveryDate();
- // 条件3: 交货日期不能为空,并且必须早于今天
+ // ✅ 条件1: 暂停项目过滤
+ if (productionOrderNo != null && productionOrderNo.contains("暂停")) {
+ log.debug("过滤掉: 暂停项目: {}", productionOrderNo);
+ continue;
+ }
+
+ // ✅ 条件2: 交货日期不能为空
if (deliveryDate == null || deliveryDate.trim().isEmpty()) {
log.debug("过滤掉: 交货日期为空");
continue;
}
try {
- String dateStr = deliveryDate.split("T")[0]; // 取 yyyy-MM-dd 部分
- LocalDate delivery = LocalDate.parse(dateStr, inputFormatter);
+ // ✅ 格式化交货日期
+ LocalDate delivery = parseDate(deliveryDate);
+ if (delivery == null) {
+ log.warn("解析交货日期失败: {}", deliveryDate);
+ continue;
+ }
- // 转换格式
String formatted = delivery.format(outputFormatter);
allOrder.setFDeliveryDate(formatted);
+ // ✅ 条件3: 只保留交货日期早于今天的
if (!delivery.isBefore(today)) {
log.debug("过滤掉: 交货日期未过期: {}", formatted);
continue;
}
- } catch (Exception e) {
- log.warn("解析交货日期失败: {}", deliveryDate, e);
- continue;
- }
+ allOrder.setFQty(formatQty(allOrder.getFQty()));
+ // ✅ 顺便格式化其他日期字段
+ allOrder.setFDate(formatDate(allOrder.getFDate()));
+ allOrder.setFDeliveryDate(formatDate(allOrder.getFDeliveryDate()));
+ allOrder.setFCreateDate(formatDate(allOrder.getFCreateDate()));
- filteredOrders.add(allOrder);
+ filteredOrders.add(allOrder);
+
+ } catch (Exception e) {
+ log.warn("处理订单异常: {}", productionOrderNo, e);
+ }
}
log.info("过滤完成,剩余数量: {}", filteredOrders.size());
@@ -1002,7 +1032,6 @@ public class KingdeeWorkCenterDataController extends BaseController {
*/
private List filterReqPurchaseOrders(List allOrders) {
LocalDate today = LocalDate.now();
- DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
log.info("开始过滤采购申请订单,总数: {}, 当前日期: {}", allOrders.size(), today.format(outputFormatter));
@@ -1010,39 +1039,54 @@ public class KingdeeWorkCenterDataController extends BaseController {
for (PurchaseRequestExcelDTO allOrder : allOrders) {
String productionOrderNo = allOrder.getFUCHNText();
- String deliveryDate = allOrder.getFArrivalDate();
- if (allOrder.getFCloseStatus().equals("A")) {
+ String arrivalDate = allOrder.getFArrivalDate();
+
+ // 状态转换
+ if ("A".equals(allOrder.getFCloseStatus())) {
allOrder.setFCloseStatus("未关闭");
}
- if (allOrder.getFDocumentStatus().equals("C")) {
+ if ("C".equals(allOrder.getFDocumentStatus())) {
allOrder.setFDocumentStatus("已审核");
}
+ // 暂停项目过滤
+ if (productionOrderNo != null && productionOrderNo.contains("暂停")) {
+ log.debug("过滤掉: 暂停项目: {}", productionOrderNo);
+ continue;
+ }
- // 条件3: 交货日期不能为空,并且必须早于今天
- if (deliveryDate == null || deliveryDate.trim().isEmpty()) {
- log.debug("过滤掉: 交货日期为空");
+ // 到货日期不能为空
+ if (arrivalDate == null || arrivalDate.trim().isEmpty()) {
+ log.debug("过滤掉: 到货日期为空");
continue;
}
try {
- String dateStr = deliveryDate.split("T")[0]; // 取 yyyy-MM-dd 部分
- LocalDate delivery = LocalDate.parse(dateStr, inputFormatter);
+ LocalDate delivery = parseDate(arrivalDate);
+ if (delivery == null) {
+ log.warn("解析到货日期失败: {}", arrivalDate);
+ continue;
+ }
- // 转换格式
+ // 转换为中文日期格式
String formatted = delivery.format(outputFormatter);
allOrder.setFArrivalDate(formatted);
+ // 只保留已过期的日期
if (!delivery.isBefore(today)) {
- log.debug("过滤掉: 交货日期未过期: {}", formatted);
+ log.debug("过滤掉: 到货日期未过期: {}", formatted);
continue;
}
- } catch (Exception e) {
- log.warn("解析交货日期失败: {}", deliveryDate, e);
- continue;
- }
+ allOrder.setFReqQty(formatQty(allOrder.getFReqQty()));
+ allOrder.setFCreateDate(formatDate(allOrder.getFCreateDate()));
+ allOrder.setFApplicationDate(formatDate(allOrder.getFApplicationDate()));
+ allOrder.setFArrivalDate(formatDate(allOrder.getFArrivalDate()));
- filteredOrders.add(allOrder);
+ filteredOrders.add(allOrder);
+
+ } catch (Exception e) {
+ log.warn("处理订单异常: {}", productionOrderNo, e);
+ }
}
log.info("过滤完成,剩余数量: {}", filteredOrders.size());
@@ -1123,4 +1167,499 @@ public class KingdeeWorkCenterDataController extends BaseController {
}
}
+ /**
+ * 将日期字符串(如 "2025-09-22T10:52:03.6" 或 "2025-09-22")格式化为 "yyyy年MM月dd日"
+ */
+ private String formatDate(String dateStr) {
+ if (dateStr == null || dateStr.isEmpty()) {
+ return null;
+ }
+ try {
+ LocalDate date = parseDate(dateStr);
+ if (date != null) {
+ return date.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));
+ }
+ } catch (Exception ignored) {
+ }
+ return dateStr; // 解析失败则返回原值
+ }
+
+ /**
+ * 解析日期字符串,支持带 T 的 ISO 格式或普通 yyyy-MM-dd 格式
+ */
+ private LocalDate parseDate(String dateStr) {
+ if (dateStr == null || dateStr.trim().isEmpty()) {
+ return null;
+ }
+ try {
+ // 先取出 T 之前的部分
+ String clean = dateStr.split("T")[0];
+ return LocalDate.parse(clean, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+ } catch (Exception e) {
+ log.debug("日期解析失败: {}", dateStr, e);
+ return null;
+ }
+ }
+
+ /**
+ * 单据状态编码到中文的映射
+ * A -> 创建,B -> 审核中,C -> 已审核,其它原样返回
+ */
+ private String mapDocumentStatus(String status) {
+ if (status == null || status.trim().isEmpty()) {
+ return "";
+ }
+ switch (status) {
+ case "A":
+ return "创建";
+ case "B":
+ return "审核中";
+ case "C":
+ return "已审核";
+ default:
+ return status;
+ }
+ }
+
+ /**
+ * 格式化数量为两位小数
+ */
+ private String formatQty(String qtyStr) {
+ if (qtyStr == null || qtyStr.trim().isEmpty()) {
+ return "0.00";
+ }
+ try {
+ double value = Double.parseDouble(qtyStr);
+ return String.format("%.2f", value);
+ } catch (NumberFormatException e) {
+ log.debug("数量格式化失败: {}", qtyStr, e);
+ return qtyStr;
+ }
+ }
+
+ @Log(title = "获取开工延时的生产订单")
+ @XxlJob("getConstructionDelay")
+ @PostMapping("/getConstructionDelay")
+ public R getConstructionDelay() {
+ try {
+
+ // String robotId = "4d2f037d-0cee-493a-a4ff-1758f67b8069";
+ String robotId = "8af8abea-3f21-4ca7-ad0a-5b7a2cf4d78e";
+ String currentTime = DateUtil.format(new Date(), "yyyy年MM月dd日 HH:mm:ss");
+ StringBuilder msg = new StringBuilder();
+ msg.append("🏭 生产订单未开工的延期通知\n\n").append("更新时间:").append(currentTime).append("\n\n").append("🔧 订单数据统计:\n");
+ // 获取生产订单数据
+ List purchaseOrderList1 = JdUtil.getConstructionDelay();
+
+ List purchaseOrderList = filterConstructionDel(purchaseOrderList1);
+ msg.append("- 到期未开工:").append(purchaseOrderList.size()).append("条\n");
+ // 生成Excel文件使用采购模板
+ String fileName = String.format("生产订单未开工的延期数据_%s.xlsx", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
+ String filePath = FileUtils.getTempDirectoryPath() + File.separator + fileName;
+ // 准备模板数据
+ Map staticDataMap = new HashMap<>();
+ staticDataMap.put("currentTime", DateUtil.format(new Date(), "yyyy年MM月dd日 HH:mm:ss"));
+ staticDataMap.put("purchaseOrderCount", purchaseOrderList.size());
+ List dynamicDataMappingList = new ArrayList<>();
+ // 添加数据(仅在此方法内映射,避免对已格式化日期再次格式化)
+ if (!purchaseOrderList.isEmpty()) {
+ List