166 lines
7.5 KiB
Java
166 lines
7.5 KiB
Java
package com.ruoyi.system.controller;
|
||
|
||
import cn.dev33.satoken.annotation.SaIgnore;
|
||
import com.alibaba.fastjson.JSON;
|
||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||
import com.ruoyi.common.annotation.Log;
|
||
import com.ruoyi.common.core.controller.BaseController;
|
||
import com.ruoyi.common.core.domain.R;
|
||
import com.ruoyi.common.enums.BusinessType;
|
||
import com.ruoyi.common.utils.ServletUtils;
|
||
import com.ruoyi.common.utils.spring.SpringUtils;
|
||
import com.ruoyi.system.domain.ProcessOrderPro;
|
||
import com.ruoyi.system.domain.bo.plm.PlmProcessRoutePushBo;
|
||
import com.ruoyi.system.domain.bo.plm.PlmProcessRoutePushNormalizer;
|
||
import com.ruoyi.system.mapper.ProcessOrderProMapper;
|
||
import com.ruoyi.system.service.IPlmProcessRoutePushService;
|
||
import com.ruoyi.system.service.IPlmReceiveLogService;
|
||
import com.ruoyi.system.service.ProcessPlanExcelPushService;
|
||
import lombok.RequiredArgsConstructor;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.validation.annotation.Validated;
|
||
import org.springframework.web.bind.annotation.PostMapping;
|
||
import org.springframework.web.bind.annotation.RequestBody;
|
||
import org.springframework.web.bind.annotation.RequestMapping;
|
||
import org.springframework.web.bind.annotation.RestController;
|
||
|
||
import java.io.File;
|
||
import java.util.LinkedHashMap;
|
||
import java.util.Map;
|
||
import java.util.concurrent.CompletableFuture;
|
||
|
||
/**
|
||
* PLM 系统推送完整工艺信息接收入口(POST JSON,英文键名)。
|
||
*
|
||
* @see PlmProcessRoutePushBo
|
||
*/
|
||
@Slf4j
|
||
@Validated
|
||
@RequiredArgsConstructor
|
||
@RestController
|
||
@RequestMapping("/system/plm")
|
||
public class ProcessRoutePushReceiveController extends BaseController {
|
||
|
||
private static final String API_PATH = "/system/plm/routReceive";
|
||
|
||
private final IPlmProcessRoutePushService plmProcessRoutePushService;
|
||
private final IPlmReceiveLogService plmReceiveLogService;
|
||
private final ProcessOrderProMapper processOrderProMapper;
|
||
/** 导出计划表落盘 + 按 plan-user-id 推送(与手动上传一致) */
|
||
private final ProcessPlanExcelPushService processPlanExcelPushService;
|
||
|
||
/**
|
||
* 接收一个生产令号下的物料、材料 BOM、工艺路线及工步数据。
|
||
* <p>
|
||
* POST /system/plm/routReceive<br>
|
||
* Content-Type: application/json; charset=UTF-8
|
||
*/
|
||
@SaIgnore
|
||
@Log(title = "PLM工艺信息推送接收", businessType = BusinessType.OTHER)
|
||
@PostMapping("/routReceive")
|
||
public R<PlmProcessRoutePushNormalizer.PlmProcessRoutePushSummary> receive(
|
||
@Validated @RequestBody PlmProcessRoutePushBo body) {
|
||
String payloadJson = JSON.toJSONString(body);
|
||
String orderNo = body == null ? null : body.getProductionOrder();
|
||
String clientIp = resolveClientIp();
|
||
try {
|
||
PlmProcessRoutePushNormalizer.normalize(body);
|
||
PlmProcessRoutePushNormalizer.PlmProcessRoutePushSummary summary = plmProcessRoutePushService.persist(body);
|
||
log.info("收到 PLM 工艺推送 productionOrder={} materialCount={} processCount={} stepCount={} bomLineCount={} savedBom={} savedRoute={}",
|
||
summary.getProductionOrder(), summary.getMaterialCount(),
|
||
summary.getProcessCount(), summary.getStepCount(), summary.getBomLineCount(),
|
||
summary.getSavedBomCount(), summary.getSavedRouteCount());
|
||
log.info("PLM 工艺推送完整 JSON:\n{}", JSON.toJSONString(body, SerializerFeature.PrettyFormat));
|
||
|
||
Map<String, Object> summaryMap = new LinkedHashMap<>();
|
||
summaryMap.put("productionOrder", summary.getProductionOrder());
|
||
summaryMap.put("materialCount", summary.getMaterialCount());
|
||
summaryMap.put("bomLineCount", summary.getBomLineCount());
|
||
summaryMap.put("processCount", summary.getProcessCount());
|
||
summaryMap.put("stepCount", summary.getStepCount());
|
||
summaryMap.put("savedBomCount", summary.getSavedBomCount());
|
||
summaryMap.put("savedMaterialBomCount", summary.getSavedMaterialBomCount());
|
||
summaryMap.put("savedRouteCount", summary.getSavedRouteCount());
|
||
int saved = summary.getSavedBomCount() + summary.getSavedMaterialBomCount() + summary.getSavedRouteCount();
|
||
plmReceiveLogService.record(
|
||
IPlmReceiveLogService.BIZ_PROCESS_ROUTE,
|
||
API_PATH,
|
||
summary.getProductionOrder(),
|
||
payloadJson,
|
||
JSON.toJSONString(summaryMap),
|
||
summary.getMaterialCount(),
|
||
saved,
|
||
Boolean.TRUE,
|
||
IPlmReceiveLogService.STATUS_SUCCESS,
|
||
null,
|
||
clientIp
|
||
);
|
||
|
||
// 入库成功后异步:导出工艺计划表 → 落盘 → 推送给 plan-user-id(与手动上传同一套用户)
|
||
final String productionOrder = summary.getProductionOrder();
|
||
CompletableFuture.runAsync(() -> exportAndPushPlanExcel(productionOrder));
|
||
|
||
return R.ok("接收成功", summary);
|
||
} catch (Exception e) {
|
||
Integer lineCount = null;
|
||
if (body != null && body.getMaterialList() != null) {
|
||
lineCount = body.getMaterialList().size();
|
||
}
|
||
plmReceiveLogService.record(
|
||
IPlmReceiveLogService.BIZ_PROCESS_ROUTE,
|
||
API_PATH,
|
||
orderNo,
|
||
payloadJson,
|
||
null,
|
||
lineCount,
|
||
null,
|
||
null,
|
||
IPlmReceiveLogService.STATUS_FAIL,
|
||
e.getMessage(),
|
||
clientIp
|
||
);
|
||
throw e;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* PLM 工艺入库后:按模板导出计划表,存到 app.plan-excel.base-dir,再按 plan-user-id 推送。
|
||
*/
|
||
private void exportAndPushPlanExcel(String productionOrder) {
|
||
try {
|
||
ProcessOrderPro order = processOrderProMapper.selectByProjectNumber(productionOrder);
|
||
if (order == null || order.getId() == null) {
|
||
log.warn("PLM 导出计划表跳过:项目不存在 productionOrder={}", productionOrder);
|
||
return;
|
||
}
|
||
// 复用现有导出(PLM 来源会走 generateRoute3ExcelFromPlm)
|
||
ProcessOrderProController controller = SpringUtils.getBean(ProcessOrderProController.class);
|
||
String generatedPath = controller.generateRoute3Excel(order.getId(), true);
|
||
File generated = new File(generatedPath);
|
||
if (!generated.exists() || generated.length() <= 0) {
|
||
log.warn("PLM 导出计划表失败:文件为空 path={}", generatedPath);
|
||
return;
|
||
}
|
||
// 落到固定目录,再推送;临时生成文件可删
|
||
File saved = processPlanExcelPushService.savePlanExcel(productionOrder, generated, generated.getName());
|
||
File toSend = saved != null ? saved : generated;
|
||
processPlanExcelPushService.sendToPlanUsers(toSend, toSend.getName());
|
||
if (saved != null && generated.exists() && !generated.getAbsolutePath().equals(saved.getAbsolutePath())) {
|
||
if (!generated.delete()) {
|
||
log.warn("删除临时计划表失败: {}", generated.getAbsolutePath());
|
||
}
|
||
}
|
||
} catch (Exception e) {
|
||
log.error("PLM 工艺推送后导出/推送计划表失败 productionOrder={}", productionOrder, e);
|
||
}
|
||
}
|
||
|
||
private static String resolveClientIp() {
|
||
try {
|
||
return ServletUtils.getClientIP();
|
||
} catch (Exception ignored) {
|
||
return null;
|
||
}
|
||
}
|
||
}
|