Compare commits
32 Commits
32fa2c89ed
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| bcea5255e6 | |||
| a718557762 | |||
| 6db871f99b | |||
| 82cffb7ea3 | |||
| f8b7d6b813 | |||
| d8f0e102c9 | |||
| a6756bc7db | |||
| cd192d86ba | |||
| b5dfb0c9b4 | |||
| 675dd43262 | |||
| 53e4635506 | |||
| a3e46674b3 | |||
| 65d9f59ac4 | |||
| e6c2b0aec2 | |||
| 26bb8f33c4 | |||
| 5622507416 | |||
| 2d2c0779b9 | |||
| 62036f85be | |||
| c179c22f25 | |||
| b36787f01f | |||
| 5e2610f087 | |||
| 8d8be94c2d | |||
| 76ad6bcbd7 | |||
| fcdefce214 | |||
| ca91e43067 | |||
| 00154d29fa | |||
| e38f787994 | |||
| dfa1ec73c8 | |||
| fc8c05d572 | |||
| 01ef096568 | |||
| f09b68bca6 | |||
| 26418f6fff |
@@ -115,6 +115,12 @@
|
||||
<version>3.1.4.0.6.15</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.xingshuangs</groupId>
|
||||
<artifactId>iot-communication</artifactId>
|
||||
<version>1.5.5</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.alibaba</groupId>-->
|
||||
|
||||
@@ -5,9 +5,10 @@ import com.fizz.business.constants.enums.OpcMessageType;
|
||||
import com.fizz.business.domain.msg.*;
|
||||
import com.fizz.business.scheduled.BaseSchedule;
|
||||
import com.fizz.business.service.hanle.OpcReceiverHandler;
|
||||
import com.fizz.business.service.ProStoppageService;
|
||||
import com.fizz.business.domain.ProStoppage;
|
||||
import com.kangaroohy.milo.model.ReadWriteEntity;
|
||||
import com.kangaroohy.milo.service.MiloService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.beanutils.BeanUtils;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
@@ -17,6 +18,9 @@ import org.springframework.stereotype.Component;
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -25,7 +29,6 @@ import static com.fizz.business.service.manager.OpcMessageIdsManager.*;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
@ConditionalOnProperty(prefix = "kangaroohy.milo", name = "enabled", havingValue = "true")
|
||||
public class MessageReceiveSchedule extends BaseSchedule {
|
||||
|
||||
@@ -34,6 +37,22 @@ public class MessageReceiveSchedule extends BaseSchedule {
|
||||
|
||||
@Resource
|
||||
private OpcReceiverHandler opcReceiverHandler;
|
||||
|
||||
@Resource
|
||||
private ProStoppageService proStoppageService;
|
||||
|
||||
/**
|
||||
* 低速监控状态
|
||||
*/
|
||||
private LocalDateTime lowSpeedStartTime;
|
||||
private boolean stopRecorded = false;
|
||||
private Long currentStopId;
|
||||
|
||||
/**
|
||||
* 恢复监控状态
|
||||
*/
|
||||
private LocalDateTime highSpeedStartTime;
|
||||
|
||||
@Scheduled(fixedDelay = 1000)
|
||||
public void L1L2LineMeasure() {
|
||||
try {
|
||||
@@ -55,6 +74,9 @@ public class MessageReceiveSchedule extends BaseSchedule {
|
||||
msg.setAppMeasureCoatMessage(coat);
|
||||
msg.setAppMeasureFurnaceMessage(fur);
|
||||
msg.setAppMeasureExitMessage(exit);
|
||||
|
||||
monitorStripSpeed(entry);
|
||||
|
||||
opcReceiverHandler.onMessageReceived(OpcMessageType.APP_MEASURE,msg);
|
||||
|
||||
} catch (Exception e) {
|
||||
@@ -86,4 +108,67 @@ public class MessageReceiveSchedule extends BaseSchedule {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* stripSpeed<5 持续5分钟判定停机,>5 持续1分钟结束停机并更新维持时间
|
||||
*/
|
||||
private void monitorStripSpeed(AppMeasureEntryMessage entry) {
|
||||
if (entry == null || entry.getStripSpeed() == null) {
|
||||
resetSpeedFlags();
|
||||
return;
|
||||
}
|
||||
|
||||
boolean lowSpeed = entry.getStripSpeed().compareTo(BigDecimal.valueOf(5)) < 0;
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
if (lowSpeed) {
|
||||
highSpeedStartTime = null; // 重置恢复计时
|
||||
if (lowSpeedStartTime == null) {
|
||||
lowSpeedStartTime = now;
|
||||
}
|
||||
// 低速已持续超过5分钟且尚未入库,则新增停机记录
|
||||
if (!stopRecorded && Duration.between(lowSpeedStartTime, now).toMinutes() >= 5) {
|
||||
ProStoppage stoppage = new ProStoppage();
|
||||
stoppage.setStartDate(lowSpeedStartTime);
|
||||
stoppage.setDuration(BigDecimal.ZERO); // 初始为0,恢复后再更新
|
||||
stoppage.setStopType("AUTO_LOW_SPEED");
|
||||
stoppage.setRemark("stripSpeed<5 自动停机");
|
||||
if (proStoppageService.save(stoppage)) {
|
||||
currentStopId = stoppage.getStopid();
|
||||
stopRecorded = true;
|
||||
log.info("自动新增低速停机记录,stopId={} start={}", currentStopId, lowSpeedStartTime);
|
||||
} else {
|
||||
log.warn("自动新增低速停机记录失败");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lowSpeedStartTime = null;
|
||||
if (stopRecorded) {
|
||||
if (highSpeedStartTime == null) {
|
||||
highSpeedStartTime = now;
|
||||
}
|
||||
if (Duration.between(highSpeedStartTime, now).toMinutes() >= 1 && currentStopId != null) {
|
||||
ProStoppage update = new ProStoppage();
|
||||
update.setStopid(currentStopId);
|
||||
update.setEndDate(now);
|
||||
// duration 以秒存储
|
||||
ProStoppage existing = proStoppageService.getById(currentStopId);
|
||||
LocalDateTime start = existing != null && existing.getStartDate() != null ? existing.getStartDate() : highSpeedStartTime;
|
||||
long seconds = Duration.between(start, now).getSeconds();
|
||||
update.setDuration(BigDecimal.valueOf(seconds));
|
||||
proStoppageService.updateById(update);
|
||||
log.info("低速停机结束更新,stopId={} duration={}s", currentStopId, seconds);
|
||||
resetSpeedFlags();
|
||||
}
|
||||
} else {
|
||||
highSpeedStartTime = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resetSpeedFlags() {
|
||||
lowSpeedStartTime = null;
|
||||
highSpeedStartTime = null;
|
||||
// 不重置 stopRecorded/currentStopId,避免短暂无值时丢失状态
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ public class MessageSubscriptionRunner implements ApplicationRunner {
|
||||
EntryMovementMessage msg =new EntryMovementMessage();
|
||||
writeMessage( msg,entryMoveIds);
|
||||
log.info("接收入口移动信号:从 {} 移动到 {} ", msg.getMaterialPlaceSource(), msg.getMaterialPlaceDestination());
|
||||
logDataService.logInfo("TRACK","Received entry movement signal: from {} to {}", msg.getMaterialPlaceSource(), msg.getMaterialPlaceDestination());
|
||||
logDataService.logInfo("TRACK","Received entry movement signal: from " + msg.getMaterialPlaceSource() + " to " + msg.getMaterialPlaceDestination());
|
||||
opcReceiverHandler.onMessageReceived(OpcMessageType.ENTRY_MOVEMENT,msg);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
@@ -96,9 +96,9 @@ public class MessageSubscriptionRunner implements ApplicationRunner {
|
||||
{
|
||||
try {
|
||||
ExitCutMessage msg = new ExitCutMessage();
|
||||
writeMessage( msg,exitCutIds);
|
||||
writeMessage(msg,exitCutIds);
|
||||
log.info("接收到出口剪切信号:剪切类型 {},剪切长度{} ", msg.getCutType().toString(), msg.getCutLength());
|
||||
logDataService.logInfo("TRACK","Received exit cut signal: cut type {}, cut length {}", msg.getCutType().toString(), msg.getCutLength());
|
||||
logDataService.logInfo("TRACK","Received exit cut signal: cut type " + msg.getCutType().toString() + ", cut length " + msg.getCutLength());
|
||||
opcReceiverHandler.onMessageReceived(OpcMessageType.EXIT_CUT,msg);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
@@ -110,7 +110,7 @@ public class MessageSubscriptionRunner implements ApplicationRunner {
|
||||
ExitMovementMessage msg = new ExitMovementMessage();
|
||||
writeMessage( msg,exitMoveIds);
|
||||
log.info("接收出口移动信号:从 {} 移动到 {} ", msg.getExSrc(), msg.getExDesc());
|
||||
logDataService.logInfo("TRACK","Received exit movement signal: from {} to {}", msg.getExSrc(), msg.getExDesc());
|
||||
logDataService.logInfo("TRACK","Received exit movement signal: from " + msg.getExSrc() + " to " + msg.getExDesc());
|
||||
opcReceiverHandler.onMessageReceived(OpcMessageType.EXIT_MOVEMENT,msg);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
@@ -122,7 +122,7 @@ public class MessageSubscriptionRunner implements ApplicationRunner {
|
||||
ExitMeasureMessage msg = new ExitMeasureMessage();
|
||||
writeMessage(msg,exitMeasureIds);
|
||||
log.info("接收出口称重信号:重量 {} ", msg.getWeight());
|
||||
logDataService.logInfo("TRACK","Received exit weight signal: weight {}", msg.getWeight());
|
||||
logDataService.logInfo("TRACK","Received exit weight signal: weight " + msg.getWeight());
|
||||
opcReceiverHandler.onMessageReceived(OpcMessageType.EXIT_MEASURE,msg);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.fizz.business.domain.msg.OpcMessage;
|
||||
import com.fizz.business.domain.msg.PdiSetup;
|
||||
import com.kangaroohy.milo.model.ReadWriteEntity;
|
||||
import com.kangaroohy.milo.service.MiloService;
|
||||
import com.fizz.business.service.LogDataService;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -14,6 +15,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.fizz.business.service.manager.OpcMessageIdsManager.findIdentifierByFieldName;
|
||||
import static com.fizz.business.service.manager.OpcMessageIdsManager.pdiSetupIds;
|
||||
|
||||
@Service
|
||||
@@ -24,6 +26,9 @@ public class OpcMessageSend {
|
||||
@Resource
|
||||
private MiloService miloService;
|
||||
|
||||
@Resource
|
||||
private LogDataService logDataService;
|
||||
|
||||
private void sendPdiSetup(PdiSetup pdiSetup) {
|
||||
try {
|
||||
List<ReadWriteEntity> entities = getWriteEntities(pdiSetup, pdiSetupIds);
|
||||
@@ -62,56 +67,75 @@ public class OpcMessageSend {
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用写入方法,用于向指定 OPC 节点写入一个值
|
||||
* @param address OPC 节点地址 (e.g., "ns=2;s=ProcessCGL.PLCLine.ExitCut.cutLength")
|
||||
* 通用写数据方法:通过字段名向指定点位写入单个值
|
||||
* @param fieldName 字段名(对象属性名),例如:coilId
|
||||
* @param value 要写入的值
|
||||
* @return 是否写入成功
|
||||
*/
|
||||
public void writeNode(String address, Object value) {
|
||||
public boolean writeDataByFieldName(String fieldName, Object value) {
|
||||
try {
|
||||
String identifier = findIdentifierByFieldName(fieldName);
|
||||
if (identifier == null) {
|
||||
log.error("未找到字段名对应的 OPC 节点路径,fieldName={}", fieldName);
|
||||
return false;
|
||||
}
|
||||
List<ReadWriteEntity> entities = new ArrayList<>();
|
||||
entities.add(ReadWriteEntity.builder()
|
||||
.identifier(address)
|
||||
.identifier(identifier)
|
||||
.value(value)
|
||||
.build());
|
||||
miloService.writeToOpcUa(entities);
|
||||
log.info("写入 OPC 成功, node={}, value={}", address, value);
|
||||
log.info("写入 OPC 数据成功,fieldName={}, identifier={}, value={}", fieldName, identifier, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error("写入 OPC 失败, node={}, value={}, 原因: {}", address, value, e.getMessage(), e);
|
||||
// 抛出运行时异常,以便上层调用者(如 SendJobServiceImpl)可以捕获并处理失败状态
|
||||
throw new RuntimeException("写入 OPC 失败: " + e.getMessage(), e);
|
||||
log.error("写入 OPC 数据失败,fieldName={}, value={},原因:{}", fieldName, value, e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入 OPC 节点(增强版):根据字符串值尝试转换为数值/布尔,再写入
|
||||
* 规则:
|
||||
* 1) 先尝试转 Integer
|
||||
* 2) 再尝试转 Double
|
||||
* 3) 再尝试转 Boolean(true/false/1/0)
|
||||
* 4) 都不行则按原字符串写入
|
||||
* 通用写数据方法:向指定点位写入单个值(直接使用节点路径)
|
||||
* @param identifier OPC 点位标识符(节点路径)
|
||||
* @param value 要写入的值
|
||||
* @return 是否写入成功
|
||||
*/
|
||||
public void writeNode(String address, String valueRaw) {
|
||||
Object v = valueRaw;
|
||||
if (valueRaw != null) {
|
||||
String s = valueRaw.trim();
|
||||
// boolean
|
||||
if ("1".equals(s) || "0".equals(s) || "true".equalsIgnoreCase(s) || "false".equalsIgnoreCase(s)) {
|
||||
v = ("1".equals(s) || "true".equalsIgnoreCase(s));
|
||||
} else {
|
||||
// int
|
||||
try {
|
||||
v = Integer.parseInt(s);
|
||||
} catch (Exception ignore) {
|
||||
// double
|
||||
try {
|
||||
v = Double.parseDouble(s);
|
||||
} catch (Exception ignore2) {
|
||||
v = valueRaw;
|
||||
}
|
||||
}
|
||||
}
|
||||
public boolean writeData(String identifier, Object value) {
|
||||
try {
|
||||
List<ReadWriteEntity> entities = new ArrayList<>();
|
||||
entities.add(ReadWriteEntity.builder()
|
||||
.identifier(identifier)
|
||||
.value(value)
|
||||
.build());
|
||||
miloService.writeToOpcUa(entities);
|
||||
log.info("写入 OPC 数据成功,identifier={}, value={}", identifier, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error("写入 OPC 数据失败,identifier={}, value={},原因:{}", identifier, value, e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量写数据方法:向多个点位写入数据(直接使用节点路径)
|
||||
* @param dataMap 点位标识符和值的映射,key 为 identifier,value 为要写入的值
|
||||
* @return 是否全部写入成功
|
||||
*/
|
||||
public boolean batchWriteData(Map<String, Object> dataMap) {
|
||||
try {
|
||||
List<ReadWriteEntity> entities = new ArrayList<>();
|
||||
for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
|
||||
entities.add(ReadWriteEntity.builder()
|
||||
.identifier(entry.getKey())
|
||||
.value(entry.getValue())
|
||||
.build());
|
||||
}
|
||||
miloService.writeToOpcUa(entities);
|
||||
logDataService.logInfo("WRITE","批量写入 OPC 数据成功,共"+ entities.size()+ "个点位");
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
logDataService.logInfo("WRITE","批量写入 OPC 数据失败,原因:"+ e.getMessage()+","+ e);
|
||||
return false;
|
||||
}
|
||||
writeNode(address, v);
|
||||
}
|
||||
|
||||
private List<ReadWriteEntity> getWriteEntities(OpcMessage msg, Map<String,String> msgIds) {
|
||||
@@ -129,7 +153,7 @@ public class OpcMessageSend {
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
// 处理字段不存在或访问异常,可记录日志或设置默认值
|
||||
e.printStackTrace();
|
||||
return new ArrayList<>();
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
ReadWriteEntity entity = ReadWriteEntity.builder()
|
||||
|
||||
@@ -14,40 +14,60 @@ import java.util.*;
|
||||
@Getter
|
||||
public enum DeviceEnum {
|
||||
// === Entry section / 入口段 ===
|
||||
POR1(0, "Uncoiler #1", 0.0, SectionType.ENTRY, SourceType.ENTRY, Arrays.asList("tensionPorBr1", "stripSpeed")),
|
||||
POR2(1, "Uncoiler #2", 0.0, SectionType.ENTRY, SourceType.ENTRY, Arrays.asList("tensionPorBr2", "stripSpeed")),
|
||||
POR1(0, "Uncoiler #1", 0.0, SectionType.ENTRY, SourceType.ENTRY, Arrays.asList("tensionPorBr1", "stripSpeed","tensionBr45Br6")),
|
||||
POR2(1, "Uncoiler #2", 0.0, SectionType.ENTRY, SourceType.ENTRY, Arrays.asList("tensionPorBr2", "stripSpeed","tensionBr45Br6")),
|
||||
WELDER(2, "Welder", 4.98, SectionType.ENTRY, SourceType.ENTRY, Arrays.asList("weldStatus")),
|
||||
ENL1(3, "Entry Looper #1", 19.04, SectionType.PROCESS, SourceType.ENTRY, Arrays.asList("celLength", "celCapacity", "tensionCel")),
|
||||
ENL2(4, "Entry Looper #2", 167.09, SectionType.PROCESS, SourceType.ENTRY, Arrays.asList("celLength", "celCapacity", "tensionCel")),
|
||||
ENL3(5, "Entry Looper #3", 198.19, SectionType.PROCESS, SourceType.ENTRY, Arrays.asList("celLength", "celCapacity", "tensionCel")),
|
||||
ENL1(3, "Entry Looper #1", 19.041, SectionType.PROCESS, SourceType.ENTRY, Arrays.asList("celLength", "celCapacity", "tensionCel")),
|
||||
ENL2(4, "Entry Looper #2", 167.091, SectionType.PROCESS, SourceType.ENTRY, Arrays.asList("celLength", "celCapacity", "tensionCel")),
|
||||
ENL3(5, "Entry Looper #3", 198.191, SectionType.PROCESS, SourceType.ENTRY, Arrays.asList("celLength", "celCapacity", "tensionCel","tensionBr45Br6")),
|
||||
|
||||
// === Process section / 工艺段 ===
|
||||
CLEAN(6, "Cleaning Section", 264.803, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList("cleaningVoltage", "cleaningCurrent", "alkaliConcentration", "alkaliTemperature")),
|
||||
FUR1(7, "Annealing Furnace - Preheating", 302.837, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList("phfExitStripTemp", "potTemperature", "gasConsumption")),
|
||||
FUR2(8, "Annealing Furnace - Heating", 381.057, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList("rtfExitStripTemp", "zincPotPower")),
|
||||
FUR3(9, "Annealing Furnace - Cooling", 416.837, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList("jcsExitStripTemp", "coolingTowerStripTemp")),
|
||||
FUR4(10, "Annealing Furnace - Equalizing", 432.16, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList("scsExitStripTemp")),
|
||||
POT(11, "Zinc Pot", 442.994, SectionType.PROCESS, SourceType.COAT, Arrays.asList("scsExitStripTemp")),
|
||||
TOWER(12, "Cooling Tower", 563.594, SectionType.PROCESS, SourceType.COAT, Arrays.asList("scsExitStripTemp")),
|
||||
TM(13, "Temper Mill", 586.529, SectionType.PROCESS, SourceType.COAT, Arrays.asList("tensionBr5Tm", "stripSpeedTmExit")),
|
||||
TL(14, "Tension Leveler", 612.909, SectionType.PROCESS, SourceType.COAT, Arrays.asList("tlElongation", "tensionTlBr7")),
|
||||
COAT(15, "Post-treatment Section", 712.699, SectionType.PROCESS, SourceType.COAT, Arrays.asList(
|
||||
FUR1(7, "Annealing Furnace - Preheating", 302.837, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList(
|
||||
"phFurnaceTemperatureActual",
|
||||
"nof1FurnaceTemperatureActual", "nof2FurnaceTemperatureActual", "nof3FurnaceTemperatureActual", "nof4FurnaceTemperatureActual",
|
||||
"nofPlateTemperatureActual",
|
||||
"nofFurnacePressureActual"
|
||||
)),
|
||||
FUR2(8, "Annealing Furnace - Heating", 381.057, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList(
|
||||
"rtf1FurnaceTemperatureActual", "rtf2FurnaceTemperatureActual",
|
||||
"rtfPlateTemperatureActual",
|
||||
"rtfFurnacePressureActual"
|
||||
)),
|
||||
FUR3(9, "Annealing Furnace - Cooling", 398.947, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList(
|
||||
"jcf1FurnaceTemperatureActual",
|
||||
"jcfFan1ActualSpeed", "jcfFan2ActualSpeed", "jcfFan3ActualSpeed", "jcfFan4ActualSpeed"
|
||||
)),
|
||||
FUR4(10, "Annealing Furnace - Equalizing", 414.27, SectionType.PROCESS, SourceType.FURNACE, Arrays.asList(
|
||||
"lthFurnaceTemperatureActual",
|
||||
"tdsFurnaceTemperatureActual",
|
||||
"lbzFurnaceTemperatureActual",
|
||||
"tdsPlateTemperatureActual",
|
||||
"tdsFurnacePressureActual"
|
||||
)),
|
||||
|
||||
POT(11, "Zinc Pot", 425.104, SectionType.PROCESS, SourceType.COAT, Arrays.asList("potTemperature")),
|
||||
TOWER(12, "Cooling Tower", 545.659, SectionType.PROCESS, SourceType.COAT, Arrays.asList("coolingTowerTemperature")),
|
||||
TM(13, "Temper Mill", 568.639, SectionType.PROCESS, SourceType.COAT, Arrays.asList("tensionBr5Tm", "stripSpeedTmExit")),
|
||||
TL(14, "Tension Leveler", 595.019, SectionType.PROCESS, SourceType.COAT, Arrays.asList("tlElongation", "tensionTlBr7")),
|
||||
COAT(15, "Post-treatment Section", 694.809, SectionType.PROCESS, SourceType.COAT, Arrays.asList(
|
||||
"avrCoatingWeightTop","stdCoatingWeightTop","maxCoatingWeightTop","minCoatingWeightTop",
|
||||
"avrCoatingWeightBottom","stdCoatingWeightBottom","maxCoatingWeightBottom","minCoatingWeightBottom",
|
||||
"airKnifePressure","airKnifeFlow","airKnifeGap","stripSpeedTmExit","tensionBr8Tm",
|
||||
"tensionTmBr9","tensionBr8Br9","tmMask","tmElongation","rollForceOperator","rollForceDrive",
|
||||
"motorTorque","bendingForce","antiCrimpingRollMesh","billyRollMesh",
|
||||
"tensionTlBr10Br11","tensionBr9toBr10Br11","tlFlag","tlElongation","levelingUnit1Mesh","levelingUnit2Mesh",
|
||||
"antiCrossBowUnitMesh","tensionBr10Br11toBr12","stripSpeedAfp","stripTempAfp"
|
||||
"antiCrossBowUnitMesh","tensionBr10Br11Br12","stripSpeedAfp","stripTempAfp",
|
||||
"potTemperature","coolingTowerTemperature","potPower"
|
||||
)),
|
||||
|
||||
// === Exit section / 出口段 ===
|
||||
CXL1(16, "Exit Looper #1", 720.709, SectionType.EXIT, SourceType.EXIT, Arrays.asList("cxlLength", "cxlCapacity", "tensionCxl")),
|
||||
CXL2(17, "Exit Looper #2", 888.789, SectionType.EXIT, SourceType.EXIT, Arrays.asList("cxlLength", "cxlCapacity", "tensionCxl")),
|
||||
CXL1(16, "Exit Looper #1", 702.819, SectionType.EXIT, SourceType.EXIT, Arrays.asList("cxlLength", "cxlCapacity", "tensionCxl")),
|
||||
CXL2(17, "Exit Looper #2", 870.899, SectionType.EXIT, SourceType.EXIT, Arrays.asList("cxlLength", "cxlCapacity", "tensionCxl")),
|
||||
// INS(18, "Inspection Station", 940.561, SectionType.EXIT, SourceType.EXIT, Arrays.asList("inspectionStatus")),
|
||||
TR(19, "Recoiler", 952.819, SectionType.EXIT, SourceType.EXIT, Arrays.asList("coilLength", "speedExitSection", "tensionBr9Tr")),
|
||||
EXC(20, "Coil Car", 9999999.0, SectionType.EXIT, SourceType.EXIT, Collections.emptyList()),
|
||||
WEIGHT(21, "Weighing Saddle", 9999999.0, SectionType.EXIT, SourceType.EXIT, Collections.emptyList());
|
||||
TR(18, "Recoiler", 934.929, SectionType.EXIT, SourceType.EXIT, Arrays.asList("coilLength", "speedExitSection", "tensionBr9Tr")),
|
||||
EXC(19, "Coil Car", 9999999.0, SectionType.EXIT, SourceType.EXIT, Collections.emptyList()),
|
||||
WEIGHT(20, "Weighing Saddle", 9999999.0, SectionType.EXIT, SourceType.EXIT, Collections.emptyList());
|
||||
|
||||
private final int idx;
|
||||
private final String desc;
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.fizz.business.service.CrmPdiPlanService;
|
||||
import com.fizz.business.comm.OPC.OpcMessageSend;
|
||||
import com.fizz.business.service.client.RedisCacheManager;
|
||||
import com.fizz.business.service.impl.BeanFactory;
|
||||
import com.fizz.business.service.strip.SegmentTrackerService;
|
||||
import com.fizz.business.utils.MatmapUtil;
|
||||
import com.fizz.business.utils.WebSocketUtil;
|
||||
import com.fizz.business.vo.CrmPdiPlanVO;
|
||||
@@ -40,6 +41,14 @@ public enum L1OperateMatEnum implements IEnum<String>, IOperateMat<L1OperateMatF
|
||||
MatmapUtil.setMatmap(form.getPorIdx(), form.getEntryMatId(), form.getPlanId(), form.getPlanNo());
|
||||
// 钢卷上线时, 缓存工艺规程
|
||||
// BeanFactory.getBean(RedisCacheManager.class).setCoilSetup(form.getPlanId());
|
||||
// ONLINE 时同步下发入口参数 + 张力下一设定值
|
||||
try {
|
||||
BeanFactory.getBean(SegmentTrackerService.class)
|
||||
.sendAllPdiOnOnline(form.getEntryMatId(), form.getPorIdx());
|
||||
} catch (Exception e) {
|
||||
BeanFactory.getBean(com.fizz.business.service.LogDataService.class)
|
||||
.logWarn("L1-ONLINE", "ONLINE下发异常, coilId={}, porIdx={}, err={}", form.getEntryMatId(), form.getPorIdx(), e.toString());
|
||||
}
|
||||
WebSocketUtil.sendSignalMsg(form);
|
||||
WebSocketUtil.sendMatmapMsg();
|
||||
}
|
||||
@@ -73,8 +82,6 @@ public enum L1OperateMatEnum implements IEnum<String>, IOperateMat<L1OperateMatF
|
||||
PRODUCT("生产完成") {
|
||||
@Override
|
||||
public void operate(L1OperateMatForm form) {
|
||||
log.error("==================================================================");
|
||||
log.error("form.planId={},entryMatId={}", form.getPlanId(), form.getEntryMatId());
|
||||
PRODUCT.syncPlanStatus(form.getPlanId(),form.getEntryMatId());
|
||||
WebSocketUtil.sendSignalMsg(form);
|
||||
}
|
||||
@@ -82,11 +89,11 @@ public enum L1OperateMatEnum implements IEnum<String>, IOperateMat<L1OperateMatF
|
||||
PAY_OVER("甩尾") {
|
||||
@Override
|
||||
public void operate(L1OperateMatForm form) {
|
||||
ArrayList<String> status = Lists.newArrayList(PlanStatusEnum.PRODUCING.name(), PlanStatusEnum.PRODUCT.name());
|
||||
// ArrayList<String> status = Lists.newArrayList(PlanStatusEnum.PRODUCING.name(), PlanStatusEnum.PRODUCT.name());
|
||||
CrmPdiPlanService planClient = BeanFactory.getBean(CrmPdiPlanService.class);
|
||||
CrmPdiPlanVO plan = planClient.getByCoilIdAndOperId(form.getEntryMatId());
|
||||
Assert.notNull(plan, "计划[{}]不存在", plan.getId());
|
||||
Assert.isTrue(status.contains(plan.getStatus()), "当前状态[{}]不支持甩尾", plan.getStatus());
|
||||
// Assert.isTrue(status.contains(plan.getStatus()), "当前状态[{}]不支持甩尾", plan.getStatus());
|
||||
MatmapUtil.clearMatmap(form.getPorIdx());
|
||||
WebSocketUtil.sendSignalMsg(form);
|
||||
WebSocketUtil.sendMatmapMsg();
|
||||
@@ -124,10 +131,14 @@ public enum L1OperateMatEnum implements IEnum<String>, IOperateMat<L1OperateMatF
|
||||
private void syncPlanStatus(String planId, String matId) {
|
||||
CrmPdiPlanService planClient = BeanFactory.getBean(CrmPdiPlanService.class);
|
||||
|
||||
planClient.changeStatus(ChangePlanStatusForm.builder()
|
||||
boolean ok = planClient.changeStatus(ChangePlanStatusForm.builder()
|
||||
.operation(this.name())
|
||||
.id(planId)
|
||||
.matId(matId)
|
||||
.build());
|
||||
|
||||
if (!ok) {
|
||||
throw new IllegalStateException(String.format("计划状态同步失败, operation=%s, planId=%s, matId=%s", this.name(), planId, matId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import java.util.Map;
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum WsTypeEnum {
|
||||
alarm, track_position, track_measure, track_signal, track_matmap,calc_setup_result;
|
||||
alarm, track_position, track_measure, track_signal, track_matmap, calc_setup_result, device_history_trend, device_chart_data, device_field_trend;
|
||||
|
||||
private static final Map<String, WsTypeEnum> MAP = new HashMap<>(8);
|
||||
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
package com.fizz.business.controller;
|
||||
|
||||
import com.fizz.business.domain.BizSendTemplate;
|
||||
import com.fizz.business.domain.BizSendTemplateItem;
|
||||
import com.fizz.business.domain.dto.SendTemplateItemsBatchSaveDTO;
|
||||
import com.fizz.business.domain.vo.BizSendTemplateVO;
|
||||
import com.fizz.business.service.IBizSendTemplateItemService;
|
||||
import com.fizz.business.service.IBizSendTemplateService;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 发送模板配置 Controller
|
||||
*/
|
||||
@@ -17,6 +25,9 @@ public class BizSendTemplateController extends BaseController {
|
||||
@Autowired
|
||||
private IBizSendTemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private IBizSendTemplateItemService templateItemService;
|
||||
|
||||
/**
|
||||
* 按模板编码获取模板(含明细)
|
||||
*/
|
||||
@@ -28,4 +39,55 @@ public class BizSendTemplateController extends BaseController {
|
||||
}
|
||||
return AjaxResult.success(vo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新模板主表(如 deviceName)
|
||||
*/
|
||||
@PutMapping
|
||||
public AjaxResult updateTemplate(@RequestBody BizSendTemplate template) {
|
||||
if (template == null || template.getTemplateId() == null) {
|
||||
return AjaxResult.error("templateId is required");
|
||||
}
|
||||
template.setUpdateBy(SecurityUtils.getUsername());
|
||||
template.setUpdateTime(new Date());
|
||||
return toAjax(templateService.updateById(template));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新模板明细(address/defaultValueRaw/enabled等)
|
||||
*/
|
||||
@PutMapping("/items")
|
||||
public AjaxResult updateTemplateItems(@RequestBody List<BizSendTemplateItem> items) {
|
||||
if (items == null || items.isEmpty()) {
|
||||
return AjaxResult.success();
|
||||
}
|
||||
Date now = new Date();
|
||||
String username = SecurityUtils.getUsername();
|
||||
for (BizSendTemplateItem it : items) {
|
||||
it.setUpdateBy(username);
|
||||
it.setUpdateTime(now);
|
||||
}
|
||||
return toAjax(templateItemService.updateItemsBatch(items));
|
||||
}
|
||||
|
||||
/**
|
||||
* 模板明细批量保存(新增/更新/删除)
|
||||
*/
|
||||
@PutMapping("/items/batchSave")
|
||||
public AjaxResult batchSaveItems(@RequestBody SendTemplateItemsBatchSaveDTO dto) {
|
||||
if (dto == null || dto.getTemplateId() == null) {
|
||||
return AjaxResult.error("templateId is required");
|
||||
}
|
||||
try {
|
||||
Boolean ok = templateItemService.batchSave(
|
||||
dto.getTemplateId(),
|
||||
dto.getItems(),
|
||||
dto.getDeleteIds(),
|
||||
SecurityUtils.getUsername()
|
||||
);
|
||||
return toAjax(ok);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@ import com.fizz.business.domain.CrmPdoExcoil;
|
||||
import com.fizz.business.form.CrmPdoExcoilForm;
|
||||
import com.fizz.business.service.CrmPdoExcoilService;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -16,7 +18,7 @@ import java.util.List;
|
||||
@RequestMapping("/api/pdo")
|
||||
@Tag(name ="实绩管理")
|
||||
@Anonymous
|
||||
public class CrmPdoExcoilController {
|
||||
public class CrmPdoExcoilController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private CrmPdoExcoilService crmPdoExcoilService;
|
||||
@@ -48,7 +50,16 @@ public class CrmPdoExcoilController {
|
||||
|
||||
@PostMapping("/list")
|
||||
@Operation(summary ="查询实绩列表")
|
||||
public R<List<CrmPdoExcoil>> list(@RequestBody CrmPdoExcoilForm form) {
|
||||
return R.ok(crmPdoExcoilService.listAll(form));
|
||||
public TableDataInfo list(@RequestBody CrmPdoExcoilForm form) {
|
||||
// 设置分页参数,默认每页20条
|
||||
if (form.getPageNum() == null || form.getPageNum() < 1) {
|
||||
form.setPageNum(1);
|
||||
}
|
||||
if (form.getPageSize() == null || form.getPageSize() < 1) {
|
||||
form.setPageSize(20);
|
||||
}
|
||||
com.github.pagehelper.PageHelper.startPage(form.getPageNum(), form.getPageSize());
|
||||
List<CrmPdoExcoil> list = crmPdoExcoilService.listAll(form);
|
||||
return getDataTable(list);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.fizz.business.controller;
|
||||
|
||||
import com.fizz.business.constants.enums.DeviceEnum;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.Data;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/deviceEnum")
|
||||
@Tag(name = "设备枚举")
|
||||
@Anonymous
|
||||
public class DeviceEnumController {
|
||||
|
||||
@GetMapping("/all")
|
||||
@Operation(description = "获取DeviceEnum全量定义(用于前端动态渲染)")
|
||||
public R<List<DeviceDefVO>> all() {
|
||||
List<DeviceDefVO> list = Arrays.stream(DeviceEnum.values())
|
||||
.map(DeviceDefVO::from)
|
||||
.collect(Collectors.toList());
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class DeviceDefVO {
|
||||
private String deviceCode; // DeviceEnum.name()
|
||||
private Integer idx;
|
||||
private String desc;
|
||||
private Double basePosition;
|
||||
private String sectionType;
|
||||
private String sourceType;
|
||||
private List<String> paramFields;
|
||||
|
||||
public static DeviceDefVO from(DeviceEnum e) {
|
||||
DeviceDefVO vo = new DeviceDefVO();
|
||||
vo.setDeviceCode(e.name());
|
||||
vo.setIdx(e.getIdx());
|
||||
vo.setDesc(e.getDesc());
|
||||
vo.setBasePosition(e.getBasePosition());
|
||||
vo.setSectionType(e.getSectionType().name());
|
||||
vo.setSourceType(e.getSourceType().name());
|
||||
vo.setParamFields(e.getParamFields());
|
||||
return vo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.fizz.business.controller;
|
||||
|
||||
import com.fizz.business.domain.msg.AppMeasureCoatMessage;
|
||||
import com.fizz.business.domain.msg.AppMeasureEntryMessage;
|
||||
import com.fizz.business.domain.msg.AppMeasureExitMessage;
|
||||
import com.fizz.business.domain.msg.AppMeasureFurnaceMessage;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.Data;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/deviceFieldMeta")
|
||||
@Tag(name = "设备字段元数据")
|
||||
@Anonymous
|
||||
public class DeviceFieldMetaController {
|
||||
|
||||
@GetMapping("/all")
|
||||
@Operation(description = "获取测量字段的友好文案(来自 @Schema(description))")
|
||||
public R<Map<String, FieldMetaVO>> all() {
|
||||
Map<String, FieldMetaVO> map = new HashMap<>();
|
||||
// 4个消息类全扫一遍
|
||||
collect(map, AppMeasureEntryMessage.class);
|
||||
collect(map, AppMeasureFurnaceMessage.class);
|
||||
collect(map, AppMeasureCoatMessage.class);
|
||||
collect(map, AppMeasureExitMessage.class);
|
||||
return R.ok(map);
|
||||
}
|
||||
|
||||
private void collect(Map<String, FieldMetaVO> map, Class<?> clazz) {
|
||||
for (Field f : clazz.getDeclaredFields()) {
|
||||
String fieldName = f.getName();
|
||||
Schema schema = f.getAnnotation(Schema.class);
|
||||
if (schema == null) continue;
|
||||
|
||||
String desc = schema.description();
|
||||
if (desc == null || desc.trim().isEmpty()) continue;
|
||||
|
||||
FieldMetaVO vo = new FieldMetaVO();
|
||||
vo.setLabel(parseLabel(desc));
|
||||
vo.setUnit(parseUnit(desc));
|
||||
vo.setDescription(desc);
|
||||
map.putIfAbsent(fieldName, vo);
|
||||
}
|
||||
}
|
||||
|
||||
// 例:"上层平均涂层重量 (g/m²)" -> label=上层平均涂层重量
|
||||
private String parseLabel(String desc) {
|
||||
int idx = desc.indexOf('(');
|
||||
if (idx > 0) return desc.substring(0, idx).trim();
|
||||
idx = desc.indexOf('(');
|
||||
if (idx > 0) return desc.substring(0, idx).trim();
|
||||
return desc.trim();
|
||||
}
|
||||
|
||||
// 例:"上层平均涂层重量 (g/m²)" -> unit=g/m²
|
||||
private String parseUnit(String desc) {
|
||||
int l = desc.indexOf('(');
|
||||
int r = desc.indexOf(')');
|
||||
if (l >= 0 && r > l) return desc.substring(l + 1, r).trim();
|
||||
l = desc.indexOf('(');
|
||||
r = desc.indexOf(')');
|
||||
if (l >= 0 && r > l) return desc.substring(l + 1, r).trim();
|
||||
return "";
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class FieldMetaVO {
|
||||
private String label;
|
||||
private String unit;
|
||||
private String description;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.fizz.business.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.fizz.business.domain.DeviceSnapshot;
|
||||
import com.fizz.business.mapper.DeviceSnapshotMapper;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/deviceSnapshot")
|
||||
@Tag(name = "设备数据快照")
|
||||
@Anonymous
|
||||
@RequiredArgsConstructor
|
||||
public class DeviceSnapshotController {
|
||||
|
||||
private final DeviceSnapshotMapper deviceSnapshotMapper;
|
||||
|
||||
@GetMapping("/latest")
|
||||
@Operation(description = "获取最新N条设备快照(可按deviceCode过滤)")
|
||||
public R<List<DeviceSnapshot>> latest(@RequestParam(value = "limit", defaultValue = "60") Integer limit,
|
||||
@RequestParam(value = "deviceCode", required = false) String deviceCode) {
|
||||
LambdaQueryWrapper<DeviceSnapshot> qw = new LambdaQueryWrapper<DeviceSnapshot>()
|
||||
.orderByDesc(DeviceSnapshot::getCreateTime)
|
||||
.last("limit " + Math.max(1, Math.min(limit, 500)));
|
||||
|
||||
if (deviceCode != null && !deviceCode.isEmpty()) {
|
||||
qw.eq(DeviceSnapshot::getDeviceCode, deviceCode);
|
||||
}
|
||||
|
||||
return R.ok(deviceSnapshotMapper.selectList(qw));
|
||||
}
|
||||
|
||||
@GetMapping("/range")
|
||||
@Operation(description = "按时间范围查询设备快照(可按deviceCode过滤)")
|
||||
public R<List<DeviceSnapshot>> range(@RequestParam("start") String start,
|
||||
@RequestParam("end") String end,
|
||||
@RequestParam(value = "deviceCode", required = false) String deviceCode) {
|
||||
LocalDateTime startTime = LocalDateTime.parse(start);
|
||||
LocalDateTime endTime = LocalDateTime.parse(end);
|
||||
|
||||
LambdaQueryWrapper<DeviceSnapshot> qw = new LambdaQueryWrapper<DeviceSnapshot>()
|
||||
.between(DeviceSnapshot::getCreateTime, startTime, endTime)
|
||||
.orderByAsc(DeviceSnapshot::getCreateTime);
|
||||
|
||||
if (deviceCode != null && !deviceCode.isEmpty()) {
|
||||
qw.eq(DeviceSnapshot::getDeviceCode, deviceCode);
|
||||
}
|
||||
|
||||
return R.ok(deviceSnapshotMapper.selectList(qw));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.fizz.business.controller;
|
||||
|
||||
import com.fizz.business.form.OpcBatchWriteDataForm;
|
||||
import com.fizz.business.form.OpcWriteDataForm;
|
||||
import com.fizz.business.service.OpcDataService;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* OPC 数据读写控制器
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/api/opc/data")
|
||||
@Tag(name = "OPC 数据读写")
|
||||
@ConditionalOnProperty(prefix = "kangaroohy.milo", name = "enabled", havingValue = "true")
|
||||
@Anonymous
|
||||
public class OpcDataController {
|
||||
|
||||
private final OpcDataService opcDataService;
|
||||
|
||||
/**
|
||||
* 向单个点位写入数据(通过字段名)
|
||||
*/
|
||||
@Operation(summary = "向单个点位写入数据", description = "通过字段名向指定的 OPC 点位写入数据")
|
||||
@PostMapping("/write")
|
||||
public R<?> writeData(@Valid @RequestBody OpcWriteDataForm form) {
|
||||
try {
|
||||
boolean success = opcDataService.writeData(form);
|
||||
if (success) {
|
||||
return R.ok("写入成功");
|
||||
} else {
|
||||
return R.fail("写入失败,可能是字段名未找到对应的 OPC 节点路径,请查看日志");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("写入 OPC 数据异常", e);
|
||||
return R.fail("写入异常:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量向多个点位写入数据(通过字段名)
|
||||
*/
|
||||
@Operation(summary = "批量向多个点位写入数据", description = "通过字段名向多个 OPC 点位批量写入数据")
|
||||
@PostMapping("/batchWrite")
|
||||
public R<?> batchWriteData(@Valid @RequestBody OpcBatchWriteDataForm form) {
|
||||
try {
|
||||
boolean success = opcDataService.batchWriteData(form);
|
||||
if (success) {
|
||||
return R.ok("批量写入成功,共 " + form.getDataList().size() + " 个点位");
|
||||
} else {
|
||||
return R.fail("批量写入失败,可能是部分字段名未找到对应的 OPC 节点路径,请查看日志");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("批量写入 OPC 数据异常", e);
|
||||
return R.fail("批量写入异常:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.fizz.business.service.IPdiSetupService;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
@@ -12,13 +11,12 @@ import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.fizz.business.domain.PdiSetups;
|
||||
import com.fizz.business.service.IPdiSetupService;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 生产计划的参数详情Controller
|
||||
*
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-09-25
|
||||
*/
|
||||
@@ -53,12 +51,12 @@ public class PdiSetupController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取生产计划的参数详情详细信息
|
||||
* 获取张力参数详细信息
|
||||
*/
|
||||
@GetMapping(value = "/{id}")
|
||||
public AjaxResult getInfo(@PathVariable("id") Long id)
|
||||
{
|
||||
return success(pdiSetupService.selectPdiSetupByid(id));
|
||||
return success(pdiSetupService.selectPdiSetupById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,12 +80,12 @@ public class PdiSetupController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除生产计划的参数详情
|
||||
* 删除张力参数
|
||||
*/
|
||||
@Log(title = "生产计划的参数详情", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
@Log(title = "张力参数", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public AjaxResult remove(@PathVariable Long[] ids)
|
||||
{
|
||||
return toAjax(pdiSetupService.deletePdiSetupByids(ids));
|
||||
return toAjax(pdiSetupService.deletePdiSetupByIds(ids));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.fizz.business.controller;
|
||||
import com.fizz.business.domain.ProStoppage;
|
||||
import com.fizz.business.form.ProStoppageForm;
|
||||
import com.fizz.business.service.ProStoppageService;
|
||||
import com.fizz.business.service.ProStoppageTypeService;
|
||||
import com.fizz.business.domain.vo.ProStoppageTypeVO;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@@ -22,6 +24,9 @@ public class ProStoppageController {
|
||||
@Resource
|
||||
private ProStoppageService proStoppageService;
|
||||
|
||||
@Resource
|
||||
private ProStoppageTypeService proStoppageTypeService;
|
||||
|
||||
// @PostMapping("/add")
|
||||
// @ApiOperation("新增停机记录")
|
||||
// public R<Boolean> add(@RequestBody ProStoppage proStoppage) {
|
||||
@@ -51,4 +56,15 @@ public class ProStoppageController {
|
||||
public R<List<Object>> calc(@RequestBody ProStoppageForm form) {
|
||||
return R.ok(proStoppageService.calc(form));
|
||||
}
|
||||
|
||||
@GetMapping("/types")
|
||||
@Operation(summary = "查询停机类型")
|
||||
public R<List<ProStoppageTypeVO>> types() {
|
||||
return R.ok(proStoppageTypeService.listAll().stream().map(item -> {
|
||||
ProStoppageTypeVO vo = new ProStoppageTypeVO();
|
||||
vo.setStopType(item.getStopType());
|
||||
vo.setRemark(item.getRemark());
|
||||
return vo;
|
||||
}).collect(java.util.stream.Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,11 @@ import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.fizz.business.domain.vo.FurnaceSendCoilInfoVO;
|
||||
import com.fizz.business.domain.vo.SendJobLastSuccessVO;
|
||||
import com.fizz.business.service.ISendJobQueryService;
|
||||
import com.fizz.business.utils.RedisUtil;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -87,4 +90,24 @@ public class SendJobController extends BaseController {
|
||||
SendJobLastSuccessVO vo = sendJobQueryService.getLastSuccess(groupType);
|
||||
return AjaxResult.success(vo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上次炉火写入的钢卷信息
|
||||
* @return 上次写入的钢卷信息(coilId、planId、sendTime)
|
||||
*/
|
||||
@GetMapping("/furnace/lastCoilInfo")
|
||||
public AjaxResult getLastFurnaceSendCoilInfo() {
|
||||
try {
|
||||
String jsonValue = RedisUtil.getValue("furnace:send:coil:info");
|
||||
if (jsonValue == null || jsonValue.isEmpty()) {
|
||||
return AjaxResult.success(null);
|
||||
}
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
FurnaceSendCoilInfoVO coilInfo = objectMapper.readValue(jsonValue, FurnaceSendCoilInfoVO.class);
|
||||
return AjaxResult.success(coilInfo);
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error("Failed to obtain the information of the last furnace fire to write the coil: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.fizz.business.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.fizz.business.domain.SetupTensionAllLine;
|
||||
import com.fizz.business.service.ISetupTensionAllLineService;
|
||||
|
||||
/**
|
||||
* 全线张力Controller(无权限控制)
|
||||
*
|
||||
* 三主键:steelGrade + thick + yieldStren
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/business/tension/all-line")
|
||||
@Anonymous
|
||||
public class SetupTensionAllLineController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISetupTensionAllLineService service;
|
||||
|
||||
/**
|
||||
* 查询全线张力列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SetupTensionAllLine query)
|
||||
{
|
||||
startPage();
|
||||
List<SetupTensionAllLine> list = service.selectList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全线张力详细信息(按三主键)
|
||||
*/
|
||||
@GetMapping
|
||||
public AjaxResult getInfo(@RequestParam("steelGrade") String steelGrade,
|
||||
@RequestParam("thick") Float thick,
|
||||
@RequestParam("yieldStren") Float yieldStren)
|
||||
{
|
||||
return success(service.selectByKey(steelGrade, thick, yieldStren));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增全线张力
|
||||
*/
|
||||
@Log(title = "全线张力", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody SetupTensionAllLine entity)
|
||||
{
|
||||
return toAjax(service.insert(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改全线张力(按三主键定位)
|
||||
*/
|
||||
@Log(title = "全线张力", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody SetupTensionAllLine entity)
|
||||
{
|
||||
return toAjax(service.updateByKey(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除全线张力(按三主键)
|
||||
*/
|
||||
@Log(title = "全线张力", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping
|
||||
public AjaxResult remove(@RequestParam("steelGrade") String steelGrade,
|
||||
@RequestParam("thick") Float thick,
|
||||
@RequestParam("yieldStren") Float yieldStren)
|
||||
{
|
||||
return toAjax(service.deleteByKey(steelGrade, thick, yieldStren));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.fizz.business.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.fizz.business.domain.SetupTensionAnnealingFurnace;
|
||||
import com.fizz.business.service.ISetupTensionAnnealingFurnaceService;
|
||||
|
||||
/**
|
||||
* 退火炉张力Controller(无权限控制)
|
||||
*
|
||||
* 三主键:steelGrade + thick + yieldStren
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/business/tension/annealing-furnace")
|
||||
@Anonymous
|
||||
public class SetupTensionAnnealingFurnaceController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISetupTensionAnnealingFurnaceService service;
|
||||
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SetupTensionAnnealingFurnace query)
|
||||
{
|
||||
startPage();
|
||||
List<SetupTensionAnnealingFurnace> list = service.selectList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public AjaxResult getInfo(@RequestParam("steelGrade") String steelGrade,
|
||||
@RequestParam("thick") Float thick,
|
||||
@RequestParam("yieldStren") Float yieldStren)
|
||||
{
|
||||
return success(service.selectByKey(steelGrade, thick, yieldStren));
|
||||
}
|
||||
|
||||
@Log(title = "退火炉张力", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody SetupTensionAnnealingFurnace entity)
|
||||
{
|
||||
return toAjax(service.insert(entity));
|
||||
}
|
||||
|
||||
@Log(title = "退火炉张力", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody SetupTensionAnnealingFurnace entity)
|
||||
{
|
||||
return toAjax(service.updateByKey(entity));
|
||||
}
|
||||
|
||||
@Log(title = "退火炉张力", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping
|
||||
public AjaxResult remove(@RequestParam("steelGrade") String steelGrade,
|
||||
@RequestParam("thick") Float thick,
|
||||
@RequestParam("yieldStren") Float yieldStren)
|
||||
{
|
||||
return toAjax(service.deleteByKey(steelGrade, thick, yieldStren));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
package com.fizz.business.controller;
|
||||
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.fizz.business.form.TensionDeleteForm;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.fizz.business.domain.SetupTension;
|
||||
import com.fizz.business.service.ISetupTensionService;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 全线张力Controller
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-26
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/business/tension")
|
||||
public class SetupTensionController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISetupTensionService setupTensionService;
|
||||
|
||||
/**
|
||||
* 查询全线张力列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SetupTension setupTension)
|
||||
{
|
||||
startPage();
|
||||
List<SetupTension> list = setupTensionService.selectSetupTensionList(setupTension);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出全线张力列表
|
||||
*/
|
||||
@Log(title = "全线张力", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, SetupTension setupTension)
|
||||
{
|
||||
List<SetupTension> list = setupTensionService.selectSetupTensionList(setupTension);
|
||||
ExcelUtil<SetupTension> util = new ExcelUtil<SetupTension>(SetupTension.class);
|
||||
util.exportExcel(response, list, "全线张力数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全线张力详细信息
|
||||
*/
|
||||
@GetMapping()
|
||||
public AjaxResult getInfo(@RequestParam(required = false) Long thick ,@RequestParam(required = false) Long yieldStren)
|
||||
{
|
||||
return success(setupTensionService.selectSetupTensionByThick(thick, yieldStren));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增全线张力
|
||||
*/
|
||||
@Log(title = "全线张力", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody SetupTension setupTension)
|
||||
{
|
||||
return toAjax(setupTensionService.insertSetupTension(setupTension));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改全线张力
|
||||
*/
|
||||
@Log(title = "全线张力", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody SetupTension setupTension)
|
||||
{
|
||||
return toAjax(setupTensionService.updateSetupTension(setupTension));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除全线张力
|
||||
*/
|
||||
@Log(title = "全线张力", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/tension") // 建议添加路径区分不同删除接口
|
||||
public AjaxResult removeTension(@RequestBody TensionDeleteForm form) {
|
||||
return toAjax(setupTensionService.deleteSetupTensionByThicks(
|
||||
form.getThicks(),
|
||||
form.getYieldStrens()
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.fizz.business.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.fizz.business.domain.SetupTensionLeveler;
|
||||
import com.fizz.business.service.ISetupTensionLevelerService;
|
||||
|
||||
/**
|
||||
* 平整机张力Controller(无权限控制)
|
||||
*
|
||||
* 三主键:steelGrade + thick + yieldStren
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/business/tension/leveler")
|
||||
@Anonymous
|
||||
public class SetupTensionLevelerController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISetupTensionLevelerService service;
|
||||
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SetupTensionLeveler query)
|
||||
{
|
||||
startPage();
|
||||
List<SetupTensionLeveler> list = service.selectList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public AjaxResult getInfo(@RequestParam("steelGrade") String steelGrade,
|
||||
@RequestParam("thick") Float thick,
|
||||
@RequestParam("yieldStren") Float yieldStren)
|
||||
{
|
||||
return success(service.selectByKey(steelGrade, thick, yieldStren));
|
||||
}
|
||||
|
||||
@Log(title = "平整机张力", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody SetupTensionLeveler entity)
|
||||
{
|
||||
return toAjax(service.insert(entity));
|
||||
}
|
||||
|
||||
@Log(title = "平整机张力", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody SetupTensionLeveler entity)
|
||||
{
|
||||
return toAjax(service.updateByKey(entity));
|
||||
}
|
||||
|
||||
@Log(title = "平整机张力", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping
|
||||
public AjaxResult remove(@RequestParam("steelGrade") String steelGrade,
|
||||
@RequestParam("thick") Float thick,
|
||||
@RequestParam("yieldStren") Float yieldStren)
|
||||
{
|
||||
return toAjax(service.deleteByKey(steelGrade, thick, yieldStren));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.fizz.business.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.fizz.business.domain.SetupTensionStraightener;
|
||||
import com.fizz.business.service.ISetupTensionStraightenerService;
|
||||
|
||||
/**
|
||||
* 矫直机张力Controller(无权限控制)
|
||||
*
|
||||
* 三主键:steelGrade + thick + yieldStren
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/business/tension/straightener")
|
||||
@Anonymous
|
||||
public class SetupTensionStraightenerController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISetupTensionStraightenerService service;
|
||||
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SetupTensionStraightener query)
|
||||
{
|
||||
startPage();
|
||||
List<SetupTensionStraightener> list = service.selectList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public AjaxResult getInfo(@RequestParam("steelGrade") String steelGrade,
|
||||
@RequestParam("thick") Float thick,
|
||||
@RequestParam("yieldStren") Float yieldStren)
|
||||
{
|
||||
return success(service.selectByKey(steelGrade, thick, yieldStren));
|
||||
}
|
||||
|
||||
@Log(title = "矫直机张力", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody SetupTensionStraightener entity)
|
||||
{
|
||||
return toAjax(service.insert(entity));
|
||||
}
|
||||
|
||||
@Log(title = "矫直机张力", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody SetupTensionStraightener entity)
|
||||
{
|
||||
return toAjax(service.updateByKey(entity));
|
||||
}
|
||||
|
||||
@Log(title = "矫直机张力", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping
|
||||
public AjaxResult remove(@RequestParam("steelGrade") String steelGrade,
|
||||
@RequestParam("thick") Float thick,
|
||||
@RequestParam("yieldStren") Float yieldStren)
|
||||
{
|
||||
return toAjax(service.deleteByKey(steelGrade, thick, yieldStren));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
package com.fizz.business.controller;
|
||||
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.fizz.business.form.TlDeleteForm;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.fizz.business.domain.SetupTl;
|
||||
import com.fizz.business.service.ISetupTlService;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 拉矫机参数Controller
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-26
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/business/tl")
|
||||
public class SetupTlController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISetupTlService setupTlService;
|
||||
|
||||
/**
|
||||
* 查询拉矫机参数列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SetupTl setupTl)
|
||||
{
|
||||
startPage();
|
||||
List<SetupTl> list = setupTlService.selectSetupTlList(setupTl);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出拉矫机参数列表
|
||||
*/
|
||||
@Log(title = "拉矫机参数", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, SetupTl setupTl)
|
||||
{
|
||||
List<SetupTl> list = setupTlService.selectSetupTlList(setupTl);
|
||||
ExcelUtil<SetupTl> util = new ExcelUtil<SetupTl>(SetupTl.class);
|
||||
util.exportExcel(response, list, "拉矫机参数数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取拉矫机参数详细信息
|
||||
*/
|
||||
@GetMapping()
|
||||
public AjaxResult getInfo(@RequestParam String steelGrade,
|
||||
@RequestParam Long yieldStren,
|
||||
@RequestParam Long thick)
|
||||
{
|
||||
return success(setupTlService.selectSetupTlBySteelGrade(steelGrade, yieldStren, thick));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增拉矫机参数
|
||||
*/
|
||||
@Log(title = "拉矫机参数", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody SetupTl setupTl)
|
||||
{
|
||||
return toAjax(setupTlService.insertSetupTl(setupTl));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改拉矫机参数
|
||||
*/
|
||||
@Log(title = "拉矫机参数", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody SetupTl setupTl)
|
||||
{
|
||||
return toAjax(setupTlService.updateSetupTl(setupTl));
|
||||
}
|
||||
|
||||
// 拉矫机参数删除接口
|
||||
@Log(title = "拉矫机参数", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/tl") // 不同路径区分
|
||||
public AjaxResult removeTl(@RequestBody TlDeleteForm form) {
|
||||
return toAjax(setupTlService.deleteSetupTlBySteelGrades(
|
||||
form.getSteelGrades(),
|
||||
form.getYieldStrens(),
|
||||
form.getThicks()
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
package com.fizz.business.controller;
|
||||
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.fizz.business.form.TmBendforceDeleteForm;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.fizz.business.domain.SetupTmBendforce;
|
||||
import com.fizz.business.service.ISetupTmBendforceService;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 光整机弯辊力Controller
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-09-26
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/business/bendforce")
|
||||
public class SetupTmBendforceController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISetupTmBendforceService setupTmBendforceService;
|
||||
|
||||
/**
|
||||
* 查询光整机弯辊力列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SetupTmBendforce setupTmBendforce)
|
||||
{
|
||||
startPage();
|
||||
List<SetupTmBendforce> list = setupTmBendforceService.selectSetupTmBendforceList(setupTmBendforce);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出光整机弯辊力列表
|
||||
*/
|
||||
@Log(title = "光整机弯辊力", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, SetupTmBendforce setupTmBendforce)
|
||||
{
|
||||
List<SetupTmBendforce> list = setupTmBendforceService.selectSetupTmBendforceList(setupTmBendforce);
|
||||
ExcelUtil<SetupTmBendforce> util = new ExcelUtil<SetupTmBendforce>(SetupTmBendforce.class);
|
||||
util.exportExcel(response, list, "光整机弯辊力数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取光整机弯辊力详细信息
|
||||
*/
|
||||
@GetMapping()
|
||||
public AjaxResult getInfo(@RequestParam Long width,
|
||||
@RequestParam Long rollForce)
|
||||
{
|
||||
return success(setupTmBendforceService.selectSetupTmBendforceByWidth(width,rollForce));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增光整机弯辊力
|
||||
*/
|
||||
@Log(title = "光整机弯辊力", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody SetupTmBendforce setupTmBendforce)
|
||||
{
|
||||
return toAjax(setupTmBendforceService.insertSetupTmBendforce(setupTmBendforce));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改光整机弯辊力
|
||||
*/
|
||||
@Log(title = "光整机弯辊力", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody SetupTmBendforce setupTmBendforce)
|
||||
{
|
||||
return toAjax(setupTmBendforceService.updateSetupTmBendforce(setupTmBendforce));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除光整机弯辊力
|
||||
*/
|
||||
@Log(title = "光整机弯辊力", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/tm/bendforce")
|
||||
public AjaxResult removeTmBendforce(@RequestBody TmBendforceDeleteForm form) {
|
||||
return toAjax(setupTmBendforceService.deleteSetupTmBendforceByWidths(
|
||||
form.getWidths(),
|
||||
form.getRollForces()
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
package com.fizz.business.controller;
|
||||
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.fizz.business.form.TmMeshDeleteForm;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.fizz.business.domain.SetupTmMesh;
|
||||
import com.fizz.business.service.ISetupTmMeshService;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 光整机插入量Controller
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-09-26
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/business/mesh")
|
||||
public class SetupTmMeshController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISetupTmMeshService setupTmMeshService;
|
||||
|
||||
/**
|
||||
* 查询光整机插入量列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SetupTmMesh setupTmMesh)
|
||||
{
|
||||
startPage();
|
||||
List<SetupTmMesh> list = setupTmMeshService.selectSetupTmMeshList(setupTmMesh);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出光整机插入量列表
|
||||
*/
|
||||
@Log(title = "光整机插入量", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, SetupTmMesh setupTmMesh)
|
||||
{
|
||||
List<SetupTmMesh> list = setupTmMeshService.selectSetupTmMeshList(setupTmMesh);
|
||||
ExcelUtil<SetupTmMesh> util = new ExcelUtil<SetupTmMesh>(SetupTmMesh.class);
|
||||
util.exportExcel(response, list, "光整机插入量数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取光整机插入量详细信息
|
||||
*/
|
||||
@GetMapping()
|
||||
public AjaxResult getInfo(@RequestParam String steelGrade,
|
||||
@RequestParam Long yieldStren,
|
||||
@RequestParam Long thick)
|
||||
{
|
||||
return success(setupTmMeshService.selectSetupTmMeshBySteelGrade(steelGrade, yieldStren, thick));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增光整机插入量
|
||||
*/
|
||||
@Log(title = "光整机插入量", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody SetupTmMesh setupTmMesh)
|
||||
{
|
||||
return toAjax(setupTmMeshService.insertSetupTmMesh(setupTmMesh));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改光整机插入量
|
||||
*/
|
||||
@Log(title = "光整机插入量", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody SetupTmMesh setupTmMesh)
|
||||
{
|
||||
return toAjax(setupTmMeshService.updateSetupTmMesh(setupTmMesh));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除光整机插入量
|
||||
*/
|
||||
@Log(title = "光整机插入量", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/tm/mesh")
|
||||
public AjaxResult removeTmMesh(@RequestBody TmMeshDeleteForm form) {
|
||||
return toAjax(setupTmMeshService.deleteSetupTmMeshBySteelGrades(
|
||||
form.getSteelGrades(),
|
||||
form.getYieldStrens(),
|
||||
form.getThicks()
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
package com.fizz.business.controller;
|
||||
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.fizz.business.form.TmRollforceDeleteForm;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.fizz.business.domain.SetupTmRollforce;
|
||||
import com.fizz.business.service.ISetupTmRollforceService;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 光整机轧制力Controller
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-09-26
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/business/rollforce")
|
||||
public class SetupTmRollforceController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISetupTmRollforceService setupTmRollforceService;
|
||||
|
||||
/**
|
||||
* 查询光整机轧制力列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SetupTmRollforce setupTmRollforce)
|
||||
{
|
||||
startPage();
|
||||
List<SetupTmRollforce> list = setupTmRollforceService.selectSetupTmRollforceList(setupTmRollforce);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出光整机轧制力列表
|
||||
*/
|
||||
@Log(title = "光整机轧制力", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, SetupTmRollforce setupTmRollforce)
|
||||
{
|
||||
List<SetupTmRollforce> list = setupTmRollforceService.selectSetupTmRollforceList(setupTmRollforce);
|
||||
ExcelUtil<SetupTmRollforce> util = new ExcelUtil<SetupTmRollforce>(SetupTmRollforce.class);
|
||||
util.exportExcel(response, list, "光整机轧制力数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取光整机轧制力详细信息
|
||||
*/
|
||||
@GetMapping()
|
||||
public AjaxResult getInfo(@RequestParam String steelGrade,
|
||||
@RequestParam Long yieldStren,
|
||||
@RequestParam Long thick,
|
||||
@RequestParam Long elong)
|
||||
{
|
||||
return success(setupTmRollforceService.selectSetupTmRollforceBySteelGrade(steelGrade, yieldStren, thick, elong));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增光整机轧制力
|
||||
*/
|
||||
@Log(title = "光整机轧制力", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody SetupTmRollforce setupTmRollforce)
|
||||
{
|
||||
return toAjax(setupTmRollforceService.insertSetupTmRollforce(setupTmRollforce));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改光整机轧制力
|
||||
*/
|
||||
@Log(title = "光整机轧制力", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody SetupTmRollforce setupTmRollforce)
|
||||
{
|
||||
return toAjax(setupTmRollforceService.updateSetupTmRollforce(setupTmRollforce));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除光整机轧制力
|
||||
*/
|
||||
@Log(title = "光整机轧制力", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/tm/rollforce")
|
||||
public AjaxResult removeTmRollforce(@RequestBody TmRollforceDeleteForm form) {
|
||||
return toAjax(setupTmRollforceService.deleteSetupTmRollforceBySteelGrades(
|
||||
form.getSteelGrades(),
|
||||
form.getThicks(),
|
||||
form.getYieldStrens(),
|
||||
form.getElongs()
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -47,5 +47,14 @@ public class BizSendJob extends BaseEntity {
|
||||
|
||||
/** 操作员姓名 */
|
||||
private String operatorName;
|
||||
|
||||
// 解决 BaseEntity 字段导致的未知列问题
|
||||
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
|
||||
private String searchValue;
|
||||
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
|
||||
private java.util.Map<String,Object> params;
|
||||
|
||||
// GroupType
|
||||
private String groupType;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,5 +36,11 @@ public class BizSendJobGroup extends BaseEntity {
|
||||
|
||||
/** 分组状态: PENDING, IN_PROGRESS, COMPLETED, FAILED */
|
||||
private String status;
|
||||
|
||||
// 解决 BaseEntity 字段导致的未知列问题
|
||||
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
|
||||
private String searchValue;
|
||||
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
|
||||
private java.util.Map<String,Object> params;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,5 +54,11 @@ public class BizSendJobItem extends BaseEntity {
|
||||
|
||||
/** 重试次数 */
|
||||
private Integer retryCount;
|
||||
|
||||
// 解决 BaseEntity 字段导致的未知列问题
|
||||
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
|
||||
private String searchValue;
|
||||
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
|
||||
private java.util.Map<String,Object> params;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,12 @@ public class BizSendTemplate extends BaseEntity {
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Integer templateId;
|
||||
|
||||
// 解决 MyBatis-Plus 父类字段映射导致的 search_value 报错
|
||||
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
|
||||
private String searchValue;
|
||||
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
|
||||
private java.util.Map<String,Object> params;
|
||||
|
||||
/** 模板编码 */
|
||||
private String templateCode;
|
||||
|
||||
|
||||
@@ -39,5 +39,11 @@ public class BizSendTemplateItem extends BaseEntity {
|
||||
|
||||
/** 是否启用 */
|
||||
private Integer enabled;
|
||||
|
||||
// 解决 BaseEntity 字段导致的未知列问题
|
||||
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
|
||||
private String searchValue;
|
||||
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
|
||||
private java.util.Map<String,Object> params;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.fizz.business.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 io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@TableName("device_snapshot")
|
||||
@Schema(description = "设备数据快照")
|
||||
public class DeviceSnapshot {
|
||||
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Schema(description = "主键")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "快照时间")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "设备idx,对应DeviceEnum.idx")
|
||||
private Integer deviceId;
|
||||
|
||||
@Schema(description = "设备枚举名,对应DeviceEnum.name()")
|
||||
private String deviceCode;
|
||||
|
||||
@Schema(description = "设备描述")
|
||||
private String deviceName;
|
||||
|
||||
@Schema(description = "段类型 ENTRY/PROCESS/EXIT")
|
||||
private String sectionType;
|
||||
|
||||
@Schema(description = "来源类型 ENTRY/FURNACE/COAT/EXIT")
|
||||
private String sourceType;
|
||||
|
||||
@Schema(description = "基准位置(m)")
|
||||
private Double basePosition;
|
||||
|
||||
@Schema(description = "快照数据JSON")
|
||||
private String snapshotData;
|
||||
}
|
||||
|
||||
@@ -5,162 +5,95 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 生产计划的参数详情对象 pdi_setup
|
||||
* 张力参数表对象 pdi_setup
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-09-25
|
||||
* 表主键为自增 id。
|
||||
*/
|
||||
@Data
|
||||
@TableName("pdi_setup")
|
||||
public class PdiSetups implements Serializable
|
||||
{
|
||||
public class PdiSetups implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 主键ID */
|
||||
@TableId(value = "ID", type = IdType.AUTO)
|
||||
/** 主键 */
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/** 钢卷号 */
|
||||
@Excel(name = "钢卷号")
|
||||
@TableField("COILID")
|
||||
private String coilid;
|
||||
|
||||
/** 计划号 */
|
||||
@Excel(name = "计划号")
|
||||
@TableField("PLANID")
|
||||
private String planid;
|
||||
|
||||
/** 钢种 */
|
||||
@Excel(name = "钢种")
|
||||
private String steelGrade;
|
||||
|
||||
/** 厚度 */
|
||||
@Excel(name = "厚度")
|
||||
private BigDecimal thick;
|
||||
|
||||
/** 屈服强度 */
|
||||
@Excel(name = "屈服强度")
|
||||
private BigDecimal yieldStren;
|
||||
|
||||
/** 开卷机张力 */
|
||||
@Excel(name = "开卷机张力")
|
||||
@TableField("POR_TENSION")
|
||||
private Long porTension;
|
||||
private BigDecimal porTension;
|
||||
|
||||
/** 入口活套张力 */
|
||||
@Excel(name = "入口活套张力")
|
||||
@TableField("CEL_TENSION")
|
||||
private Long celTension;
|
||||
private BigDecimal celTension;
|
||||
|
||||
/** 清洗段张力 */
|
||||
@Excel(name = "清洗段张力")
|
||||
@TableField("CLEAN_TENSION")
|
||||
private Long cleanTension;
|
||||
private BigDecimal cleanTension;
|
||||
|
||||
/** 炉区张力 */
|
||||
@Excel(name = "炉区张力")
|
||||
@TableField("FUR_TENSION")
|
||||
private Long furTension;
|
||||
|
||||
/** 冷却塔张力 */
|
||||
@Excel(name = "冷却塔张力")
|
||||
@TableField("TOWER_TENSION")
|
||||
private Long towerTension;
|
||||
|
||||
/** 光整机不投张力 */
|
||||
@Excel(name = "光整机不投张力")
|
||||
@TableField("TM_NONE_TENSION")
|
||||
private Long tmNoneTension;
|
||||
|
||||
/** 光整机入口张力 */
|
||||
@Excel(name = "光整机入口张力")
|
||||
@TableField("TM_ENTRY_TENSION")
|
||||
private Long tmEntryTension;
|
||||
|
||||
/** 光整机出口张力 */
|
||||
@Excel(name = "光整机出口张力")
|
||||
@TableField("TM_EXIT_TENSION")
|
||||
private Long tmExitTension;
|
||||
|
||||
/** 光整机轧制力 */
|
||||
@Excel(name = "光整机轧制力")
|
||||
@TableField("TM_ROLLFORCE")
|
||||
private Long tmRollforce;
|
||||
|
||||
/** 光整机弯辊力 */
|
||||
@Excel(name = "光整机弯辊力")
|
||||
@TableField("TM_BENDFORCE")
|
||||
private Long tmBendforce;
|
||||
|
||||
/** 光整机防皱辊插入量 */
|
||||
@Excel(name = "光整机防皱辊插入量")
|
||||
@TableField("TM_ACR_MESH")
|
||||
private Long tmAcrMesh;
|
||||
|
||||
/** 光整机防颤辊插入量 */
|
||||
@Excel(name = "光整机防颤辊插入量")
|
||||
@TableField("TM_BR_MESH")
|
||||
private Long tmBrMesh;
|
||||
|
||||
/** 拉矫机不投张力 */
|
||||
@Excel(name = "拉矫机不投张力")
|
||||
@TableField("TL_NONE_TENSION")
|
||||
private Long tlNoneTension;
|
||||
|
||||
/** 拉矫机出口张力 */
|
||||
@Excel(name = "拉矫机出口张力")
|
||||
@TableField("TL_EXIT_TENSION")
|
||||
private Long tlExitTension;
|
||||
|
||||
/** 拉矫机延伸率 */
|
||||
@Excel(name = "拉矫机延伸率")
|
||||
@TableField("TL_ELONG")
|
||||
private Long tlElong;
|
||||
|
||||
/** 拉矫机矫直辊插入量1 */
|
||||
@Excel(name = "拉矫机矫直辊插入量1")
|
||||
@TableField("TL_LVL_MESH1")
|
||||
private Long tlLvlMesh1;
|
||||
|
||||
/** 拉矫机矫直辊插入量2 */
|
||||
@Excel(name = "拉矫机矫直辊插入量2")
|
||||
@TableField("TL_LVL_MESH2")
|
||||
private Long tlLvlMesh2;
|
||||
|
||||
/** 拉矫机防横弓插入量 */
|
||||
@Excel(name = "拉矫机防横弓插入量")
|
||||
@TableField("TL_ACB_MESH")
|
||||
private Long tlAcbMesh;
|
||||
|
||||
/** 后处理张力 */
|
||||
@Excel(name = "后处理张力")
|
||||
@TableField("COAT_TENSION")
|
||||
private Long coatTension;
|
||||
/** 钝化段张力 */
|
||||
@Excel(name = "钝化段张力")
|
||||
private BigDecimal passivationTension;
|
||||
|
||||
/** 出口活套张力 */
|
||||
@Excel(name = "出口活套张力")
|
||||
@TableField("CXL_TENSION")
|
||||
private Long cxlTension;
|
||||
private BigDecimal cxlTension;
|
||||
|
||||
/** 卷取机张力 */
|
||||
@Excel(name = "卷取机张力")
|
||||
@TableField("TR_TENSION")
|
||||
private Long trTension;
|
||||
private BigDecimal trTension;
|
||||
|
||||
/** 类型,或可用于记录更改次数 */
|
||||
@Excel(name = "类型,或可用于记录更改次数")
|
||||
@TableField("TYPE")
|
||||
private Long type;
|
||||
/** 平整机入口张力 */
|
||||
@Excel(name = "平整机入口张力")
|
||||
private BigDecimal levelerEntryTension;
|
||||
|
||||
/** 预热段出口板温 */
|
||||
@Excel(name = "预热段出口板温")
|
||||
@TableField("PREHEATING_SECTION")
|
||||
private Float preheatingSection;
|
||||
/** 平整机出口张力 */
|
||||
@Excel(name = "平整机出口张力")
|
||||
private BigDecimal levelerExitTension;
|
||||
|
||||
/** 加热段出口板温 */
|
||||
@Excel(name = "加热段出口板温")
|
||||
@TableField("HEATING_SECTION")
|
||||
private Float heatingSection;
|
||||
/** 矫直机出口张力 */
|
||||
@Excel(name = "矫直机出口张力")
|
||||
private BigDecimal straightenerExitTension;
|
||||
|
||||
/** 冷却段出口板温 */
|
||||
@Excel(name = "冷却段出口板温")
|
||||
@TableField("COOLING_SECTION")
|
||||
private Float coolingSection;
|
||||
/** 炉区张力 */
|
||||
@Excel(name = "炉区张力")
|
||||
private BigDecimal furTension;
|
||||
|
||||
/** 冷却塔张力 */
|
||||
@Excel(name = "冷却塔张力")
|
||||
private BigDecimal towerTension;
|
||||
|
||||
/** 创建时间 */
|
||||
@Excel(name = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
/** 更新时间 */
|
||||
@Excel(name = "更新时间")
|
||||
private Date updateTime;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.fizz.business.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@TableName("pro_stoppage_type")
|
||||
public class ProStoppageType {
|
||||
|
||||
@TableId(value = "STOP_TYPE", type = IdType.INPUT)
|
||||
private Integer stopType;
|
||||
|
||||
@TableField("REMARK")
|
||||
private String remark;
|
||||
|
||||
@TableField("INSDATE")
|
||||
private LocalDateTime insdate;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
package com.fizz.business.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 全线张力对象 setup_tension_all_line
|
||||
*
|
||||
* 三主键:steel_grade + thick + yield_stren
|
||||
*/
|
||||
public class SetupTensionAllLine extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 钢种 */
|
||||
@Excel(name = "钢种")
|
||||
private String steelGrade;
|
||||
|
||||
/** 厚度 */
|
||||
@Excel(name = "厚度")
|
||||
private Float thick;
|
||||
|
||||
/** 屈服强度 */
|
||||
@Excel(name = "屈服强度")
|
||||
private Float yieldStren;
|
||||
|
||||
/** 开卷机张力 */
|
||||
@Excel(name = "开卷机张力")
|
||||
private Float value1;
|
||||
|
||||
/** 入口活套张力 */
|
||||
@Excel(name = "入口活套张力")
|
||||
private Float value2;
|
||||
|
||||
/** 清洗段张力 */
|
||||
@Excel(name = "清洗段张力")
|
||||
private Float value3;
|
||||
|
||||
/** 钝化段张力 */
|
||||
@Excel(name = "钝化段张力")
|
||||
private Float value4;
|
||||
|
||||
/** 出口活套张力 */
|
||||
@Excel(name = "出口活套张力")
|
||||
private Float value5;
|
||||
|
||||
/** 卷取机张力 */
|
||||
@Excel(name = "卷取机张力")
|
||||
private Float value6;
|
||||
|
||||
/** 创建时间(表字段) */
|
||||
private Date createTime;
|
||||
|
||||
/** 更新时间(表字段) */
|
||||
private Date updateTime;
|
||||
|
||||
public String getSteelGrade() {
|
||||
return steelGrade;
|
||||
}
|
||||
|
||||
public void setSteelGrade(String steelGrade) {
|
||||
this.steelGrade = steelGrade;
|
||||
}
|
||||
|
||||
public Float getThick() {
|
||||
return thick;
|
||||
}
|
||||
|
||||
public void setThick(Float thick) {
|
||||
this.thick = thick;
|
||||
}
|
||||
|
||||
public Float getYieldStren() {
|
||||
return yieldStren;
|
||||
}
|
||||
|
||||
public void setYieldStren(Float yieldStren) {
|
||||
this.yieldStren = yieldStren;
|
||||
}
|
||||
|
||||
public Float getValue1() {
|
||||
return value1;
|
||||
}
|
||||
|
||||
public void setValue1(Float value1) {
|
||||
this.value1 = value1;
|
||||
}
|
||||
|
||||
public Float getValue2() {
|
||||
return value2;
|
||||
}
|
||||
|
||||
public void setValue2(Float value2) {
|
||||
this.value2 = value2;
|
||||
}
|
||||
|
||||
public Float getValue3() {
|
||||
return value3;
|
||||
}
|
||||
|
||||
public void setValue3(Float value3) {
|
||||
this.value3 = value3;
|
||||
}
|
||||
|
||||
public Float getValue4() {
|
||||
return value4;
|
||||
}
|
||||
|
||||
public void setValue4(Float value4) {
|
||||
this.value4 = value4;
|
||||
}
|
||||
|
||||
public Float getValue5() {
|
||||
return value5;
|
||||
}
|
||||
|
||||
public void setValue5(Float value5) {
|
||||
this.value5 = value5;
|
||||
}
|
||||
|
||||
public Float getValue6() {
|
||||
return value6;
|
||||
}
|
||||
|
||||
public void setValue6(Float value6) {
|
||||
this.value6 = value6;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.fizz.business.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 退火炉张力对象 setup_tension_annealing_furnace
|
||||
*
|
||||
* 三主键:steel_grade + thick + yield_stren
|
||||
*/
|
||||
public class SetupTensionAnnealingFurnace extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Excel(name = "钢种")
|
||||
private String steelGrade;
|
||||
|
||||
@Excel(name = "厚度")
|
||||
private Float thick;
|
||||
|
||||
@Excel(name = "屈服强度")
|
||||
private Float yieldStren;
|
||||
|
||||
@Excel(name = "炉区张力")
|
||||
private Float value1;
|
||||
|
||||
@Excel(name = "冷却塔张力")
|
||||
private Float value2;
|
||||
|
||||
private Date createTime;
|
||||
private Date updateTime;
|
||||
|
||||
public String getSteelGrade() { return steelGrade; }
|
||||
public void setSteelGrade(String steelGrade) { this.steelGrade = steelGrade; }
|
||||
|
||||
public Float getThick() { return thick; }
|
||||
public void setThick(Float thick) { this.thick = thick; }
|
||||
|
||||
public Float getYieldStren() { return yieldStren; }
|
||||
public void setYieldStren(Float yieldStren) { this.yieldStren = yieldStren; }
|
||||
|
||||
public Float getValue1() { return value1; }
|
||||
public void setValue1(Float value1) { this.value1 = value1; }
|
||||
|
||||
public Float getValue2() { return value2; }
|
||||
public void setValue2(Float value2) { this.value2 = value2; }
|
||||
|
||||
@Override
|
||||
public Date getCreateTime() { return createTime; }
|
||||
|
||||
@Override
|
||||
public void setCreateTime(Date createTime) { this.createTime = createTime; }
|
||||
|
||||
@Override
|
||||
public Date getUpdateTime() { return updateTime; }
|
||||
|
||||
@Override
|
||||
public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.fizz.business.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 平整机张力对象 setup_tension_leveler
|
||||
*
|
||||
* 三主键:steel_grade + thick + yield_stren
|
||||
*/
|
||||
public class SetupTensionLeveler extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Excel(name = "钢种")
|
||||
private String steelGrade;
|
||||
|
||||
@Excel(name = "厚度")
|
||||
private Float thick;
|
||||
|
||||
@Excel(name = "屈服强度")
|
||||
private Float yieldStren;
|
||||
|
||||
@Excel(name = "平整机入口张力")
|
||||
private Float value1;
|
||||
|
||||
@Excel(name = "平整机出口张力")
|
||||
private Float value2;
|
||||
|
||||
private Date createTime;
|
||||
private Date updateTime;
|
||||
|
||||
public String getSteelGrade() { return steelGrade; }
|
||||
public void setSteelGrade(String steelGrade) { this.steelGrade = steelGrade; }
|
||||
|
||||
public Float getThick() { return thick; }
|
||||
public void setThick(Float thick) { this.thick = thick; }
|
||||
|
||||
public Float getYieldStren() { return yieldStren; }
|
||||
public void setYieldStren(Float yieldStren) { this.yieldStren = yieldStren; }
|
||||
|
||||
public Float getValue1() { return value1; }
|
||||
public void setValue1(Float value1) { this.value1 = value1; }
|
||||
|
||||
public Float getValue2() { return value2; }
|
||||
public void setValue2(Float value2) { this.value2 = value2; }
|
||||
|
||||
@Override
|
||||
public Date getCreateTime() { return createTime; }
|
||||
|
||||
@Override
|
||||
public void setCreateTime(Date createTime) { this.createTime = createTime; }
|
||||
|
||||
@Override
|
||||
public Date getUpdateTime() { return updateTime; }
|
||||
|
||||
@Override
|
||||
public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.fizz.business.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 矫直机张力对象 setup_tension_straightener
|
||||
*
|
||||
* 三主键:steel_grade + thick + yield_stren
|
||||
*/
|
||||
public class SetupTensionStraightener extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Excel(name = "钢种")
|
||||
private String steelGrade;
|
||||
|
||||
@Excel(name = "厚度")
|
||||
private Float thick;
|
||||
|
||||
@Excel(name = "屈服强度")
|
||||
private Float yieldStren;
|
||||
|
||||
@Excel(name = "矫直机出口张力")
|
||||
private Float value1;
|
||||
|
||||
private Date createTime;
|
||||
private Date updateTime;
|
||||
|
||||
public String getSteelGrade() { return steelGrade; }
|
||||
public void setSteelGrade(String steelGrade) { this.steelGrade = steelGrade; }
|
||||
|
||||
public Float getThick() { return thick; }
|
||||
public void setThick(Float thick) { this.thick = thick; }
|
||||
|
||||
public Float getYieldStren() { return yieldStren; }
|
||||
public void setYieldStren(Float yieldStren) { this.yieldStren = yieldStren; }
|
||||
|
||||
public Float getValue1() { return value1; }
|
||||
public void setValue1(Float value1) { this.value1 = value1; }
|
||||
|
||||
@Override
|
||||
public Date getCreateTime() { return createTime; }
|
||||
|
||||
@Override
|
||||
public void setCreateTime(Date createTime) { this.createTime = createTime; }
|
||||
|
||||
@Override
|
||||
public Date getUpdateTime() { return updateTime; }
|
||||
|
||||
@Override
|
||||
public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; }
|
||||
}
|
||||
|
||||
@@ -66,7 +66,6 @@ public class SendJobCreateDTO {
|
||||
private String address;
|
||||
|
||||
/** 设定的原始值 */
|
||||
@NotBlank(message = "valueRaw不能为空")
|
||||
private String valueRaw;
|
||||
|
||||
/** 参数的设定时间 */
|
||||
|
||||
@@ -14,5 +14,8 @@ public class SendJobQueryDTO {
|
||||
|
||||
/** 状态: PENDING, IN_PROGRESS, COMPLETED, PARTIAL_SUCCESS, FAILED, DELETED */
|
||||
private String status;
|
||||
|
||||
/** 分组类型: DRIVE / FURNACE */
|
||||
private String groupType;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.fizz.business.domain.dto;
|
||||
|
||||
import com.fizz.business.domain.BizSendTemplateItem;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 模板明细批量保存(新增/更新/删除)
|
||||
*/
|
||||
@Data
|
||||
public class SendTemplateItemsBatchSaveDTO {
|
||||
|
||||
/** 模板ID */
|
||||
private Integer templateId;
|
||||
|
||||
/** 需要新增/更新的明细 */
|
||||
private List<BizSendTemplateItem> items;
|
||||
|
||||
/** 需要删除的明细ID */
|
||||
private List<Integer> deleteIds;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,9 @@ public class AppMeasureEntryMessage extends OpcMessage {
|
||||
@Schema(description = "钢带张力 BR2 – BR3 (daN)")
|
||||
private BigDecimal tensionBr2Br3;
|
||||
|
||||
@Schema(description = "钢带张力 BR4/5 – BR6 (daN)")
|
||||
private BigDecimal tensionBr45Br6;
|
||||
|
||||
@Schema(description = "钢带速度 (m/min)")
|
||||
private BigDecimal stripSpeed;
|
||||
|
||||
@@ -74,6 +77,4 @@ public class AppMeasureEntryMessage extends OpcMessage {
|
||||
@Schema(description = "热风压力 (Pa)")
|
||||
private BigDecimal hotAirPressure;
|
||||
|
||||
@Schema(description = "钢带张力 BR4/5 – BR6 (daN)")
|
||||
private BigDecimal bR4or5toBR6Tension;
|
||||
}
|
||||
@@ -120,6 +120,56 @@ public class PdiSetup extends OpcMessage{
|
||||
@Schema(description = "BR9-TR 张力")
|
||||
private BigDecimal tensionBR9TR;
|
||||
|
||||
// 新增的张力设定值字段
|
||||
@Schema(description = "开卷机1当前张力")
|
||||
private BigDecimal tensionPor1Current;
|
||||
@Schema(description = "开卷机1下一设定张力")
|
||||
private BigDecimal tensionPor1Next;
|
||||
@Schema(description = "开卷机2当前张力")
|
||||
private BigDecimal tensionPor2Current;
|
||||
@Schema(description = "开卷机2下一设定张力")
|
||||
private BigDecimal tensionPor2Next;
|
||||
@Schema(description = "入口活套当前张力")
|
||||
private BigDecimal tensionEnLpCurrent;
|
||||
@Schema(description = "入口活套下一设定张力")
|
||||
private BigDecimal tensionEnLpNext;
|
||||
@Schema(description = "清洗段当前张力")
|
||||
private BigDecimal tensionCleaningCurrent;
|
||||
@Schema(description = "清洗段下一设定张力")
|
||||
private BigDecimal tensionCleaningNext;
|
||||
@Schema(description = "炉区当前张力")
|
||||
private BigDecimal tensionFuranceCurrent;
|
||||
@Schema(description = "炉区下一设定张力")
|
||||
private BigDecimal tensionFuranceNext;
|
||||
@Schema(description = "镀后冷却当前张力")
|
||||
private BigDecimal tensionGalvanizingCoolCurrent;
|
||||
@Schema(description = "镀后冷却下一设定张力")
|
||||
private BigDecimal tensionGalvanizingCoolNext;
|
||||
@Schema(description = "光整机入口当前张力")
|
||||
private BigDecimal tensionTmEntryCurrent;
|
||||
@Schema(description = "光整机入口下一设定张力")
|
||||
private BigDecimal tensionTmEntryNext;
|
||||
@Schema(description = "光整机出口当前张力")
|
||||
private BigDecimal tensionTmExitCurrent;
|
||||
@Schema(description = "光整机出口下一设定张力")
|
||||
private BigDecimal tensionTmExitNext;
|
||||
@Schema(description = "拉矫机当前张力")
|
||||
private BigDecimal tensionTlCurrent;
|
||||
@Schema(description = "拉矫机下一设定张力")
|
||||
private BigDecimal tensionTlNext;
|
||||
@Schema(description = "涂敷段当前张力")
|
||||
private BigDecimal tensionCoatingCurrent;
|
||||
@Schema(description = "涂敷段下一设定张力")
|
||||
private BigDecimal tensionCoatingNext;
|
||||
@Schema(description = "出口活套当前张力")
|
||||
private BigDecimal tensionExLpCurrent;
|
||||
@Schema(description = "出口活套下一设定张力")
|
||||
private BigDecimal tensionExLpNext;
|
||||
@Schema(description = "卷取机当前张力")
|
||||
private BigDecimal tensionTrCurrent;
|
||||
@Schema(description = "卷取机下一设定张力")
|
||||
private BigDecimal tensionTrNext;
|
||||
|
||||
@Schema(description = "涂油投入")
|
||||
private Integer oilingFlag;
|
||||
@Schema(description = "上表面涂油量")
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.fizz.business.domain.s7;
|
||||
|
||||
import com.github.xingshuangs.iot.common.enums.EDataType;
|
||||
import com.github.xingshuangs.iot.protocol.s7.serializer.S7Variable;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DB35501Data {
|
||||
@S7Variable(address = "DB35501.0", type = EDataType.STRING, count = 20)
|
||||
private String coilId;
|
||||
|
||||
@S7Variable(address = "DB35501.30", type = EDataType.FLOAT32)
|
||||
private float entryCoilWeight;
|
||||
|
||||
@S7Variable(address = "DB35501.34", type = EDataType.FLOAT32)
|
||||
private float entryCoilLength;
|
||||
|
||||
@S7Variable(address = "DB35501.38", type = EDataType.FLOAT32)
|
||||
private float entryCoilWidth;
|
||||
|
||||
@S7Variable(address = "DB35501.42", type = EDataType.FLOAT32)
|
||||
private float entryCoilThick;
|
||||
|
||||
@S7Variable(address = "DB35501.46", type = EDataType.FLOAT32)
|
||||
private float entryCoilInnerDia;
|
||||
|
||||
@S7Variable(address = "DB35501.50", type = EDataType.FLOAT32)
|
||||
private float entryCoilOuterDia;
|
||||
|
||||
@S7Variable(address = "DB35501.54", type = EDataType.BYTE)
|
||||
private byte alloyCode;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.fizz.business.domain.s7;
|
||||
|
||||
import com.github.xingshuangs.iot.common.enums.EDataType;
|
||||
import com.github.xingshuangs.iot.protocol.s7.serializer.S7Variable;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DB35502Data {
|
||||
@S7Variable(address = "DB35502.114", type = EDataType.FLOAT32)
|
||||
private float tensionPor1Next;
|
||||
|
||||
@S7Variable(address = "DB35502.122", type = EDataType.FLOAT32)
|
||||
private float tensionPor2Next;
|
||||
|
||||
@S7Variable(address = "DB35502.130", type = EDataType.FLOAT32)
|
||||
private float tensionEnLpNext;
|
||||
|
||||
@S7Variable(address = "DB35502.138", type = EDataType.FLOAT32)
|
||||
private float tensionCleaningNext;
|
||||
|
||||
@S7Variable(address = "DB35502.162", type = EDataType.FLOAT32)
|
||||
private float tensionGalvanizingCoolNext;
|
||||
|
||||
@S7Variable(address = "DB35502.266", type = EDataType.FLOAT32)
|
||||
private float tensionExLpNext;
|
||||
|
||||
@S7Variable(address = "DB35502.232", type = EDataType.FLOAT32)
|
||||
private float tensionTlNext;
|
||||
|
||||
@S7Variable(address = "DB35502.198", type = EDataType.FLOAT32)
|
||||
private float tensionTmExitNext;
|
||||
|
||||
@S7Variable(address = "DB35502.146", type = EDataType.FLOAT32)
|
||||
private float tensionFuranceNext;
|
||||
|
||||
@S7Variable(address = "DB35502.274", type = EDataType.FLOAT32)
|
||||
private float tensionTrNext;
|
||||
}
|
||||
|
||||
@@ -15,5 +15,8 @@ public class BizSendTemplateItemVO {
|
||||
private String groupNameEn;
|
||||
private String address;
|
||||
private String defaultValueRaw;
|
||||
|
||||
private Boolean enabled;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.fizz.business.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 炉火写入时的钢卷信息(存储到 Redis)
|
||||
*/
|
||||
@Data
|
||||
public class FurnaceSendCoilInfoVO {
|
||||
|
||||
/** 钢卷号 */
|
||||
private String coilId;
|
||||
|
||||
/** 计划ID */
|
||||
private String planId;
|
||||
|
||||
/** 写入时间 */
|
||||
private Date sendTime;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.fizz.business.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ProStoppageTypeVO {
|
||||
|
||||
private Integer stopType;
|
||||
|
||||
private String remark;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.fizz.business.domain.vo;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,5 +19,8 @@ public class SendJobLastSuccessVO {
|
||||
|
||||
/** 最近一次成功的jobId(可选) */
|
||||
private Integer jobId;
|
||||
|
||||
//IsFromHistory
|
||||
private Boolean isFromHistory;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
package com.fizz.business.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 设备图表数据 DTO
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(description = "设备图表数据")
|
||||
public class DeviceChartDataDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "设备类型分布饼图数据")
|
||||
private PieChartData deviceTypePieChart;
|
||||
|
||||
@Schema(description = "数据来源分布条形图数据")
|
||||
private BarChartData sourceTypeBarChart;
|
||||
|
||||
@Schema(description = "同类型设备对比折线图数据(单位相同)")
|
||||
private LineChartData sameTypeDeviceCompareChart;
|
||||
|
||||
@Schema(description = "设备统计数据")
|
||||
private List<DeviceStatistics> deviceStatistics;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(description = "饼图数据")
|
||||
public static class PieChartData implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "数据系列")
|
||||
private List<PieSeries> series;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(description = "饼图系列")
|
||||
public static class PieSeries implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "数值")
|
||||
private Double data;
|
||||
|
||||
@Schema(description = "颜色")
|
||||
private String color;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(description = "条形图数据")
|
||||
public static class BarChartData implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "分类轴")
|
||||
private List<String> categories;
|
||||
|
||||
@Schema(description = "数据系列")
|
||||
private List<BarSeries> series;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(description = "条形图系列")
|
||||
public static class BarSeries implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "系列名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "数据值列表")
|
||||
private List<Double> data;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(description = "折线图数据")
|
||||
public static class LineChartData implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "时间轴")
|
||||
private List<String> categories;
|
||||
|
||||
@Schema(description = "数据系列")
|
||||
private List<LineSeries> series;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(description = "折线图系列")
|
||||
public static class LineSeries implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "系列名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "数据值列表")
|
||||
private List<Double> data;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(description = "设备统计数据")
|
||||
public static class DeviceStatistics implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "设备代码")
|
||||
private String deviceCode;
|
||||
|
||||
@Schema(description = "设备名称")
|
||||
private String deviceName;
|
||||
|
||||
@Schema(description = "平均值")
|
||||
private String avg;
|
||||
|
||||
@Schema(description = "最大值")
|
||||
private String max;
|
||||
|
||||
@Schema(description = "最小值")
|
||||
private String min;
|
||||
|
||||
@Schema(description = "当前值")
|
||||
private String current;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.fizz.business.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 单设备-单字段的趋势与统计
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(description = "设备字段趋势数据")
|
||||
public class DeviceFieldTrendDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "设备代码")
|
||||
private String deviceCode;
|
||||
|
||||
@Schema(description = "设备名称")
|
||||
private String deviceName;
|
||||
|
||||
@Schema(description = "字段名")
|
||||
private String fieldName;
|
||||
|
||||
@Schema(description = "字段中文名(可选)")
|
||||
private String fieldLabel;
|
||||
|
||||
@Schema(description = "单位(可选)")
|
||||
private String unit;
|
||||
|
||||
@Schema(description = "时间轴(HH:mm)")
|
||||
private List<String> categories;
|
||||
|
||||
@Schema(description = "数据点")
|
||||
private List<Double> data;
|
||||
|
||||
@Schema(description = "统计-平均值")
|
||||
private Double avg;
|
||||
|
||||
@Schema(description = "统计-最大值")
|
||||
private Double max;
|
||||
|
||||
@Schema(description = "统计-最小值")
|
||||
private Double min;
|
||||
|
||||
@Schema(description = "统计-最新值")
|
||||
private Double last;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.fizz.business.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* WS 订阅:设备字段趋势
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "设备字段趋势订阅请求")
|
||||
public class DeviceFieldTrendSubscribeReq implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "设备代码列表,为空表示不变")
|
||||
private List<String> deviceCodes;
|
||||
|
||||
@Schema(description = "字段名列表,为空表示不变")
|
||||
private List<String> fieldNames;
|
||||
|
||||
@Schema(description = "是否只推送可见范围(用于懒加载),true=只推 deviceCodes/fieldNames 命中的数据")
|
||||
private Boolean lazy;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.fizz.business.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 设备历史趋势数据 DTO
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(description = "设备历史趋势数据")
|
||||
public class DeviceHistoryTrendDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "设备代码")
|
||||
private String deviceCode;
|
||||
|
||||
@Schema(description = "设备描述")
|
||||
private String deviceName;
|
||||
|
||||
@Schema(description = "时间轴(格式:HH:mm)")
|
||||
private List<String> categories;
|
||||
|
||||
@Schema(description = "数据系列,key为字段名,value为数据值列表")
|
||||
private List<SeriesData> series;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(description = "数据系列")
|
||||
public static class SeriesData implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "系列名称(字段标签)")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "字段名")
|
||||
private String fieldName;
|
||||
|
||||
@Schema(description = "数据值列表")
|
||||
private List<Double> data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,4 +22,10 @@ public class CrmPdoExcoilForm {
|
||||
@Schema(description = "锌层厚度")
|
||||
private BigDecimal zincCoatingThickness;
|
||||
|
||||
@Schema(description = "页码", example = "1")
|
||||
private Integer pageNum = 1;
|
||||
|
||||
@Schema(description = "每页数量", example = "20")
|
||||
private Integer pageSize = 20;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.fizz.business.form;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* OPC 批量写数据请求表单
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "OPC 批量写数据请求")
|
||||
public class OpcBatchWriteDataForm implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 批量写数据列表
|
||||
*/
|
||||
@Schema(description = "批量写数据列表")
|
||||
@NotEmpty(message = "写数据列表不能为空")
|
||||
@Valid
|
||||
private List<OpcWriteDataForm> dataList;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.fizz.business.form;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* OPC 写数据请求表单
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "OPC 写数据请求")
|
||||
public class OpcWriteDataForm implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 字段名(对象属性名),例如:coilId
|
||||
* 系统会自动查找对应的 OPC 节点路径
|
||||
*/
|
||||
@Schema(description = "字段名(对象属性名)", example = "coilId")
|
||||
@NotBlank(message = "字段名不能为空")
|
||||
private String fieldName;
|
||||
|
||||
/**
|
||||
* 要写入的值(支持多种类型:String, Integer, Double, Boolean 等)
|
||||
*/
|
||||
@Schema(description = "要写入的值", example = "COIL001")
|
||||
@NotNull(message = "写入值不能为空")
|
||||
private Object value;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.fizz.business.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.fizz.business.domain.DeviceSnapshot;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface DeviceSnapshotMapper extends BaseMapper<DeviceSnapshot> {
|
||||
}
|
||||
|
||||
@@ -1,63 +1,16 @@
|
||||
package com.fizz.business.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.fizz.business.domain.PdiSetups;
|
||||
|
||||
/**
|
||||
* 生产计划的参数详情Mapper接口
|
||||
*
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-09-25
|
||||
*/
|
||||
public interface PdiSetupMapper extends BaseMapper<PdiSetups>
|
||||
{
|
||||
/**
|
||||
* 查询生产计划的参数详情
|
||||
*
|
||||
* @param id 生产计划的参数详情主键
|
||||
* @return 生产计划的参数详情
|
||||
*/
|
||||
public PdiSetups selectPdiSetupById(Long id);
|
||||
|
||||
/**
|
||||
* 查询生产计划的参数详情列表
|
||||
*
|
||||
* @param pdiSetup 生产计划的参数详情
|
||||
* @return 生产计划的参数详情集合
|
||||
*/
|
||||
public List<PdiSetups> selectPdiSetupList(PdiSetups pdiSetup);
|
||||
|
||||
/**
|
||||
* 新增生产计划的参数详情
|
||||
*
|
||||
* @param pdiSetup 生产计划的参数详情
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertPdiSetup(PdiSetups pdiSetup);
|
||||
|
||||
/**
|
||||
* 修改生产计划的参数详情
|
||||
*
|
||||
* @param pdiSetup 生产计划的参数详情
|
||||
* @return 结果
|
||||
*/
|
||||
public int updatePdiSetup(PdiSetups pdiSetup);
|
||||
|
||||
/**
|
||||
* 删除生产计划的参数详情
|
||||
*
|
||||
* @param id 生产计划的参数详情主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deletePdiSetupById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除生产计划的参数详情
|
||||
*
|
||||
* @param ids 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deletePdiSetupByIds(Long[] ids);
|
||||
// 使用 MyBatis-Plus BaseMapper 提供基础 CRUD(含按 id 的 selectById/deleteById/updateById 等)。
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.fizz.business.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.fizz.business.domain.ProStoppageType;
|
||||
|
||||
public interface ProStoppageTypeMapper extends BaseMapper<ProStoppageType> {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.fizz.business.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.fizz.business.domain.SetupTensionAllLine;
|
||||
|
||||
/**
|
||||
* 全线张力Mapper接口
|
||||
*/
|
||||
public interface SetupTensionAllLineMapper
|
||||
{
|
||||
SetupTensionAllLine selectByKey(@Param("steelGrade") String steelGrade,
|
||||
@Param("thick") Float thick,
|
||||
@Param("yieldStren") Float yieldStren);
|
||||
|
||||
List<SetupTensionAllLine> selectList(SetupTensionAllLine query);
|
||||
|
||||
int insert(SetupTensionAllLine entity);
|
||||
|
||||
int updateByKey(SetupTensionAllLine entity);
|
||||
|
||||
int deleteByKey(@Param("steelGrade") String steelGrade,
|
||||
@Param("thick") Float thick,
|
||||
@Param("yieldStren") Float yieldStren);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.fizz.business.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.fizz.business.domain.SetupTensionAnnealingFurnace;
|
||||
|
||||
/**
|
||||
* 退火炉张力Mapper接口
|
||||
*/
|
||||
public interface SetupTensionAnnealingFurnaceMapper
|
||||
{
|
||||
SetupTensionAnnealingFurnace selectByKey(@Param("steelGrade") String steelGrade,
|
||||
@Param("thick") Float thick,
|
||||
@Param("yieldStren") Float yieldStren);
|
||||
|
||||
List<SetupTensionAnnealingFurnace> selectList(SetupTensionAnnealingFurnace query);
|
||||
|
||||
int insert(SetupTensionAnnealingFurnace entity);
|
||||
|
||||
int updateByKey(SetupTensionAnnealingFurnace entity);
|
||||
|
||||
int deleteByKey(@Param("steelGrade") String steelGrade,
|
||||
@Param("thick") Float thick,
|
||||
@Param("yieldStren") Float yieldStren);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.fizz.business.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.fizz.business.domain.SetupTensionLeveler;
|
||||
|
||||
/**
|
||||
* 平整机张力Mapper接口
|
||||
*/
|
||||
public interface SetupTensionLevelerMapper
|
||||
{
|
||||
SetupTensionLeveler selectByKey(@Param("steelGrade") String steelGrade,
|
||||
@Param("thick") Float thick,
|
||||
@Param("yieldStren") Float yieldStren);
|
||||
|
||||
List<SetupTensionLeveler> selectList(SetupTensionLeveler query);
|
||||
|
||||
int insert(SetupTensionLeveler entity);
|
||||
|
||||
int updateByKey(SetupTensionLeveler entity);
|
||||
|
||||
int deleteByKey(@Param("steelGrade") String steelGrade,
|
||||
@Param("thick") Float thick,
|
||||
@Param("yieldStren") Float yieldStren);
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
package com.fizz.business.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.fizz.business.domain.SetupTension;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 全线张力Mapper接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-26
|
||||
*/
|
||||
public interface SetupTensionMapper
|
||||
{
|
||||
/**
|
||||
* 查询全线张力
|
||||
*
|
||||
* @param thick 全线张力主键
|
||||
* @return 全线张力
|
||||
*/
|
||||
public SetupTension selectSetupTensionByThick(@Param("thick") Long thick,@Param("yieldStren") Long yieldStren);
|
||||
|
||||
/**
|
||||
* 查询全线张力列表
|
||||
*
|
||||
* @param setupTension 全线张力
|
||||
* @return 全线张力集合
|
||||
*/
|
||||
public List<SetupTension> selectSetupTensionList(SetupTension setupTension);
|
||||
|
||||
/**
|
||||
* 新增全线张力
|
||||
*
|
||||
* @param setupTension 全线张力
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertSetupTension(SetupTension setupTension);
|
||||
|
||||
/**
|
||||
* 修改全线张力
|
||||
*
|
||||
* @param setupTension 全线张力
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateSetupTension(SetupTension setupTension);
|
||||
|
||||
/**
|
||||
* 删除全线张力
|
||||
*
|
||||
* @param thick 全线张力主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTensionByThick(Long thick);
|
||||
|
||||
/**
|
||||
* 批量删除全线张力
|
||||
*
|
||||
* @param thicks 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTensionByThicks(@Param("thicks") Long[] thicks,@Param("yieldStrens") Long[] yieldStrens);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.fizz.business.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.fizz.business.domain.SetupTensionStraightener;
|
||||
|
||||
/**
|
||||
* 矫直机张力Mapper接口
|
||||
*/
|
||||
public interface SetupTensionStraightenerMapper
|
||||
{
|
||||
SetupTensionStraightener selectByKey(@Param("steelGrade") String steelGrade,
|
||||
@Param("thick") Float thick,
|
||||
@Param("yieldStren") Float yieldStren);
|
||||
|
||||
List<SetupTensionStraightener> selectList(SetupTensionStraightener query);
|
||||
|
||||
int insert(SetupTensionStraightener entity);
|
||||
|
||||
int updateByKey(SetupTensionStraightener entity);
|
||||
|
||||
int deleteByKey(@Param("steelGrade") String steelGrade,
|
||||
@Param("thick") Float thick,
|
||||
@Param("yieldStren") Float yieldStren);
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
package com.fizz.business.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.fizz.business.domain.SetupTl;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 拉矫机参数Mapper接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-26
|
||||
*/
|
||||
public interface SetupTlMapper
|
||||
{
|
||||
/**
|
||||
* 查询拉矫机参数
|
||||
*
|
||||
* @param steelGrade 拉矫机参数主键
|
||||
* @return 拉矫机参数
|
||||
*/
|
||||
public SetupTl selectSetupTlBySteelGrade(@Param("steelGrade") String steelGrade,@Param("yieldStren") Long yieldStren,@Param("thick") Long thick);
|
||||
|
||||
/**
|
||||
* 查询拉矫机参数列表
|
||||
*
|
||||
* @param setupTl 拉矫机参数
|
||||
* @return 拉矫机参数集合
|
||||
*/
|
||||
public List<SetupTl> selectSetupTlList(SetupTl setupTl);
|
||||
|
||||
/**
|
||||
* 新增拉矫机参数
|
||||
*
|
||||
* @param setupTl 拉矫机参数
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertSetupTl(SetupTl setupTl);
|
||||
|
||||
/**
|
||||
* 修改拉矫机参数
|
||||
*
|
||||
* @param setupTl 拉矫机参数
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateSetupTl(SetupTl setupTl);
|
||||
|
||||
/**
|
||||
* 删除拉矫机参数
|
||||
*
|
||||
* @param steelGrade 拉矫机参数主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTlBySteelGrade(String steelGrade);
|
||||
|
||||
/**
|
||||
* 批量删除拉矫机参数
|
||||
*
|
||||
* @param steelGrades 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTlBySteelGrades(@Param("steelGrades") String[] steelGrades,@Param("yieldStrens") Long[] yieldStrens,@Param("thicks") Long[] thicks);
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package com.fizz.business.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.fizz.business.domain.SetupTmBendforce;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 光整机弯辊力Mapper接口
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-09-26
|
||||
*/
|
||||
public interface SetupTmBendforceMapper
|
||||
{
|
||||
/**
|
||||
* 查询光整机弯辊力
|
||||
*
|
||||
* @param width 光整机弯辊力主键
|
||||
* @return 光整机弯辊力
|
||||
*/
|
||||
public SetupTmBendforce selectSetupTmBendforceByWidth(@Param("width") Long width,@Param("rollForce") Long rollForce);
|
||||
|
||||
/**
|
||||
* 查询光整机弯辊力列表
|
||||
*
|
||||
* @param setupTmBendforce 光整机弯辊力
|
||||
* @return 光整机弯辊力集合
|
||||
*/
|
||||
public List<SetupTmBendforce> selectSetupTmBendforceList(SetupTmBendforce setupTmBendforce);
|
||||
|
||||
/**
|
||||
* 新增光整机弯辊力
|
||||
*
|
||||
* @param setupTmBendforce 光整机弯辊力
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertSetupTmBendforce(SetupTmBendforce setupTmBendforce);
|
||||
|
||||
/**
|
||||
* 修改光整机弯辊力
|
||||
*
|
||||
* @param setupTmBendforce 光整机弯辊力
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateSetupTmBendforce(SetupTmBendforce setupTmBendforce);
|
||||
|
||||
/**
|
||||
* 删除光整机弯辊力
|
||||
*
|
||||
* @param width 光整机弯辊力主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTmBendforceByWidth(Long width);
|
||||
|
||||
/**
|
||||
* 批量删除光整机弯辊力
|
||||
*
|
||||
* @param widths 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTmBendforceByWidths(@Param("widths") Long[] widths,@Param("rollForces") Long[] rollForces);
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package com.fizz.business.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.fizz.business.domain.SetupTmMesh;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 光整机插入量Mapper接口
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-09-26
|
||||
*/
|
||||
public interface SetupTmMeshMapper
|
||||
{
|
||||
/**
|
||||
* 查询光整机插入量
|
||||
*
|
||||
* @param steelGrade 光整机插入量主键
|
||||
* @return 光整机插入量
|
||||
*/
|
||||
public SetupTmMesh selectSetupTmMeshBySteelGrade(@Param("steelGrade") String steelGrade,@Param("yieldStren") Long yieldStren,@Param("thick") Long thick);
|
||||
|
||||
/**
|
||||
* 查询光整机插入量列表
|
||||
*
|
||||
* @param setupTmMesh 光整机插入量
|
||||
* @return 光整机插入量集合
|
||||
*/
|
||||
public List<SetupTmMesh> selectSetupTmMeshList(SetupTmMesh setupTmMesh);
|
||||
|
||||
/**
|
||||
* 新增光整机插入量
|
||||
*
|
||||
* @param setupTmMesh 光整机插入量
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertSetupTmMesh(SetupTmMesh setupTmMesh);
|
||||
|
||||
/**
|
||||
* 修改光整机插入量
|
||||
*
|
||||
* @param setupTmMesh 光整机插入量
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateSetupTmMesh(SetupTmMesh setupTmMesh);
|
||||
|
||||
/**
|
||||
* 删除光整机插入量
|
||||
*
|
||||
* @param steelGrade 光整机插入量主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTmMeshBySteelGrade(String steelGrade);
|
||||
|
||||
/**
|
||||
* 批量删除光整机插入量
|
||||
*
|
||||
* @param steelGrades 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTmMeshBySteelGrades(@Param("steelGrades") String[] steelGrades,
|
||||
@Param("yieldStrens") Long[] yieldStrens,
|
||||
@Param("thicks") Long[] thicks);
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package com.fizz.business.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.fizz.business.domain.SetupTmRollforce;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 光整机轧制力Mapper接口
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-09-26
|
||||
*/
|
||||
public interface SetupTmRollforceMapper
|
||||
{
|
||||
/**
|
||||
* 查询光整机轧制力
|
||||
*
|
||||
* @param steelGrade 光整机轧制力主键
|
||||
* @return 光整机轧制力
|
||||
*/
|
||||
public SetupTmRollforce selectSetupTmRollforceBySteelGrade(@Param("steelGrade") String steelGrade,@Param("yieldStren") Long yieldStren,@Param("thick") Long thick,@Param("elong") Long elong);
|
||||
|
||||
/**
|
||||
* 查询光整机轧制力列表
|
||||
*
|
||||
* @param setupTmRollforce 光整机轧制力
|
||||
* @return 光整机轧制力集合
|
||||
*/
|
||||
public List<SetupTmRollforce> selectSetupTmRollforceList(SetupTmRollforce setupTmRollforce);
|
||||
|
||||
/**
|
||||
* 新增光整机轧制力
|
||||
*
|
||||
* @param setupTmRollforce 光整机轧制力
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertSetupTmRollforce(SetupTmRollforce setupTmRollforce);
|
||||
|
||||
/**
|
||||
* 修改光整机轧制力
|
||||
*
|
||||
* @param setupTmRollforce 光整机轧制力
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateSetupTmRollforce(SetupTmRollforce setupTmRollforce);
|
||||
|
||||
/**
|
||||
* 删除光整机轧制力
|
||||
*
|
||||
* @param steelGrade 光整机轧制力主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTmRollforceBySteelGrade(String steelGrade);
|
||||
|
||||
/**
|
||||
* 批量删除光整机轧制力
|
||||
*
|
||||
* @param steelGrades 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTmRollforceBySteelGrades(@Param("steelGrades") String[] steelGrades,
|
||||
@Param("thicks") Long[] thicks,
|
||||
@Param("yieldStrens") Long[] yieldStrens,
|
||||
@Param("elongs") Long[] elongs);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.fizz.business.scheduled;
|
||||
|
||||
import com.fizz.business.service.DeviceSnapshotService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 设备数据快照定时任务
|
||||
* 每10分钟执行一次设备数据快照
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class DeviceSnapshotSchedule {
|
||||
|
||||
private final DeviceSnapshotService deviceSnapshotService;
|
||||
|
||||
/**
|
||||
* 每10分钟执行一次设备数据快照
|
||||
* 使用cron表达式:0 0/10 * * * ?
|
||||
* 表示每10分钟执行一次,在每分钟的0秒触发
|
||||
*/
|
||||
@Scheduled(cron = "0 0/10 * * * ?")
|
||||
public void captureDeviceSnapshots() {
|
||||
try {
|
||||
log.info("开始执行设备数据快照任务...");
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
// 创建设备数据快照
|
||||
deviceSnapshotService.createDeviceSnapshots();
|
||||
|
||||
long endTime = System.currentTimeMillis();
|
||||
log.info("设备数据快照任务执行完成,耗时:{}ms", (endTime - startTime));
|
||||
} catch (Exception e) {
|
||||
log.error("执行设备数据快照任务失败: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,5 +28,11 @@ public interface CrmPdiPlanService extends IService<CrmPdiPlan> {
|
||||
*/
|
||||
CrmPdiPlan getFirstUnProducedCoil();
|
||||
|
||||
void changeStatus(ChangePlanStatusForm build);
|
||||
boolean changeStatus(ChangePlanStatusForm build);
|
||||
|
||||
/**
|
||||
* 获取当前正在线上的钢卷(优先级:ONLINE > PRODUCING > READY/NEW)
|
||||
* @return 当前正在线上的钢卷,如果没有则返回null
|
||||
*/
|
||||
CrmPdiPlan getCurrentOnlineCoil();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,793 @@
|
||||
package com.fizz.business.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.fizz.business.constants.enums.DeviceEnum;
|
||||
import com.fizz.business.constants.enums.WsTypeEnum;
|
||||
import com.fizz.business.domain.DeviceSnapshot;
|
||||
import com.fizz.business.domain.msg.*;
|
||||
import com.fizz.business.dto.DeviceChartDataDTO;
|
||||
import com.fizz.business.dto.DeviceFieldTrendDTO;
|
||||
import com.fizz.business.dto.DeviceHistoryTrendDTO;
|
||||
import com.fizz.business.mapper.DeviceSnapshotMapper;
|
||||
import com.fizz.business.utils.WebSocketUtil;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 设备数据快照服务
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DeviceSnapshotService {
|
||||
|
||||
// 使用ConcurrentHashMap存储最新的测量数据
|
||||
private final Map<Class<?>, OpcMessage> latestMeasurements = new ConcurrentHashMap<>();
|
||||
private final DeviceSnapshotMapper deviceSnapshotMapper;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
/**
|
||||
* 更新最新的测量数据
|
||||
* @param message 测量数据消息
|
||||
*/
|
||||
public void updateLatestMeasurement(OpcMessage message) {
|
||||
if (message != null) {
|
||||
latestMeasurements.put(message.getClass(), message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建当前所有设备的数据快照
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void createDeviceSnapshots() {
|
||||
try {
|
||||
// 获取当前时间戳
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
// 获取最新的测量数据
|
||||
AppMeasureEntryMessage entry = (AppMeasureEntryMessage) latestMeasurements.get(AppMeasureEntryMessage.class);
|
||||
AppMeasureFurnaceMessage furnace = (AppMeasureFurnaceMessage) latestMeasurements.get(AppMeasureFurnaceMessage.class);
|
||||
AppMeasureCoatMessage coat = (AppMeasureCoatMessage) latestMeasurements.get(AppMeasureCoatMessage.class);
|
||||
AppMeasureExitMessage exit = (AppMeasureExitMessage) latestMeasurements.get(AppMeasureExitMessage.class);
|
||||
|
||||
if (entry == null && furnace == null && coat == null && exit == null) {
|
||||
log.warn("没有可用的测量数据,跳过快照创建");
|
||||
return;
|
||||
}
|
||||
|
||||
// 为每个设备创建快照
|
||||
List<DeviceSnapshot> snapshots = new ArrayList<>();
|
||||
for (DeviceEnum device : DeviceEnum.values()) {
|
||||
try {
|
||||
DeviceSnapshot snapshot = createDeviceSnapshot(device, now, entry, furnace, coat, exit);
|
||||
if (snapshot != null) {
|
||||
snapshots.add(snapshot);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("创建设备[{}]快照失败: {}", device.name(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
// 批量保存快照
|
||||
if (!snapshots.isEmpty()) {
|
||||
for (DeviceSnapshot snapshot : snapshots) {
|
||||
deviceSnapshotMapper.insert(snapshot);
|
||||
}
|
||||
log.info("成功创建{}个设备数据快照", snapshots.size());
|
||||
|
||||
// 推送所有设备的历史趋势数据
|
||||
pushAllDevicesHistoryTrend();
|
||||
|
||||
// 推送设备统计数据
|
||||
pushAllChartData();
|
||||
|
||||
// 推送每个设备每个字段的趋势数据(供前端画“点位趋势小图”)
|
||||
pushAllDeviceFieldTrends();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("创建设备数据快照失败: {}", e.getMessage(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 推送所有设备的历史趋势数据(今天一天的数据,10分钟间隔)
|
||||
*/
|
||||
public void pushAllDevicesHistoryTrend() {
|
||||
try {
|
||||
for (DeviceEnum device : DeviceEnum.values()) {
|
||||
DeviceHistoryTrendDTO trendData = getDeviceHistoryTrend(device.name());
|
||||
if (trendData != null && trendData.getSeries() != null && !trendData.getSeries().isEmpty()) {
|
||||
WebSocketUtil.sendHistoryTrendMessage(trendData);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("推送设备历史趋势数据失败: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 推送设备统计数据
|
||||
*/
|
||||
public void pushAllChartData() {
|
||||
try {
|
||||
DeviceChartDataDTO chartData = buildAllChartData();
|
||||
if (chartData != null) {
|
||||
WebSocketUtil.sendChartDataMessage(chartData);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("推送统计数据失败: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 推送每个设备每个字段的趋势数据(今天范围,10分钟间隔采样)
|
||||
*/
|
||||
public void pushAllDeviceFieldTrends() {
|
||||
try {
|
||||
for (DeviceEnum device : DeviceEnum.values()) {
|
||||
List<String> fields = device.getParamFields();
|
||||
if (fields == null || fields.isEmpty()) continue;
|
||||
for (String field : fields) {
|
||||
DeviceFieldTrendDTO dto = getDeviceFieldTrend(device.name(), field);
|
||||
if (dto != null) {
|
||||
WebSocketUtil.sendDeviceFieldTrendMessage(dto);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("推送设备字段趋势失败: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 单设备-单字段 今日趋势与统计(10分钟采样)
|
||||
*/
|
||||
public DeviceFieldTrendDTO getDeviceFieldTrend(String deviceCode, String fieldName) {
|
||||
try {
|
||||
DeviceEnum device = DeviceEnum.fromName(deviceCode);
|
||||
if (device == null) return null;
|
||||
|
||||
// 今天范围
|
||||
LocalDate today = LocalDate.now();
|
||||
LocalDateTime startTime = today.atStartOfDay();
|
||||
LocalDateTime endTime = today.atTime(LocalTime.MAX);
|
||||
|
||||
// 查询今天的快照
|
||||
LambdaQueryWrapper<DeviceSnapshot> qw = new LambdaQueryWrapper<DeviceSnapshot>()
|
||||
.eq(DeviceSnapshot::getDeviceCode, deviceCode)
|
||||
.between(DeviceSnapshot::getCreateTime, startTime, endTime)
|
||||
.orderByAsc(DeviceSnapshot::getCreateTime);
|
||||
|
||||
List<DeviceSnapshot> rows = deviceSnapshotMapper.selectList(qw);
|
||||
if (rows == null || rows.isEmpty()) return null;
|
||||
|
||||
// 10分钟采样
|
||||
List<DeviceSnapshot> sampled = sampleDataByInterval(rows, 10);
|
||||
|
||||
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");
|
||||
List<String> categories = new ArrayList<>(sampled.size());
|
||||
List<Double> data = new ArrayList<>(sampled.size());
|
||||
|
||||
for (DeviceSnapshot s : sampled) {
|
||||
categories.add(s.getCreateTime().format(timeFormatter));
|
||||
double v = 0.0;
|
||||
try {
|
||||
Map<String, Object> json = objectMapper.readValue(s.getSnapshotData(), Map.class);
|
||||
Object raw = json.get(fieldName);
|
||||
if (raw instanceof Number) v = ((Number) raw).doubleValue();
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
data.add(v);
|
||||
}
|
||||
|
||||
// 统计(忽略全0)
|
||||
List<Double> valid = new ArrayList<>();
|
||||
for (Double v : data) {
|
||||
if (v != null && v != 0.0) valid.add(v);
|
||||
}
|
||||
|
||||
Double avg = null, max = null, min = null;
|
||||
if (!valid.isEmpty()) {
|
||||
double sum = 0;
|
||||
max = valid.get(0);
|
||||
min = valid.get(0);
|
||||
for (Double v : valid) {
|
||||
sum += v;
|
||||
if (v > max) max = v;
|
||||
if (v < min) min = v;
|
||||
}
|
||||
avg = sum / valid.size();
|
||||
}
|
||||
|
||||
Double last = data.isEmpty() ? null : data.get(data.size() - 1);
|
||||
|
||||
return DeviceFieldTrendDTO.builder()
|
||||
.deviceCode(deviceCode)
|
||||
.deviceName(device.getDesc())
|
||||
.fieldName(fieldName)
|
||||
// label/unit 目前后端没有统一来源,这里先留空,前端可用 fieldMeta 补齐
|
||||
.fieldLabel(null)
|
||||
.unit(null)
|
||||
.categories(categories)
|
||||
.data(data)
|
||||
.avg(avg)
|
||||
.max(max)
|
||||
.min(min)
|
||||
.last(last)
|
||||
.build();
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("获取设备字段趋势失败, deviceCode={}, fieldName={}, err={}", deviceCode, fieldName, e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建设备图表数据
|
||||
*/
|
||||
private DeviceChartDataDTO buildAllChartData() {
|
||||
try {
|
||||
// 1. 设备类型分布饼图
|
||||
DeviceChartDataDTO.PieChartData pieChartData = buildDeviceTypePieChart();
|
||||
|
||||
// 2. 数据来源分布条形图
|
||||
DeviceChartDataDTO.BarChartData barChartData = buildSourceTypeBarChart();
|
||||
|
||||
// 3. 同类型设备对比折线图(只对比单位相同的设备)
|
||||
DeviceChartDataDTO.LineChartData lineChartData = buildSameTypeDeviceCompareChart();
|
||||
|
||||
// 4. 设备统计数据
|
||||
List<DeviceChartDataDTO.DeviceStatistics> statistics = buildDeviceStatistics();
|
||||
|
||||
return DeviceChartDataDTO.builder()
|
||||
.deviceTypePieChart(pieChartData)
|
||||
.sourceTypeBarChart(barChartData)
|
||||
.sameTypeDeviceCompareChart(lineChartData)
|
||||
.deviceStatistics(statistics)
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
log.error("构建图表数据失败: {}", e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建设备类型分布饼图数据
|
||||
*/
|
||||
private DeviceChartDataDTO.PieChartData buildDeviceTypePieChart() {
|
||||
Map<String, Integer> distribution = new HashMap<>();
|
||||
distribution.put("入口段", 0);
|
||||
distribution.put("处理段", 0);
|
||||
distribution.put("出口段", 0);
|
||||
distribution.put("其他", 0);
|
||||
|
||||
for (DeviceEnum device : DeviceEnum.values()) {
|
||||
String sectionType = device.getSectionType().name();
|
||||
if ("ENTRY".equals(sectionType)) {
|
||||
distribution.put("入口段", distribution.get("入口段") + 1);
|
||||
} else if ("PROCESS".equals(sectionType)) {
|
||||
distribution.put("处理段", distribution.get("处理段") + 1);
|
||||
} else if ("EXIT".equals(sectionType)) {
|
||||
distribution.put("出口段", distribution.get("出口段") + 1);
|
||||
} else {
|
||||
distribution.put("其他", distribution.get("其他") + 1);
|
||||
}
|
||||
}
|
||||
|
||||
String[] colors = {"#0066cc", "#409eff", "#66b1ff", "#a0cfff"};
|
||||
List<DeviceChartDataDTO.PieSeries> series = new ArrayList<>();
|
||||
int colorIndex = 0;
|
||||
|
||||
for (Map.Entry<String, Integer> entry : distribution.entrySet()) {
|
||||
if (entry.getValue() > 0) {
|
||||
series.add(DeviceChartDataDTO.PieSeries.builder()
|
||||
.name(entry.getKey())
|
||||
.data(entry.getValue().doubleValue())
|
||||
.color(colors[colorIndex % colors.length])
|
||||
.build());
|
||||
colorIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
return DeviceChartDataDTO.PieChartData.builder()
|
||||
.series(series)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建数据来源分布条形图数据
|
||||
*/
|
||||
private DeviceChartDataDTO.BarChartData buildSourceTypeBarChart() {
|
||||
Map<String, Integer> distribution = new HashMap<>();
|
||||
distribution.put("ENTRY", 0);
|
||||
distribution.put("FURNACE", 0);
|
||||
distribution.put("COAT", 0);
|
||||
distribution.put("EXIT", 0);
|
||||
|
||||
for (DeviceEnum device : DeviceEnum.values()) {
|
||||
String sourceType = device.getSourceType().name();
|
||||
if (distribution.containsKey(sourceType)) {
|
||||
distribution.put(sourceType, distribution.get(sourceType) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> categories = new ArrayList<>();
|
||||
List<Double> data = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, Integer> entry : distribution.entrySet()) {
|
||||
if (entry.getValue() > 0) {
|
||||
categories.add(entry.getKey());
|
||||
data.add(entry.getValue().doubleValue());
|
||||
}
|
||||
}
|
||||
|
||||
return DeviceChartDataDTO.BarChartData.builder()
|
||||
.categories(categories)
|
||||
.series(Collections.singletonList(
|
||||
DeviceChartDataDTO.BarSeries.builder()
|
||||
.name("设备数量")
|
||||
.data(data)
|
||||
.build()
|
||||
))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建同类型设备对比折线图数据(只对比单位相同的设备)
|
||||
*/
|
||||
private DeviceChartDataDTO.LineChartData buildSameTypeDeviceCompareChart() {
|
||||
// 获取今天的数据
|
||||
LocalDate today = LocalDate.now();
|
||||
LocalDateTime startTime = today.atStartOfDay();
|
||||
LocalDateTime endTime = today.atTime(LocalTime.MAX);
|
||||
|
||||
// 按数据来源分组,同一来源的设备单位相同,可以对比
|
||||
Map<String, List<DeviceEnum>> devicesBySource = new HashMap<>();
|
||||
for (DeviceEnum device : DeviceEnum.values()) {
|
||||
if (device.getParamFields() == null || device.getParamFields().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
String sourceType = device.getSourceType().name();
|
||||
devicesBySource.computeIfAbsent(sourceType, k -> new ArrayList<>()).add(device);
|
||||
}
|
||||
|
||||
// 选择设备数量最多的数据源,取前5个设备进行对比
|
||||
String selectedSource = devicesBySource.entrySet().stream()
|
||||
.max(Map.Entry.comparingByValue((a, b) -> Integer.compare(a.size(), b.size())))
|
||||
.map(Map.Entry::getKey)
|
||||
.orElse(null);
|
||||
|
||||
if (selectedSource == null || devicesBySource.get(selectedSource).isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<DeviceEnum> selectedDevices = devicesBySource.get(selectedSource).stream()
|
||||
.limit(5)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<String> categories = new ArrayList<>();
|
||||
List<DeviceChartDataDTO.LineSeries> series = new ArrayList<>();
|
||||
|
||||
// 生成时间轴(最近10个时间点,每10分钟一个)
|
||||
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
for (int i = 9; i >= 0; i--) {
|
||||
LocalDateTime time = now.minusMinutes(i * 10L);
|
||||
categories.add(time.format(timeFormatter));
|
||||
}
|
||||
|
||||
// 为每个设备生成数据系列
|
||||
for (DeviceEnum device : selectedDevices) {
|
||||
if (device.getParamFields() == null || device.getParamFields().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取该设备今天的历史数据
|
||||
LambdaQueryWrapper<DeviceSnapshot> qw = new LambdaQueryWrapper<DeviceSnapshot>()
|
||||
.eq(DeviceSnapshot::getDeviceCode, device.name())
|
||||
.between(DeviceSnapshot::getCreateTime, startTime, endTime)
|
||||
.orderByAsc(DeviceSnapshot::getCreateTime);
|
||||
|
||||
List<DeviceSnapshot> rows = deviceSnapshotMapper.selectList(qw);
|
||||
List<DeviceSnapshot> sampledRows = sampleDataByInterval(rows, 10);
|
||||
|
||||
// 使用第一个字段的数据
|
||||
String firstField = device.getParamFields().get(0);
|
||||
List<Double> data = new ArrayList<>();
|
||||
|
||||
// 填充数据(如果历史数据不足,用0填充)
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (i < sampledRows.size()) {
|
||||
try {
|
||||
Map<String, Object> jsonData = objectMapper.readValue(
|
||||
sampledRows.get(i).getSnapshotData(), Map.class);
|
||||
Object value = jsonData.get(firstField);
|
||||
double numValue = 0.0;
|
||||
if (value instanceof Number) {
|
||||
numValue = ((Number) value).doubleValue();
|
||||
}
|
||||
data.add(numValue);
|
||||
} catch (Exception e) {
|
||||
data.add(0.0);
|
||||
}
|
||||
} else {
|
||||
data.add(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
series.add(DeviceChartDataDTO.LineSeries.builder()
|
||||
.name(device.getDesc())
|
||||
.data(data)
|
||||
.build());
|
||||
}
|
||||
|
||||
if (series.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return DeviceChartDataDTO.LineChartData.builder()
|
||||
.categories(categories)
|
||||
.series(series)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建设备统计数据
|
||||
*/
|
||||
private List<DeviceChartDataDTO.DeviceStatistics> buildDeviceStatistics() {
|
||||
List<DeviceChartDataDTO.DeviceStatistics> statistics = new ArrayList<>();
|
||||
LocalDate today = LocalDate.now();
|
||||
LocalDateTime startTime = today.atStartOfDay();
|
||||
LocalDateTime endTime = today.atTime(LocalTime.MAX);
|
||||
|
||||
// 获取最新的测量数据
|
||||
AppMeasureEntryMessage entry = (AppMeasureEntryMessage) latestMeasurements.get(AppMeasureEntryMessage.class);
|
||||
AppMeasureFurnaceMessage furnace = (AppMeasureFurnaceMessage) latestMeasurements.get(AppMeasureFurnaceMessage.class);
|
||||
AppMeasureCoatMessage coat = (AppMeasureCoatMessage) latestMeasurements.get(AppMeasureCoatMessage.class);
|
||||
AppMeasureExitMessage exit = (AppMeasureExitMessage) latestMeasurements.get(AppMeasureExitMessage.class);
|
||||
|
||||
for (DeviceEnum device : DeviceEnum.values()) {
|
||||
if (device.getParamFields() == null || device.getParamFields().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String firstField = device.getParamFields().get(0);
|
||||
|
||||
// 获取当前值
|
||||
double currentValue = 0.0;
|
||||
switch (device.getSourceType()) {
|
||||
case ENTRY:
|
||||
if (entry != null) {
|
||||
currentValue = getFieldValue(entry, firstField);
|
||||
}
|
||||
break;
|
||||
case FURNACE:
|
||||
if (furnace != null) {
|
||||
currentValue = getFieldValue(furnace, firstField);
|
||||
}
|
||||
break;
|
||||
case COAT:
|
||||
if (coat != null) {
|
||||
currentValue = getFieldValue(coat, firstField);
|
||||
}
|
||||
break;
|
||||
case EXIT:
|
||||
if (exit != null) {
|
||||
currentValue = getFieldValue(exit, firstField);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 从历史数据中计算统计值
|
||||
LambdaQueryWrapper<DeviceSnapshot> qw = new LambdaQueryWrapper<DeviceSnapshot>()
|
||||
.eq(DeviceSnapshot::getDeviceCode, device.name())
|
||||
.between(DeviceSnapshot::getCreateTime, startTime, endTime)
|
||||
.orderByAsc(DeviceSnapshot::getCreateTime);
|
||||
|
||||
List<DeviceSnapshot> rows = deviceSnapshotMapper.selectList(qw);
|
||||
List<Double> values = new ArrayList<>();
|
||||
|
||||
for (DeviceSnapshot snapshot : rows) {
|
||||
try {
|
||||
Map<String, Object> jsonData = objectMapper.readValue(
|
||||
snapshot.getSnapshotData(), Map.class);
|
||||
Object value = jsonData.get(firstField);
|
||||
if (value instanceof Number) {
|
||||
double numValue = ((Number) value).doubleValue();
|
||||
if (numValue > 0) {
|
||||
values.add(numValue);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
String avg = "—";
|
||||
String max = "—";
|
||||
String min = "—";
|
||||
|
||||
if (!values.isEmpty()) {
|
||||
double avgValue = values.stream().mapToDouble(Double::doubleValue).average().orElse(0.0);
|
||||
double maxValue = values.stream().mapToDouble(Double::doubleValue).max().orElse(0.0);
|
||||
double minValue = values.stream().mapToDouble(Double::doubleValue).min().orElse(0.0);
|
||||
|
||||
avg = String.format("%.2f", avgValue);
|
||||
max = String.format("%.2f", maxValue);
|
||||
min = String.format("%.2f", minValue);
|
||||
}
|
||||
|
||||
statistics.add(DeviceChartDataDTO.DeviceStatistics.builder()
|
||||
.deviceCode(device.name())
|
||||
.deviceName(device.getDesc())
|
||||
.avg(avg)
|
||||
.max(max)
|
||||
.min(min)
|
||||
.current(currentValue > 0 ? String.format("%.2f", currentValue) : "—")
|
||||
.build());
|
||||
}
|
||||
|
||||
return statistics;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字段值
|
||||
*/
|
||||
private double getFieldValue(Object message, String fieldName) {
|
||||
try {
|
||||
java.lang.reflect.Field field = message.getClass().getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
Object value = field.get(message);
|
||||
if (value instanceof Number) {
|
||||
return ((Number) value).doubleValue();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设备今天一天的历史趋势数据(10分钟间隔采样)
|
||||
* @param deviceCode 设备代码
|
||||
* @return 历史趋势数据
|
||||
*/
|
||||
public DeviceHistoryTrendDTO getDeviceHistoryTrend(String deviceCode) {
|
||||
try {
|
||||
// 获取今天开始和结束时间
|
||||
LocalDate today = LocalDate.now();
|
||||
LocalDateTime startTime = today.atStartOfDay();
|
||||
LocalDateTime endTime = today.atTime(LocalTime.MAX);
|
||||
|
||||
// 查询今天的所有快照数据
|
||||
LambdaQueryWrapper<DeviceSnapshot> qw = new LambdaQueryWrapper<DeviceSnapshot>()
|
||||
.eq(DeviceSnapshot::getDeviceCode, deviceCode)
|
||||
.between(DeviceSnapshot::getCreateTime, startTime, endTime)
|
||||
.orderByAsc(DeviceSnapshot::getCreateTime);
|
||||
|
||||
List<DeviceSnapshot> rows = deviceSnapshotMapper.selectList(qw);
|
||||
if (rows == null || rows.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 按10分钟间隔采样数据
|
||||
List<DeviceSnapshot> sampledRows = sampleDataByInterval(rows, 10);
|
||||
|
||||
// 获取设备信息
|
||||
DeviceEnum device = DeviceEnum.valueOf(deviceCode);
|
||||
if (device == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 构建历史趋势数据
|
||||
List<String> categories = new ArrayList<>();
|
||||
Map<String, List<Double>> seriesMap = new HashMap<>();
|
||||
List<String> fields = device.getParamFields();
|
||||
|
||||
if (fields == null || fields.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 初始化系列数据
|
||||
for (String field : fields) {
|
||||
seriesMap.put(field, new ArrayList<>());
|
||||
}
|
||||
|
||||
// 处理采样后的数据
|
||||
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");
|
||||
for (DeviceSnapshot snapshot : sampledRows) {
|
||||
categories.add(snapshot.getCreateTime().format(timeFormatter));
|
||||
|
||||
Map<String, Object> jsonData = new HashMap<>();
|
||||
try {
|
||||
jsonData = objectMapper.readValue(snapshot.getSnapshotData(), Map.class);
|
||||
} catch (Exception e) {
|
||||
log.warn("解析快照数据失败: {}", snapshot.getSnapshotData());
|
||||
}
|
||||
|
||||
for (String field : fields) {
|
||||
Object value = jsonData.get(field);
|
||||
double numValue = 0.0;
|
||||
if (value instanceof Number) {
|
||||
numValue = ((Number) value).doubleValue();
|
||||
}
|
||||
seriesMap.get(field).add(numValue);
|
||||
}
|
||||
}
|
||||
|
||||
// 构建系列数据(最多6个字段)
|
||||
List<DeviceHistoryTrendDTO.SeriesData> series = fields.stream()
|
||||
.limit(6)
|
||||
.map(field -> DeviceHistoryTrendDTO.SeriesData.builder()
|
||||
.fieldName(field)
|
||||
.name(field) // 前端可以根据字段元数据替换为标签
|
||||
.data(seriesMap.get(field))
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return DeviceHistoryTrendDTO.builder()
|
||||
.deviceCode(deviceCode)
|
||||
.deviceName(device.getDesc())
|
||||
.categories(categories)
|
||||
.series(series)
|
||||
.build();
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("获取设备[{}]历史趋势数据失败: {}", deviceCode, e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按时间间隔采样数据(每N分钟取一条)
|
||||
* @param rows 原始数据列表
|
||||
* @param intervalMinutes 间隔分钟数
|
||||
* @return 采样后的数据列表
|
||||
*/
|
||||
private List<DeviceSnapshot> sampleDataByInterval(List<DeviceSnapshot> rows, int intervalMinutes) {
|
||||
if (rows == null || rows.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<DeviceSnapshot> sampled = new ArrayList<>();
|
||||
LocalDateTime lastTime = null;
|
||||
|
||||
for (DeviceSnapshot row : rows) {
|
||||
LocalDateTime rowTime = row.getCreateTime();
|
||||
|
||||
if (lastTime == null) {
|
||||
// 第一条数据
|
||||
sampled.add(row);
|
||||
lastTime = rowTime;
|
||||
} else {
|
||||
// 计算时间差(分钟)
|
||||
long diffMinutes = java.time.Duration.between(lastTime, rowTime).toMinutes();
|
||||
|
||||
// 如果时间差大于等于间隔,则采样这条数据
|
||||
if (diffMinutes >= intervalMinutes) {
|
||||
sampled.add(row);
|
||||
lastTime = rowTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sampled;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建设备快照
|
||||
*/
|
||||
private DeviceSnapshot createDeviceSnapshot(DeviceEnum device, LocalDateTime timestamp,
|
||||
AppMeasureEntryMessage entry,
|
||||
AppMeasureFurnaceMessage furnace,
|
||||
AppMeasureCoatMessage coat,
|
||||
AppMeasureExitMessage exit) {
|
||||
try {
|
||||
// 创建快照对象
|
||||
DeviceSnapshot snapshot = new DeviceSnapshot();
|
||||
snapshot.setCreateTime(timestamp);
|
||||
snapshot.setDeviceId(device.getIdx());
|
||||
snapshot.setDeviceCode(device.name());
|
||||
snapshot.setDeviceName(device.getDesc());
|
||||
snapshot.setSectionType(device.getSectionType().name());
|
||||
snapshot.setSourceType(device.getSourceType().name());
|
||||
snapshot.setBasePosition(device.getBasePosition());
|
||||
|
||||
// 根据设备类型获取对应的测量数据
|
||||
ObjectNode dataNode = objectMapper.createObjectNode();
|
||||
switch (device.getSourceType()) {
|
||||
case ENTRY:
|
||||
if (entry != null) {
|
||||
extractData(entry, device.getParamFields(), dataNode);
|
||||
}
|
||||
break;
|
||||
case FURNACE:
|
||||
if (furnace != null) {
|
||||
extractData(furnace, device.getParamFields(), dataNode);
|
||||
}
|
||||
break;
|
||||
case COAT:
|
||||
if (coat != null) {
|
||||
extractData(coat, device.getParamFields(), dataNode);
|
||||
}
|
||||
break;
|
||||
case EXIT:
|
||||
if (exit != null) {
|
||||
extractData(exit, device.getParamFields(), dataNode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 如果没有数据,则跳过
|
||||
if (dataNode.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 设置快照数据
|
||||
snapshot.setSnapshotData(dataNode.toString());
|
||||
return snapshot;
|
||||
} catch (Exception e) {
|
||||
log.error("创建设备[{}]快照时发生错误: {}", device.name(), e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从消息对象中提取指定字段的数据
|
||||
*/
|
||||
private void extractData(Object message, List<String> fields, ObjectNode dataNode) {
|
||||
if (message == null || fields == null || fields.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
for (String field : fields) {
|
||||
try {
|
||||
// 使用反射获取字段值
|
||||
java.lang.reflect.Field declaredField = message.getClass().getDeclaredField(field);
|
||||
declaredField.setAccessible(true);
|
||||
Object value = declaredField.get(message);
|
||||
|
||||
// 处理不同类型的值
|
||||
if (value != null) {
|
||||
if (value instanceof Integer) {
|
||||
dataNode.put(field, (Integer) value);
|
||||
} else if (value instanceof Long) {
|
||||
dataNode.put(field, (Long) value);
|
||||
} else if (value instanceof Float) {
|
||||
dataNode.put(field, (Float) value);
|
||||
} else if (value instanceof Double) {
|
||||
dataNode.put(field, (Double) value);
|
||||
} else if (value instanceof Boolean) {
|
||||
dataNode.put(field, (Boolean) value);
|
||||
} else if (value instanceof String) {
|
||||
dataNode.put(field, (String) value);
|
||||
} else if (value instanceof Enum) {
|
||||
dataNode.put(field, value.toString());
|
||||
}
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
log.trace("字段[{}]在消息[{}]中不存在", field, message.getClass().getSimpleName());
|
||||
} catch (Exception e) {
|
||||
log.warn("获取字段[{}]值失败: {}", field, e.getMessage());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("提取数据时发生错误: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.fizz.business.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.fizz.business.domain.BizSendTemplateItem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 发送模板明细 Service
|
||||
*/
|
||||
public interface IBizSendTemplateItemService extends IService<BizSendTemplateItem> {
|
||||
|
||||
/**
|
||||
* 批量更新模板明细(仅更新已有ID)
|
||||
*/
|
||||
Boolean updateItemsBatch(List<BizSendTemplateItem> items);
|
||||
|
||||
/**
|
||||
* 批量保存模板明细(新增/更新/删除)
|
||||
*/
|
||||
Boolean batchSave(Integer templateId, List<BizSendTemplateItem> items, List<Integer> deleteIds, String username);
|
||||
}
|
||||
|
||||
@@ -4,62 +4,39 @@ import java.util.List;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.fizz.business.domain.PdiSetups;
|
||||
import com.fizz.business.domain.ProStoppage;
|
||||
import com.fizz.business.domain.msg.PdiSetup;
|
||||
|
||||
|
||||
/**
|
||||
* 生产计划的参数详情Service接口
|
||||
*
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-09-25
|
||||
*/
|
||||
public interface IPdiSetupService extends IService<PdiSetups>
|
||||
{
|
||||
/**
|
||||
* 查询生产计划的参数详情
|
||||
*
|
||||
* @param id 生产计划的参数详情主键
|
||||
* @return 生产计划的参数详情
|
||||
* 查询张力参数列表
|
||||
*/
|
||||
public PdiSetups selectPdiSetupByid(Long id);
|
||||
List<PdiSetups> selectPdiSetupList(PdiSetups pdiSetup);
|
||||
|
||||
/**
|
||||
* 查询生产计划的参数详情列表
|
||||
*
|
||||
* @param pdiSetup 生产计划的参数详情
|
||||
* @return 生产计划的参数详情集合
|
||||
* 按 id 查询
|
||||
*/
|
||||
public List<PdiSetups> selectPdiSetupList(PdiSetups pdiSetup);
|
||||
PdiSetups selectPdiSetupById(Long id);
|
||||
|
||||
/**
|
||||
* 新增生产计划的参数详情
|
||||
*
|
||||
* @param pdiSetup 生产计划的参数详情
|
||||
* @return 结果
|
||||
* 新增
|
||||
*/
|
||||
public Boolean insertPdiSetup(PdiSetups pdiSetup);
|
||||
Boolean insertPdiSetup(PdiSetups pdiSetup);
|
||||
|
||||
/**
|
||||
* 修改生产计划的参数详情
|
||||
*
|
||||
* @param pdiSetup 生产计划的参数详情
|
||||
* @return 结果
|
||||
* 按 id 更新
|
||||
*/
|
||||
public Boolean updatePdiSetup(PdiSetups pdiSetup);
|
||||
Boolean updatePdiSetup(PdiSetups pdiSetup);
|
||||
|
||||
/**
|
||||
* 批量删除生产计划的参数详情
|
||||
*
|
||||
* @param ids 需要删除的生产计划的参数详情主键集合
|
||||
* @return 结果
|
||||
* 按 id 批量删除
|
||||
*/
|
||||
public Boolean deletePdiSetupByids(Long[] ids);
|
||||
|
||||
/**
|
||||
* 删除生产计划的参数详情信息
|
||||
*
|
||||
* @param id 生产计划的参数详情主键
|
||||
* @return 结果
|
||||
*/
|
||||
public Boolean deletePdiSetupByid(Long id);
|
||||
Boolean deletePdiSetupByIds(Long[] ids);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.fizz.business.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.fizz.business.domain.SetupTensionAllLine;
|
||||
|
||||
/**
|
||||
* 全线张力Service接口
|
||||
*/
|
||||
public interface ISetupTensionAllLineService
|
||||
{
|
||||
SetupTensionAllLine selectByKey(String steelGrade, Float thick, Float yieldStren);
|
||||
|
||||
List<SetupTensionAllLine> selectList(SetupTensionAllLine query);
|
||||
|
||||
int insert(SetupTensionAllLine entity);
|
||||
|
||||
int updateByKey(SetupTensionAllLine entity);
|
||||
|
||||
int deleteByKey(String steelGrade, Float thick, Float yieldStren);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.fizz.business.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.fizz.business.domain.SetupTensionAnnealingFurnace;
|
||||
|
||||
/**
|
||||
* 退火炉张力Service接口
|
||||
*/
|
||||
public interface ISetupTensionAnnealingFurnaceService
|
||||
{
|
||||
SetupTensionAnnealingFurnace selectByKey(String steelGrade, Float thick, Float yieldStren);
|
||||
|
||||
List<SetupTensionAnnealingFurnace> selectList(SetupTensionAnnealingFurnace query);
|
||||
|
||||
int insert(SetupTensionAnnealingFurnace entity);
|
||||
|
||||
int updateByKey(SetupTensionAnnealingFurnace entity);
|
||||
|
||||
int deleteByKey(String steelGrade, Float thick, Float yieldStren);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.fizz.business.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.fizz.business.domain.SetupTensionLeveler;
|
||||
|
||||
/**
|
||||
* 平整机张力Service接口
|
||||
*/
|
||||
public interface ISetupTensionLevelerService
|
||||
{
|
||||
SetupTensionLeveler selectByKey(String steelGrade, Float thick, Float yieldStren);
|
||||
|
||||
List<SetupTensionLeveler> selectList(SetupTensionLeveler query);
|
||||
|
||||
int insert(SetupTensionLeveler entity);
|
||||
|
||||
int updateByKey(SetupTensionLeveler entity);
|
||||
|
||||
int deleteByKey(String steelGrade, Float thick, Float yieldStren);
|
||||
}
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
package com.fizz.business.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.fizz.business.domain.SetupTension;
|
||||
|
||||
/**
|
||||
* 全线张力Service接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-26
|
||||
*/
|
||||
public interface ISetupTensionService
|
||||
{
|
||||
/**
|
||||
* 查询全线张力
|
||||
*
|
||||
* @param thick 全线张力主键
|
||||
* @return 全线张力
|
||||
*/
|
||||
public SetupTension selectSetupTensionByThick(Long thick,Long yieldStren);
|
||||
|
||||
/**
|
||||
* 查询全线张力列表
|
||||
*
|
||||
* @param setupTension 全线张力
|
||||
* @return 全线张力集合
|
||||
*/
|
||||
public List<SetupTension> selectSetupTensionList(SetupTension setupTension);
|
||||
|
||||
/**
|
||||
* 新增全线张力
|
||||
*
|
||||
* @param setupTension 全线张力
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertSetupTension(SetupTension setupTension);
|
||||
|
||||
/**
|
||||
* 修改全线张力
|
||||
*
|
||||
* @param setupTension 全线张力
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateSetupTension(SetupTension setupTension);
|
||||
|
||||
/**
|
||||
* 批量删除全线张力
|
||||
*
|
||||
* @param thicks 需要删除的全线张力主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTensionByThicks(Long[] thicks,Long[] yieldStrens );
|
||||
|
||||
/**
|
||||
* 删除全线张力信息
|
||||
*
|
||||
* @param thick 全线张力主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTensionByThick(Long thick);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.fizz.business.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.fizz.business.domain.SetupTensionStraightener;
|
||||
|
||||
/**
|
||||
* 矫直机张力Service接口
|
||||
*/
|
||||
public interface ISetupTensionStraightenerService
|
||||
{
|
||||
SetupTensionStraightener selectByKey(String steelGrade, Float thick, Float yieldStren);
|
||||
|
||||
List<SetupTensionStraightener> selectList(SetupTensionStraightener query);
|
||||
|
||||
int insert(SetupTensionStraightener entity);
|
||||
|
||||
int updateByKey(SetupTensionStraightener entity);
|
||||
|
||||
int deleteByKey(String steelGrade, Float thick, Float yieldStren);
|
||||
}
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
package com.fizz.business.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.fizz.business.domain.SetupTl;
|
||||
|
||||
/**
|
||||
* 拉矫机参数Service接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-09-26
|
||||
*/
|
||||
public interface ISetupTlService
|
||||
{
|
||||
/**
|
||||
* 查询拉矫机参数
|
||||
*
|
||||
* @param steelGrade 拉矫机参数主键
|
||||
* @return 拉矫机参数
|
||||
*/
|
||||
public SetupTl selectSetupTlBySteelGrade(String steelGrade,Long yieldStren,Long thick);
|
||||
|
||||
/**
|
||||
* 查询拉矫机参数列表
|
||||
*
|
||||
* @param setupTl 拉矫机参数
|
||||
* @return 拉矫机参数集合
|
||||
*/
|
||||
public List<SetupTl> selectSetupTlList(SetupTl setupTl);
|
||||
|
||||
/**
|
||||
* 新增拉矫机参数
|
||||
*
|
||||
* @param setupTl 拉矫机参数
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertSetupTl(SetupTl setupTl);
|
||||
|
||||
/**
|
||||
* 修改拉矫机参数
|
||||
*
|
||||
* @param setupTl 拉矫机参数
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateSetupTl(SetupTl setupTl);
|
||||
|
||||
/**
|
||||
* 批量删除拉矫机参数
|
||||
*
|
||||
* @param steelGrades 需要删除的拉矫机参数主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTlBySteelGrades(String[] steelGrades,Long[] yieldStrens,Long[] thicks);
|
||||
|
||||
/**
|
||||
* 删除拉矫机参数信息
|
||||
*
|
||||
* @param steelGrade 拉矫机参数主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTlBySteelGrade(String steelGrade);
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package com.fizz.business.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.fizz.business.domain.SetupTmBendforce;
|
||||
|
||||
/**
|
||||
* 光整机弯辊力Service接口
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-09-26
|
||||
*/
|
||||
public interface ISetupTmBendforceService
|
||||
{
|
||||
/**
|
||||
* 查询光整机弯辊力
|
||||
*
|
||||
* @param width 光整机弯辊力主键
|
||||
* @return 光整机弯辊力
|
||||
*/
|
||||
public SetupTmBendforce selectSetupTmBendforceByWidth(Long width,Long rollForce);
|
||||
|
||||
/**
|
||||
* 查询光整机弯辊力列表
|
||||
*
|
||||
* @param setupTmBendforce 光整机弯辊力
|
||||
* @return 光整机弯辊力集合
|
||||
*/
|
||||
public List<SetupTmBendforce> selectSetupTmBendforceList(SetupTmBendforce setupTmBendforce);
|
||||
|
||||
/**
|
||||
* 新增光整机弯辊力
|
||||
*
|
||||
* @param setupTmBendforce 光整机弯辊力
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertSetupTmBendforce(SetupTmBendforce setupTmBendforce);
|
||||
|
||||
/**
|
||||
* 修改光整机弯辊力
|
||||
*
|
||||
* @param setupTmBendforce 光整机弯辊力
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateSetupTmBendforce(SetupTmBendforce setupTmBendforce);
|
||||
|
||||
/**
|
||||
* 批量删除光整机弯辊力
|
||||
*
|
||||
* @param widths 需要删除的光整机弯辊力主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTmBendforceByWidths(Long[] widths,Long[] rollForces);
|
||||
|
||||
/**
|
||||
* 删除光整机弯辊力信息
|
||||
*
|
||||
* @param width 光整机弯辊力主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTmBendforceByWidth(Long width);
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package com.fizz.business.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.fizz.business.domain.SetupTmMesh;
|
||||
|
||||
/**
|
||||
* 光整机插入量Service接口
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-09-26
|
||||
*/
|
||||
public interface ISetupTmMeshService
|
||||
{
|
||||
/**
|
||||
* 查询光整机插入量
|
||||
*
|
||||
* @param steelGrade 光整机插入量主键
|
||||
* @return 光整机插入量
|
||||
*/
|
||||
public SetupTmMesh selectSetupTmMeshBySteelGrade(String steelGrade,Long yildStren,Long thick);
|
||||
|
||||
/**
|
||||
* 查询光整机插入量列表
|
||||
*
|
||||
* @param setupTmMesh 光整机插入量
|
||||
* @return 光整机插入量集合
|
||||
*/
|
||||
public List<SetupTmMesh> selectSetupTmMeshList(SetupTmMesh setupTmMesh);
|
||||
|
||||
/**
|
||||
* 新增光整机插入量
|
||||
*
|
||||
* @param setupTmMesh 光整机插入量
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertSetupTmMesh(SetupTmMesh setupTmMesh);
|
||||
|
||||
/**
|
||||
* 修改光整机插入量
|
||||
*
|
||||
* @param setupTmMesh 光整机插入量
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateSetupTmMesh(SetupTmMesh setupTmMesh);
|
||||
|
||||
/**
|
||||
* 批量删除光整机插入量
|
||||
*
|
||||
* @param steelGrades 需要删除的光整机插入量主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTmMeshBySteelGrades(String[] steelGrades,Long[] yildStrens,Long[] thicks);
|
||||
|
||||
/**
|
||||
* 删除光整机插入量信息
|
||||
*
|
||||
* @param steelGrade 光整机插入量主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTmMeshBySteelGrade(String steelGrade);
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package com.fizz.business.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.fizz.business.domain.SetupTmRollforce;
|
||||
|
||||
/**
|
||||
* 光整机轧制力Service接口
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-09-26
|
||||
*/
|
||||
public interface ISetupTmRollforceService
|
||||
{
|
||||
/**
|
||||
* 查询光整机轧制力
|
||||
*
|
||||
* @param steelGrade 光整机轧制力主键
|
||||
* @return 光整机轧制力
|
||||
*/
|
||||
public SetupTmRollforce selectSetupTmRollforceBySteelGrade(String steelGrade,Long yieldStren,Long thick,Long elong);
|
||||
|
||||
/**
|
||||
* 查询光整机轧制力列表
|
||||
*
|
||||
* @param setupTmRollforce 光整机轧制力
|
||||
* @return 光整机轧制力集合
|
||||
*/
|
||||
public List<SetupTmRollforce> selectSetupTmRollforceList(SetupTmRollforce setupTmRollforce);
|
||||
|
||||
/**
|
||||
* 新增光整机轧制力
|
||||
*
|
||||
* @param setupTmRollforce 光整机轧制力
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertSetupTmRollforce(SetupTmRollforce setupTmRollforce);
|
||||
|
||||
/**
|
||||
* 修改光整机轧制力
|
||||
*
|
||||
* @param setupTmRollforce 光整机轧制力
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateSetupTmRollforce(SetupTmRollforce setupTmRollforce);
|
||||
|
||||
/**
|
||||
* 批量删除光整机轧制力
|
||||
*
|
||||
* @param steelGrades 需要删除的光整机轧制力主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTmRollforceBySteelGrades(String[] steelGrades,Long[] yieldStrens,Long[] thicks,Long[] elongs);
|
||||
|
||||
/**
|
||||
* 删除光整机轧制力信息
|
||||
*
|
||||
* @param steelGrade 光整机轧制力主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteSetupTmRollforceBySteelGrade(String steelGrade);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.fizz.business.service;
|
||||
|
||||
import com.fizz.business.form.OpcBatchWriteDataForm;
|
||||
import com.fizz.business.form.OpcWriteDataForm;
|
||||
|
||||
/**
|
||||
* OPC 数据读写服务接口
|
||||
*/
|
||||
public interface OpcDataService {
|
||||
|
||||
/**
|
||||
* 向单个点位写入数据(通过字段名)
|
||||
* @param form 写数据请求表单
|
||||
* @return 是否写入成功
|
||||
*/
|
||||
boolean writeData(OpcWriteDataForm form);
|
||||
|
||||
/**
|
||||
* 批量向多个点位写入数据(通过字段名)
|
||||
* @param form 批量写数据请求表单
|
||||
* @return 是否全部写入成功
|
||||
*/
|
||||
boolean batchWriteData(OpcBatchWriteDataForm form);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.fizz.business.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.fizz.business.domain.ProStoppageType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ProStoppageTypeService extends IService<ProStoppageType> {
|
||||
|
||||
List<ProStoppageType> listAll();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.fizz.business.service.client;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 每个 WS session 的订阅状态(懒加载用)
|
||||
*/
|
||||
@Data
|
||||
public class DeviceFieldTrendSessionState {
|
||||
|
||||
/**
|
||||
* 订阅的 deviceCode 集合;为空代表未订阅任何(不推送)
|
||||
*/
|
||||
private Set<String> deviceCodes = new HashSet<>();
|
||||
|
||||
/**
|
||||
* 订阅的 fieldName 集合;为空代表未订阅任何(不推送)
|
||||
*/
|
||||
private Set<String> fieldNames = new HashSet<>();
|
||||
|
||||
/**
|
||||
* 是否启用懒加载过滤
|
||||
*/
|
||||
private boolean lazy = true;
|
||||
|
||||
public boolean match(String deviceCode, String fieldName) {
|
||||
if (!lazy) return true;
|
||||
if (deviceCodes != null && !deviceCodes.isEmpty() && !deviceCodes.contains(deviceCode)) return false;
|
||||
if (fieldNames != null && !fieldNames.isEmpty() && !fieldNames.contains(fieldName)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static DeviceFieldTrendSessionState emptyLazyOn() {
|
||||
DeviceFieldTrendSessionState s = new DeviceFieldTrendSessionState();
|
||||
s.setLazy(true);
|
||||
s.setDeviceCodes(Collections.emptySet());
|
||||
s.setFieldNames(Collections.emptySet());
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.fizz.business.service.client;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.fizz.business.constants.enums.WsTypeEnum;
|
||||
import com.fizz.business.dto.DeviceFieldTrendSubscribeReq;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.socket.CloseStatus;
|
||||
@@ -7,8 +10,7 @@ import org.springframework.web.socket.TextMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.springframework.web.socket.handler.AbstractWebSocketHandler;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
@@ -19,8 +21,22 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
@Component
|
||||
public class TrackWsHandler extends AbstractWebSocketHandler {
|
||||
|
||||
public static DeviceFieldTrendSessionState getFieldTrendState(String sessionId) {
|
||||
return fieldTrendStates.get(sessionId);
|
||||
}
|
||||
|
||||
public static Map<String, DeviceFieldTrendSessionState> getAllFieldTrendStates() {
|
||||
return fieldTrendStates;
|
||||
}
|
||||
|
||||
private static final ConcurrentHashMap<String, Map<String, WebSocketSession>> clients = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 懒加载订阅状态:只用于 device_field_trend
|
||||
* sessionId -> state
|
||||
*/
|
||||
private static final ConcurrentHashMap<String, DeviceFieldTrendSessionState> fieldTrendStates = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* socket 建立成功事件
|
||||
*
|
||||
@@ -38,6 +54,12 @@ public class TrackWsHandler extends AbstractWebSocketHandler {
|
||||
sessionMap.put(sid, session);
|
||||
// 添加 session
|
||||
clients.put(type, sessionMap);
|
||||
|
||||
// device_field_trend 默认启用懒加载:不主动推送,等前端发送订阅消息
|
||||
if (WsTypeEnum.device_field_trend.name().equals(type)) {
|
||||
fieldTrendStates.put(sid, DeviceFieldTrendSessionState.emptyLazyOn());
|
||||
}
|
||||
|
||||
log.info("[websocket]建立连接:{}", type + sid);
|
||||
} catch (Exception e) {
|
||||
log.error("[websocket]建立连接错误:{}", e.getMessage(), e);
|
||||
@@ -58,6 +80,35 @@ public class TrackWsHandler extends AbstractWebSocketHandler {
|
||||
// 心跳
|
||||
if (payload.equals("ping")) {
|
||||
session.sendMessage(new TextMessage("pong"));
|
||||
return;
|
||||
}
|
||||
|
||||
// device_field_trend 订阅(懒加载)
|
||||
String type = (String) session.getAttributes().get("type");
|
||||
if (WsTypeEnum.device_field_trend.name().equals(type)) {
|
||||
try {
|
||||
DeviceFieldTrendSubscribeReq req = JSONUtil.toBean(payload, DeviceFieldTrendSubscribeReq.class);
|
||||
DeviceFieldTrendSessionState state = fieldTrendStates.get(session.getId());
|
||||
if (state == null) {
|
||||
state = DeviceFieldTrendSessionState.emptyLazyOn();
|
||||
fieldTrendStates.put(session.getId(), state);
|
||||
}
|
||||
if (req.getLazy() != null) {
|
||||
state.setLazy(req.getLazy());
|
||||
}
|
||||
if (req.getDeviceCodes() != null) {
|
||||
state.setDeviceCodes(new HashSet<>(req.getDeviceCodes()));
|
||||
}
|
||||
if (req.getFieldNames() != null) {
|
||||
state.setFieldNames(new HashSet<>(req.getFieldNames()));
|
||||
}
|
||||
log.info("[websocket]device_field_trend订阅更新 sid={}, lazy={}, deviceCodes.size={}, fieldNames.size={}",
|
||||
session.getId(), state.isLazy(),
|
||||
state.getDeviceCodes() == null ? 0 : state.getDeviceCodes().size(),
|
||||
state.getFieldNames() == null ? 0 : state.getFieldNames().size());
|
||||
} catch (Exception e) {
|
||||
log.error("[websocket]解析device_field_trend订阅失败 sid={}, payload={}", session.getId(), payload, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +143,10 @@ public class TrackWsHandler extends AbstractWebSocketHandler {
|
||||
if (webSocketSession != null) {
|
||||
webSocketSession.close();
|
||||
}
|
||||
// 如果是 field_trend 连接,清除订阅状态
|
||||
if (WsTypeEnum.device_field_trend.name().equals(type)) {
|
||||
fieldTrendStates.remove(sid);
|
||||
}
|
||||
}
|
||||
log.info("[websocket]连接关闭:{}", type + "-" + sid);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.fizz.business.anno.OpcMessageHandlerType;
|
||||
import com.fizz.business.constants.enums.OpcMessageType;
|
||||
import com.fizz.business.domain.msg.*;
|
||||
import com.fizz.business.dto.MatmapDTO;
|
||||
import com.fizz.business.service.DeviceSnapshotService;
|
||||
import com.fizz.business.service.LogDataService;
|
||||
import com.fizz.business.service.OpcMessageHandler;
|
||||
import com.fizz.business.service.strip.SegmentTrackerService;
|
||||
@@ -27,6 +28,7 @@ public class AppMeasureHandler implements OpcMessageHandler<AppMeasureMessage> {
|
||||
private final SegmentTrackerService tracker;
|
||||
private final LogDataService logDataService;
|
||||
private final Executor coilTrackExecutor; // 注入线程池接口
|
||||
private final DeviceSnapshotService deviceSnapshotService;
|
||||
|
||||
private static final AtomicInteger LOG_COUNTER = new AtomicInteger(0);
|
||||
|
||||
@@ -39,22 +41,20 @@ public class AppMeasureHandler implements OpcMessageHandler<AppMeasureMessage> {
|
||||
AppMeasureCoatMessage coat = message.getAppMeasureCoatMessage();
|
||||
AppMeasureExitMessage exit = message.getAppMeasureExitMessage();
|
||||
|
||||
// 缓存最新测量数据,供10分钟快照任务使用
|
||||
if (entry != null) deviceSnapshotService.updateLatestMeasurement(entry);
|
||||
if (furnace != null) deviceSnapshotService.updateLatestMeasurement(furnace);
|
||||
if (coat != null) deviceSnapshotService.updateLatestMeasurement(coat);
|
||||
if (exit != null) deviceSnapshotService.updateLatestMeasurement(exit);
|
||||
|
||||
WebSocketUtil.sendMeasureMsg(message);
|
||||
|
||||
|
||||
BigDecimal lengthAtWelder = entry == null || entry.getStripLocation() == null ? BigDecimal.ZERO : entry.getStripLocation();
|
||||
// 处理钢卷ID为空的情况
|
||||
String coilId ="";
|
||||
// if (entry != null && entry.getEntryCoilId() != null){
|
||||
// coilId = entry.getEntryCoilId();
|
||||
//
|
||||
// }else {
|
||||
if (entry != null) {
|
||||
log.error("entry{}",entry.getPayOffReelNumber());
|
||||
}
|
||||
MatmapDTO matmapDTO =getCurrentRunningCoilId(entry);
|
||||
coilId = matmapDTO.getMatId();
|
||||
// }
|
||||
coilId = matmapDTO.getMatId();
|
||||
|
||||
if (StringUtils.isEmpty(coilId) || "".equals(coilId)){
|
||||
log.error("钢卷号为空,无法执行焊缝跟踪!!!!!!");
|
||||
@@ -67,7 +67,7 @@ public class AppMeasureHandler implements OpcMessageHandler<AppMeasureMessage> {
|
||||
int count = LOG_COUNTER.incrementAndGet();
|
||||
if (count % 10 == 0) {
|
||||
logDataService.logInfo("WELDER",
|
||||
"Received weld tracking signal: lengthAtWelder={}, coilId={}",
|
||||
"Received the coil weld tracking signal: Current weld length lengthAtWelder:{} Current coil information coilId:{}",
|
||||
lengthAtWelder, coilId);
|
||||
|
||||
}
|
||||
@@ -75,23 +75,11 @@ public class AppMeasureHandler implements OpcMessageHandler<AppMeasureMessage> {
|
||||
// 核心逻辑处理
|
||||
tracker.handleMeasure(coilId, lengthAtWelder, entry, furnace, coat, exit);
|
||||
|
||||
// 异步执行 trackCoilHeadPosition
|
||||
// coilTrackExecutor.execute(() -> {
|
||||
// try {
|
||||
// log.warn(">>> trackCoilHeadPosition start, thread: {}, coilId: {}",
|
||||
// Thread.currentThread().getName(), coilId);
|
||||
//
|
||||
// tracker.trackCoilHeadPosition(coilId, lengthAtWelder, entry, exit);
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// log.error("trackCoilHeadPosition 执行异常,coilId=" + coilId, e);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
private MatmapDTO getCurrentRunningCoilId(AppMeasureEntryMessage entry) {
|
||||
|
||||
return MatmapUtil.getMatmap(entry.getPayOffReelNumber()-1);
|
||||
return MatmapUtil.getMatmap(entry.getPayOffReelNumber()-1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.fizz.business.domain.msg.ExitCutMessage;
|
||||
import com.fizz.business.dto.ExitCoilInfoDTO;
|
||||
import com.fizz.business.dto.MatmapDTO;
|
||||
import com.fizz.business.form.L1OperateMatForm;
|
||||
import com.fizz.business.service.LogDataService;
|
||||
import com.fizz.business.service.OpcMessageHandler;
|
||||
import com.fizz.business.service.PdoExCoilService;
|
||||
import com.fizz.business.service.TrackService;
|
||||
@@ -32,17 +33,18 @@ public class ExitCutHandler implements OpcMessageHandler<ExitCutMessage> {
|
||||
private final TrackService trackService;
|
||||
@Resource
|
||||
private OpcReceiverHandler opcReceiverHandler;
|
||||
private final LogDataService logDataService;
|
||||
@Override
|
||||
public void handle(ExitCutMessage message) {
|
||||
// 1. 获取卷取机 (TR) 上的物料信息
|
||||
MatmapDTO trMatmap = MatmapUtil.getMatmap(TR.getIdx());
|
||||
|
||||
if (trMatmap == null) {
|
||||
log.error("卷取机不存在");
|
||||
com.fizz.business.service.impl.BeanFactory.getBean(com.fizz.business.service.LogDataService.class)
|
||||
.logInfo("EXIT_CUT", "卷取机不存在");
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("接受到出口剪切信号:{}", JSONUtil.toJsonStr(message));
|
||||
// 2. 根据剪切类型,生成产出卷信息
|
||||
ExitCoilInfoDTO exitCoilInfo = pdoExCoilService.genExitCoilInfo(trMatmap, message.getCutType());
|
||||
|
||||
@@ -54,24 +56,17 @@ public class ExitCutHandler implements OpcMessageHandler<ExitCutMessage> {
|
||||
pdoExCoilService.saveExCoil(exitCoilInfo);
|
||||
|
||||
if (exitCoilInfo.isLastFlag()) {
|
||||
|
||||
logDataService.logInfo("TRACK", "当前trMatmap的值为 -> matId=" + trMatmap.getMatId() + ", planId=" + trMatmap.getPlanId());
|
||||
trackService.l1OperateMat(L1OperateMatForm.builder()
|
||||
.trIdx(TR.getIdx())
|
||||
.entryMatId(trMatmap.getMatId())
|
||||
.planId(trMatmap.getPlanId())
|
||||
.entryMatId(exitCoilInfo.getEntryMatId())
|
||||
.planId(exitCoilInfo.getPlanId())
|
||||
.operation(L1OperateMatEnum.PRODUCT)
|
||||
.build());
|
||||
|
||||
// wangyu 配合二级发一个甩尾信号 01全甩一下
|
||||
EntryMovementMessage msg = new EntryMovementMessage();
|
||||
msg.setCounter(message.getCounter());
|
||||
msg.setMaterialPlaceSource(0);
|
||||
msg.setMaterialPlaceDestination(200);
|
||||
opcReceiverHandler.onMessageReceived(OpcMessageType.ENTRY_MOVEMENT,msg);
|
||||
msg.setMaterialPlaceSource(1);
|
||||
opcReceiverHandler.onMessageReceived(OpcMessageType.ENTRY_MOVEMENT,msg);
|
||||
|
||||
logDataService.logInfo("EXIT_CUT", "成功处理 EXIT_CUT 消息,已保存成品卷 -> exitMatId=" + exitCoilInfo.getExitMatId() + ", planId=" + exitCoilInfo.getPlanId() + ", entryMatId=" + trMatmap.getMatId());
|
||||
}
|
||||
|
||||
log.info("成功处理 EXIT_CUT 消息,已保存成品卷: " + exitCoilInfo.getExitMatId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.fizz.business.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fizz.business.domain.BizSendTemplateItem;
|
||||
import com.fizz.business.mapper.BizSendTemplateItemMapper;
|
||||
import com.fizz.business.service.IBizSendTemplateItemService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
public class BizSendTemplateItemServiceImpl extends ServiceImpl<BizSendTemplateItemMapper, BizSendTemplateItem> implements IBizSendTemplateItemService {
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean updateItemsBatch(List<BizSendTemplateItem> items) {
|
||||
if (items == null || items.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
// MyBatis-Plus 批量更新:这里简单循环 updateById(数量约40~100可接受)
|
||||
for (BizSendTemplateItem it : items) {
|
||||
this.updateById(it);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean batchSave(Integer templateId, List<BizSendTemplateItem> items, List<Integer> deleteIds, String username) {
|
||||
Date now = new Date();
|
||||
|
||||
// 1) 删除(物理删除)。如果你们希望逻辑删除,可在此改为 enabled=0 / deleted 标记。
|
||||
if (deleteIds != null && !deleteIds.isEmpty()) {
|
||||
this.removeByIds(deleteIds);
|
||||
}
|
||||
|
||||
// 2) 新增/更新
|
||||
if (items == null) {
|
||||
items = Collections.emptyList();
|
||||
}
|
||||
|
||||
// 基础校验:templateId 必须一致
|
||||
for (BizSendTemplateItem it : items) {
|
||||
if (it.getTemplateId() == null) {
|
||||
it.setTemplateId(templateId);
|
||||
}
|
||||
}
|
||||
|
||||
// 校验:同一 templateId 下 paramCode 唯一
|
||||
// - 先校验本次提交内是否重复
|
||||
Set<String> seen = new HashSet<>();
|
||||
for (BizSendTemplateItem it : items) {
|
||||
if (it.getParamCode() == null || it.getParamCode().trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("paramCode is required");
|
||||
}
|
||||
String code = it.getParamCode().trim();
|
||||
if (!seen.add(code)) {
|
||||
throw new IllegalArgumentException("Duplicate paramCode in request: " + code);
|
||||
}
|
||||
it.setParamCode(code);
|
||||
}
|
||||
|
||||
// - 再校验数据库里是否已存在同 paramCode(排除自身ID)
|
||||
for (BizSendTemplateItem it : items) {
|
||||
LambdaQueryWrapper<BizSendTemplateItem> qw = new LambdaQueryWrapper<>();
|
||||
qw.eq(BizSendTemplateItem::getTemplateId, templateId)
|
||||
.eq(BizSendTemplateItem::getParamCode, it.getParamCode());
|
||||
if (it.getTemplateItemId() != null) {
|
||||
qw.ne(BizSendTemplateItem::getTemplateItemId, it.getTemplateItemId());
|
||||
}
|
||||
long cnt = this.count(qw);
|
||||
if (cnt > 0) {
|
||||
throw new IllegalArgumentException("paramCode already exists: " + it.getParamCode());
|
||||
}
|
||||
}
|
||||
|
||||
for (BizSendTemplateItem it : items) {
|
||||
it.setTemplateId(templateId);
|
||||
if (it.getTemplateItemId() == null) {
|
||||
it.setCreateBy(username);
|
||||
it.setCreateTime(now);
|
||||
it.setUpdateBy(username);
|
||||
it.setUpdateTime(now);
|
||||
this.save(it);
|
||||
} else {
|
||||
it.setUpdateBy(username);
|
||||
it.setUpdateTime(now);
|
||||
this.updateById(it);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,20 +7,26 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fizz.business.domain.CrmPdiPlan;
|
||||
import com.fizz.business.form.ChangePlanStatusForm;
|
||||
import com.fizz.business.constants.enums.PlanStatusEnum;
|
||||
import com.fizz.business.form.PlanQueryForm;
|
||||
import com.fizz.business.mapper.CrmPdiPlanMapper;
|
||||
import com.fizz.business.service.CrmPdiPlanService;
|
||||
import com.fizz.business.service.LogDataService;
|
||||
import com.fizz.business.vo.CrmPdiPlanVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class CrmPdiPlanServiceImpl extends ServiceImpl<CrmPdiPlanMapper, CrmPdiPlan> implements CrmPdiPlanService {
|
||||
|
||||
@javax.annotation.Resource
|
||||
private LogDataService logDataService;
|
||||
|
||||
|
||||
/**
|
||||
* 根据卷ID和操作员ID查询单个记录
|
||||
@@ -112,8 +118,15 @@ public class CrmPdiPlanServiceImpl extends ServiceImpl<CrmPdiPlanMapper, CrmPdiP
|
||||
}
|
||||
|
||||
// 状态
|
||||
// 前端可能传 "NEW,READY,ONLINE,PRODUCING" 这种逗号分隔字符串,这里按 in 查询
|
||||
if (StrUtil.isNotBlank(form.getStatus())) {
|
||||
queryWrapper.eq("status", form.getStatus());
|
||||
String statusStr = form.getStatus();
|
||||
// 兼容英文逗号/中文逗号、以及可能的空格
|
||||
statusStr = statusStr.replace(',', ',');
|
||||
List<String> statusList = StrUtil.splitTrim(statusStr, ',');
|
||||
if (statusList != null && !statusList.isEmpty()) {
|
||||
queryWrapper.in("status", statusList);
|
||||
}
|
||||
} else {
|
||||
// 如果没传状态,默认查 NEW 和 READY
|
||||
queryWrapper.in("status", "NEW", "READY");
|
||||
@@ -143,23 +156,102 @@ public class CrmPdiPlanServiceImpl extends ServiceImpl<CrmPdiPlanMapper, CrmPdiP
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeStatus(ChangePlanStatusForm build) {
|
||||
public boolean changeStatus(ChangePlanStatusForm build) {
|
||||
|
||||
if (build == null) {
|
||||
if (logDataService != null) {
|
||||
logDataService.logInfo("PLAN", "changeStatus 参数为空");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QueryWrapper<CrmPdiPlan> wrapper = new QueryWrapper<>();
|
||||
|
||||
if (StrUtil.isBlank(build.getMatId())) {
|
||||
|
||||
logDataService.logInfo("PLAN", "changeStatus matId为空, planId=" + build.getId() + ", operation=" + build.getOperation());
|
||||
return false;
|
||||
}
|
||||
|
||||
wrapper.eq("coilid", build.getMatId());
|
||||
wrapper.eq("planid", build.getId());
|
||||
|
||||
// planId 非空时:matId + planId 精确匹配
|
||||
// planId 为空时:仅用 matId 匹配(coilid 唯一)
|
||||
if (StrUtil.isNotBlank(build.getId())) {
|
||||
wrapper.eq("planid", build.getId());
|
||||
}
|
||||
|
||||
CrmPdiPlan pdiPlan = baseMapper.selectOne(wrapper);
|
||||
|
||||
if (pdiPlan == null) {
|
||||
log.error("未找到ID为{}的计划记录", build.getId());
|
||||
return;
|
||||
logDataService.logInfo("PLAN", "未找到计划记录, matId=" + build.getMatId() + ", planId=" + build.getId() + ", operation=" + build.getOperation());
|
||||
return false;
|
||||
}
|
||||
|
||||
pdiPlan.setStatus(build.getOperation());
|
||||
String oldStatus = pdiPlan.getStatus();
|
||||
String newStatus = build.getOperation();
|
||||
|
||||
baseMapper.updateById(pdiPlan);
|
||||
log.info("计划状态更新成功,ID: {}, 新状态: {}", build.getId(), build.getOperation());
|
||||
// 状态机保护:禁止已完成(PRODUCT)的计划回退到生产中(PRODUCING)
|
||||
if (PlanStatusEnum.PRODUCT.name().equals(oldStatus) && PlanStatusEnum.PRODUCING.name().equals(newStatus)) {
|
||||
logDataService.logWarn("PLAN", "拦截计划状态回退: matId=" + build.getMatId() + ", planId=" + build.getId() + ", " + oldStatus + " -> " + newStatus);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 幂等:同状态重复更新直接放行(避免重复写库导致的误判)
|
||||
if (Objects.equals(oldStatus, newStatus)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
pdiPlan.setStatus(newStatus);
|
||||
|
||||
int rows = baseMapper.updateById(pdiPlan);
|
||||
if (rows <= 0) {
|
||||
logDataService.logInfo("PLAN", "计划状态更新失败, matId=" + build.getMatId() + ", planId=" + build.getId() + ", operation=" + newStatus);
|
||||
return false;
|
||||
}
|
||||
logDataService.logInfo("PLAN", "计划状态更新成功, matId=" + build.getMatId() + ", planId=" + build.getId() + ", {} -> {}", oldStatus, newStatus);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前正在线上的钢卷(优先级:ONLINE > PRODUCING > READY/NEW)
|
||||
* @return 当前正在线上的钢卷,如果没有则返回null
|
||||
*/
|
||||
@Override
|
||||
public CrmPdiPlan getCurrentOnlineCoil() {
|
||||
|
||||
|
||||
// 1. 优先查找 PRODUCING 状态的钢卷
|
||||
CrmPdiPlan producingPlan = this.lambdaQuery()
|
||||
.eq(CrmPdiPlan::getStatus, "PRODUCING")
|
||||
.orderByAsc(CrmPdiPlan::getSeqid)
|
||||
.last("limit 1")
|
||||
.one();
|
||||
|
||||
if (producingPlan != null) {
|
||||
return producingPlan;
|
||||
}
|
||||
|
||||
// 2. 其次查找 ONLINE 状态的钢卷
|
||||
CrmPdiPlan onlinePlan = this.lambdaQuery()
|
||||
.eq(CrmPdiPlan::getStatus, "ONLINE")
|
||||
.orderByAsc(CrmPdiPlan::getSeqid)
|
||||
.last("limit 1")
|
||||
.one();
|
||||
|
||||
if (onlinePlan != null) {
|
||||
return onlinePlan;
|
||||
}
|
||||
|
||||
|
||||
// 3. 最后查找 READY 或 NEW 状态的钢卷(按顺序号排序,取第一个)
|
||||
CrmPdiPlan readyOrNewPlan = this.lambdaQuery()
|
||||
.in(CrmPdiPlan::getStatus, "READY", "NEW")
|
||||
.orderByAsc(CrmPdiPlan::getSeqid)
|
||||
.last("limit 1")
|
||||
.one();
|
||||
|
||||
return readyOrNewPlan;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public class CrmPdoExcoilServiceImpl extends ServiceImpl<CrmPdoExcoilMapper, Crm
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有记录
|
||||
* 查询所有记录(支持分页)
|
||||
*
|
||||
* @return CrmPdoExcoil对象的列表
|
||||
*/
|
||||
@@ -80,8 +80,6 @@ public class CrmPdoExcoilServiceImpl extends ServiceImpl<CrmPdoExcoilMapper, Crm
|
||||
// 根据 exit_coilid 和 encoilid 进行查询
|
||||
if (!StringUtils.isEmpty(form.getCoilid())) {
|
||||
queryWrapper.like("exit_mat_id", form.getCoilid());
|
||||
|
||||
return baseMapper.selectList(queryWrapper);
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(form.getStartDate())&& !StringUtils.isEmpty(form.getEndDate())){
|
||||
|
||||
@@ -77,9 +77,6 @@ public class LogDataServiceImpl extends ServiceImpl<LogDataMapper, LogData> impl
|
||||
@Override
|
||||
public void logInfo(String module, String content, Object... args) {
|
||||
try {
|
||||
if (args.length > 0) {
|
||||
content = formatMessage(content, args);
|
||||
}
|
||||
saveLogData("INFORMATION", module, content);
|
||||
} catch (Exception e) {
|
||||
log.error("没存进去,没事,{}",e);
|
||||
@@ -88,9 +85,6 @@ public class LogDataServiceImpl extends ServiceImpl<LogDataMapper, LogData> impl
|
||||
|
||||
@Override
|
||||
public void logWarn(String module, String content, Object... args) {
|
||||
if (args.length > 0) {
|
||||
content = formatMessage(content, args);
|
||||
}
|
||||
saveLogData("WARN", module, content);
|
||||
}
|
||||
|
||||
@@ -105,34 +99,4 @@ public class LogDataServiceImpl extends ServiceImpl<LogDataMapper, LogData> impl
|
||||
save(logData);
|
||||
}
|
||||
|
||||
private String formatMessage(String pattern, Object[] arguments) {
|
||||
if (pattern == null) {
|
||||
return null;
|
||||
}
|
||||
if (arguments == null || arguments.length == 0) {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int argIndex = 0;
|
||||
int i = 0;
|
||||
|
||||
while (i < pattern.length()) {
|
||||
char c = pattern.charAt(i);
|
||||
if (c == '{' && i + 1 < pattern.length() && pattern.charAt(i + 1) == '}') {
|
||||
if (argIndex < arguments.length) {
|
||||
sb.append(String.valueOf(arguments[argIndex++]));
|
||||
} else {
|
||||
sb.append("{}");
|
||||
}
|
||||
i += 2;
|
||||
} else {
|
||||
sb.append(c);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.fizz.business.service.impl;
|
||||
|
||||
import com.fizz.business.comm.OPC.OpcMessageSend;
|
||||
import com.fizz.business.form.OpcBatchWriteDataForm;
|
||||
import com.fizz.business.form.OpcWriteDataForm;
|
||||
import com.fizz.business.service.LogDataService;
|
||||
import com.fizz.business.service.OpcDataService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* OPC 数据读写服务实现类
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(prefix = "kangaroohy.milo", name = "enabled", havingValue = "true")
|
||||
public class OpcDataServiceImpl implements OpcDataService {
|
||||
|
||||
private final OpcMessageSend opcMessageSend;
|
||||
private final LogDataService logDataService;
|
||||
|
||||
@Override
|
||||
public boolean writeData(OpcWriteDataForm form) {
|
||||
try {
|
||||
return opcMessageSend.writeDataByFieldName(form.getFieldName(), form.getValue());
|
||||
} catch (Exception e) {
|
||||
log.error("写入 OPC 数据异常,fieldName={}, value={}", form.getFieldName(), form.getValue(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean batchWriteData(OpcBatchWriteDataForm form) {
|
||||
try {
|
||||
|
||||
int rawSize = form.getDataList().size();
|
||||
|
||||
int nullItemCount = 0;
|
||||
int nullFieldNameCount = 0;
|
||||
int nullValueCount = 0;
|
||||
StringBuilder nullValueFields = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < form.getDataList().size(); i++) {
|
||||
OpcWriteDataForm d = form.getDataList().get(i);
|
||||
if (d == null) {
|
||||
nullItemCount++;
|
||||
continue;
|
||||
}
|
||||
if (d.getFieldName() == null) {
|
||||
nullFieldNameCount++;
|
||||
continue;
|
||||
}
|
||||
if (d.getValue() == null) {
|
||||
nullValueCount++;
|
||||
if (nullValueFields.length() < 1500) {
|
||||
if (nullValueFields.length() > 0) {
|
||||
nullValueFields.append(",");
|
||||
}
|
||||
nullValueFields.append(d.getFieldName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> fieldDataMap = form.getDataList().stream()
|
||||
.filter(d -> d != null && d.getFieldName() != null)
|
||||
.collect(Collectors.toMap(
|
||||
OpcWriteDataForm::getFieldName,
|
||||
OpcWriteDataForm::getValue,
|
||||
(v1, v2) -> v2 // 如果有重复的 key,保留后面的值
|
||||
));
|
||||
|
||||
return opcMessageSend.batchWriteData(fieldDataMap);
|
||||
} catch (Exception e) {
|
||||
log.error("批量写入 OPC 数据异常", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package com.fizz.business.service.impl;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.fizz.business.mapper.PdiSetupMapper;
|
||||
import com.fizz.business.domain.PdiSetups;
|
||||
@@ -15,83 +14,48 @@ import com.fizz.business.service.IPdiSetupService;
|
||||
|
||||
/**
|
||||
* 生产计划的参数详情Service业务层处理
|
||||
*
|
||||
*
|
||||
* @author Joshi
|
||||
* @date 2025-09-25
|
||||
*/
|
||||
@Service
|
||||
public class PdiSetupServiceImpl extends ServiceImpl<PdiSetupMapper, PdiSetups> implements IPdiSetupService {
|
||||
/**
|
||||
* 查询生产计划的参数详情
|
||||
*
|
||||
* @param id 生产计划的参数详情主键
|
||||
* @return 生产计划的参数详情
|
||||
*/
|
||||
|
||||
@Override
|
||||
public PdiSetups selectPdiSetupByid(Long id)
|
||||
{
|
||||
return baseMapper.selectById(id);
|
||||
public List<PdiSetups> selectPdiSetupList(PdiSetups pdiSetup) {
|
||||
return lambdaQuery()
|
||||
.eq(StrUtil.isNotBlank(pdiSetup.getCoilid()), PdiSetups::getCoilid, pdiSetup.getCoilid())
|
||||
.eq(StrUtil.isNotBlank(pdiSetup.getPlanid()), PdiSetups::getPlanid, pdiSetup.getPlanid())
|
||||
.eq(StrUtil.isNotBlank(pdiSetup.getSteelGrade()), PdiSetups::getSteelGrade, pdiSetup.getSteelGrade())
|
||||
.eq(Objects.nonNull(pdiSetup.getThick()), PdiSetups::getThick, pdiSetup.getThick())
|
||||
.eq(Objects.nonNull(pdiSetup.getYieldStren()), PdiSetups::getYieldStren, pdiSetup.getYieldStren())
|
||||
.orderByDesc(PdiSetups::getUpdateTime)
|
||||
.list();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询生产计划的参数详情列表
|
||||
*
|
||||
* @param pdiSetup 生产计划的参数详情
|
||||
* @return 生产计划的参数详情
|
||||
*/
|
||||
@Override
|
||||
public List<PdiSetups> selectPdiSetupList(PdiSetups pdiSetup)
|
||||
{
|
||||
QueryWrapper<PdiSetups> queryWrapper = new QueryWrapper<>(pdiSetup);
|
||||
queryWrapper.orderByDesc("create_time");
|
||||
return baseMapper.selectList(queryWrapper);
|
||||
public PdiSetups selectPdiSetupById(Long id) {
|
||||
return getById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增生产计划的参数详情
|
||||
*
|
||||
* @param pdiSetup 生产计划的参数详情
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertPdiSetup(PdiSetups pdiSetup)
|
||||
{
|
||||
return this.save(pdiSetup);
|
||||
public Boolean insertPdiSetup(PdiSetups pdiSetup) {
|
||||
pdiSetup.setCreateTime(ObjectUtil.defaultIfNull(pdiSetup.getCreateTime(), new Date()));
|
||||
pdiSetup.setUpdateTime(new Date());
|
||||
return save(pdiSetup);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改生产计划的参数详情
|
||||
*
|
||||
* @param pdiSetup 生产计划的参数详情
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public Boolean updatePdiSetup(PdiSetups pdiSetup)
|
||||
{
|
||||
return this.updateById(pdiSetup);
|
||||
public Boolean updatePdiSetup(PdiSetups pdiSetup) {
|
||||
if (pdiSetup.getId() == null) {
|
||||
throw new IllegalArgumentException("When updating the tension parameter, the id cannot be empty");
|
||||
}
|
||||
pdiSetup.setUpdateTime(new Date());
|
||||
return updateById(pdiSetup);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除生产计划的参数详情
|
||||
*
|
||||
* @param ids 需要删除的生产计划的参数详情主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public Boolean deletePdiSetupByids(Long[] ids)
|
||||
{
|
||||
return this.removeByIds(Arrays.asList(ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除生产计划的参数详情信息
|
||||
*
|
||||
* @param id 生产计划的参数详情主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public Boolean deletePdiSetupByid(Long id)
|
||||
{
|
||||
return this.removeById(id);
|
||||
public Boolean deletePdiSetupByIds(Long[] ids) {
|
||||
return removeByIds(java.util.Arrays.asList(ids));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class ProStoppageServiceImpl extends ServiceImpl<ProStoppageMapper, ProSt
|
||||
|
||||
@Override
|
||||
public boolean deleteProStoppage(Long stopid) {
|
||||
return this.deleteProStoppage(stopid);
|
||||
return this.removeById(stopid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.fizz.business.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fizz.business.domain.ProStoppageType;
|
||||
import com.fizz.business.mapper.ProStoppageTypeMapper;
|
||||
import com.fizz.business.service.ProStoppageTypeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class ProStoppageTypeServiceImpl extends ServiceImpl<ProStoppageTypeMapper, ProStoppageType> implements ProStoppageTypeService {
|
||||
|
||||
@Override
|
||||
public List<ProStoppageType> listAll() {
|
||||
return baseMapper.selectList(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,17 +4,26 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.fizz.business.domain.BizSendJob;
|
||||
import com.fizz.business.domain.BizSendJobGroup;
|
||||
import com.fizz.business.domain.BizSendJobItem;
|
||||
import com.fizz.business.domain.CrmPdiPlan;
|
||||
import com.fizz.business.domain.vo.BizSendTemplateItemVO;
|
||||
import com.fizz.business.domain.vo.BizSendTemplateVO;
|
||||
import com.fizz.business.domain.vo.SendJobLastSuccessVO;
|
||||
import com.fizz.business.mapper.BizSendJobGroupMapper;
|
||||
import com.fizz.business.mapper.BizSendJobItemMapper;
|
||||
import com.fizz.business.mapper.BizSendJobMapper;
|
||||
import com.fizz.business.mapper.CrmPdiPlanMapper;
|
||||
import com.fizz.business.service.IBizSendTemplateService;
|
||||
import com.fizz.business.service.ISendJobQueryService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class SendJobQueryServiceImpl implements ISendJobQueryService {
|
||||
@@ -28,50 +37,160 @@ public class SendJobQueryServiceImpl implements ISendJobQueryService {
|
||||
@Autowired
|
||||
private BizSendJobItemMapper itemMapper;
|
||||
|
||||
@Autowired
|
||||
private IBizSendTemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private CrmPdiPlanMapper planMapper;
|
||||
|
||||
@Override
|
||||
public SendJobLastSuccessVO getLastSuccess(String groupType) {
|
||||
// 1) 先找最近一次 COMPLETED 的 job(倒序)
|
||||
// 1. 根据 groupType 从 group 表中找到所有相关的 job_id
|
||||
List<BizSendJobGroup> groupsWithType = groupMapper.selectList(
|
||||
new LambdaQueryWrapper<BizSendJobGroup>().eq(BizSendJobGroup::getGroupType, groupType)
|
||||
);
|
||||
|
||||
if (CollectionUtils.isEmpty(groupsWithType)) {
|
||||
// 如果一个相关的 group 都没有,直接走 fallback 逻辑
|
||||
return getFallbackValues(groupType);
|
||||
}
|
||||
|
||||
List<Integer> jobIds = groupsWithType.stream()
|
||||
.map(BizSendJobGroup::getJobId)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 2. 在这些 job_id 中,找到状态为 COMPLETED 且时间最新的一个 job
|
||||
BizSendJob lastJob = jobMapper.selectOne(
|
||||
new LambdaQueryWrapper<BizSendJob>()
|
||||
.in(BizSendJob::getJobId, jobIds)
|
||||
.eq(BizSendJob::getStatus, "COMPLETED")
|
||||
.orderByDesc(BizSendJob::getFinishTime)
|
||||
.last("LIMIT 1")
|
||||
);
|
||||
if (lastJob == null) {
|
||||
return null;
|
||||
|
||||
// 如果找到了,直接返回上次成功的值
|
||||
if (lastJob != null) {
|
||||
List<BizSendJobGroup> groups = groupMapper.selectList(
|
||||
new LambdaQueryWrapper<BizSendJobGroup>()
|
||||
.eq(BizSendJobGroup::getJobId, lastJob.getJobId())
|
||||
);
|
||||
if (groups != null && !groups.isEmpty()) {
|
||||
List<Integer> groupIdsForJob = groups.stream().map(BizSendJobGroup::getGroupId).collect(Collectors.toList());
|
||||
List<BizSendJobItem> items = itemMapper.selectList(
|
||||
new LambdaQueryWrapper<BizSendJobItem>()
|
||||
.in(BizSendJobItem::getGroupId, groupIdsForJob)
|
||||
.eq(BizSendJobItem::getResultStatus, "SUCCESS")
|
||||
.orderByAsc(BizSendJobItem::getItemId)
|
||||
);
|
||||
|
||||
Map<String, String> values = new HashMap<>();
|
||||
for (BizSendJobItem it : items) {
|
||||
if (it.getParamCode() == null) continue;
|
||||
values.put(it.getParamCode(), it.getValueRaw());
|
||||
}
|
||||
|
||||
SendJobLastSuccessVO vo = new SendJobLastSuccessVO();
|
||||
vo.setJobId(lastJob.getJobId());
|
||||
vo.setLastSendTime(lastJob.getFinishTime());
|
||||
vo.setValues(values);
|
||||
// 添加一个标志,告诉前端这是真实发送过的值
|
||||
vo.setIsFromHistory(true);
|
||||
return vo;
|
||||
}
|
||||
}
|
||||
|
||||
// 2) 找该 job 下对应 groupType 的 groups
|
||||
List<BizSendJobGroup> groups = groupMapper.selectList(
|
||||
new LambdaQueryWrapper<BizSendJobGroup>()
|
||||
.eq(BizSendJobGroup::getJobId, lastJob.getJobId())
|
||||
.eq(groupType != null && !groupType.trim().isEmpty(), BizSendJobGroup::getGroupType, groupType)
|
||||
);
|
||||
if (groups == null || groups.isEmpty()) {
|
||||
return null;
|
||||
// 如果没找到符合条件的 job,走 fallback 逻辑
|
||||
return getFallbackValues(groupType);
|
||||
}
|
||||
|
||||
private SendJobLastSuccessVO getFallbackValues(String groupType) {
|
||||
if ("FURNACE".equalsIgnoreCase(groupType)) {
|
||||
return getFurnaceTemplateValues();
|
||||
} else if ("DRIVE".equalsIgnoreCase(groupType)) {
|
||||
return getDrivePlanValues();
|
||||
}
|
||||
return null; // 其他情况返回 null
|
||||
}
|
||||
|
||||
List<Integer> groupIds = groups.stream().map(BizSendJobGroup::getGroupId).collect(java.util.stream.Collectors.toList());
|
||||
|
||||
// 3) 取这些 group 的 item,按 paramCode 聚合最后一次值(同 paramCode 取最后一条 itemId 最大)
|
||||
List<BizSendJobItem> items = itemMapper.selectList(
|
||||
new LambdaQueryWrapper<BizSendJobItem>()
|
||||
.in(BizSendJobItem::getGroupId, groupIds)
|
||||
.eq(BizSendJobItem::getResultStatus, "SUCCESS")
|
||||
.orderByAsc(BizSendJobItem::getItemId)
|
||||
);
|
||||
/**
|
||||
* 获取炉火工艺模板的默认值
|
||||
*/
|
||||
private SendJobLastSuccessVO getFurnaceTemplateValues() {
|
||||
// "FURNACE_DEFAULT" 是前端写死的模板编码
|
||||
BizSendTemplateVO template = templateService.getTemplateWithItems("FURNACE_DEFAULT");
|
||||
if (template == null || template.getItems() == null || template.getItems().isEmpty()) {
|
||||
return createEmptyResponse("Furnace template 'FURNACE_DEFAULT' not found or is empty.");
|
||||
}
|
||||
|
||||
Map<String, String> values = new HashMap<>();
|
||||
for (BizSendJobItem it : items) {
|
||||
if (it.getParamCode() == null) continue;
|
||||
values.put(it.getParamCode(), it.getValueRaw());
|
||||
for (BizSendTemplateItemVO item : template.getItems()) {
|
||||
if (item.getEnabled() && item.getParamCode() != null) {
|
||||
values.put(item.getParamCode(), item.getDefaultValueRaw());
|
||||
}
|
||||
}
|
||||
|
||||
SendJobLastSuccessVO vo = new SendJobLastSuccessVO();
|
||||
vo.setJobId(lastJob.getJobId());
|
||||
vo.setLastSendTime(lastJob.getFinishTime());
|
||||
vo.setValues(values);
|
||||
// 标志为非历史值
|
||||
vo.setIsFromHistory(false);
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前计划的传动参数
|
||||
*/
|
||||
private SendJobLastSuccessVO getDrivePlanValues() {
|
||||
// 优先找 PRODUCING 或 ONLINE 状态的计划,按更新时间倒序取最新的一个
|
||||
CrmPdiPlan currentPlan = planMapper.selectOne(
|
||||
new LambdaQueryWrapper<CrmPdiPlan>()
|
||||
.in(CrmPdiPlan::getStatus, "PRODUCING", "ONLINE")
|
||||
.orderByDesc(CrmPdiPlan::getUpdateTime)
|
||||
.last("LIMIT 1")
|
||||
);
|
||||
|
||||
// 如果没有正在生产的,就找第一个 READY 的计划
|
||||
if (currentPlan == null) {
|
||||
currentPlan = planMapper.selectOne(
|
||||
new LambdaQueryWrapper<CrmPdiPlan>()
|
||||
.eq(CrmPdiPlan::getStatus, "READY")
|
||||
.orderByAsc(CrmPdiPlan::getSeqid)
|
||||
.last("LIMIT 1")
|
||||
);
|
||||
}
|
||||
|
||||
if (currentPlan == null) {
|
||||
return createEmptyResponse("No active or ready plan found.");
|
||||
}
|
||||
|
||||
// 将 CrmPdiPlan 对象的字段反射为 Map
|
||||
Map<String, String> values = new HashMap<>();
|
||||
Field[] fields = CrmPdiPlan.class.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
Object value = field.get(currentPlan);
|
||||
if (value != null) {
|
||||
values.put(field.getName(), String.valueOf(value));
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
// 忽略无法访问的字段
|
||||
}
|
||||
}
|
||||
|
||||
SendJobLastSuccessVO vo = new SendJobLastSuccessVO();
|
||||
vo.setValues(values);
|
||||
vo.setIsFromHistory(false); // 标志为非历史值
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个空的带消息的返回对象
|
||||
*/
|
||||
private SendJobLastSuccessVO createEmptyResponse(String message) {
|
||||
SendJobLastSuccessVO vo = new SendJobLastSuccessVO();
|
||||
vo.setValues(Collections.singletonMap("_message", message));
|
||||
vo.setIsFromHistory(false);
|
||||
return vo;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,8 +13,13 @@ import com.fizz.business.domain.vo.SendJobItemVO;
|
||||
import com.fizz.business.mapper.BizSendJobGroupMapper;
|
||||
import com.fizz.business.mapper.BizSendJobItemMapper;
|
||||
import com.fizz.business.mapper.BizSendJobMapper;
|
||||
import com.fizz.business.domain.CrmPdiPlan;
|
||||
import com.fizz.business.domain.vo.FurnaceSendCoilInfoVO;
|
||||
import com.fizz.business.service.CrmPdiPlanService;
|
||||
import com.fizz.business.service.ISendJobService;
|
||||
import com.fizz.business.service.manager.OpcMessageIdsManager;
|
||||
import com.fizz.business.utils.RedisUtil;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -45,15 +50,20 @@ public class SendJobServiceImpl extends ServiceImpl<BizSendJobMapper, BizSendJob
|
||||
@Autowired
|
||||
private OpcMessageIdsManager opcMessageIdsManager;
|
||||
|
||||
@Autowired
|
||||
private CrmPdiPlanService crmPdiPlanService;
|
||||
|
||||
private static final String REDIS_KEY_FURNACE_SEND_COIL_INFO = "furnace:send:coil:info";
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer createSendJob(SendJobCreateDTO dto) {
|
||||
// 1. 创建批次
|
||||
BizSendJob job = new BizSendJob();
|
||||
BeanUtils.copyProperties(dto, job);
|
||||
|
||||
// 生成业务唯一键
|
||||
String bizKey = opcMessageIdsManager.generateMessageId("SEND_JOB");
|
||||
|
||||
// 生成业务唯一键(OpcMessageIdsManager 目前没有 generateMessageId 方法,改用 UUID)
|
||||
String bizKey = "SEND_JOB_" + UUID.randomUUID();
|
||||
job.setBizKey(bizKey);
|
||||
job.setStatus("PENDING");
|
||||
|
||||
@@ -107,12 +117,36 @@ public class SendJobServiceImpl extends ServiceImpl<BizSendJobMapper, BizSendJob
|
||||
@Override
|
||||
public List<BizSendJob> selectSendJobList(SendJobQueryDTO query) {
|
||||
LambdaQueryWrapper<BizSendJob> qw = new LambdaQueryWrapper<>();
|
||||
qw.eq(StringUtils.isNotBlank(query.getDeviceName()),
|
||||
qw.eq(StringUtils.isNotBlank(query.getDeviceName()),
|
||||
BizSendJob::getDeviceName, query.getDeviceName())
|
||||
.eq(StringUtils.isNotBlank(query.getStatus()),
|
||||
.eq(StringUtils.isNotBlank(query.getStatus()),
|
||||
BizSendJob::getStatus, query.getStatus())
|
||||
.orderByDesc(BizSendJob::getCreateTime);
|
||||
return baseMapper.selectList(qw);
|
||||
|
||||
List<BizSendJob> jobs = baseMapper.selectList(qw);
|
||||
if (jobs == null || jobs.isEmpty()) {
|
||||
return jobs;
|
||||
}
|
||||
|
||||
// 如果传了 groupType(如 FURNACE),则仅保留包含该 groupType 的 job
|
||||
if (StringUtils.isNotBlank(query.getGroupType())) {
|
||||
String gt = query.getGroupType().trim();
|
||||
|
||||
List<Integer> jobIds = jobs.stream().map(BizSendJob::getJobId).collect(Collectors.toList());
|
||||
List<BizSendJobGroup> groups = jobGroupMapper.selectList(
|
||||
new LambdaQueryWrapper<BizSendJobGroup>()
|
||||
.in(BizSendJobGroup::getJobId, jobIds)
|
||||
.eq(BizSendJobGroup::getGroupType, gt)
|
||||
);
|
||||
if (groups == null || groups.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Set<Integer> allowedJobIds = groups.stream().map(BizSendJobGroup::getJobId).collect(Collectors.toSet());
|
||||
return jobs.stream().filter(j -> allowedJobIds.contains(j.getJobId())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
return jobs;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -268,7 +302,9 @@ public class SendJobServiceImpl extends ServiceImpl<BizSendJobMapper, BizSendJob
|
||||
boolean success = true;
|
||||
String failMsg = null;
|
||||
try {
|
||||
opcMessageSend.writeNode(last.getAddress(), last.getValueRaw());
|
||||
// OpcMessageSend 没有 writeNode 方法,使用 writeData(identifier, value)
|
||||
// address 字段在本业务里就是 OPC 的 identifier(如:ns=2;s=...)
|
||||
opcMessageSend.writeData(last.getAddress(), last.getValueRaw());
|
||||
} catch (Exception ex) {
|
||||
success = false;
|
||||
allSuccess = false;
|
||||
@@ -314,6 +350,35 @@ public class SendJobServiceImpl extends ServiceImpl<BizSendJobMapper, BizSendJob
|
||||
finish.setRemark(allSuccess ? "全部发送成功" : "部分发送失败");
|
||||
baseMapper.updateById(finish);
|
||||
|
||||
// 如果是炉火写入(FURNACE),获取当前正在线上的钢卷信息并存储到 Redis
|
||||
try {
|
||||
boolean isFurnaceSend = groups.stream()
|
||||
.anyMatch(g -> "FURNACE".equalsIgnoreCase(g.getGroupType()));
|
||||
|
||||
if (isFurnaceSend && allSuccess) {
|
||||
CrmPdiPlan currentCoil = crmPdiPlanService.getCurrentOnlineCoil();
|
||||
if (currentCoil != null) {
|
||||
FurnaceSendCoilInfoVO coilInfo = new FurnaceSendCoilInfoVO();
|
||||
coilInfo.setCoilId(currentCoil.getCoilid());
|
||||
coilInfo.setPlanId(currentCoil.getPlanid());
|
||||
coilInfo.setSendTime(new Date());
|
||||
|
||||
// 存储到 Redis(使用 JSON 格式)
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
String jsonValue = objectMapper.writeValueAsString(coilInfo);
|
||||
RedisUtil.setValue(REDIS_KEY_FURNACE_SEND_COIL_INFO, jsonValue);
|
||||
|
||||
log.info("炉火写入成功,已保存钢卷信息到 Redis: coilId={}, planId={}",
|
||||
coilInfo.getCoilId(), coilInfo.getPlanId());
|
||||
} else {
|
||||
log.warn("炉火写入成功,但未找到当前正在线上的钢卷");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("保存炉火写入钢卷信息到 Redis 失败", e);
|
||||
// 不影响主流程,只记录日志
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,10 @@ public class SetupFurTempServiceImpl implements ISetupFurTempService
|
||||
@Override
|
||||
public int insertSetupFurTemp(SetupFurTemp setupFurTemp)
|
||||
{
|
||||
//如果 String steelGrade 存在则不能新增
|
||||
if (setupFurTempMapper.selectSetupFurTempBySteelGrade(setupFurTemp.getSteelGrade()) != null) {
|
||||
throw new RuntimeException("The parameter already exists.");
|
||||
}
|
||||
setupFurTemp.setCreateTime(DateUtils.getNowDate());
|
||||
return setupFurTempMapper.insertSetupFurTemp(setupFurTemp);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.fizz.business.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.fizz.business.domain.SetupTensionAllLine;
|
||||
import com.fizz.business.mapper.SetupTensionAllLineMapper;
|
||||
import com.fizz.business.service.ISetupTensionAllLineService;
|
||||
|
||||
/**
|
||||
* 全线张力Service业务层处理
|
||||
*/
|
||||
@Service
|
||||
public class SetupTensionAllLineServiceImpl implements ISetupTensionAllLineService
|
||||
{
|
||||
@Autowired
|
||||
private SetupTensionAllLineMapper mapper;
|
||||
|
||||
@Override
|
||||
public SetupTensionAllLine selectByKey(String steelGrade, Float thick, Float yieldStren)
|
||||
{
|
||||
return mapper.selectByKey(steelGrade, thick, yieldStren);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SetupTensionAllLine> selectList(SetupTensionAllLine query)
|
||||
{
|
||||
return mapper.selectList(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insert(SetupTensionAllLine entity)
|
||||
{
|
||||
// 三主键存在则禁止新增
|
||||
if (mapper.selectByKey(entity.getSteelGrade(), entity.getThick(), entity.getYieldStren()) != null) {
|
||||
throw new RuntimeException("该参数已存在");
|
||||
}
|
||||
entity.setCreateTime(DateUtils.getNowDate());
|
||||
entity.setUpdateTime(DateUtils.getNowDate());
|
||||
return mapper.insert(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateByKey(SetupTensionAllLine entity)
|
||||
{
|
||||
entity.setUpdateTime(DateUtils.getNowDate());
|
||||
return mapper.updateByKey(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteByKey(String steelGrade, Float thick, Float yieldStren)
|
||||
{
|
||||
return mapper.deleteByKey(steelGrade, thick, yieldStren);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user