From 9571229a2013472dc701ecf5767f2873b36d8f90 Mon Sep 17 00:00:00 2001
From: huang <1532065656@qq.com>
Date: 星期四, 11 十二月 2025 17:07:19 +0800
Subject: [PATCH] 修复导入Excel功能工程号自增; 添加选择工程号自动填写玻璃id列表
---
mes-processes/mes-plcSend/src/main/java/com/mes/device/service/GlassInfoService.java | 35 ++
mes-processes/mes-plcSend/src/main/java/com/mes/device/mapper/DeviceGlassInfoMapper.java | 9
mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/transfer/handler/HorizontalTransferLogicHandler.java | 16
mes-processes/mes-plcSend/src/main/java/com/mes/device/controller/GlassInfoImportController.java | 157 +++++++++++
mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/EngineeringSequenceServiceImpl.java | 82 ++---
mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/scanner/handler/HorizontalScannerLogicHandler.java | 47 +-
mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java | 19 +
mes-web/src/api/engineering.js | 27 ++
mes-processes/mes-plcSend/src/main/java/com/mes/device/entity/GlassInfo.java | 8
mes-web/src/views/device/components/DeviceLogicConfig/WorkstationTransferConfig.vue | 2
mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/GlassInfoServiceImpl.java | 157 +++++++++++
mes-processes/mes-plcSend/src/main/java/com/mes/device/mapper/EngineeringSequenceMapper.java | 11
mes-web/src/views/plcTest/components/MultiDeviceTest/TaskOrchestration.vue | 175 ++++++++++++
13 files changed, 636 insertions(+), 109 deletions(-)
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/device/controller/GlassInfoImportController.java b/mes-processes/mes-plcSend/src/main/java/com/mes/device/controller/GlassInfoImportController.java
index f310f10..59670ef 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/device/controller/GlassInfoImportController.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/device/controller/GlassInfoImportController.java
@@ -1,19 +1,21 @@
package com.mes.device.controller;
+import com.mes.device.entity.EngineeringSequence;
+import com.mes.device.entity.GlassInfo;
+import com.mes.device.service.EngineeringSequenceService;
import com.mes.device.service.GlassInfoService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
/**
* @author :huang
@@ -27,6 +29,7 @@
public class GlassInfoImportController {
private final GlassInfoService glassInfoService;
+ private final EngineeringSequenceService engineeringSequenceService;
private final RestTemplate restTemplate = new RestTemplate();
@@ -54,12 +57,56 @@
Map<String, Object> payload = glassInfoService.buildEngineerImportPayload(excelRows);
log.info("鏋勫缓鐨� MES 瀵煎叆鏁版嵁: {}", payload);
+ // 浠巔ayload涓彁鍙栧伐绋嬪彿锛坧ayload涓娇鐢ㄧ殑鏄痚ngineerId锛�
+ String engineeringId = (String) payload.get("engineerId");
+ if (engineeringId == null || engineeringId.isEmpty()) {
+ // 濡傛灉payload涓病鏈塭ngineerId锛屽皾璇曚粠glassInfolList涓幏鍙�
+ @SuppressWarnings("unchecked")
+ List<Map<String, Object>> glassInfoList = (List<Map<String, Object>>) payload.get("glassInfolList");
+ if (glassInfoList != null && !glassInfoList.isEmpty()) {
+ Object firstEngineerId = glassInfoList.get(0).get("engineerId");
+ if (firstEngineerId != null) {
+ engineeringId = firstEngineerId.toString();
+ }
+ }
+ }
+
String mesEngineeringImportUrl = glassInfoService.getMesEngineeringImportUrl();
try {
ResponseEntity<Map> mesResp = restTemplate.postForEntity(mesEngineeringImportUrl, payload, Map.class);
+ Map<String, Object> mesBody = mesResp.getBody();
+
+ // 妫�鏌ES鍝嶅簲鏄惁鐪熸鎴愬姛锛堜笉浠呮鏌TTP鐘舵�佺爜锛岃繕瑕佹鏌ュ搷搴斾綋涓殑code瀛楁锛�
+ boolean mesSuccess = false;
+ if (mesResp.getStatusCode().is2xxSuccessful() && mesBody != null) {
+ Object codeObj = mesBody.get("code");
+ if (codeObj != null) {
+ int code = codeObj instanceof Number ? ((Number) codeObj).intValue() :
+ Integer.parseInt(String.valueOf(codeObj));
+ // MES鎴愬姛閫氬父杩斿洖code=200鎴�0
+ mesSuccess = (code == 200 || code == 0);
+ } else {
+ // 濡傛灉娌℃湁code瀛楁锛岃涓篐TTP 2xx灏辨槸鎴愬姛
+ mesSuccess = true;
+ }
+ }
+
+ // 鍙湁MES瀵煎叆鐪熸鎴愬姛鏃讹紝鎵嶄繚瀛樼幓鐠冧俊鎭埌鏈湴鏁版嵁搴擄紝骞跺叧鑱攅ngineering_id
+ if (mesSuccess && engineeringId != null) {
+ try {
+ glassInfoService.saveGlassInfosFromExcel(excelRows, engineeringId);
+ log.info("MES瀵煎叆鎴愬姛锛屽凡淇濆瓨鐜荤拑淇℃伅鍒版湰鍦版暟鎹簱锛屽伐绋嬪彿: {}", engineeringId);
+ } catch (Exception e) {
+ log.error("MES瀵煎叆鎴愬姛锛屼絾淇濆瓨鐜荤拑淇℃伅鍒版湰鍦版暟鎹簱澶辫触: engineeringId={}", engineeringId, e);
+ // 鍗充娇淇濆瓨澶辫触锛屼篃杩斿洖MES鐨勬垚鍔熷搷搴旓紝浣嗚褰曢敊璇棩蹇�
+ }
+ } else {
+ log.warn("MES瀵煎叆鏈垚鍔燂紝涓嶄繚瀛樼幓鐠冧俊鎭埌鏈湴鏁版嵁搴�: engineeringId={}, mesSuccess={}", engineeringId, mesSuccess);
+ }
+
// 鐩存帴杩斿洖 MES 鐨勫搷搴旓紝璁╁墠绔牴鎹搷搴斾綋涓殑 code 瀛楁鍒ゆ柇鏄惁鎴愬姛
- return ResponseEntity.status(mesResp.getStatusCode()).body(mesResp.getBody());
+ return ResponseEntity.status(mesResp.getStatusCode()).body(mesBody);
} catch (org.springframework.web.client.ResourceAccessException e) {
// 杩炴帴瓒呮椂鎴栨棤娉曡繛鎺�
log.error("杞彂 MES 瀵煎叆鎺ュ彛澶辫触锛堣繛鎺ラ棶棰橈級 url={}, error={}", mesEngineeringImportUrl, e.getMessage(), e);
@@ -78,6 +125,106 @@
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
}
}
+
+ /**
+ * 鏌ヨ鎵�鏈夊伐绋嬪彿鍒楄〃
+ */
+ @GetMapping("/engineering/list")
+ public ResponseEntity<?> getEngineeringList() {
+ try {
+ List<EngineeringSequence> list = engineeringSequenceService.list();
+ List<Map<String, Object>> result = list.stream()
+ .map(seq -> {
+ Map<String, Object> map = new HashMap<>();
+ map.put("engineeringId", seq.getEngineeringId());
+ map.put("date", seq.getDate());
+ map.put("sequence", seq.getSequence());
+ return map;
+ })
+ .collect(Collectors.toList());
+ return ResponseEntity.ok(result);
+ } catch (Exception e) {
+ log.error("鏌ヨ宸ョ▼鍙峰垪琛ㄥけ璐�", e);
+ Map<String, Object> errorResponse = new HashMap<>();
+ errorResponse.put("code", 500);
+ errorResponse.put("message", "鏌ヨ宸ョ▼鍙峰垪琛ㄥけ璐�: " + e.getMessage());
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
+ }
+ }
+
+ /**
+ * 鏍规嵁宸ョ▼鍙锋煡璇㈠搴旂殑鐜荤拑ID鍒楄〃
+ */
+ @GetMapping("/engineering/{engineeringId}/glassIds")
+ public ResponseEntity<?> getGlassIdsByEngineeringId(@PathVariable String engineeringId) {
+ try {
+ List<GlassInfo> glassInfos = glassInfoService.getGlassInfosByEngineeringId(engineeringId);
+ List<String> glassIds = glassInfos.stream()
+ .map(GlassInfo::getGlassId)
+ .filter(id -> id != null && !id.trim().isEmpty())
+ .collect(Collectors.toList());
+
+ Map<String, Object> result = new HashMap<>();
+ result.put("engineeringId", engineeringId);
+ result.put("glassIds", glassIds);
+ result.put("count", glassIds.size());
+
+ return ResponseEntity.ok(result);
+ } catch (Exception e) {
+ log.error("鏍规嵁宸ョ▼鍙锋煡璇㈢幓鐠僆D鍒楄〃澶辫触: engineeringId={}", engineeringId, e);
+ Map<String, Object> errorResponse = new HashMap<>();
+ errorResponse.put("code", 500);
+ errorResponse.put("message", "鏌ヨ鐜荤拑ID鍒楄〃澶辫触: " + e.getMessage());
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
+ }
+ }
+
+ /**
+ * 鍒犻櫎宸ョ▼鍙峰強鍏跺叧鑱旂殑鐜荤拑淇℃伅
+ */
+ @DeleteMapping("/engineering/{engineeringId}")
+ public ResponseEntity<?> deleteEngineering(@PathVariable String engineeringId) {
+ try {
+ // 1. 鍒犻櫎glass_info琛ㄤ腑瀵瑰簲宸ョ▼鍙风殑鐜荤拑淇℃伅
+ int deletedGlassCount = glassInfoService.deleteGlassInfosByEngineeringId(engineeringId);
+
+ // 2. 鍒犻櫎engineering_sequence琛ㄤ腑鐨勫伐绋嬪彿璁板綍锛堥�昏緫鍒犻櫎锛�
+ EngineeringSequence sequence = engineeringSequenceService.getOne(
+ new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<EngineeringSequence>()
+ .eq(EngineeringSequence::getEngineeringId, engineeringId)
+ .eq(EngineeringSequence::getIsDeleted, 0) // 鍙煡璇㈡湭鍒犻櫎鐨勮褰�
+ .last("LIMIT 1")
+ );
+
+ boolean deletedSequence = false;
+ if (sequence != null) {
+ // removeById 浼氳嚜鍔ㄤ娇鐢ㄩ�昏緫鍒犻櫎锛堝洜涓哄疄浣撶被鏈� @TableLogic 娉ㄨВ锛�
+ deletedSequence = engineeringSequenceService.removeById(sequence.getId());
+ log.info("宸插垹闄ゅ伐绋嬪彿璁板綍: engineeringId={}, sequenceId={}", engineeringId, sequence.getId());
+ } else {
+ log.warn("鏈壘鍒板伐绋嬪彿璁板綍: engineeringId={}", engineeringId);
+ }
+
+ Map<String, Object> result = new HashMap<>();
+ result.put("engineeringId", engineeringId);
+ result.put("deletedGlassCount", deletedGlassCount);
+ result.put("deletedSequence", deletedSequence);
+ result.put("success", true);
+ result.put("message", String.format("宸插垹闄ゅ伐绋嬪彿 %s锛屽叡鍒犻櫎 %d 鏉$幓鐠冧俊鎭�", engineeringId, deletedGlassCount));
+
+ log.info("鍒犻櫎宸ョ▼鍙锋垚鍔�: engineeringId={}, deletedGlassCount={}, deletedSequence={}",
+ engineeringId, deletedGlassCount, deletedSequence);
+
+ return ResponseEntity.ok(result);
+ } catch (Exception e) {
+ log.error("鍒犻櫎宸ョ▼鍙峰け璐�: engineeringId={}", engineeringId, e);
+ Map<String, Object> errorResponse = new HashMap<>();
+ errorResponse.put("code", 500);
+ errorResponse.put("message", "鍒犻櫎宸ョ▼鍙峰け璐�: " + e.getMessage());
+ errorResponse.put("success", false);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
+ }
+ }
}
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/device/entity/GlassInfo.java b/mes-processes/mes-plcSend/src/main/java/com/mes/device/entity/GlassInfo.java
index bae1225..74fdf93 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/device/entity/GlassInfo.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/device/entity/GlassInfo.java
@@ -65,6 +65,14 @@
@TableField("work_line")
private Integer workLine;
+ @ApiModelProperty(value = "宸ョ▼鍙凤紙鍏宠仈 engineering_sequence 琛級", example = "P25010801")
+ @TableField("engineering_id")
+ private String engineeringId;
+
+ @ApiModelProperty(value = "鐘舵�侊細0-鍒濆淇濆瓨, 1-宸叉壂鐮佷氦浜�", example = "0")
+ @TableField("state")
+ private Integer state;
+
@ApiModelProperty(value = "鍒涘缓鏃堕棿")
@TableField(value = "created_time", fill = FieldFill.INSERT)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/device/mapper/DeviceGlassInfoMapper.java b/mes-processes/mes-plcSend/src/main/java/com/mes/device/mapper/DeviceGlassInfoMapper.java
index ad8dd1c..f0d531d 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/device/mapper/DeviceGlassInfoMapper.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/device/mapper/DeviceGlassInfoMapper.java
@@ -42,5 +42,14 @@
*/
@Select("SELECT * FROM glass_info WHERE status = #{status} AND is_deleted = 0 ORDER BY created_time DESC")
List<GlassInfo> selectByStatus(@Param("status") String status);
+
+ /**
+ * 鏍规嵁宸ョ▼鍙锋煡璇㈢幓鐠僆D鍒楄〃
+ *
+ * @param engineeringId 宸ョ▼鍙�
+ * @return 鐜荤拑淇℃伅鍒楄〃
+ */
+ @Select("SELECT * FROM glass_info WHERE engineering_id = #{engineeringId} AND is_deleted = 0")
+ List<GlassInfo> selectByEngineeringId(@Param("engineeringId") String engineeringId);
}
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/device/mapper/EngineeringSequenceMapper.java b/mes-processes/mes-plcSend/src/main/java/com/mes/device/mapper/EngineeringSequenceMapper.java
index 422cc58..12b1323 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/device/mapper/EngineeringSequenceMapper.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/device/mapper/EngineeringSequenceMapper.java
@@ -23,17 +23,8 @@
* @param date 鏃ユ湡
* @return 鏈�澶у簭鍙凤紝濡傛灉娌℃湁璁板綍杩斿洖0
*/
- @Select("SELECT COALESCE(MAX(sequence), 0) FROM engineering_sequence WHERE date = #{date} AND is_deleted = 0")
+ @Select("SELECT COALESCE(MAX(sequence), 0) FROM engineering_sequence WHERE DATE(date) = DATE(#{date})")
Integer selectMaxSequenceByDate(@Param("date") Date date);
-
- /**
- * 鏌ヨ鎸囧畾鏃ユ湡鐨勬渶澶у簭鍙峰苟鍔犺閿侊紝閬垮厤骞跺彂鐢熸垚閲嶅搴忓彿
- *
- * @param date 鏃ユ湡
- * @return 鏈�澶у簭鍙凤紝濡傛灉娌℃湁璁板綍杩斿洖0
- */
- @Select("SELECT COALESCE(MAX(sequence), 0) FROM engineering_sequence WHERE date = #{date} AND is_deleted = 0 FOR UPDATE")
- Integer selectMaxSequenceByDateForUpdate(@Param("date") Date date);
/**
* 鏍规嵁宸ョ▼鍙锋煡璇㈠伐绋嬪簭鍙蜂俊鎭�
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/GlassInfoService.java b/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/GlassInfoService.java
index 497e6bd..2095c13 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/GlassInfoService.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/GlassInfoService.java
@@ -91,5 +91,40 @@
* @return 绗﹀悎 MES 鎺ュ彛瑕佹眰鐨勮姹備綋 Map
*/
Map<String, Object> buildEngineerImportPayload(List<Map<String, Object>> excelRows);
+
+ /**
+ * 鏍规嵁宸ョ▼鍙锋煡璇㈢幓鐠冧俊鎭垪琛�
+ *
+ * @param engineeringId 宸ョ▼鍙�
+ * @return 鐜荤拑淇℃伅鍒楄〃
+ */
+ List<GlassInfo> getGlassInfosByEngineeringId(String engineeringId);
+
+ /**
+ * 浠嶦xcel鏁版嵁淇濆瓨鐜荤拑淇℃伅鍒版湰鍦版暟鎹簱锛屽苟鍏宠仈engineering_id
+ *
+ * @param excelRows Excel琛屾暟鎹�
+ * @param engineeringId 宸ョ▼鍙�
+ */
+ void saveGlassInfosFromExcel(List<Map<String, Object>> excelRows, String engineeringId);
+
+ /**
+ * 鎵爜浜や簰鍚庢洿鏂扮幓鐠冧俊鎭姸鎬侊紙灏唖tate浠�0鏀逛负1锛�
+ *
+ * @param glassId 鐜荤拑ID
+ * @param width 瀹藉害锛堝彲閫夛級
+ * @param height 楂樺害锛堝彲閫夛級
+ * @param workLine 浜х嚎缂栧彿锛堝彲閫夛級
+ * @return 鏄惁鏇存柊鎴愬姛
+ */
+ boolean updateGlassStateAfterScan(String glassId, Integer width, Integer height, Integer workLine);
+
+ /**
+ * 鏍规嵁宸ョ▼鍙峰垹闄ょ幓鐠冧俊鎭�
+ *
+ * @param engineeringId 宸ョ▼鍙�
+ * @return 鍒犻櫎鐨勭幓鐠冩暟閲�
+ */
+ int deleteGlassInfosByEngineeringId(String engineeringId);
}
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/EngineeringSequenceServiceImpl.java b/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/EngineeringSequenceServiceImpl.java
index 2eb888c..0a37fb0 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/EngineeringSequenceServiceImpl.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/EngineeringSequenceServiceImpl.java
@@ -16,66 +16,54 @@
/**
* 宸ョ▼搴忓彿淇℃伅鏈嶅姟瀹炵幇绫�
- *
+ *
* @author mes
- * @since 2024-11-20
+ * @since 2025-11-20
*/
@Slf4j
@Service
public class EngineeringSequenceServiceImpl extends ServiceImpl<EngineeringSequenceMapper, EngineeringSequence> implements EngineeringSequenceService {
- // 鏃ユ湡鏍煎紡鍖栧櫒锛堢嚎绋嬩笉瀹夊叏锛屼娇鐢═hreadLocal淇濊瘉绾跨▼瀹夊叏锛�
- private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyMMdd");
+ // 淇锛氫娇鐢═hreadLocal淇濊瘉DateTimeFormatter鐨勭嚎绋嬪畨鍏�
+ private static final ThreadLocal<DateTimeFormatter> DATE_FORMATTER_THREAD_LOCAL = ThreadLocal.withInitial(
+ () -> DateTimeFormatter.ofPattern("yyMMdd")
+ );
+
+ // 閲嶈瘯闂撮殧锛堟绉掞級锛屼娇鐢ㄩ殢鏈烘暟閬垮厤骞跺彂璇锋眰鍚屾椂閲嶈瘯
+ private static final int RETRY_INTERVAL_MIN = 50;
+ private static final int RETRY_INTERVAL_MAX = 200;
@Override
@Transactional(rollbackFor = Exception.class)
public String generateAndSaveEngineeringId(Date date) {
- // 涔愯閲嶈瘯锛岄槻姝㈠苟鍙戝啓鍏ラ�犳垚閲嶅閿�
- int retry = 0;
- final int maxRetry = 5;
- while (true) {
- try {
- // 1. 鏌ヨ褰撳ぉ鏈�澶у簭鍙凤紝骞跺姞琛岄攣閬垮厤骞跺彂閲嶅
- Integer maxSequence = baseMapper.selectMaxSequenceByDateForUpdate(date);
- if (maxSequence == null) {
- maxSequence = 0;
- }
+ try {
+ Integer maxSequence = baseMapper.selectMaxSequenceByDate(date);
+ maxSequence = (maxSequence == null) ? 0 : maxSequence;
+ int newSequence = maxSequence + 1;
- // 2. 搴忓彿鑷1
- int newSequence = maxSequence + 1;
+ LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+ String dateStr = DATE_FORMATTER_THREAD_LOCAL.get().format(localDate);
+ String engineeringId = "P" + dateStr + String.format("%02d", newSequence);
- // 3. 鐢熸垚宸ョ▼鍙凤細P + yyMMdd + 涓や綅搴忓彿
- LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
- String dateStr = localDate.format(DATE_FORMATTER);
- String engineeringId = "P" + dateStr + String.format("%02d", newSequence);
+ EngineeringSequence engineeringSequence = new EngineeringSequence();
+ engineeringSequence.setEngineeringId(engineeringId);
+ engineeringSequence.setDate(date);
+ engineeringSequence.setSequence(newSequence);
+ engineeringSequence.setCreatedTime(new Date());
+ engineeringSequence.setUpdatedTime(new Date());
+ engineeringSequence.setCreatedBy("system");
+ engineeringSequence.setUpdatedBy("system");
- // 4. 淇濆瓨鍒版暟鎹簱
- EngineeringSequence engineeringSequence = new EngineeringSequence();
- engineeringSequence.setEngineeringId(engineeringId);
- engineeringSequence.setDate(date);
- engineeringSequence.setSequence(newSequence);
- engineeringSequence.setCreatedTime(new Date());
- engineeringSequence.setUpdatedTime(new Date());
- engineeringSequence.setCreatedBy("system");
- engineeringSequence.setUpdatedBy("system");
+ save(engineeringSequence);
- save(engineeringSequence);
-
- log.info("鐢熸垚宸ョ▼鍙锋垚鍔�: engineeringId={}, date={}, sequence={}", engineeringId, date, newSequence);
- return engineeringId;
-
- } catch (DuplicateKeyException dup) {
- // 骞跺彂瀵艰嚧鐨勫敮涓�閿啿绐侊紝閲嶈瘯
- if (++retry > maxRetry) {
- log.error("鐢熸垚宸ョ▼鍙烽噸璇曡秴杩囦笂闄�, date={}", date, dup);
- throw new RuntimeException("鐢熸垚宸ョ▼鍙峰け璐�", dup);
- }
- log.warn("宸ョ▼鍙风敓鎴愬彂鐢熷苟鍙戝啿绐侊紝鍑嗗閲嶈瘯锛岀{}娆★紝date={}", retry, date);
- } catch (Exception e) {
- log.error("鐢熸垚宸ョ▼鍙峰け璐�, date={}", date, e);
- throw new RuntimeException("鐢熸垚宸ョ▼鍙峰け璐�", e);
- }
+ log.info("鐢熸垚宸ョ▼鍙锋垚鍔�: engineeringId={}, date={}, sequence={}", engineeringId, date, newSequence);
+ return engineeringId;
+ } catch (DuplicateKeyException dup) {
+ log.error("鐢熸垚宸ョ▼鍙峰敮涓�閿啿绐�: date={}", date, dup);
+ throw new RuntimeException("鐢熸垚宸ョ▼鍙峰け璐�", dup);
+ } catch (Exception e) {
+ log.error("鐢熸垚宸ョ▼鍙峰け璐�, date={}", date, e);
+ throw new RuntimeException("鐢熸垚宸ョ▼鍙峰け璐�", e);
}
}
-}
-
+}
\ No newline at end of file
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/GlassInfoServiceImpl.java b/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/GlassInfoServiceImpl.java
index 6c26414..36e73b8 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/GlassInfoServiceImpl.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/GlassInfoServiceImpl.java
@@ -14,6 +14,7 @@
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
+import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
@@ -230,7 +231,7 @@
return result;
}
- // 宸ョ▼鍙风敓鎴愶細浣跨敤鏁版嵁搴撹嚜澧炲簭鍙凤紝閬垮厤閲嶅
+ // 宸ョ▼鍙风敓鎴愶細姣忔瀵煎叆閮界敓鎴愭柊鐨勫伐绋嬪彿锛堜娇鐢ㄦ暟鎹簱鑷搴忓彿锛岄伩鍏嶉噸澶嶏級
final String engineerId = engineeringSequenceService.generateAndSaveEngineeringId(new Date());
final String filmsIdDefault = firstValue(excelRows, "filmsId", "鐧界幓");
final double thicknessDefault = parseDouble(firstValue(excelRows, "thickness"), 0d);
@@ -242,8 +243,9 @@
List<Map<String, Object>> glassInfolList = excelRows.stream()
.flatMap(row -> {
- int qty = (int) parseDouble(row.getOrDefault("quantity", 1), 1);
- if (qty <= 0) qty = 1;
+ Object qtyObj = row.getOrDefault("quantity", 1);
+ int qty = parseDouble(qtyObj, 1) > 0 ? (int) parseDouble(qtyObj, 1) : 1;
+
String glassId = str(row.get("glassId"));
String filmsId = strOrDefault(row.get("filmsId"), filmsIdDefaultFinal);
String flowCardId = str(row.get("flowCardId"));
@@ -254,9 +256,15 @@
double thickness = parseDouble(row.get("thickness"), thicknessDefaultFinal);
int finalQty = qty;
+ log.info("瑙f瀽鍒版暟閲忥細row={}, quantity={}, 鏈�缁坬ty={}", row, qtyObj, finalQty);
return range(0, qty).mapToObj(idx -> {
- String finalGlassId = finalQty > 1 ? glassId + "_" + (idx + 1) : glassId;
- String finalFlowCardId = flowCardId.isEmpty() ? finalGlassId : flowCardId;
+ String baseGlassId = engineerIdFinal + glassId;
+ String finalGlassId = finalQty > 1 ? baseGlassId + "_" + (idx + 1) : baseGlassId;
+
+ String baseFlowCardId = flowCardId.isEmpty() ? baseGlassId : flowCardId;
+ String finalFlowCardSequence = baseFlowCardId + "/" + (idx + 1);
+ String finalFlowCardId = baseFlowCardId;
+
Map<String, Object> m = new HashMap<>();
m.put("xAxis", 0);
m.put("xCoordinate", 0);
@@ -287,7 +295,7 @@
m.put("combine", 0);
m.put("markIcon", "");
m.put("filmRemove", 0);
- m.put("flowCardSequence", flowCardId + "/" + (idx + 1));
+ m.put("flowCardSequence", finalFlowCardSequence);
m.put("process", "");
m.put("rawAngle", 0);
m.put("graphNo", 0);
@@ -473,5 +481,142 @@
return Math.round(v * 100.0) / 100.0;
}
+ @Override
+ public List<GlassInfo> getGlassInfosByEngineeringId(String engineeringId) {
+ if (engineeringId == null || engineeringId.trim().isEmpty()) {
+ return Collections.emptyList();
+ }
+ try {
+ return baseMapper.selectByEngineeringId(engineeringId.trim());
+ } catch (Exception e) {
+ log.error("鏍规嵁宸ョ▼鍙锋煡璇㈢幓鐠冧俊鎭け璐�, engineeringId={}", engineeringId, e);
+ return Collections.emptyList();
+ }
+ }
+
+ @Override
+ public void saveGlassInfosFromExcel(List<Map<String, Object>> excelRows, String engineeringId) {
+ if (excelRows == null || excelRows.isEmpty() || engineeringId == null || engineeringId.trim().isEmpty()) {
+ return;
+ }
+
+ List<GlassInfo> glassInfos = new ArrayList<>();
+ Date now = new Date();
+
+ for (Map<String, Object> row : excelRows) {
+ String glassId = str(row.get("glassId"));
+ if (glassId == null || glassId.trim().isEmpty()) {
+ continue;
+ }
+
+ int qty = (int) parseDouble(row.getOrDefault("quantity", 1), 1);
+ if (qty <= 0) qty = 1;
+
+ double width = parseDouble(row.get("width"), 0d);
+ double height = parseDouble(row.get("height"), 0d);
+ double thickness = parseDouble(row.get("thickness"), 0d);
+
+ // 涓庡鍏ヨ鍒欎繚鎸佷竴鑷达細glassId 鍓嶅姞宸ョ▼鍙峰墠缂�锛屾暟閲�>1鏃惰拷鍔犲簭鍙�
+ String baseGlassId = engineeringId.trim() + glassId;
+ for (int idx = 0; idx < qty; idx++) {
+ String finalGlassId = qty > 1 ? baseGlassId + "_" + (idx + 1) : baseGlassId;
+
+ GlassInfo glassInfo = new GlassInfo();
+ glassInfo.setGlassId(finalGlassId);
+ glassInfo.setEngineeringId(engineeringId.trim());
+ glassInfo.setGlassLength((int) Math.round(height));
+ glassInfo.setGlassWidth((int) Math.round(width));
+ glassInfo.setGlassThickness(BigDecimal.valueOf(thickness));
+ glassInfo.setStatus(GlassInfo.Status.ACTIVE);
+ glassInfo.setState(0);
+ glassInfo.setCreatedTime(now);
+ glassInfo.setUpdatedTime(now);
+ glassInfo.setCreatedBy("system");
+ glassInfo.setUpdatedBy("system");
+
+ glassInfos.add(glassInfo);
+ }
+ }
+
+ if (!glassInfos.isEmpty()) {
+ batchSaveOrUpdateGlassInfo(glassInfos);
+ log.info("宸蹭繚瀛� {} 鏉$幓鐠冧俊鎭埌鏈湴鏁版嵁搴擄紝宸ョ▼鍙�: {}", glassInfos.size(), engineeringId);
+ }
+ }
+
+ @Override
+ public boolean updateGlassStateAfterScan(String glassId, Integer width, Integer height, Integer workLine) {
+ if (glassId == null || glassId.trim().isEmpty()) {
+ return false;
+ }
+
+ try {
+ // 鏌ヨ宸插瓨鍦ㄧ殑鐜荤拑淇℃伅
+ GlassInfo existing = baseMapper.selectByGlassId(glassId.trim());
+ if (existing == null) {
+ log.debug("鐜荤拑淇℃伅涓嶅瓨鍦紝鏃犳硶鏇存柊鐘舵��: glassId={}", glassId);
+ return false;
+ }
+
+ // 鏇存柊鐘舵�佷负1锛堝凡鎵爜浜や簰锛�
+ LambdaUpdateWrapper<GlassInfo> wrapper = new LambdaUpdateWrapper<>();
+ wrapper.eq(GlassInfo::getGlassId, glassId.trim())
+ .eq(GlassInfo::getIsDeleted, 0)
+ .set(GlassInfo::getState, 1)
+ .set(GlassInfo::getUpdatedTime, new Date())
+ .set(GlassInfo::getUpdatedBy, "system");
+
+ // 濡傛灉鎻愪緵浜嗗昂瀵镐俊鎭紝涔熸洿鏂板昂瀵�
+ if (width != null) {
+ wrapper.set(GlassInfo::getGlassWidth, width);
+ }
+ if (height != null) {
+ wrapper.set(GlassInfo::getGlassLength, height);
+ }
+ if (workLine != null) {
+ wrapper.set(GlassInfo::getWorkLine, workLine);
+ }
+
+ boolean updated = this.update(wrapper);
+ if (updated) {
+ log.info("宸叉洿鏂扮幓鐠冧俊鎭姸鎬佷负宸叉壂鐮佷氦浜�: glassId={}, state=1", glassId);
+ }
+ return updated;
+ } catch (Exception e) {
+ log.error("鏇存柊鐜荤拑淇℃伅鐘舵�佸け璐�: glassId={}", glassId, e);
+ return false;
+ }
+ }
+
+ @Override
+ public int deleteGlassInfosByEngineeringId(String engineeringId) {
+ if (engineeringId == null || engineeringId.trim().isEmpty()) {
+ return 0;
+ }
+
+ try {
+ // 鍏堟煡璇㈣鍒犻櫎鐨勬暟閲忥紙鍒犻櫎鍓嶏級
+ LambdaQueryWrapper<GlassInfo> countWrapper = new LambdaQueryWrapper<>();
+ countWrapper.eq(GlassInfo::getEngineeringId, engineeringId.trim())
+ .eq(GlassInfo::getIsDeleted, 0); // 鏌ヨ鏈垹闄ょ殑璁板綍
+ long count = this.count(countWrapper);
+
+ // 浣跨敤MyBatis-Plus鐨剅emove鏂规硶锛屼細鏍规嵁@TableLogic鑷姩杩涜閫昏緫鍒犻櫎
+ LambdaQueryWrapper<GlassInfo> removeWrapper = new LambdaQueryWrapper<>();
+ removeWrapper.eq(GlassInfo::getEngineeringId, engineeringId.trim())
+ .eq(GlassInfo::getIsDeleted, 0); // 鍙垹闄ゆ湭鍒犻櫎鐨勮褰�
+
+ boolean result = this.remove(removeWrapper);
+ if (result) {
+ log.info("宸插垹闄ゅ伐绋嬪彿涓嬬殑鐜荤拑淇℃伅: engineeringId={}, count={}", engineeringId, count);
+ return (int) count;
+ }
+ return 0;
+ } catch (Exception e) {
+ log.error("鍒犻櫎宸ョ▼鍙蜂笅鐨勭幓鐠冧俊鎭け璐�: engineeringId={}", engineeringId, e);
+ return 0;
+ }
+ }
+
}
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/scanner/handler/HorizontalScannerLogicHandler.java b/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/scanner/handler/HorizontalScannerLogicHandler.java
index 7e25e57..5dd8525 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/scanner/handler/HorizontalScannerLogicHandler.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/scanner/handler/HorizontalScannerLogicHandler.java
@@ -133,28 +133,29 @@
// 4. 娓呯┖plcRequest鍜宲lcGlassId锛堝彧娓呴櫎PLC瀛楁锛�
clearPlcRequestFields(deviceConfig, serializer);
+ // 5. 鏇存柊鐜荤拑淇℃伅鐘舵�侊細灏唖tate浠�0鏀逛负1锛堝凡鎵爜浜や簰锛�
+ boolean updated = glassInfoService.updateGlassStateAfterScan(glassId, rawWidth, rawHeight, workLine);
+ if (!updated) {
+ log.warn("鏇存柊鐜荤拑淇℃伅鐘舵�佸け璐ワ紝鐜荤拑鍙兘涓嶅瓨鍦�: glassId={}", glassId);
+ // 涓嶈繑鍥為敊璇紝缁х画鎵ц锛屽洜涓哄彲鑳芥槸鏂扮幓鐠冭繕鏈鍏�
+ }
+
+ // 6. 灏嗘壂鎻忓埌鐨勭幓鐠僆D淇濆瓨鍒板叡浜暟鎹腑锛堜緵澶ц溅璁惧瀹氭椂鍣ㄨ鍙栵級
+ saveScannedGlassId(params, glassId);
- // 5. 淇濆瓨鐜荤拑淇℃伅鍒版暟鎹簱
- GlassInfo glassInfo = buildGlassInfo(glassId, rawWidth, rawHeight, workLine);
- boolean saved = glassInfoService.saveOrUpdateGlassInfo(glassInfo);
- if (!saved) {
- return buildResult(deviceConfig, "scanOnce", false, "淇濆瓨鐜荤拑淇℃伅澶辫触: " + glassId, null);
- }
-
- // 6. 灏嗘壂鎻忓埌鐨勭幓鐠僆D淇濆瓨鍒板叡浜暟鎹腑锛堜緵澶ц溅璁惧瀹氭椂鍣ㄨ鍙栵級
- saveScannedGlassId(params, glassId);
-
- String msg = String.format("鐜荤拑[%s] 灏哄[琛ㄥ:%s x 闀�:%s] 宸叉帴鏀跺苟鍏ュ簱锛寃orkLine=%s",
- glassId,
- rawWidth != null ? rawWidth + "mm" : "-",
- rawHeight != null ? rawHeight + "mm" : "-",
- workLine != null ? workLine : "-");
- Map<String, Object> resultData = new HashMap<>();
- resultData.put("glassIds", Collections.singletonList(glassId));
- if (workLine != null) {
- resultData.put("workLine", workLine);
- }
- return buildResult(deviceConfig, "scanOnce", true, msg, resultData);
+ Integer intervalMs = config != null ? config.getScanIntervalMs() : null;
+ String msg = String.format("鐜荤拑[%s] 灏哄[琛ㄥ:%s x 闀�:%s] 宸叉帴鏀讹紝workLine=%s锛屾壂鎻忛棿闅�=%s",
+ glassId,
+ rawWidth != null ? rawWidth + "mm" : "-",
+ rawHeight != null ? rawHeight + "mm" : "-",
+ workLine != null ? workLine : "-",
+ intervalMs != null ? intervalMs + "ms" : "-");
+ Map<String, Object> resultData = new HashMap<>();
+ resultData.put("glassIds", Collections.singletonList(glassId));
+ if (workLine != null) {
+ resultData.put("workLine", workLine);
+ }
+ return buildResult(deviceConfig, "scanOnce", true, msg, resultData);
}
/**
@@ -273,10 +274,10 @@
glassInfo.setGlassId(glassId.trim());
// mesWidth=琛ㄥ -> glassWidth, mesHeight=闀� -> glassLength
if (width != null) {
- glassInfo.setGlassWidth(width); // 琛ㄥ
+ glassInfo.setGlassWidth(width);
}
if (height != null) {
- glassInfo.setGlassLength(height); // 闀�
+ glassInfo.setGlassLength(height);
}
glassInfo.setStatus(GlassInfo.Status.PENDING);
if (workLine != null) {
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/transfer/handler/HorizontalTransferLogicHandler.java b/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/transfer/handler/HorizontalTransferLogicHandler.java
index b5d7d50..e1e177d 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/transfer/handler/HorizontalTransferLogicHandler.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/transfer/handler/HorizontalTransferLogicHandler.java
@@ -261,12 +261,10 @@
// 浠庨厤缃腑鑾峰彇workLine锛岀敤浜庤繃婊わ紙閰嶇疆涓槸Integer绫诲瀷锛�
Integer workLine = getLogicParam(logicParams, "workLine", null);
- // 鏌ヨ鏈�杩�2鍒嗛挓鍐呯殑鐜荤拑璁板綍锛堟墿澶ф椂闂寸獥鍙o紝纭繚涓嶉仐婕忥級
- Date twoMinutesAgo = new Date(System.currentTimeMillis() - 120000);
-
+ // 鏌ヨstate=1鐨勭幓鐠冭褰曪紙宸叉壂鐮佷氦浜掑畬鎴愶紝绛夊緟鍗ц浆绔嬪鐞嗭級
LambdaQueryWrapper<GlassInfo> wrapper = new LambdaQueryWrapper<>();
wrapper.in(GlassInfo::getStatus, GlassInfo.Status.PENDING, GlassInfo.Status.ACTIVE)
- .ge(GlassInfo::getCreatedTime, twoMinutesAgo)
+ .eq(GlassInfo::getState, 1) // 鍙煡璇tate=1鐨勭幓鐠冿紙宸叉壂鐮佸畬鎴愶級
.orderByDesc(GlassInfo::getCreatedTime)
.last("LIMIT 20"); // 闄愬埗鏌ヨ鏁伴噺锛岄伩鍏嶈繃澶�
@@ -419,19 +417,16 @@
// 鍐欏叆鐜荤拑鏁伴噺
payload.put("plcGlassCount", count);
- // 鍐欏叆鍗ц浆绔嬬紪鍙凤紙浼樺厛浠庝换鍔″弬鏁拌幏鍙栵紝鍏舵浠庤澶囬厤缃幏鍙栵級
- Integer inPosition = null;
+ // 鍐欏叆鍗ц浆绔嬬紪鍙凤紙浼樺厛浠庝换鍔″弬鏁拌幏鍙栵紝鍏舵浠庤澶囬厤缃幏鍙栵紝鐩存帴鍐欏叆缂栧彿锛屼笉杩涜浣嶇疆鏄犲皠锛�
+ Object inPosition = null;
if (params != null) {
try {
Object ctxObj = params.get("_taskContext");
if (ctxObj instanceof com.mes.task.model.TaskExecutionContext) {
com.mes.task.model.TaskExecutionContext ctx =
(com.mes.task.model.TaskExecutionContext) ctxObj;
- Object positionObj = ctx.getParameters().getExtra() != null
+ inPosition = ctx.getParameters().getExtra() != null
? ctx.getParameters().getExtra().get("inPosition") : null;
- if (positionObj instanceof Number) {
- inPosition = ((Number) positionObj).intValue();
- }
}
} catch (Exception e) {
log.debug("浠庝换鍔″弬鏁拌幏鍙栧崸杞珛缂栧彿澶辫触: deviceId={}", deviceConfig.getId(), e);
@@ -442,6 +437,7 @@
inPosition = getLogicParam(logicParams, "inPosition", null);
}
if (inPosition != null) {
+ // 鐩存帴鍐欏叆缂栧彿鏈韩锛屼笉杩涜浣嶇疆鏄犲皠杞崲
payload.put("inPosition", inPosition);
log.info("鍐欏叆鍗ц浆绔嬬紪鍙�: deviceId={}, inPosition={}", deviceConfig.getId(), inPosition);
} else {
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java b/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java
index 6d9c433..4c5f2d3 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java
@@ -992,6 +992,25 @@
log.debug("鍑虹墖澶ц溅璁惧瀹氭椂鍣ㄦ娴嬪埌宸插鐞嗙殑鐜荤拑淇℃伅: taskId={}, deviceId={}, glassCount={}",
task.getTaskId(), device.getId(), processedGlassIds.size());
+
+ // 闇�绛夊緟澶х悊鐗囩瀹屾垚鍏ㄩ儴鐜荤拑鐨勫鐞嗗悗鍐嶅嚭鐗�
+ @SuppressWarnings("unchecked")
+ List<String> initialGlassIds = (List<String>) context.getSharedData().get("initialGlassIds");
+ if (!CollectionUtils.isEmpty(initialGlassIds)
+ && !processedGlassIds.containsAll(initialGlassIds)) {
+ // 閮ㄥ垎鐜荤拑灏氭湭鐢卞ぇ鐞嗙墖绗煎鐞嗗畬鎴愶紝淇濇寔绛夊緟
+ deviceCoordinationService.syncDeviceStatus(device,
+ DeviceCoordinationService.DeviceStatus.WAITING, context);
+ if (!TaskStepDetail.Status.PENDING.name().equals(step.getStatus())) {
+ step.setStatus(TaskStepDetail.Status.PENDING.name());
+ step.setSuccessMessage("绛夊緟澶х悊鐗囩澶勭悊鍏ㄩ儴鐜荤拑鍚庡啀鍑虹墖");
+ taskStepDetailMapper.updateById(step);
+ notificationService.notifyStepUpdate(task.getTaskId(), step);
+ }
+ log.debug("鍑虹墖澶ц溅绛夊緟澶х悊鐗囩瀹屾垚鍏ㄩ儴鐜荤拑: taskId={}, deviceId={}, processed={}, initial={}",
+ task.getTaskId(), device.getId(), processedGlassIds.size(), initialGlassIds.size());
+ return;
+ }
// 鎵ц鍑虹墖鎿嶄綔
Map<String, Object> checkParams = new HashMap<>();
diff --git a/mes-web/src/api/engineering.js b/mes-web/src/api/engineering.js
index 7dee2ce..d83fa60 100644
--- a/mes-web/src/api/engineering.js
+++ b/mes-web/src/api/engineering.js
@@ -12,6 +12,33 @@
method: 'post',
data
})
+ },
+ /**
+ * 鏌ヨ鎵�鏈夊伐绋嬪彿鍒楄〃
+ */
+ getEngineeringList() {
+ return request({
+ url: `${BASE_URL}/engineering/list`,
+ method: 'get'
+ })
+ },
+ /**
+ * 鏍规嵁宸ョ▼鍙锋煡璇㈠搴旂殑鐜荤拑ID鍒楄〃
+ */
+ getGlassIdsByEngineeringId(engineeringId) {
+ return request({
+ url: `${BASE_URL}/engineering/${engineeringId}/glassIds`,
+ method: 'get'
+ })
+ },
+ /**
+ * 鍒犻櫎宸ョ▼鍙峰強鍏跺叧鑱旂殑鐜荤拑淇℃伅
+ */
+ deleteEngineering(engineeringId) {
+ return request({
+ url: `${BASE_URL}/engineering/${engineeringId}`,
+ method: 'delete'
+ })
}
}
diff --git a/mes-web/src/views/device/components/DeviceLogicConfig/WorkstationTransferConfig.vue b/mes-web/src/views/device/components/DeviceLogicConfig/WorkstationTransferConfig.vue
index 8c7756a..9585961 100644
--- a/mes-web/src/views/device/components/DeviceLogicConfig/WorkstationTransferConfig.vue
+++ b/mes-web/src/views/device/components/DeviceLogicConfig/WorkstationTransferConfig.vue
@@ -75,7 +75,7 @@
<el-input-number
v-model="config.inPosition"
:min="0"
- :max="1000"
+ :max="1999"
:step="1"
style="width: 100%;"
/>
diff --git a/mes-web/src/views/plcTest/components/MultiDeviceTest/TaskOrchestration.vue b/mes-web/src/views/plcTest/components/MultiDeviceTest/TaskOrchestration.vue
index 3021519..05e0b07 100644
--- a/mes-web/src/views/plcTest/components/MultiDeviceTest/TaskOrchestration.vue
+++ b/mes-web/src/views/plcTest/components/MultiDeviceTest/TaskOrchestration.vue
@@ -35,12 +35,51 @@
</div>
<el-form :model="form" label-width="120px" :rules="rules" ref="formRef">
+ <div style="width: 350px; margin-bottom: 12px; margin-left: 120px;">
+ <el-select
+ v-model="selectedEngineeringId"
+ placeholder="閫夋嫨宸ョ▼鍙凤紙閫夋嫨鍚庤嚜鍔ㄥ~鍏呯幓鐠僆D锛�"
+ clearable
+ filterable
+ :disabled="!group"
+ :loading="engineeringListLoading"
+ @change="handleEngineeringChange"
+ style="width: 100%"
+ >
+ <el-option
+ v-for="item in engineeringList"
+ :key="item.engineeringId"
+ :label="item.engineeringId"
+ :value="item.engineeringId"
+ >
+ <div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
+ <div style="flex: 1;">
+ <span>{{ item.engineeringId }}</span>
+ <span style="margin-left: 8px; color: #8492a6; font-size: 12px">
+ {{ item.date ? new Date(item.date).toLocaleDateString() : '' }}
+ </span>
+ </div>
+ <el-button
+ type="danger"
+ link
+ size="small"
+ :loading="deletingEngineeringId === item.engineeringId"
+ @click.stop="handleDeleteEngineering(item.engineeringId)"
+ style="margin-left: 8px; padding: 0 4px;"
+ >
+ <el-icon><Delete /></el-icon>
+ </el-button>
+ </div>
+ </el-option>
+ </el-select>
+ </div>
+
<el-form-item label="鐜荤拑ID鍒楄〃" prop="glassIds">
<el-input
v-model="glassIdsInput"
type="textarea"
:rows="4"
- placeholder="鍙�夛細杈撳叆鐜荤拑ID锛屽皢浣跨敤杈撳叆鐨処D杩涜娴嬭瘯"
+ placeholder="鍙�夛細杈撳叆鐜荤拑ID锛屽皢浣跨敤杈撳叆鐨処D杩涜娴嬭瘯锛堟垨閫氳繃涓婃柟閫夋嫨宸ョ▼鍙疯嚜鍔ㄥ~鍏咃級"
show-word-limit
:maxlength="5000"
/>
@@ -57,8 +96,8 @@
</template>
<script setup>
-import { computed, reactive, ref, watch } from 'vue'
-import { ElMessage } from 'element-plus'
+import { computed, reactive, ref, watch, onMounted } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
import { Delete, Promotion, Upload } from '@element-plus/icons-vue'
import * as XLSX from 'xlsx'
import { multiDeviceTaskApi } from '@/api/device/multiDeviceTask'
@@ -116,13 +155,27 @@
const loadDeviceLoading = ref(false)
const fileInputRef = ref(null)
+// 宸ョ▼鍙风浉鍏�
+const selectedEngineeringId = ref('')
+const engineeringList = ref([])
+const engineeringListLoading = ref(false)
+const glassIdsLoading = ref(false)
+const deletingEngineeringId = ref('')
+
watch(
() => props.group,
() => {
glassIdsInput.value = ''
+ selectedEngineeringId.value = ''
fetchLoadDevice()
+ fetchEngineeringList()
}
)
+
+// 缁勪欢鎸傝浇鏃跺姞杞藉伐绋嬪彿鍒楄〃
+onMounted(() => {
+ fetchEngineeringList()
+})
const glassIds = computed(() => {
if (!glassIdsInput.value) return []
@@ -131,6 +184,108 @@
.map((item) => item.trim())
.filter((item) => item.length > 0)
})
+
+// 鑾峰彇宸ョ▼鍙峰垪琛�
+const fetchEngineeringList = async () => {
+ try {
+ engineeringListLoading.value = true
+ const response = await engineeringApi.getEngineeringList()
+
+ if (Array.isArray(response)) {
+ engineeringList.value = response
+ } else if (Array.isArray(response?.data)) {
+ engineeringList.value = response.data
+ } else {
+ engineeringList.value = []
+ }
+ // 鎸夋棩鏈熷�掑簭鎺掑垪
+ engineeringList.value.sort((a, b) => {
+ const dateA = a.date ? new Date(a.date).getTime() : 0
+ const dateB = b.date ? new Date(b.date).getTime() : 0
+ return dateB - dateA
+ })
+ } catch (error) {
+ console.error('鑾峰彇宸ョ▼鍙峰垪琛ㄥけ璐�:', error)
+ ElMessage.error(error?.message || '鑾峰彇宸ョ▼鍙峰垪琛ㄥけ璐�')
+ engineeringList.value = []
+ } finally {
+ engineeringListLoading.value = false
+ }
+}
+
+// 澶勭悊宸ョ▼鍙烽�夋嫨鍙樺寲
+const handleEngineeringChange = async (engineeringId) => {
+ if (!engineeringId) {
+ // 娓呯┖閫夋嫨鏃讹紝涓嶆竻绌哄凡杈撳叆鐨勭幓鐠僆D锛岃鐢ㄦ埛淇濈暀
+ return
+ }
+
+ try {
+ glassIdsLoading.value = true
+ const response = await engineeringApi.getGlassIdsByEngineeringId(engineeringId)
+
+ const glassIds = response?.glassIds || response?.data?.glassIds || []
+
+ if (glassIds.length > 0) {
+ glassIdsInput.value = glassIds.join('\n')
+ ElMessage.success(`宸插姞杞藉伐绋嬪彿 ${engineeringId} 鐨� ${glassIds.length} 涓幓鐠僆D`)
+ } else {
+ ElMessage.warning(`宸ョ▼鍙� ${engineeringId} 涓嬫病鏈夋壘鍒扮幓鐠僆D`)
+ }
+ } catch (error) {
+ console.error('鑾峰彇鐜荤拑ID鍒楄〃澶辫触:', error)
+ ElMessage.error(error?.message || '鑾峰彇鐜荤拑ID鍒楄〃澶辫触')
+ } finally {
+ glassIdsLoading.value = false
+ }
+}
+
+// 澶勭悊鍒犻櫎宸ョ▼鍙�
+const handleDeleteEngineering = async (engineeringId) => {
+ if (!engineeringId) {
+ return
+ }
+
+ try {
+ await ElMessageBox.confirm(
+ `纭畾瑕佸垹闄ゅ伐绋嬪彿 "${engineeringId}" 鍙婂叾鍏宠仈鐨勬墍鏈夌幓鐠冧俊鎭悧锛熸鎿嶄綔涓嶅彲鎭㈠锛乣,
+ '纭鍒犻櫎',
+ {
+ confirmButtonText: '纭畾鍒犻櫎',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning',
+ dangerouslyUseHTMLString: false
+ }
+ )
+
+ deletingEngineeringId.value = engineeringId
+ const response = await engineeringApi.deleteEngineering(engineeringId)
+
+ const result = response?.data || response
+ if (result?.success !== false) {
+ const deletedCount = result?.deletedGlassCount || 0
+ ElMessage.success(`宸插垹闄ゅ伐绋嬪彿 ${engineeringId}锛屽叡鍒犻櫎 ${deletedCount} 鏉$幓鐠冧俊鎭痐)
+
+ // 濡傛灉鍒犻櫎鐨勬槸褰撳墠閫変腑鐨勫伐绋嬪彿锛屾竻绌洪�夋嫨
+ if (selectedEngineeringId.value === engineeringId) {
+ selectedEngineeringId.value = ''
+ glassIdsInput.value = ''
+ }
+
+ // 鍒锋柊宸ョ▼鍙峰垪琛�
+ await fetchEngineeringList()
+ } else {
+ throw new Error(result?.message || '鍒犻櫎澶辫触')
+ }
+ } catch (error) {
+ if (error !== 'cancel') {
+ console.error('鍒犻櫎宸ョ▼鍙峰け璐�:', error)
+ ElMessage.error(error?.message || '鍒犻櫎宸ョ▼鍙峰け璐�')
+ }
+ } finally {
+ deletingEngineeringId.value = ''
+ }
+}
const normalizeType = (type) => (type || '').trim().toUpperCase()
@@ -508,10 +663,16 @@
: `鎴愬姛瀵煎叆 ${glassDataList.length} 鏉$幓鐠冩暟鎹甡
ElMessage.success(successMsg)
- // 灏嗗鍏ョ殑鐜荤拑ID濉厖鍒拌緭鍏ユ锛屾柟渚跨敤鎴锋煡鐪嬪拰缂栬緫
- const glassIds = glassDataList.map(item => item.glassId).filter(id => id)
- if (glassIds.length > 0) {
- glassIdsInput.value = glassIds.join('\n')
+ // 鎴愬姛鍚庡埛鏂板伐绋嬪彿涓嬫媺鍒楄〃锛屽苟閫変腑鏈�鏂板伐绋嬪彿
+ try {
+ await fetchEngineeringList()
+ if (engineerId) {
+ selectedEngineeringId.value = engineerId
+ // 鍒锋柊骞跺洖濉悗绔繚瀛樼殑 glassId锛堝甫宸ョ▼鍙峰墠缂�锛夛紝閬垮厤浣跨敤鍓嶇鍘熷鍊�
+ await handleEngineeringChange(engineerId)
+ }
+ } catch (refreshErr) {
+ console.error('鍒锋柊宸ョ▼鍙峰垪琛ㄥけ璐�:', refreshErr)
}
} else {
// MES 鎺ュ彛杩斿洖澶辫触
--
Gitblit v1.8.0