Compare commits

...

38 Commits

Author SHA1 Message Date
de48dec1b4 修复版本问题 2026-04-13 15:48:37 +08:00
8610b76a1d 引入依赖 2026-04-13 15:10:36 +08:00
80032fa758 更新2级写入,以及前端处理 2026-04-13 15:06:32 +08:00
a128bf7905 快速排查新增字段与前端保存逻辑 2026-03-23 15:33:10 +08:00
12b2cc7e20 二级更新计划新增软推荐,计划录入和实绩内容添加入场钢卷号信息 2026-03-20 14:36:21 +08:00
bcb33f3033 git资源对齐 2026-01-19 13:52:39 +08:00
14aa9bf13c app更新对l2数据显示 2026-01-15 20:18:36 +08:00
0c94099e5a 二级后端添加数据快照修正 2026-01-15 18:27:53 +08:00
c50f63df73 二级后端添加数据快照修正。前端添加数字孪生 2026-01-15 17:37:55 +08:00
8f522973c7 计划列表接口添加分页 2026-01-13 09:56:55 +08:00
ca4516dd03 更正前端内容 2026-01-09 19:04:00 +08:00
ef0836d098 fix(opc): 修正OPC消息ID配置中的PLC路径
- 修正nof2炉温实际值和设定值的PLC路径从PLCLine到PLCFur
- 修正nof3炉温实际值和设定值的PLC路径从PLCLine到PLCFur
- 修正nof4炉温实际值和设定值的PLC路径从PLCLine到PLCFur
- 修正nof5炉温实际值和设定值的PLC路径从PLCLine到PLCFur
- 修正rtf1炉温实际值和设定值的PLC路径从PLCLine到PLCFur
- 修正rtf2炉温实际值和设定值的PLC路径从PLCLine到PLCFur
- 修正sf炉温实际值和设定值的PLC路径从PLCLine到PLCFur
- 修正jcf1炉温实际值和设定值的PLC路径从PLCLine到PLCFur
- 修正jcf2炉温实际值和设定值的PLC路径从PLCLine到PLCFur
- 修正lth炉温实际值和设定值的PLC路径从PLCLine到PLCFur
- 修正tds炉温实际值和设定值的PLC路径从PLCLine到PLCFur
- 修正lbz炉温实际值和设定值的PLC路径从PLCLine到PLCFur
2026-01-08 15:57:18 +08:00
ef89acbc39 feat(opc): 启用炉温测量数据点映射
- 启用 nof2 炉温实际值和设定值数据点映射
- 启用 nof3 炉温实际值和设定值数据点映射
- 启用 nof4 炉温实际值和设定值数据点映射
- 启用 nof5 炉温实际值和设定值数据点映射
- 启用 rtf1 炉温实际值和设定值数据点映射
- 启用 rtf2 炉温实际值和设定值数据点映射
- 启用 sf 炉温实际值和设定值数据点映射
- 启用 jcf1 炉温实际值和设定值数据点映射
- 启用 jcf2 炉温实际值和设定值数据点映射
- 启用 lth 炉温实际值和设定值数据点映射
- 启用 tds 炉温实际值和设定值数据点映射
- 启用 lbz 炉温实际值和设定值数据点映射
2026-01-08 15:20:58 +08:00
806e438c8c 修复注入问题 2026-01-08 15:14:32 +08:00
010c96a06d 停机逻辑加入 2026-01-08 14:20:23 +08:00
a373fdb371 更正前端内容 2026-01-07 20:15:33 +08:00
f32176a31d 二级修改 2026-01-07 17:56:33 +08:00
c5a31075b8 refactor(DeviceSnapshotService): 优化数值类型处理逻辑
- 将通用Number类型转换为具体数值类型(Integer、Long、Float、Double)
- 添加具体的数值类型判断和转换逻辑
- 保持Boolean和String类型的原有处理方式
- 在WebSocketUtil中添加lombok.var导入
2026-01-07 13:49:52 +08:00
5db2617028 Merge remote-tracking branch 'origin/master' 2026-01-07 13:42:46 +08:00
0f7d83e3f8 二级修改 2026-01-07 13:39:46 +08:00
0580893798 Merge remote-tracking branch 'gitea/master' 2026-01-07 13:08:35 +08:00
c426294c7a feat(mapper): 完善参数重复检查
- 在SegmentTotalMapper.xml中添加根据入库钢卷号查询最新一段total_values_json的方法
- 为SetupFurTempServiceImpl添加钢种参数重复检查机制
- 为SetupTensionServiceImpl添加厚度和屈服强度参数重复检查机制
- 为SetupTlServiceImpl添加钢种、屈服强度和厚度参数重复检查机制
- 为SetupTmBendforceServiceImpl添加宽度和轧制力参数重复检查机制
- 为SetupTmMeshServiceImpl添加钢种、屈服强度和厚度参数重复检查机制
- 为SetupTmRollforceServiceImpl添加钢种、屈服强度、厚度和延伸率参数重复检查机制
2026-01-07 13:07:47 +08:00
53f8ccbadd 二级和app修改 2026-01-05 14:29:32 +08:00
d48028a3b4 二级和app修改 2026-01-05 10:05:13 +08:00
d752188d01 feat(send-job): 新增炉火写入钢卷信息功能并优化发送作业服务
- 新增 FurnaceSendCoilInfoVO 类用于存储炉火写入的钢卷信息
- 在 SendJobController 中添加获取上次炉火写入钢卷信息的接口
- 在 SendJobServiceImpl 中实现炉火写入成功后自动存储钢卷信息到 Redis
- 新增 getCurrentOnlineCoil 方法用于获取当前正在线上的钢卷
- 优化 CrmPdiPlanService 接口定义和实现类代码格式
- 修复 SendJobQueryServiceImpl 中的错误提示信息国际化
- 优化 SendJobServiceImpl 中的代码结构和依赖注入
- 添加完整的 Java 代码注释和文档说明
2026-01-04 15:09:55 +08:00
a75d47479e config(logging): 移除错误日志文件大小限制配置
- 移除了 sys-error 日志文件的 maxFileSize 配置项
- 保持日志保留策略为0天和总大小限制为0MB的设置不变
2026-01-04 11:21:36 +08:00
b72dfd61a5 Merge remote-tracking branch 'gitea/master' 2026-01-04 10:44:46 +08:00
0a47283828 feat(crm): 支持按逗号分隔的状态列表查询PDI计划
- 兼容前端传入的逗号分隔状态字符串格式
- 支持中英文逗号及空格的自动处理
- 将状态查询从等值匹配改为in查询支持多状态筛选
2026-01-04 10:39:55 +08:00
42c9d12504 feat(business): 同步G30添加发送任务模板功能并扩展计划实体
- 新增 BizSendJob、BizSendJobGroup、BizSendJobItem 实体类用于发送任务管理
- 新增 BizSendTemplate、BizSendTemplateItem 实体类用于发送模板配置
- 实现发送模板的增删改查和批量保存功能
- 添加 DashboardController 提供首页仪表板统计接口
- 实现发送任务查询和执行服务
- 扩展 PdiPlan 相关实体类增加锌层厚度字段
- 优化 OPC 消息发送功能,支持多种数据类型转换
- 更新日志配置,调整错误日志处理策略
2026-01-04 10:30:38 +08:00
f52b1a9e0e 办公V3 2025-12-30 13:47:49 +08:00
8717c55aca config(log): 修改错误配置
- 移除了 maxFileSize 配置项,不再限制单个日志文件大小
- 保持日志滚动策略按天分割文件
- 维持最大历史记录为0天的设置
2025-12-29 13:26:39 +08:00
207e6a5ad6 chore(config): 调整服务器端口和日志配置
- 将服务器端口从8089更改为8081
- 在logback配置中添加最大文件大小限制为100MB
- 设置日志最大保留天数为0天并禁用存储
- 修改ERROR日志过滤策略为拒绝所有ERROR日志
- 注释掉file_error appender引用
- 添加StringUtils导入以支持字符串工具类使用
2025-12-29 11:19:32 +08:00
4993ef87b5 hcm前端2版 2025-12-22 16:54:49 +08:00
89b217c6f9 二级代码修复 2025-12-20 15:50:37 +08:00
de8d8bf4f1 二级代码修复 2025-12-20 14:48:19 +08:00
3517ce909c 二级代码修复 2025-12-19 21:01:32 +08:00
af941c2fd4 二级代码修复 2025-12-18 09:45:25 +08:00
aeed29dbca l2后端牛该修改 2025-12-16 13:20:59 +08:00
223 changed files with 6260 additions and 8498 deletions

12
.idea/dbnavigator.xml generated
View File

@@ -7,9 +7,21 @@
<component name="DBNavigator.Project.DatabaseAssistantManager">
<assistants />
</component>
<component name="DBNavigator.Project.DatabaseBrowserManager">
<autoscroll-to-editor value="false" />
<autoscroll-from-editor value="true" />
<show-object-properties value="true" />
<loaded-nodes />
</component>
<component name="DBNavigator.Project.DatabaseFileManager">
<open-files />
</component>
<component name="DBNavigator.Project.ExecutionManager">
<retain-sticky-names value="false" />
</component>
<component name="DBNavigator.Project.ParserDiagnosticsManager">
<diagnostics-history />
</component>
<component name="DBNavigator.Project.Settings">
<connections />
<browser-settings>

View File

@@ -16,6 +16,15 @@
</description>
<dependencies>
<dependency>
<groupId>com.github.xingshuangs</groupId>
<artifactId>iot-communication</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-framework</artifactId>
</dependency>
<!-- 通用工具-->
<dependency>
@@ -42,10 +51,7 @@
<!-- </dependency>-->
<!-- 核心模块-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-framework</artifactId>
</dependency>
<!-- 加密解密工具 opc-->
<!-- <dependency>-->
@@ -108,12 +114,13 @@
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- OPC UA 集成 -->
<!-- OPC UA 集成(读取仍使用) -->
<dependency>
<groupId>com.kangaroohy</groupId>
<artifactId>milo-spring-boot-starter</artifactId>
<version>3.1.4.0.6.15</version>
</dependency>
<!-- iot-communication写入改造使用 -->
<!-- <dependency>-->
@@ -124,4 +131,4 @@
</dependencies>
</project>
</project>

View File

@@ -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,65 @@ 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恢复后再更新
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避免短暂无值时丢失状态
}
}

View File

@@ -1,13 +1,10 @@
package com.fizz.business.comm.OPC;
import com.fizz.business.constants.enums.ExitCutTypeEnum;
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 lombok.extern.log4j.Log4j2;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.compress.utils.Lists;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
@@ -17,6 +14,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
@@ -37,6 +35,146 @@ public class OpcMessageSend {
}
/**
* 单独写入当前钢卷号到 OPC
* 使用 pdiSetupIds 中 coilId 对应的节点
*/
public void sendCoilId(String coilId) {
try {
String coilNode = pdiSetupIds.entrySet().stream()
.filter(e -> "coilId".equals(e.getValue()))
.map(Map.Entry::getKey)
.findFirst()
.orElse(null);
if (coilNode == null) {
log.warn("未找到 coilId 对应的 OPC 节点,写入跳过");
return;
}
List<ReadWriteEntity> entities = new ArrayList<>();
entities.add(ReadWriteEntity.builder()
.identifier(coilNode)
.value(coilId)
.build());
miloService.writeToOpcUa(entities);
log.info("写入 OPC coilId 成功node={} value={}", coilNode, coilId);
} catch (Exception e) {
log.error("写入 OPC coilId 失败coilId={},原因:{}", coilId, e.getMessage(), e);
}
}
/**
* 通用写数据方法:通过字段名向指定点位写入单个值
* @param fieldName 字段名对象属性名例如coilId
* @param value 要写入的值
* @return 是否写入成功
*/
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(identifier)
.value(value)
.build());
miloService.writeToOpcUa(entities);
log.info("写入 OPC 数据成功fieldName={}, identifier={}, value={}", fieldName, identifier, value);
return true;
} catch (Exception e) {
log.error("写入 OPC 数据失败fieldName={}, value={},原因:{}", fieldName, value, e.getMessage(), e);
return false;
}
}
/**
* 通用写数据方法:向指定点位写入单个值(直接使用节点路径)
* @param identifier OPC 点位标识符(节点路径)
* @param value 要写入的值
* @return 是否写入成功
*/
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 fieldDataMap 字段名和值的映射key 为 fieldNamevalue 为要写入的值
* @return 是否全部写入成功
*/
public boolean batchWriteDataByFieldName(Map<String, Object> fieldDataMap) {
try {
if (fieldDataMap == null || fieldDataMap.isEmpty()) {
log.warn("批量写数据:数据映射为空,跳过写入");
return false;
}
List<ReadWriteEntity> entities = new ArrayList<>();
for (Map.Entry<String, Object> entry : fieldDataMap.entrySet()) {
String fieldName = entry.getKey();
String identifier = findIdentifierByFieldName(fieldName);
if (identifier == null) {
log.warn("未找到字段名对应的 OPC 节点路径fieldName={},跳过该字段", fieldName);
continue;
}
entities.add(ReadWriteEntity.builder()
.identifier(identifier)
.value(entry.getValue())
.build());
}
if (entities.isEmpty()) {
log.warn("批量写数据:没有有效的字段映射,跳过写入");
return false;
}
miloService.writeToOpcUa(entities);
log.info("批量写入 OPC 数据成功,共 {} 个点位", entities.size());
return true;
} catch (Exception e) {
log.error("批量写入 OPC 数据失败,原因:{}", e.getMessage(), e);
return false;
}
}
/**
* 批量写数据方法:向多个点位写入数据(直接使用节点路径)
* @param dataMap 点位标识符和值的映射key 为 identifiervalue 为要写入的值
* @return 是否全部写入成功
*/
public boolean batchWriteData(Map<String, Object> dataMap) {
try {
if (dataMap == null || dataMap.isEmpty()) {
log.warn("批量写数据:数据映射为空,跳过写入");
return false;
}
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);
log.info("批量写入 OPC 数据成功,共 {} 个点位", entities.size());
return true;
} catch (Exception e) {
log.error("批量写入 OPC 数据失败,原因:{}", e.getMessage(), e);
return false;
}
}
private List<ReadWriteEntity> getWriteEntities(OpcMessage msg, Map<String,String> msgIds) {
List<ReadWriteEntity> entities = new ArrayList<>();
for (String key : msgIds.keySet()) {

View File

@@ -0,0 +1,48 @@
package com.fizz.business.comm.iot;
import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType;
import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import java.util.Locale;
/**
* 基于 iot-communication 的 S7 写入客户端(仅用于写入)。
*/
@Slf4j
@Component
@ConditionalOnProperty(prefix = "iot.communication", name = "enabled", havingValue = "true")
public class S7WriteClient {
@Value("${iot.communication.s7.ip:127.0.0.1}")
private String ip;
@Value("${iot.communication.s7.port:102}")
private int port;
@Value("${iot.communication.s7.rack:0}")
private int rack;
@Value("${iot.communication.s7.slot:1}")
private int slot;
@Value("${iot.communication.s7.plc-type:S1200}")
private String plcType;
public S7PLC newClient() {
EPlcType type = parsePlcType(plcType);
return new S7PLC(type, ip, port, rack, slot);
}
private EPlcType parsePlcType(String value) {
try {
return EPlcType.valueOf(value.trim().toUpperCase(Locale.ROOT));
} catch (Exception e) {
log.warn("未知 plc-type: {},回退到 S1200", value);
return EPlcType.S1200;
}
}
}

View File

@@ -7,6 +7,7 @@ import com.fasterxml.jackson.annotation.JsonValue;
import com.fizz.business.form.ChangePlanStatusForm;
import com.fizz.business.form.L1OperateMatForm;
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.utils.MatmapUtil;
@@ -15,17 +16,20 @@ import com.fizz.business.vo.CrmPdiPlanVO;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
* 钢卷操作
*
* @author chenhao
* @date 2023/04/24
*/
@Slf4j
@Getter
@AllArgsConstructor
public enum L1OperateMatEnum implements IEnum<String>, IOperateMat<L1OperateMatForm> {
@@ -55,7 +59,13 @@ public enum L1OperateMatEnum implements IEnum<String>, IOperateMat<L1OperateMatF
PRODUCING("生产中") {
@Override
public void operate(L1OperateMatForm form) {
PRODUCING.syncPlanStatus(form.getPlanId(),form.getEntryMatId());
// L1 指令将计划置为 PRODUCING 时,写入钢卷号到 OPC
if (form.getEntryMatId() != null) {
BeanFactory.getBean(OpcMessageSend.class).sendCoilId(form.getEntryMatId());
}
WebSocketUtil.sendSignalMsg(form);
}
@@ -63,6 +73,8 @@ 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);
}

View File

@@ -110,7 +110,6 @@ public enum WebOperateMatEnum implements IEnum<String>, IOperateMat<WebOperateMa
@Override
public void operate(WebOperateMatForm form) {
PRODUCING.syncPlanStatus(form.getPlanId(), form.getEntryMatId());
;
WebSocketUtil.sendSignalMsg(form);
}
},
@@ -206,7 +205,7 @@ public enum WebOperateMatEnum implements IEnum<String>, IOperateMat<WebOperateMa
* 2. 尾部卷: entryMatId=A01-2, returnMatId=A01。由于计划号+钢卷号唯一所以回退的尾部卷生成新计划时将entryMatId设置为A01-2真实的原料卷号保存在returnMatId中
* 半卷回退上报产出
* 1. 头部卷产出时原料卷号A01, 产出卷号: A01-1, 分卷标识: true, 尾卷标识: false
* 2. 尾部卷产出时原料卷号A01产出卷号: A01-2, 分卷标识: false, 尾卷标识: true
* 2. 尾部卷产出时原料卷号A01产出卷号: A01-2, 分卷标ACT_EVT_LOG识: false, 尾卷标识: true
*
* @param form
*/

View File

@@ -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);

View File

@@ -0,0 +1,93 @@
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
*/
@RestController
@RequestMapping("/business/sendTemplate")
public class BizSendTemplateController extends BaseController {
@Autowired
private IBizSendTemplateService templateService;
@Autowired
private IBizSendTemplateItemService templateItemService;
/**
* 按模板编码获取模板(含明细)
*/
@GetMapping("/{templateCode}")
public AjaxResult getByCode(@PathVariable String templateCode) {
BizSendTemplateVO vo = templateService.getTemplateWithItems(templateCode);
if (vo == null) {
return AjaxResult.error("模板未找到");
}
return AjaxResult.success(vo);
}
/**
* 更新模板主表(如 deviceName
*/
@PutMapping
public AjaxResult updateTemplate(@RequestBody BizSendTemplate template) {
if (template == null || template.getTemplateId() == null) {
return AjaxResult.error("模板ID是必需的");
}
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("模板ID是必需的");
}
try {
Boolean ok = templateItemService.batchSave(
dto.getTemplateId(),
dto.getItems(),
dto.getDeleteIds(),
SecurityUtils.getUsername()
);
return toAjax(ok);
} catch (IllegalArgumentException e) {
return AjaxResult.error(e.getMessage());
}
}
}

View File

@@ -5,7 +5,9 @@ import com.fizz.business.form.CalcPdiPlanForm;
import com.fizz.business.form.CrmPdiPlanForm;
import com.fizz.business.form.PlanQueryForm;
import com.fizz.business.service.CrmPdiPlanService;
import com.fizz.business.service.L3PickupRecommendService;
import com.fizz.business.vo.CrmPdiPlanVO;
import com.fizz.business.vo.L3PickupRecommendVO;
import com.fizz.business.vo.PdiPlanSetupInfoVO;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.domain.R;
@@ -25,6 +27,9 @@ public class CrmPdiPlanController {
@Resource
private CrmPdiPlanService crmPdiPlanService;
@Resource
private L3PickupRecommendService l3PickupRecommendService;
@PostMapping("/add")
@Operation(summary ="新增计划")
public R<Boolean> add(@RequestBody CrmPdiPlan crmPdiPlan) {
@@ -55,4 +60,10 @@ public class CrmPdiPlanController {
return R.ok(crmPdiPlanService.listAll(form));
}
@GetMapping("/l3PickupRecommend")
@Operation(summary ="三级领料推荐")
public R<List<L3PickupRecommendVO>> l3PickupRecommend(@RequestParam(required = false, defaultValue = "10") Integer limit) {
return R.ok(l3PickupRecommendService.listPickupRecommend(limit));
}
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,39 @@
package com.fizz.business.controller;
import com.fizz.business.service.DashboardService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 首页仪表板相关接口
*/
@RestController
public class DashboardController extends BaseController {
@Resource
private DashboardService dashboardService;
/**
* 当前生产中的计划信息crm_pdi_plan.status = 'PRODUCING'
*/
@GetMapping("/api/business/dashboard/currentPlan")
public AjaxResult getCurrentProducingPlan() {
return AjaxResult.success(dashboardService.getCurrentProducingPlan());
}
/**
* 当前生产卷的关键工艺参数
* - 从 cpl_segment_total.total_values_json 解析
* - 键名来自 DeviceEnum.paramFields
*/
@GetMapping("/api/business/dashboard/currentProcess")
public AjaxResult getCurrentProcessParams() {
return AjaxResult.success(dashboardService.getCurrentProcessParams());
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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));
}
}

View File

@@ -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 = "iot.communication", 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());
}
}
}

View File

@@ -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,7 +11,6 @@ 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;
@@ -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)
@Log(title = "张力参数", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(pdiSetupService.deletePdiSetupByids(ids));
return toAjax(pdiSetupService.deletePdiSetupByIds(ids));
}
}

View File

@@ -0,0 +1,113 @@
package com.fizz.business.controller;
import com.fizz.business.domain.BizSendJob;
import com.fizz.business.domain.dto.SendJobCreateDTO;
import com.fizz.business.domain.dto.SendJobQueryDTO;
import com.fizz.business.domain.vo.SendJobDetailVO;
import com.fizz.business.service.ISendJobService;
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;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 发送任务 Controller
*/
@RestController
@RequestMapping("/business/sendJob")
public class SendJobController extends BaseController {
@Autowired
private ISendJobService sendJobService;
@Autowired
private ISendJobQueryService sendJobQueryService;
/**
* 创建发送任务
*/
@Log(title = "发送任务", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult create(@Validated @RequestBody SendJobCreateDTO dto) {
Integer jobId = sendJobService.createSendJob(dto);
return success(jobId);
}
/**
* 查询发送任务列表
*/
@GetMapping("/list")
public TableDataInfo list(SendJobQueryDTO query) {
startPage(); // 使用BaseController的分页方法
List<BizSendJob> list = sendJobService.selectSendJobList(query);
return getDataTable(list);
}
/**
* 获取发送任务详情
*/
@GetMapping("/{jobId}")
public AjaxResult getDetail(@PathVariable Integer jobId) {
SendJobDetailVO detail = sendJobService.selectSendJobDetail(jobId);
return success(detail);
}
/**
* 删除发送任务(逻辑删除)
*/
@Log(title = "发送任务", businessType = BusinessType.DELETE)
@DeleteMapping("/{jobIds}")
public AjaxResult remove(@PathVariable Integer[] jobIds) {
return toAjax(sendJobService.deleteSendJobByJobIds(jobIds));
}
/**
* 执行发送任务
*/
@Log(title = "发送任务", businessType = BusinessType.UPDATE)
@PostMapping("/{jobId}/execute")
public AjaxResult execute(@PathVariable Integer jobId) {
return toAjax(sendJobService.executeSendJob(jobId));
}
/**
* 查询最近一次成功发送(用于界面显示上次发送时间 + 推荐上次值)
* @param groupType DRIVE / FURNACE
*/
@GetMapping("/lastSuccess")
public AjaxResult lastSuccess(@RequestParam String groupType) {
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("获取上次炉火写入钢卷信息失败: " + e.getMessage());
}
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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()
));
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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()
));
}
}

View File

@@ -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()
));
}
}

View File

@@ -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()
));
}
}

View File

@@ -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()
));
}
}

View File

@@ -6,6 +6,7 @@ import com.fizz.business.service.SteelGradeInfoService;
import com.fizz.business.vo.StdAlloyVO;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.StringUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.BeanUtils;
@@ -27,54 +28,47 @@ public class SteelGradeInfoController {
@GetMapping("/list")
@Operation(summary = "查询钢种列表")
public R<List<StdAlloyVO>> list() {
public R<List<StdAlloyVO>> list(@RequestParam(value = "keyword", required = false) String keyword) {
// 使用 LambdaQueryWrapper 查询 StdAlloy 表中的数据
// 严格按 cgldb.sql查询 std_alloy(GRADEID, NAME)
LambdaQueryWrapper<StdAlloy> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.select(StdAlloy::getGradeid, StdAlloy::getName) // 只查询 gradeId 和 name 字段
.orderByAsc(StdAlloy::getName); // 按 name 排序
queryWrapper.select(StdAlloy::getGradeid, StdAlloy::getName);
if (StringUtils.isNotBlank(keyword)) {
queryWrapper.like(StdAlloy::getName, keyword)
.or()
.like(StdAlloy::getGradeid, keyword);
}
queryWrapper.orderByAsc(StdAlloy::getName);
// 查询 StdAlloy 数据
List<StdAlloy> stdAlloyList = steelGradeInfoService.list(queryWrapper);
// 使用 BeanUtils 将 StdAlloy 对象的字段映射到 StdAlloyVO
List<StdAlloyVO> stdAlloyVOList = new ArrayList<>();
for (StdAlloy stdAlloy : stdAlloyList) {
StdAlloyVO stdAlloyVO = new StdAlloyVO();
BeanUtils.copyProperties(stdAlloy, stdAlloyVO); // 将 StdAlloy 属性复制到 StdAlloyVO
BeanUtils.copyProperties(stdAlloy, stdAlloyVO);
stdAlloyVOList.add(stdAlloyVO);
}
// 返回结果
return R.ok(stdAlloyVOList);
}
@GetMapping("/info")
@Operation(summary ="询单个钢种详情")
public R<StdAlloy> getSteelGradeInfo(@RequestParam Integer gradeid) {
// 使用 LambdaQueryWrapper 查询 StdAlloy 表中的数据
LambdaQueryWrapper<StdAlloy> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StdAlloy::getGradeid, gradeid); // 只查询 gradeId 和 name 字段
// 查询 StdAlloy 数据
StdAlloy stdAlloyList = steelGradeInfoService.getById(gradeid);
// 返回结果
return R.ok(stdAlloyList);
return R.ok(steelGradeInfoService.getById(gradeid));
}
@PostMapping("/add")
@Operation(summary ="新增")
public R<Boolean> add(@RequestBody StdAlloy steelGradeInfo) {
return R.ok(steelGradeInfoService.save(steelGradeInfo));
public R<Boolean> add(@RequestBody StdAlloy stdAlloy) {
return R.ok(steelGradeInfoService.save(stdAlloy));
}
@PutMapping("/update")
@Operation(summary ="更新")
public R<Boolean> update(@RequestBody StdAlloy steelGradeInfo) {
return R.ok(steelGradeInfoService.updateById(steelGradeInfo));
public R<Boolean> update(@RequestBody StdAlloy stdAlloy) {
return R.ok(steelGradeInfoService.updateById(stdAlloy));
}
@Operation(summary ="删除")

View File

@@ -0,0 +1,60 @@
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.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
/**
* 业务发送批次表 biz_send_job
*
* @author Cascade
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("biz_send_job")
public class BizSendJob extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 批次ID */
@TableId(type = IdType.AUTO)
private Integer jobId;
/** 业务唯一键, 用于幂等控制 */
private String bizKey;
/** 目标设备/产线名称 (如 CGL_LINE_1, FURNACE_A) */
private String deviceName;
/** 计划发送时间 */
private Date planSendTime;
/** 实际开始发送时间 */
private Date actualSendTime;
/** 发送完成时间 */
private Date finishTime;
/** 批次状态: PENDING, IN_PROGRESS, COMPLETED, PARTIAL_SUCCESS, FAILED */
private String status;
/** 操作员ID */
private Long operatorId;
/** 操作员姓名 */
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;
}

View File

@@ -0,0 +1,46 @@
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.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 业务发送分组表 biz_send_job_group
*
* @author Cascade
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("biz_send_job_group")
public class BizSendJobGroup extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 分组ID */
@TableId(type = IdType.AUTO)
private Integer groupId;
/** 所属批次ID */
private Integer jobId;
/** 在本批次内的组序号 */
private Integer groupNo;
/** 组类型: DRIVE(传动), FURNACE(炉火) */
private String groupType;
/** 组名称 (可选) */
private String groupName;
/** 分组状态: 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;
}

View File

@@ -0,0 +1,64 @@
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.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
/**
* 业务发送项历史表 biz_send_job_item
*
* @author Cascade
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("biz_send_job_item")
public class BizSendJobItem extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 发送项ID */
@TableId(type = IdType.AUTO)
private Integer itemId;
/** 所属批次ID (冗余) */
private Integer jobId;
/** 所属分组ID */
private Integer groupId;
/** 参数业务编码 */
private String paramCode;
/** 设定地址 (OPC地址) */
private String address;
/** 设定的原始值 */
private String valueRaw;
/** 设定值的数值形式 */
private BigDecimal valueNum;
/** 参数的设定时间 */
private Date setTime;
/** 发送结果: PENDING, SUCCESS, FAILED */
private String resultStatus;
/** 结果消息 */
private String resultMsg;
/** 重试次数 */
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;
}

View File

@@ -0,0 +1,41 @@
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.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 发送默认模板主表
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("biz_send_template")
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;
/** 模板名称 */
private String templateName;
/** 默认设备名称 */
private String deviceName;
/** 组类型 DRIVE / FURNACE */
private String groupType;
/** 是否启用 */
private Integer enabled;
}

View File

@@ -0,0 +1,49 @@
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.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 发送默认模板明细表
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("biz_send_template_item")
public class BizSendTemplateItem extends BaseEntity {
@TableId(type = IdType.AUTO)
private Integer templateItemId;
private Integer templateId;
/** 明细序号 */
private Integer itemNo;
/** 参数编码 */
private String paramCode;
/** 英文显示名 */
private String labelEn;
/** 英文分组名 */
private String groupNameEn;
/** OPC地址 */
private String address;
/** 默认值(字符串) */
private String defaultValueRaw;
/** 是否启用 */
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;
}

View File

@@ -26,6 +26,9 @@ public class CrmPdiPlan implements Serializable {
@Schema(description = "钢卷号")
private String coilid;
@Schema(description = "入场钢卷号")
private String enterCoilNo;
@Schema(description = "机组号")
private String unitCode;
@@ -313,4 +316,8 @@ public class CrmPdiPlan implements Serializable {
@Schema(description = "原卷号")
private String originCoilid;
//锌层厚度 zinc_coating_thickness
@Schema(description = "锌层厚度")
private BigDecimal zincCoatingThickness;
}

View File

@@ -8,6 +8,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.LocalDateTime;
@@ -26,6 +27,9 @@ public class CrmPdoExcoil implements Serializable {
@Schema(description = "来料卷")
private String entryMatId;
@Schema(description = "入场钢卷号")
private String enterCoilNo;
@Schema(description = "分切数")
private Integer subId;
@@ -130,4 +134,7 @@ public class CrmPdoExcoil implements Serializable {
@Schema(description = "计划来源L3-L3计划MANUAL-人工")
private String planOrigin;
@Schema(description = "锌层厚度")
private BigDecimal zincCoatingThickness;
}

View File

@@ -0,0 +1,46 @@
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 = "快照数据JSON")
private String snapshotData;
}

View File

@@ -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;
}

View File

@@ -7,7 +7,7 @@ import com.ruoyi.common.core.domain.BaseEntity;
/**
* 全线张力对象 setup_tension
*
*
* @author ruoyi
* @date 2025-09-26
*/
@@ -81,156 +81,156 @@ public class SetupTension extends BaseEntity
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
private Long value15;
public void setThick(Long thick)
public void setThick(Long thick)
{
this.thick = thick;
}
public Long getThick()
public Long getThick()
{
return thick;
}
public void setYieldStren(Long yieldStren)
public void setYieldStren(Long yieldStren)
{
this.yieldStren = yieldStren;
}
public Long getYieldStren()
public Long getYieldStren()
{
return yieldStren;
}
public void setValue1(Long value1)
public void setValue1(Long value1)
{
this.value1 = value1;
}
public Long getValue1()
public Long getValue1()
{
return value1;
}
public void setValue2(Long value2)
public void setValue2(Long value2)
{
this.value2 = value2;
}
public Long getValue2()
public Long getValue2()
{
return value2;
}
public void setValue3(Long value3)
public void setValue3(Long value3)
{
this.value3 = value3;
}
public Long getValue3()
public Long getValue3()
{
return value3;
}
public void setValue4(Long value4)
public void setValue4(Long value4)
{
this.value4 = value4;
}
public Long getValue4()
public Long getValue4()
{
return value4;
}
public void setValue5(Long value5)
public void setValue5(Long value5)
{
this.value5 = value5;
}
public Long getValue5()
public Long getValue5()
{
return value5;
}
public void setValue6(Long value6)
public void setValue6(Long value6)
{
this.value6 = value6;
}
public Long getValue6()
public Long getValue6()
{
return value6;
}
public void setValue7(Long value7)
public void setValue7(Long value7)
{
this.value7 = value7;
}
public Long getValue7()
public Long getValue7()
{
return value7;
}
public void setValue8(Long value8)
public void setValue8(Long value8)
{
this.value8 = value8;
}
public Long getValue8()
public Long getValue8()
{
return value8;
}
public void setValue9(Long value9)
public void setValue9(Long value9)
{
this.value9 = value9;
}
public Long getValue9()
public Long getValue9()
{
return value9;
}
public void setValue10(Long value10)
public void setValue10(Long value10)
{
this.value10 = value10;
}
public Long getValue10()
public Long getValue10()
{
return value10;
}
public void setValue11(Long value11)
public void setValue11(Long value11)
{
this.value11 = value11;
}
public Long getValue11()
public Long getValue11()
{
return value11;
}
public void setValue12(Long value12)
public void setValue12(Long value12)
{
this.value12 = value12;
}
public Long getValue12()
public Long getValue12()
{
return value12;
}
public void setValue13(Long value13)
public void setValue13(Long value13)
{
this.value13 = value13;
}
public Long getValue13()
public Long getValue13()
{
return value13;
}
public void setValue14(Long value14)
public void setValue14(Long value14)
{
this.value14 = value14;
}
public Long getValue14()
public Long getValue14()
{
return value14;
}
public void setValue15(Long value15)
public void setValue15(Long value15)
{
this.value15 = value15;
}
public Long getValue15()
public Long getValue15()
{
return value15;
}

View File

@@ -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;
}
}

View File

@@ -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; }
}

View File

@@ -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; }
}

View File

@@ -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; }
}

View File

@@ -2,10 +2,12 @@ package com.fizz.business.domain;
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("std_alloy")
public class StdAlloy {
@TableId("GRADEID")

View File

@@ -0,0 +1,75 @@
package com.fizz.business.domain.dto;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.Date;
import java.util.List;
/**
* 创建发送任务 DTO
*/
@Data
public class SendJobCreateDTO {
/** 目标设备/产线名称 (如 CGL_LINE_1, FURNACE_A) */
@NotBlank(message = "deviceName不能为空")
private String deviceName;
/** 计划发送时间 */
private Date planSendTime;
/** 操作员ID */
private Long operatorId;
/** 操作员姓名 */
private String operatorName;
/** 分组列表 */
@Valid
@NotNull(message = "groups不能为空")
@Size(min = 1, message = "至少需要一个分组")
private List<GroupDTO> groups;
@Data
public static class GroupDTO {
/** 在本批次内的组序号 */
@NotNull(message = "groupNo不能为空")
private Integer groupNo;
/** 组类型: DRIVE(传动), FURNACE(炉火) */
@NotBlank(message = "groupType不能为空")
private String groupType;
/** 组名称 (可选) */
private String groupName;
/** 参数项列表 */
@Valid
@NotNull(message = "items不能为空")
@Size(min = 1, message = "至少需要一个参数项")
private List<ItemDTO> items;
}
@Data
public static class ItemDTO {
/** 参数业务编码 */
private String paramCode;
/** 设定地址 (OPC地址) */
@NotBlank(message = "address不能为空")
private String address;
/** 设定的原始值 */
private String valueRaw;
/** 参数的设定时间 */
private Date setTime;
}
}

View File

@@ -0,0 +1,21 @@
package com.fizz.business.domain.dto;
import lombok.Data;
/**
* 发送任务查询 DTO
* 说明:分页参数沿用 RuoYi BaseController 的 startPage() 机制,从 request 里取 pageNum/pageSize。
*/
@Data
public class SendJobQueryDTO {
/** 设备/产线名称 */
private String deviceName;
/** 状态: PENDING, IN_PROGRESS, COMPLETED, PARTIAL_SUCCESS, FAILED, DELETED */
private String status;
/** 分组类型: DRIVE / FURNACE */
private String groupType;
}

View File

@@ -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;
}

View File

@@ -0,0 +1,22 @@
package com.fizz.business.domain.vo;
import lombok.Data;
/**
* 模板明细 VO
*/
@Data
public class BizSendTemplateItemVO {
private Integer templateItemId;
private Integer templateId;
private Integer itemNo;
private String paramCode;
private String labelEn;
private String groupNameEn;
private String address;
private String defaultValueRaw;
private Boolean enabled;
}

View File

@@ -0,0 +1,21 @@
package com.fizz.business.domain.vo;
import lombok.Data;
import java.util.List;
/**
* 模板主VO含明细
*/
@Data
public class BizSendTemplateVO {
private Integer templateId;
private String templateCode;
private String templateName;
private String deviceName;
private String groupType;
private Integer enabled;
private List<BizSendTemplateItemVO> items;
}

View File

@@ -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;
}

View File

@@ -0,0 +1,26 @@
package com.fizz.business.domain.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import java.util.List;
/**
* 发送任务详情 VO
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class SendJobDetailVO extends SendJobVO {
private Date planSendTime;
private Date actualSendTime;
private Date finishTime;
private String remark;
private List<SendJobGroupVO> groups;
}

View File

@@ -0,0 +1,27 @@
package com.fizz.business.domain.vo;
import lombok.Data;
import java.util.List;
/**
* 发送任务分组 VO
*/
@Data
public class SendJobGroupVO {
private Integer groupId;
private Integer jobId;
private Integer groupNo;
private String groupType;
private String groupName;
private String status;
private List<SendJobItemVO> items;
}

View File

@@ -0,0 +1,39 @@
package com.fizz.business.domain.vo;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 发送任务明细项 VO
*/
@Data
public class SendJobItemVO {
private Integer itemId;
private Integer jobId;
private Integer groupId;
private String paramCode;
private String address;
private String valueRaw;
private BigDecimal valueNum;
private Date setTime;
private String resultStatus;
private String resultMsg;
private Integer retryCount;
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,26 @@
package com.fizz.business.domain.vo;
import lombok.Data;
import java.util.Date;
import java.util.Map;
/**
* 最近一次成功发送结果(用于前端推荐默认值 + 显示上次发送时间)
*/
@Data
public class SendJobLastSuccessVO {
/** 最近一次成功发送时间job.finish_time */
private Date lastSendTime;
/** paramCode -> valueRaw */
private Map<String, String> values;
/** 最近一次成功的jobId可选 */
private Integer jobId;
//IsFromHistory
private Boolean isFromHistory;
}

View File

@@ -0,0 +1,27 @@
package com.fizz.business.domain.vo;
import lombok.Data;
import java.util.Date;
/**
* 发送任务列表 VO
*/
@Data
public class SendJobVO {
private Integer jobId;
private String bizKey;
private String deviceName;
private String status;
private Long operatorId;
private String operatorName;
private Date createTime;
}

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -5,6 +5,7 @@ import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 子计划数据
@@ -57,4 +58,7 @@ public class PdiPlanSubDTO implements Serializable {
@Schema(description = "实际重量")
private Double actualWeight;
@Schema(description = "锌层厚度")
private BigDecimal zincCoatingThickness;
}

View File

@@ -6,6 +6,7 @@ import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
@@ -71,4 +72,7 @@ public class PdoExCoilSubDTO implements Serializable {
@Schema(description = "结束时间")
private LocalDateTime endTime;
@Schema(description = "锌层厚度")
private BigDecimal zincCoatingThickness;
}

View File

@@ -15,9 +15,12 @@ public class SegValue implements Serializable {
private BigDecimal avg;
private BigDecimal std;
private int cnt;
private BigDecimal sum;
private BigDecimal sum = BigDecimal.ZERO;
public void add(BigDecimal value) {
if (value == null) {
return;
}
this.sum = this.sum.add(value);
this.cnt++;
}

View File

@@ -16,6 +16,7 @@ public class CrmPdiPlanForm {
private Integer seqid; // 主键ID
private String coilid; // 钢卷号
private String enterCoilNo; // 入场钢卷号
private String unitCode; // 钢卷号
private Integer picklingCount; // 酸洗次数
private Integer dummyCoilFlag; // 虚卷标识
@@ -115,5 +116,5 @@ public class CrmPdiPlanForm {
private BigDecimal tailendGaugeLength; // 尾端测厚长度(mm)
private String origin; // 产地
private String originCoilid; // 原卷号
private BigDecimal zincCoatingThickness;//锌层厚度
}

View File

@@ -3,6 +3,7 @@ package com.fizz.business.form;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@@ -18,4 +19,13 @@ public class CrmPdoExcoilForm {
@Schema(description = "结束日期")
private String endDate;
@Schema(description = "锌层厚度")
private BigDecimal zincCoatingThickness;
@Schema(description = "页码", example = "1")
private Integer pageNum = 1;
@Schema(description = "每页数量", example = "20")
private Integer pageSize = 20;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -0,0 +1,10 @@
package com.fizz.business.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fizz.business.domain.BizSendJobGroup;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BizSendJobGroupMapper extends BaseMapper<BizSendJobGroup> {
}

View File

@@ -0,0 +1,10 @@
package com.fizz.business.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fizz.business.domain.BizSendJobItem;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BizSendJobItemMapper extends BaseMapper<BizSendJobItem> {
}

View File

@@ -0,0 +1,10 @@
package com.fizz.business.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fizz.business.domain.BizSendJob;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BizSendJobMapper extends BaseMapper<BizSendJob> {
}

View File

@@ -0,0 +1,10 @@
package com.fizz.business.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fizz.business.domain.BizSendTemplateItem;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BizSendTemplateItemMapper extends BaseMapper<BizSendTemplateItem> {
}

View File

@@ -0,0 +1,10 @@
package com.fizz.business.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fizz.business.domain.BizSendTemplate;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BizSendTemplateMapper extends BaseMapper<BizSendTemplate> {
}

View File

@@ -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> {
}

View File

@@ -0,0 +1,21 @@
package com.fizz.business.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Map;
@Mapper
public interface L3PickupRecommendMapper {
@Select("SELECT action_id, coil_id, current_coil_no, priority, scan_time " +
"FROM wms_coil_pending_action " +
"WHERE action_type = 501 AND action_status = 0 AND del_flag = 0 " +
"ORDER BY priority DESC, scan_time ASC, action_id ASC LIMIT #{limit}")
List<Map<String, Object>> selectPendingActions(@Param("limit") Integer limit);
@Select("SELECT coil_id, enter_coil_no FROM wms_material_coil WHERE coil_id = #{coilId} LIMIT 1")
Map<String, Object> selectMaterialByCoilId(@Param("coilId") Long coilId);
}

View File

@@ -1,7 +1,5 @@
package com.fizz.business.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fizz.business.domain.PdiSetups;
@@ -13,51 +11,6 @@ import com.fizz.business.domain.PdiSetups;
*/
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 等)。
}

View File

@@ -0,0 +1,20 @@
package com.fizz.business.mapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.Map;
/**
* 计划相关仪表板 Mappercrm_pdi_plan
*/
@Mapper
public interface PlanDashboardMapper {
/**
* 查询当前生产中的计划status = 'PRODUCING'
* 返回字段至少包括:
* - coilid, planid, steel_grade, entry_weight, entry_thick, entry_width, start_date 等
*/
Map<String, Object> selectCurrentProducingPlan();
}

View File

@@ -1,18 +1,16 @@
package com.fizz.business.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fizz.business.domain.SegmentTotal;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* <p>
* 各机张力,电流等架跟踪表 Mapper 接口
* </p>
*
* @author baomidou
* @since 2023-10-26
* 带钢段工艺参数 Mappercpl_segment_total
*/
@Mapper
public interface SegmentTotalMapper extends BaseMapper<SegmentTotal> {
SegmentTotal getLatestRecord();
public interface SegmentTotalMapper {
/**
* 根据入库钢卷号查询最新一段的 total_values_json
*/
String selectLatestTotalValuesJsonByCoilId(@Param("coilId") String coilId);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -3,7 +3,6 @@ package com.fizz.business.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fizz.business.domain.StdAlloy;
import com.fizz.business.domain.SteelGradeInfo;
import org.apache.ibatis.annotations.Mapper;
@Mapper

View File

@@ -0,0 +1,40 @@
package com.fizz.business.schedule;
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;
/**
* 设备数据快照定时任务
* 每5分钟执行一次设备数据快照
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class DeviceSnapshotSchedule {
private final DeviceSnapshotService deviceSnapshotService;
/**
* 每5分钟执行一次设备数据快照
* 使用cron表达式0 0/5 * * * ?
* 表示每5分钟执行一次在每分钟的0秒触发
*/
@Scheduled(cron = "0 0/5 * * * ?")
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);
}
}
}

View File

@@ -13,15 +13,15 @@ import java.util.List;
public interface CrmPdiPlanService extends IService<CrmPdiPlan> {
CrmPdiPlanVO getByCoilIdAndOperId(String coilid);
CrmPdiPlanVO getByCoilIdAndOperId(String coilid);
boolean addCrmPdiPlan(CrmPdiPlan crmPdiPlan);
boolean addCrmPdiPlan(CrmPdiPlan crmPdiPlan);
boolean updateCrmPdiPlan(CrmPdiPlan crmPdiPlan);
boolean updateCrmPdiPlan(CrmPdiPlan crmPdiPlan);
boolean deleteCrmPdiPlan(List<Long> coilid);
boolean deleteCrmPdiPlan(List<Long> coilid);
List<CrmPdiPlanVO> listAll(PlanQueryForm form);
List<CrmPdiPlanVO> listAll(PlanQueryForm form);
/**
* 获取未生产的第一个钢卷(按顺序号或创建时间最早)
@@ -29,4 +29,10 @@ public interface CrmPdiPlanService extends IService<CrmPdiPlan> {
CrmPdiPlan getFirstUnProducedCoil();
void changeStatus(ChangePlanStatusForm build);
/**
* 获取当前正在线上的钢卷优先级ONLINE > PRODUCING > READY/NEW
* @return 当前正在线上的钢卷如果没有则返回null
*/
CrmPdiPlan getCurrentOnlineCoil();
}

View File

@@ -0,0 +1,27 @@
package com.fizz.business.service;
import java.util.Map;
/**
* 首页仪表板统计服务
*/
public interface DashboardService {
/**
* 当前生产中的计划信息(包含卷号、规格、时间等)
*/
Map<String, Object> getCurrentProducingPlan();
/**
* 当前生产卷的关键工艺参数
* 结构说明(示例):
* {
* "coilId": "...",
* "entrySection": { "POR1": { ... }, "POR2": { ... }, ... },
* "processSection":{ "CLEAN": { ... }, "FUR1": { ... }, ... },
* "exitSection": { "TR": { ... }, "CXL1": { ... }, ... }
* }
*/
Map<String, Object> getCurrentProcessParams();
}

View File

@@ -0,0 +1,883 @@
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;
/**
* 最近一次成功创建设备快照的时间(用于兜底触发,避免完全依赖调度器)
*/
private volatile LocalDateTime lastSnapshotTime;
/**
* 更新最新的测量数据
* @param message 测量数据消息
*/
public void updateLatestMeasurement(OpcMessage message) {
if (message != null) {
latestMeasurements.put(message.getClass(), message);
log.trace("更新测量数据缓存: {}", message.getClass().getSimpleName());
}
}
/**
* 由实时测量处理链路兜底触发快照创建:
* - 与定时任务互不冲突
* - 仅当距离上次快照 >= 5 分钟时才真正落库
*/
public void captureSnapshotIfNeeded() {
try {
LocalDateTime now = LocalDateTime.now();
LocalDateTime last = lastSnapshotTime;
if (last == null || java.time.Duration.between(last, now).toMinutes() >= 5) {
createDeviceSnapshots();
lastSnapshotTime = now;
}
} catch (Exception e) {
log.error("兜底创建设备数据快照失败: {}", e.getMessage(), e);
}
}
/**
* 创建当前所有设备的数据快照
*/
@Transactional(rollbackFor = Exception.class)
public void createDeviceSnapshots() {
try {
// 获取当前时间戳
LocalDateTime now = LocalDateTime.now();
log.info("开始创建设备快照,当前时间: {}, latestMeasurements缓存大小: {}", now, latestMeasurements.size());
// 获取最新的测量数据
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);
log.info("测量数据状态 - entry: {}, furnace: {}, coat: {}, exit: {}",
entry != null ? "有数据" : "null",
furnace != null ? "有数据" : "null",
coat != null ? "有数据" : "null",
exit != null ? "有数据" : "null");
if (entry == null && furnace == null && coat == null && exit == null) {
log.warn("没有可用的测量数据跳过快照创建。latestMeasurements缓存内容: {}", latestMeasurements.keySet());
return;
}
// 为每个设备创建快照
List<DeviceSnapshot> snapshots = new ArrayList<>();
int deviceCount = 0;
for (DeviceEnum device : DeviceEnum.values()) {
deviceCount++;
try {
DeviceSnapshot snapshot = createDeviceSnapshot(device, now, entry, furnace, coat, exit);
if (snapshot != null) {
snapshots.add(snapshot);
log.debug("设备[{}]快照创建成功", device.name());
} else {
log.debug("设备[{}]快照返回null可能没有对应数据", device.name());
}
} catch (Exception e) {
log.error("创建设备[{}]快照失败: {}", device.name(), e.getMessage(), e);
}
}
log.info("共处理{}个设备,成功创建{}个快照", deviceCount, snapshots.size());
// 批量保存快照
if (!snapshots.isEmpty()) {
int savedCount = 0;
for (DeviceSnapshot snapshot : snapshots) {
try {
int result = deviceSnapshotMapper.insert(snapshot);
if (result > 0) {
savedCount++;
log.debug("设备快照保存成功: deviceCode={}, createTime={}",
snapshot.getDeviceCode(), snapshot.getCreateTime());
} else {
log.warn("设备快照保存失败insert返回0: deviceCode={}", snapshot.getDeviceCode());
}
} catch (Exception e) {
log.error("保存设备快照到数据库失败: deviceCode={}, error={}",
snapshot.getDeviceCode(), e.getMessage(), e);
}
}
log.info("成功保存{}个设备数据快照到数据库", savedCount);
// 推送所有设备的历史趋势数据
pushAllDevicesHistoryTrend();
// 推送设备统计数据
pushAllChartData();
// 推送每个设备每个字段的趋势数据(供前端画"点位趋势小图"
pushAllDeviceFieldTrends();
} else {
log.warn("没有可保存的快照数据所有设备快照创建都返回null");
}
} 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());
List<String> paramFields = device.getParamFields();
log.debug("设备[{}]参数字段列表: {}", device.name(), paramFields);
// 根据设备类型获取对应的测量数据
ObjectNode dataNode = objectMapper.createObjectNode();
switch (device.getSourceType()) {
case ENTRY:
if (entry != null) {
extractData(entry, paramFields, dataNode);
log.debug("设备[{}]从ENTRY提取数据dataNode大小: {}", device.name(), dataNode.size());
} else {
log.debug("设备[{}]需要ENTRY数据但entry为null", device.name());
}
break;
case FURNACE:
if (furnace != null) {
extractData(furnace, paramFields, dataNode);
log.debug("设备[{}]从FURNACE提取数据dataNode大小: {}", device.name(), dataNode.size());
} else {
log.debug("设备[{}]需要FURNACE数据但furnace为null", device.name());
}
break;
case COAT:
if (coat != null) {
extractData(coat, paramFields, dataNode);
log.debug("设备[{}]从COAT提取数据dataNode大小: {}", device.name(), dataNode.size());
} else {
log.debug("设备[{}]需要COAT数据但coat为null", device.name());
}
break;
case EXIT:
if (exit != null) {
extractData(exit, paramFields, dataNode);
log.debug("设备[{}]从EXIT提取数据dataNode大小: {}", device.name(), dataNode.size());
} else {
log.debug("设备[{}]需要EXIT数据但exit为null", device.name());
}
break;
}
// 如果没有数据,则跳过
if (dataNode.isEmpty()) {
log.debug("设备[{}]快照数据为空,跳过快照创建", device.name());
return null;
}
// 设置快照数据
snapshot.setSnapshotData(dataNode.toString());
log.debug("设备[{}]快照创建成功,数据长度: {}", device.name(), dataNode.toString().length());
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()) {
log.debug("extractData参数无效: message={}, fields={}",
message != null ? message.getClass().getSimpleName() : "null",
fields != null ? fields.size() : "null");
return;
}
int extractedCount = 0;
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);
extractedCount++;
} else if (value instanceof Long) {
dataNode.put(field, (Long) value);
extractedCount++;
} else if (value instanceof Float) {
dataNode.put(field, (Float) value);
extractedCount++;
} else if (value instanceof Double) {
dataNode.put(field, (Double) value);
extractedCount++;
} else if (value instanceof Boolean) {
dataNode.put(field, (Boolean) value);
extractedCount++;
} else if (value instanceof String) {
dataNode.put(field, (String) value);
extractedCount++;
} else if (value instanceof Enum) {
dataNode.put(field, value.toString());
extractedCount++;
} else if (value instanceof java.math.BigDecimal) {
// 处理BigDecimal类型很多测量字段是BigDecimal
dataNode.put(field, ((java.math.BigDecimal) value).doubleValue());
extractedCount++;
} else {
log.debug("字段[{}]类型[{}]未处理,值: {}", field, value.getClass().getSimpleName(), value);
}
} else {
log.trace("字段[{}]值为null", field);
}
} catch (NoSuchFieldException e) {
log.trace("字段[{}]在消息[{}]中不存在", field, message.getClass().getSimpleName());
} catch (Exception e) {
log.warn("获取字段[{}]值失败: {}", field, e.getMessage());
}
}
log.debug("从[{}]提取了{}个字段,共{}个字段",
message.getClass().getSimpleName(), extractedCount, fields.size());
} catch (Exception e) {
log.error("提取数据时发生错误: {}", e.getMessage(), e);
}
}
}

View File

@@ -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);
}

View File

@@ -0,0 +1,17 @@
package com.fizz.business.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.fizz.business.domain.BizSendTemplate;
import com.fizz.business.domain.vo.BizSendTemplateVO;
/**
* 发送默认模板 Service
*/
public interface IBizSendTemplateService extends IService<BizSendTemplate> {
/**
* 按模板编码获取模板(含明细)
*/
BizSendTemplateVO getTemplateWithItems(String templateCode);
}

View File

@@ -4,8 +4,7 @@ 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接口
@@ -16,50 +15,28 @@ import com.fizz.business.domain.msg.PdiSetup;
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);
}

View File

@@ -0,0 +1,15 @@
package com.fizz.business.service;
import com.fizz.business.domain.vo.SendJobLastSuccessVO;
/**
* 发送任务查询扩展(用于推荐值、上次发送时间)
*/
public interface ISendJobQueryService {
/**
* 查询最近一次成功发送(按 groupType 过滤DRIVE / FURNACE
*/
SendJobLastSuccessVO getLastSuccess(String groupType);
}

View File

@@ -0,0 +1,41 @@
package com.fizz.business.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.fizz.business.domain.BizSendJob;
import com.fizz.business.domain.dto.SendJobCreateDTO;
import com.fizz.business.domain.dto.SendJobQueryDTO;
import com.fizz.business.domain.vo.SendJobDetailVO;
import java.util.List;
/**
* 发送任务 Service
*/
public interface ISendJobService extends IService<BizSendJob> {
/**
* 创建发送任务(包含分组与明细)
*/
Integer createSendJob(SendJobCreateDTO dto);
/**
* 查询发送任务列表(分页由 Controller 的 startPage() 控制)
*/
List<BizSendJob> selectSendJobList(SendJobQueryDTO query);
/**
* 查询发送任务详情(包含分组与明细)
*/
SendJobDetailVO selectSendJobDetail(Integer jobId);
/**
* 删除任务逻辑删除status=DELETED
*/
Boolean deleteSendJobByJobIds(Integer[] jobIds);
/**
* 执行发送:写入 OPC并将发送结果保存为历史更新 job/group/item 状态)
*/
Boolean executeSendJob(Integer jobId);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

Some files were not shown because too many files have changed in this diff Show More