添加nacos配置中心,可动态更新mes导入工程接口;修改Excel表数据转json格式
8个文件已修改
1个文件已添加
126 ■■■■ 已修改文件
mes-processes/mes-plcSend/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
mes-processes/mes-plcSend/src/main/java/com/mes/device/controller/GlassInfoImportController.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
mes-processes/mes-plcSend/src/main/java/com/mes/device/service/GlassInfoService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/GlassInfoServiceImpl.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
mes-processes/mes-plcSend/src/main/resources/application.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
mes-processes/mes-plcSend/src/main/resources/bootstrap.yml 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
mes-web/public/config.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
mes-web/src/utils/constants.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
mes-web/src/views/plcTest/components/MultiDeviceTest/TaskOrchestration.vue 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
mes-processes/mes-plcSend/pom.xml
@@ -27,6 +27,11 @@
            <artifactId>serverBase</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>2.1.4.RELEASE</version>
        </dependency>
    </dependencies>
</project>
mes-processes/mes-plcSend/src/main/java/com/mes/device/controller/GlassInfoImportController.java
@@ -3,11 +3,13 @@
import com.mes.device.service.GlassInfoService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
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.client.RestTemplate;
import java.util.List;
@@ -27,15 +29,13 @@
    private final GlassInfoService glassInfoService;
    private final RestTemplate restTemplate = new RestTemplate();
    @Value("${mes.engineering.import-url}")
    private String mesEngineeringImportUrl;
    /**
     * 导入工程
     * 前端入参示例:
     * {
     *   "excelRows": [
     *     {"glassId":"GL001","width":"1000","height":"2000","thickness":"5","quantity":"2","orderNumber":"NG25082101","filmsId":"白玻"}
     *     {"glassId":"GL001","width":"1000","height":"2000","thickness":"5","quantity":"2","flowCardId":"NG25082101","filmsId":"白玻"}
     *   ]
     * }
     */
@@ -54,12 +54,28 @@
        Map<String, Object> payload = glassInfoService.buildEngineerImportPayload(excelRows);
        log.info("构建的 MES 导入数据: {}", payload);
        String mesEngineeringImportUrl = glassInfoService.getMesEngineeringImportUrl();
        try {
            ResponseEntity<Map> mesResp = restTemplate.postForEntity(mesEngineeringImportUrl, payload, Map.class);
            // 直接返回 MES 的响应,让前端根据响应体中的 code 字段判断是否成功
            return ResponseEntity.status(mesResp.getStatusCode()).body(mesResp.getBody());
        } catch (org.springframework.web.client.ResourceAccessException e) {
            // 连接超时或无法连接
            log.error("转发 MES 导入接口失败(连接问题) url={}, error={}", mesEngineeringImportUrl, e.getMessage(), e);
            Map<String, Object> errorResponse = new java.util.HashMap<>();
            errorResponse.put("code", 500);
            errorResponse.put("message", "无法连接到 MES 接口,请检查网络连接或联系管理员");
            errorResponse.put("data", false);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
        } catch (Exception e) {
            // 其他异常
            log.error("转发 MES 导入接口失败 url={}, error={}", mesEngineeringImportUrl, e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("转发 MES 失败: " + e.getMessage());
            Map<String, Object> errorResponse = new java.util.HashMap<>();
            errorResponse.put("code", 500);
            errorResponse.put("message", "转发 MES 失败: " + e.getMessage());
            errorResponse.put("data", false);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
        }
    }
}
mes-processes/mes-plcSend/src/main/java/com/mes/device/service/GlassInfoService.java
@@ -76,6 +76,13 @@
     */
    boolean updateGlassStatus(List<String> glassIds, String status);
     /**
     * 获取 MES 工程导入 URL
     *
     * @return MES 工程导入 URL
     */
    String getMesEngineeringImportUrl();
    /**
     * 将前端上传的 Excel 行数据转换为 MES 导入工程所需的 JSON 结构
     *
mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/GlassInfoServiceImpl.java
@@ -7,6 +7,8 @@
import com.mes.device.mapper.DeviceGlassInfoMapper;
import com.mes.device.service.GlassInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@@ -27,6 +29,7 @@
 * @since 2024-11-20
 */
@Slf4j
@RefreshScope
@Service("deviceGlassInfoService")
public class GlassInfoServiceImpl extends ServiceImpl<DeviceGlassInfoMapper, GlassInfo> implements GlassInfoService {
@@ -212,6 +215,14 @@
        }
    }
    @Value("${mes.engineering.import-url}")
    private String mesEngineeringImportUrl;
    @Override
    public String getMesEngineeringImportUrl() {
        return mesEngineeringImportUrl;
    }
    @Override
    public Map<String, Object> buildEngineerImportPayload(List<Map<String, Object>> excelRows) {
        Map<String, Object> result = new HashMap<>();
@@ -235,7 +246,6 @@
                    int qty = (int) parseDouble(row.getOrDefault("quantity", 1), 1);
                    if (qty <= 0) qty = 1;
                    String glassId = str(row.get("glassId"));
                    Integer orderNumber = Integer.parseInt(str(row.get("orderNumber")));
                    String filmsId = strOrDefault(row.get("filmsId"), filmsIdDefaultFinal);
                    String flowCardId = str(row.get("flowCardId"));
                    String productName = str(row.get("productName"));
@@ -256,7 +266,6 @@
                        m.put("glassId", finalGlassId);
                        m.put("engineerId", engineerIdFinal);
                        m.put("flowCardId", finalFlowCardId);
                        m.put("orderNumber", orderNumber);
                        m.put("productSortNumber", idx + 1);
                        m.put("hollowCombineDirection", "0");
                        m.put("width", width);
@@ -279,7 +288,7 @@
                        m.put("combine", 0);
                        m.put("markIcon", "");
                        m.put("filmRemove", 0);
                        m.put("flowCardSequence", String.valueOf(idx + 1));
                        m.put("flowCardSequence", flowCardId + "/" + (idx + 1));
                        m.put("process", "");
                        m.put("rawAngle", 0);
                        m.put("graphNo", 0);
@@ -324,7 +333,7 @@
            double height = parseDouble(row.get("height"), 0d);
            double thickness = parseDouble(row.get("thickness"), thicknessDefaultFinal);
            String filmsId = strOrDefault(row.get("filmsId"), filmsIdDefaultFinal);
            Integer orderNumber = Integer.parseInt(str(row.get("orderNumber")));
            String productName = str(row.get("productName"));
            String customerName = str(row.get("customerName"));
@@ -339,7 +348,6 @@
                m.put("totalLayer", 0);
                m.put("layer", 0);
                m.put("glassTotal", 1);
                m.put("orderNumber", orderNumber);
                m.put("productName", productName);
                m.put("customerName", customerName);
                flowCardMap.put(flowCardId, m);
mes-processes/mes-plcSend/src/main/resources/application.yml
@@ -48,7 +48,3 @@
      max-target: 100
      min-glass-count: 1
      max-glass-count: 50
mes:
  width: 2800
  height: 5000
mes-processes/mes-plcSend/src/main/resources/bootstrap.yml
New file
@@ -0,0 +1,18 @@
# bootstrap.yml 优先级高于 application.yml,仅配置Nacos核心连接
spring:
  application:
    name: plcSend  # 必须和application.yml中的name完全一致
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848  # 替换为你的Nacos服务端IP+端口(运维提供)
        file-extension: yml               # 配置文件格式(和本地保持一致)
        group: DEFAULT_GROUP              # 默认分组,无需修改(可按环境改如DEV_GROUP)
  profiles:
    active: dev
# 可选:关闭Nacos配置缓存(开发环境用,生产默认即可)
#  nacos:
#    config:
#      refresh-enabled: true
#      cache-time: 5000  # 配置拉取间隔(毫秒)
mes-web/public/config.js
@@ -1,5 +1,5 @@
const ip = '127.0.0.1'
// const ip = '10.153.19.6'
// const ip = '127.0.0.1'
const ip = '10.153.19.192'
// const ip = '10.100.0.183'
// const ip = '192.168.2.8'
window.ipConfig = {
mes-web/src/utils/constants.js
@@ -1,6 +1,6 @@
// export const WebSocketHost = "10.153.19.150";
// export const WebSocketHost = "172.17.2.7";
export const WebSocketHost = "10.153.19.225";//hxl
export const WebSocketHost = "10.153.19.166";//hxl
// export const WebSocketHost = "10.153.19.2";//zt
//export const WebSocketHost = "10.153.19.20";//wsx
// export const WebSocketHost = "127.0.0.1";
mes-web/src/views/plcTest/components/MultiDeviceTest/TaskOrchestration.vue
@@ -323,7 +323,7 @@
          return
        }
        // 发送数据到 MES 接口
        // 发送数据
        submitGlassData(parsedData)
      } catch (error) {
@@ -391,11 +391,6 @@
      headerStr.includes('qty') || headerStr === '数量') {
      headerMap.quantity = index
    }
    // 订单号
    else if (headerStr.includes('订单') || headerStr.includes('order') ||
      headerStr.includes('orderno') || headerStr === '订单号') {
      headerMap.orderNumber = index
    }
    // 膜系
    else if (headerStr.includes('膜系') || headerStr.includes('films') ||
      headerStr.includes('film') || headerStr === '膜系id') {
@@ -439,8 +434,6 @@
    const height = row[headerMap.height] ? String(row[headerMap.height]).trim() : ''
    const thickness = row[headerMap.thickness] ? String(row[headerMap.thickness]).trim() : ''
    const quantity = row[headerMap.quantity] ? String(row[headerMap.quantity]).trim() : ''
    // 订单序号(接口要求整数,这里尝试解析为整数,不可解析则置空)
    const orderNumber = parseInt(row[headerMap.orderNumber]) || ''
    const filmsId = row[headerMap.filmsId] ? String(row[headerMap.filmsId]).trim() : ''
    const flowCardId = row[headerMap.flowCardId] ? String(row[headerMap.flowCardId]).trim() : ''
    const productName = row[headerMap.productName] ? String(row[headerMap.productName]).trim() : ''
@@ -476,7 +469,6 @@
        height: parseNumber(height),
        thickness: parseNumber(thickness),
        quantity: '1', // 每条记录数量为1
        orderNumber: orderNumber,
        filmsId: filmsId,
        flowCardId: flowCardId || finalGlassId,
        productName: productName,
@@ -506,8 +498,15 @@
    const response = await engineeringApi.importEngineer(requestData)
    if (response?.code === 200 || response?.code === 0 || response?.data) {
      ElMessage.success(`成功导入 ${glassDataList.length} 条玻璃数据,工程号:${requestData.engineerId}`)
    // 检查 MES 接口是否调用成功
    // MES 接口成功时返回格式:{ code: 200/0, data: true/false, message: "..." }
    if (response?.code === 200 || response?.code === 0) {
      // MES 接口调用成功
      const engineerId = response?.data?.engineerId || response?.engineerId || ''
      const successMsg = engineerId
        ? `成功导入 ${glassDataList.length} 条玻璃数据,工程号:${engineerId}`
        : `成功导入 ${glassDataList.length} 条玻璃数据`
      ElMessage.success(successMsg)
      // 将导入的玻璃ID填充到输入框,方便用户查看和编辑
      const glassIds = glassDataList.map(item => item.glassId).filter(id => id)
@@ -515,13 +514,26 @@
        glassIdsInput.value = glassIds.join('\n')
      }
    } else {
      throw new Error(response?.message || '导入失败')
      // MES 接口返回失败
      throw new Error(response?.message || 'MES 接口返回失败')
    }
  } catch (error) {
    console.error('提交玻璃数据失败:', error)
    // 显示错误信息
    const errorMsg = error?.response?.data?.message || error?.message || '未知错误'
    // 判断错误类型,给出更友好的提示
    let errorMsg = '未知错误'
    // 检查是否是后端返回的错误响应(后端转发 MES 失败)
    if (error?.response?.status === 500 && error?.response?.data) {
      // 后端返回的统一错误格式
      errorMsg = error.response.data.message || error.response.data || '转发 MES 接口失败'
    } else if (error?.response?.data?.message) {
      // MES 接口返回的错误
      errorMsg = error.response.data.message
    } else if (error?.message) {
      errorMsg = error.message
    }
    ElMessage.error('提交数据失败: ' + errorMsg)
    // 即使失败,也尝试填充玻璃ID到输入框