zhoushihao
2025-11-06 b21caa5499c50384f3a3a5dd795a7a0ad197d36f
Merge remote-tracking branch 'origin/master'

# Conflicts:
# hangzhoumesParent/moduleService/hollowGlassModule/src/main/java/com/mes/job/OpcPlcStorageCageHollowTask.java
31个文件已修改
8个文件已添加
1808 ■■■■ 已修改文件
UI-Project/src/assets/ganghuaqian.png 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/assets/ganghuaqian1.png 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/assets/zhongkong.png 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/assets/zhongkong1.png 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/assets/微信图片_20251104132805_3454_72.jpg 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/lang/en.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/lang/kr.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/lang/py.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/lang/zh.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/router/index.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/Caching/cachingbefore.vue 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/Caching/cachingun.vue 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/Returns/upreturns.vue 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/Returns/upreturns2.vue 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/Slicecage/slicecage.vue 267 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/User/alarmLog.vue 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/hollow/hollowslicecage.vue 223 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/menu/entity/SysMenu.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/menu/service/impl/SysMenuServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/job/OpcCacheGlassNewTask.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/job/PushMessageToIndex.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/controller/BigStorageCageDetailsController.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/entity/request/BigCageDetailsRequest.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/entity/vo/BigCageDetailsVO.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/mapper/BigStorageCageDetailsMapper.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/BigStorageCageDetailsService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/impl/BigStorageCageDetailsServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/impl/BigStorageGlassInfoServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/job/OpcPlcStorageCageNewTask.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/mapper/BigStorageCageDetailsMapper.xml 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/job/Downpush.java 85 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/hollowGlassModule/src/main/java/com/mes/hollow/controller/HollowBigStorageCageDetailsController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/hollowGlassModule/src/main/java/com/mes/hollow/entity/request/HollowBigCageDetailsRequest.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/hollowGlassModule/src/main/java/com/mes/hollow/entity/vo/HollowBigCageDetailsVO.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/hollowGlassModule/src/main/java/com/mes/hollow/mapper/HollowBigStorageCageDetailsMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/hollowGlassModule/src/main/java/com/mes/hollow/service/HollowBigStorageCageDetailsService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/hollowGlassModule/src/main/java/com/mes/hollow/service/impl/HollowBigStorageCageDetailsServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/hollowGlassModule/src/main/java/com/mes/job/OpcPlcStorageCageHollowTask.java 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/hollowGlassModule/src/main/resources/mapper/HollowBigStorageCageDetailsMapper.xml 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/assets/ganghuaqian.png

UI-Project/src/assets/ganghuaqian1.png
UI-Project/src/assets/zhongkong.png

UI-Project/src/assets/zhongkong1.png
UI-Project/src/assets/΢ÐÅͼƬ_20251104132805_3454_72.jpg
UI-Project/src/lang/en.js
@@ -36,6 +36,7 @@
    basicData: {
        untask: 'No task',
        tonumber: 'Total number of films uploaded',
        sectionUpperSuccessful:'Upper section operation successful!',
        finishnumber: 'Completed quantity',
        rackreset: 'Rack reset',
        prackreset: 'Is the rack reset?',
@@ -811,6 +812,9 @@
        Content:'Content',
        idSame:'The glass ID for the entry task is the same',
        sizeSame:'There are glass pieces of the same specification inside the cage',
        slotLess:'Insufficient remaining slots',
        overSize:'There is glass in the straight-through feeder, end this feeding process.',
        noGlass:'Glass information not found, please collect the project',
        projectMsg2:'Please select a label template',
        clickmakesure: 'Whether or not to confirm the click?',
        logarithm: 'logarithm:',
UI-Project/src/lang/kr.js
@@ -36,6 +36,7 @@
      basicData:{
          untask:'작업 ì—†ìŒ',
          tonumber:'총 ì˜í™” ìˆ˜',
          sectionUpperSuccessful:'상부 ì¡°ìž‘ ì„±ê³µï¼',
          finishnumber:'완료된 ìˆ˜ëŸ‰',
          rackreset:'쉘프 ìž¬ì„¤ì •',
          prackreset:'쉘프가 ìž¬ì„¤ì •되는지 ì—¬ë¶€ï¼Ÿ',
@@ -812,6 +813,9 @@
        content:'내용',
        idSame:'진입 ìž‘ì—… ìœ ë¦¬ ID가 ë™ì¼í•©ë‹ˆë‹¤.',
        sizeSame:'우리 ì•ˆì— ë™ì¼í•œ ê·œê²©ì˜ ìœ ë¦¬ê°€ ì¡´ìž¬í•©ë‹ˆë‹¤.',
        slotLess:'나머지 ê·¸ë¦¬ë“œê°€ ë¶€ì¡±í•©ë‹ˆë‹¤.',
        overSize:'직통 í”¼ë”©ëŒ€ì— ìœ ë¦¬ê°€ ìžˆì–´ ì´ë²ˆ í”¼ë”©ì„ ì¢…료합니다',
        noGlass:'유리 ì •보를 ì°¾ì„ ìˆ˜ ì—†ìŠµë‹ˆë‹¤. ê³µì •을 ë°›ìœ¼ì„¸ìš”.',
        clickmakesure: '클릭 í™•인 ì—¬ë¶€ï¼Ÿ',
        logarithm: '대수:',
        totalPairQuantitya: '총 ìž„무 ì§ìˆ˜',
UI-Project/src/lang/py.js
@@ -36,6 +36,7 @@
    basicData: {
        untask:'无任务',
        tonumber:'上片总数量',
        sectionUpperSuccessful:'上片操作成功!',
        finishnumber:'已完成数量',
        rackreset:'架子复位',
        prackreset:'是否架子复位?',
@@ -731,6 +732,9 @@
        content:'内容',
        idSame:'进片任务玻璃ID相同',
        sizeSame:'笼内存在相同规格的玻璃',
        slotLess:'剩余格子不足',
        overSize:'直通片台存在玻璃,结束本次进片',
        noGlass:'未找到玻璃信息,请领取工程',
        clickmakesure: '是否确认点击?',
        logarithm: '对数:',
        totalPairQuantitya: '任务总配对数',
UI-Project/src/lang/zh.js
@@ -36,6 +36,7 @@
      basicData:{
          untask:'无任务',
          tonumber:'上片总数量',
          sectionUpperSuccessful:'上片操作成功!',
          finishnumber:'已完成数量',
          rackreset:'架子复位',
          prackreset:'是否架子复位?',
@@ -469,6 +470,11 @@
          prompt:'提示',
      },
      delivery:{
          alarmStartTime:'报警开始时间',
          alarmEndTime:'报警结束时间',
          equipment:'设备',
          content:'内容',
          confirmer:'确认人',
          addrole:'添加角色',
          editrole:'修改角色',
          role :'角色',
@@ -815,6 +821,9 @@
        content:'内容',
        idSame:'进片任务玻璃ID相同',
        sizeSame:'笼内存在相同规格的玻璃',
        slotLess:'剩余格子不足',
        overSize:'直通片台存在玻璃,结束本次进片',
        noGlass:'未找到玻璃信息,请领取工程',
        projectMsg2:'请选择标签模板',
        clickmakesure: '是否确认点击?',
        logarithm: '对数:',
UI-Project/src/router/index.js
@@ -230,6 +230,11 @@
      path: '/User/userpageNo',
      name: 'userpageNo',
      component: () => import('../views/User/userpageNo.vue')
    },
    {
      path: '/User/alarmLog',
      name: 'alarmLog',
      component: () => import('../views/User/alarmLog.vue')
    }
  ]
 },
UI-Project/src/views/Caching/cachingbefore.vue
@@ -17,14 +17,50 @@
const adjustedRects = ref([]);
const selectValuesa = reactive([]);
const timeRange = ref([])
const tableDataAlert = ref([])
const taskState = ref('')
const taskStat = ref('')
const taskType = ref('')
const glassId = ref('')
const alertText = ref('')
const alertMessage = ref('')
const alarmData = ref('')
// const alarmData = ref<any>(null)
const showAlert = ref(false)
const showModal = ref(false)
const blindb = ref(false)
let socket = null;
const socketUrl = `ws://${WebSocketHost}:${host}/api/cacheGlass/api/talk/cacheGlassOne`;
const handleMessage = (data) => {
    // æŠ¥è­¦ä¿¡æ¯
if (data.alarmInfo[0] != null && data.alarmInfo[0].length > 0) {
  const alert = data.alarmInfo[0];
  const { id, alarmMessage, ...rest } = alert[0];
  alertMessage.value = `${alarmMessage}`;
  alertMessage.value = `${alert[0].alarmMessage}`;
  if (alert[0].alarmCode === 'sizeSame') {
    alertText.value = t('hellow.sizeSame');
  } else if (alert[0].alarmCode === 'idSame') {
    alertText.value = t('hellow.idSame');
  } else if (alert[0].alarmCode === 'slotLess') {
    alertText.value = t('hellow.slotLess');
  } else if (alert[0].alarmCode === 'overSize') {
    alertText.value = t('hellow.overSize');
  } else if (alert[0].alarmCode === 'noGlass') {
    alertText.value = t('hellow.noGlass');
  } else {
    alertText.value = t('hellow.unknownAlert');
  }
    alarmData.value = data; // å­˜å‚¨å®Œæ•´æ•°æ®ç”¨äºŽå¼¹çª—
    showAlert.value = true;
}
  const formattedData = data.alarmInfo[0].map(record => ({
     ...record,
     formattedCreateTime: formatTimestamp(record.createTime),
     alarmCode: record.alarmCode,
     alarmMessage: record.alarmMessage
   }));
    tableDataAlert.value = formattedData;
  const cageInfo = data.taskMessage[0];
  if (cageInfo && cageInfo.createTime) {
    cageInfo.formattedCreateTime = formatTimestamp(cageInfo.createTime);
@@ -226,7 +262,53 @@
    }  
  } catch (error) {
  }  
};
};
// è­¦æŠ¥ç¡®è®¤
const handleSure = async (row) => {
  try {
    const confirmResult = await ElMessageBox.confirm(
      t('hellow.clickmakesure'),
      t('productStock.prompt'),
      {
        confirmButtonText: t('productStock.yes'),
        cancelButtonText: t('productStock.cancel'),
        type: 'warning',
      }
    );
    if (confirmResult === 'confirm') {
      const response = await request.post('/hollowGlass/productAlarmInfo/updateAlarmInfo', {
        id: row.id
      })
      if (response.code === 200) {
        showModal.value = false;
        showAlert.value = false;
        ElMessage.success(response.message);
      } else {
        ElMessage.error(response.msg);
      }
    }
  } catch (error) {
    console.error('发生错误:', error);
  }
};
// è­¦æŠ¥åŒå‡»å¼¹çª—
const handleDoubleClick = () => {
  showModal.value = true;
};
const getAlertText = (alarmCode) => {
  const codeMap = {
    sizeSame: 'hellow.sizeSame',
    idSame: 'hellow.idSame',
    slotLess: 'hellow.slotLess',
    overSize: 'hellow.overSize',
    noGlass: 'hellow.noGlass'
  };
  return alarmCode in codeMap
    ? t(codeMap[alarmCode])
    : t('hellow.unknownAlert');
};
const rowClassName = ({ row }) => {
  // æ ¹æ® enableState è®¾ç½®è¡Œçš„ CSS ç±»
  return row.slot % 2 === 0 ? 'success-row' : '';
@@ -324,6 +406,15 @@
</script>
<template>
  <div style="height: 500px;">
    <div v-if="showAlert" class="global-alert-bar" @dblclick="handleDoubleClick">
    <div class="alert-content">
      <el-icon><WarnTriangleFilled /></el-icon>
      <span class="alert-text">
        {{ alertText }} (id:{{ alertMessage }})
      </span>
    </div>
    <button @click="showAlert = false" class="close-btn">×</button>
  </div>
    <el-card style="flex: 1;margin-left: 10px;margin-top: 10px;">
    <el-button style="margin-bottom: 15px;margin-left: 20px;" @click="handlehistorical" type="primary">{{ $t('searchOrder.historicaltasks') }}</el-button>
    <el-button style="margin-bottom: 15px;margin-left: 20px;" @click="handleptask()" type="warning">{{ $t('searchOrder.partask') }}</el-button>
@@ -449,6 +540,40 @@
     frameborder="0"
     ></iframe>
  </el-dialog>
  <!-- æŠ¥è­¦å¼¹çª— -->
  <el-dialog
    v-model="showModal"
    width="40%"
    center
  >
      <el-table
      ref="table"
      border
      :data="tableDataAlert"
      max-height="calc(500px - 35px)"
      style="width: 100%;"
    >
      <el-table-column prop="formattedCreateTime" align="center" :label="$t('film.createtime')" min-width="100" />
      <el-table-column
       :label="$t('hellow.content')"
       align="center"
       min-width="220"
     >
       <template #default="scope">
           <span>
             {{ getAlertText(scope.row.alarmCode) }}
             (id:{{ scope.row.alarmMessage }})
           </span>
       </template>
     </el-table-column>
      <el-table-column fixed="right" :label="$t('film.operate')" align="center" width="100">
        <template #default="scope">
          <el-button type="text" plain
            @click="handleSure(scope.row)">{{ $t('basicData.yes') }}</el-button>
        </template>
      </el-table-column>
    </el-table>
  </el-dialog>
<!-- <el-dialog v-model="blindb" top="10vh" width="90%">
  <div style="display: flex;">
    <el-input v-model="glassId" style="margin-left: 10px;margin-bottom: 10px;width: 270px;" :placeholder="$t('searchOrder.inglassID')" />
@@ -546,4 +671,19 @@
  max-width: 100%;
  margin-left: 10%
}
.global-alert-bar {
  position: fixed;
  top: 0;
  left: 50%; /* æ°´å¹³å±…中关键 */
  transform: translateX(-50%); /* æ°´å¹³å±…中关键 */
  padding: 12px 20px;
  background-color: #dbdbd7;
  box-shadow: 0 2px 10px rgba(0,0,0,0.2);
  display: flex;
  justify-content: space-between;
  align-items: center;
  z-index: 9999;
  max-width: 80%; /* é˜²æ­¢å°å±å¹•溢出 */
  min-width: 400px; /* æœ€å°å®½åº¦ä¿è¯ */
}
</style>
UI-Project/src/views/Caching/cachingun.vue
@@ -17,13 +17,48 @@
const adjustedRects = ref([]);
const selectValuesa = reactive([]);
const timeRange = ref([])
const tableDataAlert = ref([])
const taskState = ref('')
const taskType = ref('')
const glassId = ref('')
const alertText = ref('')
const alertMessage = ref('')
const alarmData = ref('')
const showAlert = ref(false)
const showModal = ref(false)
const blindb = ref(false)
let socket = null;
const socketUrl = `ws://${WebSocketHost}:${host}/api/cacheGlass/api/talk/cacheGlassTwo`;
const handleMessage = (data) => {
    // æŠ¥è­¦ä¿¡æ¯
if (data.alarmInfo[0] != null && data.alarmInfo[0].length > 0) {
  const alert = data.alarmInfo[0];
  const { id, alarmMessage, ...rest } = alert[0];
  alertMessage.value = `${alarmMessage}`;
  alertMessage.value = `${alert[0].alarmMessage}`;
  if (alert[0].alarmCode === 'sizeSame') {
    alertText.value = t('hellow.sizeSame');
  } else if (alert[0].alarmCode === 'idSame') {
    alertText.value = t('hellow.idSame');
  } else if (alert[0].alarmCode === 'slotLess') {
    alertText.value = t('hellow.slotLess');
  } else if (alert[0].alarmCode === 'overSize') {
    alertText.value = t('hellow.overSize');
  } else if (alert[0].alarmCode === 'noGlass') {
    alertText.value = t('hellow.noGlass');
  } else {
    alertText.value = t('hellow.unknownAlert');
  }
    alarmData.value = data; // å­˜å‚¨å®Œæ•´æ•°æ®ç”¨äºŽå¼¹çª—
    showAlert.value = true;
}
  const formattedData = data.alarmInfo[0].map(record => ({
     ...record,
     formattedCreateTime: formatTimestamp(record.createTime),
     alarmCode: record.alarmCode,
     alarmMessage: record.alarmMessage
   }));
    tableDataAlert.value = formattedData;
  const cageInfo = data.taskMessage[0];
  if (cageInfo && cageInfo.createTime) {
    cageInfo.formattedCreateTime = formatTimestamp(cageInfo.createTime);
@@ -209,6 +244,52 @@
  } catch (error) {
  }  
}; 
// è­¦æŠ¥ç¡®è®¤
const handleSure = async (row) => {
  try {
    const confirmResult = await ElMessageBox.confirm(
      t('hellow.clickmakesure'),
      t('productStock.prompt'),
      {
        confirmButtonText: t('productStock.yes'),
        cancelButtonText: t('productStock.cancel'),
        type: 'warning',
      }
    );
    if (confirmResult === 'confirm') {
      const response = await request.post('/hollowGlass/productAlarmInfo/updateAlarmInfo', {
        id: row.id
      })
      if (response.code === 200) {
        showModal.value = false;
        showAlert.value = false;
        ElMessage.success(response.message);
      } else {
        ElMessage.error(response.msg);
      }
    }
  } catch (error) {
    console.error('发生错误:', error);
  }
};
// è­¦æŠ¥åŒå‡»å¼¹çª—
const handleDoubleClick = () => {
  showModal.value = true;
};
const getAlertText = (alarmCode) => {
  const codeMap = {
    sizeSame: 'hellow.sizeSame',
    idSame: 'hellow.idSame',
    slotLess: 'hellow.slotLess',
    overSize: 'hellow.overSize',
    noGlass: 'hellow.noGlass'
  };
  return alarmCode in codeMap
    ? t(codeMap[alarmCode])
    : t('hellow.unknownAlert');
};
const rowClassName = ({ row }) => {
  // æ ¹æ® enableState è®¾ç½®è¡Œçš„ CSS ç±»
  return row.slot % 2 === 0 ? 'success-row' : '';
@@ -306,6 +387,15 @@
</script>
<template>
  <div style="height: 500px;">
    <div v-if="showAlert" class="global-alert-bar" @dblclick="handleDoubleClick">
    <div class="alert-content">
      <el-icon><WarnTriangleFilled /></el-icon>
      <span class="alert-text">
        {{ alertText }} (id:{{ alertMessage }})
      </span>
    </div>
    <button @click="showAlert = false" class="close-btn">×</button>
  </div>
    <el-card style="flex: 1;margin-left: 10px;margin-top: 10px;">
    <el-button style="margin-bottom: 15px;margin-left: 20px;" @click="handlehistorical" type="primary">{{ $t('searchOrder.historicaltasks') }}</el-button>
    <el-button style="margin-bottom: 15px;margin-left: 20px;" @click="handleptask()" type="warning">{{ $t('searchOrder.partask') }}</el-button>
@@ -431,6 +521,40 @@
     frameborder="0"
     ></iframe>
  </el-dialog>
  <!-- æŠ¥è­¦å¼¹çª— -->
  <el-dialog
    v-model="showModal"
    width="40%"
    center
  >
      <el-table
      ref="table"
      border
      :data="tableDataAlert"
      max-height="calc(500px - 35px)"
      style="width: 100%;"
    >
      <el-table-column prop="formattedCreateTime" align="center" :label="$t('film.createtime')" min-width="100" />
      <el-table-column
       :label="$t('hellow.content')"
       align="center"
       min-width="220"
     >
       <template #default="scope">
           <span>
             {{ getAlertText(scope.row.alarmCode) }}
             (id:{{ scope.row.alarmMessage }})
           </span>
       </template>
     </el-table-column>
      <el-table-column fixed="right" :label="$t('film.operate')" align="center" width="100">
        <template #default="scope">
          <el-button type="text" plain
            @click="handleSure(scope.row)">{{ $t('basicData.yes') }}</el-button>
        </template>
      </el-table-column>
    </el-table>
  </el-dialog>
</template>
<style scoped>
#dt { display:block; float:left;line-height: 20px;margin-left: 100px;}
@@ -454,4 +578,19 @@
  max-width: 100%;
  margin-left: 10%
}
.global-alert-bar {
  position: fixed;
  top: 0;
  left: 50%; /* æ°´å¹³å±…中关键 */
  transform: translateX(-50%); /* æ°´å¹³å±…中关键 */
  padding: 12px 20px;
  background-color: #dbdbd7;
  box-shadow: 0 2px 10px rgba(0,0,0,0.2);
  display: flex;
  justify-content: space-between;
  align-items: center;
  z-index: 9999;
  max-width: 80%; /* é˜²æ­¢å°å±å¹•溢出 */
  min-width: 400px; /* æœ€å°å®½åº¦ä¿è¯ */
}
</style>
UI-Project/src/views/Returns/upreturns.vue
@@ -185,7 +185,22 @@
        state: 1,
      })
      if (response.code == 200) {
        ElMessage.success(response.message);
        let timeoutId = setTimeout(() => {
          // æ¨¡æ‹ŸæŒ‰ä¸‹ç¡®è®¤æŒ‰é’®
          const confirmBtn = document.querySelector('.el-message-box__btns .el-button--primary');
          if (confirmBtn) {
            confirmBtn.click();
          }
        }, 5000)
        await ElMessageBox.alert(' ', t('basicData.sectionUpperSuccessful'), {
          confirmButtonText: t('searchOrder.sure'),
          type: 'success',
          center: true,
          customClass: 'center-message-box',
        });
        // æ¸…除定时器
        clearTimeout(timeoutId);
        // æ‰§è¡Œç¡®è®¤åŽçš„逻辑
        canSelectProjecta.value = false;
        canSelectProjectb.value = false;
        canSelectProjectc.value = true;
UI-Project/src/views/Returns/upreturns2.vue
@@ -248,17 +248,32 @@
// å¼€å§‹ä¸Šç‰‡
const handleon = async () => {
  let filmRemove = window.localStorage.getItem('filmRemove')
  let engineeringIda = window.localStorage.getItem('engineeringIda')
  let engineeringId = window.localStorage.getItem('engineeringIda')
  if (markingMachineStatus.value === 'green' && cuttingMachineStatus.value === 'green') {
    try {
      const response = await request.post('/loadGlass/engineering/engineering/changeTask', {
        stationCell: 6,
        filmRemove: filmRemove,
        engineerId: engineeringIda,
        engineerId: engineeringId,
        state: 1,
      })
      if (response.code == 200) {
        ElMessage.success(response.message);
        let timeoutId = setTimeout(() => {
          // æ¨¡æ‹ŸæŒ‰ä¸‹ç¡®è®¤æŒ‰é’®
          const confirmBtn = document.querySelector('.el-message-box__btns .el-button--primary');
          if (confirmBtn) {
            confirmBtn.click();
          }
        }, 5000)
        await ElMessageBox.alert(' ', t('basicData.sectionUpperSuccessful'), {
          confirmButtonText: t('searchOrder.sure'),
          type: 'success',
          center: true,
          customClass: 'center-message-box',
        });
        // æ¸…除定时器
        clearTimeout(timeoutId);
        // æ‰§è¡Œç¡®è®¤åŽçš„逻辑
        canSelectProjecta.value = false;
        canSelectProjectb.value = false;
        canSelectProjectc.value = true;
UI-Project/src/views/Slicecage/slicecage.vue
@@ -41,6 +41,7 @@
const selectValuesa = reactive([]);
const carPosition = ref([])
const ganghua = ref('')
const engineerId = ref('')
const diaodu = ref('')
const flowCardId = ref('')
const filmsId = ref('')
@@ -50,10 +51,14 @@
const adjustedRectsa = ref([]);
const adjustedRectsb = ref([]);
const adjustedRectsc = ref([]);
const adjustedRectsd = ref([]);
const adjustedRectse = ref([]);
const subRectsCounts = ref([]);
const subRectsCountsa = ref([]);
const subRectsCountsb = ref([]);
const subRectsCountsc = ref([]);
const subRectsCountsd = ref([]);
const subRectsCountse = ref([]);
const currentRow = reactive({}); // å½“前行的数据 
const showAlert = ref(false)
const alertMessage = ref('')
@@ -80,6 +85,8 @@
const cell2=ref(true);
const cell3=ref(true);
const cell4=ref(true);
const cell5=ref(true);
const cell6=ref(true);
const canEdit = ref(true);
const selectedRow = ref(null);
const temperingtotal = ref(0);
@@ -540,7 +547,10 @@
const getAlertText = (alarmCode) => {
  const codeMap = {
    sizeSame: 'hellow.sizeSame',
    idSame: 'hellow.idSame'
    idSame: 'hellow.idSame',
    slotLess: 'hellow.slotLess',
    overSize: 'hellow.overSize',
    noGlass: 'hellow.noGlass'
  };
  return alarmCode in codeMap 
    ? t(codeMap[alarmCode]) 
@@ -564,10 +574,13 @@
const fetchxiang = async () => {
    isLoading.value = true;
  try {
    const response = await request.post('/cacheVerticalGlass/bigStorageCage/querybigStorageCageDetail',{
    const response = await request.post('/cacheVerticalGlass/bigStorageCageDetails/queryVerticalSheetCageDetailsList',{
        // deviceId: page,
        engineerId: engineerId.value,
        filmsId: filmsId.value,
        flowCardId: flowCardId.value,
        glassId: glassId.value,
        thickness: -1,
    })
    // æ¨¡æ‹Ÿæœ€å°åŠ è½½æ—¶é—´
    await new Promise(resolve => setTimeout(resolve, 300));
@@ -586,10 +599,13 @@
const fetchxianga = async () => {
  let page = window.localStorage.getItem('pagenumber')
  try {     
    const response = await request.post('/cacheVerticalGlass/bigStorageCage/querybigStorageCageDetail',{
    const response = await request.post('/cacheVerticalGlass/bigStorageCageDetails/queryVerticalSheetCageDetailsList',{
        deviceId: page,
        engineerId: engineerId.value,
        filmsId: filmsId.value,
        flowCardId: flowCardId.value,
        glassId: glassId.value,
        thickness: thickness.value ? thickness.value : -1,
    })
    if (response.code === 200) {  
      ElMessage.success(response.message);
@@ -773,18 +789,27 @@
const socketUrl = `ws://${WebSocketHost}:${host}/api/cacheVerticalGlass/api/talk/slicecage`;
const handleMessage = (data) => {
  // æŠ¥è­¦ä¿¡æ¯
  if (data.alarmInfo[0] !=null && data.alarmInfo[0].length > 0) {
    const alert = data.alarmInfo[0]
    const { id,alarmMessage, ...rest } = alert[0];
    alertMessage.value = `${alarmMessage}`;
    alertMessage.value = `${alert[0].alarmMessage}`;
    // åŠ¨æ€ç¿»è¯‘é€»è¾‘ï¼šæ ¹æ®alarmCode选择翻译键
    alertText.value = alert[0].alarmCode === 'sizeSame'
      ? t('hellow.sizeSame')
      : t('hellow.idSame');
if (data.alarmInfo[0] != null && data.alarmInfo[0].length > 0) {
  const alert = data.alarmInfo[0];
  const { id, alarmMessage, ...rest } = alert[0];
  alertMessage.value = `${alarmMessage}`;
  alertMessage.value = `${alert[0].alarmMessage}`;
  if (alert[0].alarmCode === 'sizeSame') {
    alertText.value = t('hellow.sizeSame');
  } else if (alert[0].alarmCode === 'idSame') {
    alertText.value = t('hellow.idSame');
  } else if (alert[0].alarmCode === 'slotLess') {
    alertText.value = t('hellow.slotLess');
  } else if (alert[0].alarmCode === 'overSize') {
    alertText.value = t('hellow.overSize');
  } else if (alert[0].alarmCode === 'noGlass') {
    alertText.value = t('hellow.noGlass');
  } else {
    alertText.value = t('hellow.unknownAlert');
  }
    alarmData.value = data; // å­˜å‚¨å®Œæ•´æ•°æ®ç”¨äºŽå¼¹çª—
    showAlert.value = true;
  }
}
   const formattedData = data.alarmInfo[0].map(record => ({
     ...record,
     formattedCreateTime: formatTimestamp(record.createTime),
@@ -897,11 +922,25 @@
    top: 53/55,
  }));
subRectsCountsc.value = data.bigStorageCageInfos[0][4].map(rect => rect.count);
adjustedRectsd.value = data.bigStorageCageInfos[0][5].map((rect, index) => ({
    id: index + 1,
    height: 20/55,
    top: 53/55,
  }));
subRectsCountsd.value = data.bigStorageCageInfos[0][5].map(rect => rect.count);
adjustedRectse.value = data.bigStorageCageInfos[0][6].map((rect, index) => ({
    id: index + 1,
    height: 20/55,
    top: 53/55,
  }));
subRectsCountse.value = data.bigStorageCageInfos[0][6].map(rect => rect.count);
  }else{
    adjustedRects.value = '',
    adjustedRectsa.value = '',
    adjustedRectsb.value = '',
    adjustedRectsc.value = ''
    adjustedRectsc.value = '',
    adjustedRectsd.value = '',
    adjustedRectse.value = ''
  }
};
// è®¡ç®—每个大矩形的样式
@@ -1020,8 +1059,74 @@
  }
  return subRects;
};
// è®¡ç®—每个大矩形的样式
const rectStyled = (rect, index) => ({
  position: 'absolute',
  width: '170px',
  right: '0px',
  top: `${index*rect.top}px`,
  height: `${rect.height}px`,
});
// è®¡ç®—每个小矩形的样式和数量
const getSubRectsd = (rectIndex) => {
  const count = subRectsCountsd.value[rectIndex];
  const subRects = [];
  for (let i = 0; i < count; i++) {
    subRects.push({});
  }
  return subRects;
};
// è®¡ç®—每个大矩形的样式
const rectStylee = (rect, index) => ({
  position: 'absolute',
  width: '170px',
  right: '0px',
  top: `${index*rect.top}px`,
  height: `${rect.height}px`,
});
// è®¡ç®—每个小矩形的样式和数量
const getSubRectse = (rectIndex) => {
  const count = subRectsCountse.value[rectIndex];
  const subRects = [];
  for (let i = 0; i < count; i++) {
    subRects.push({});
  }
  return subRects;
};
// è®¡ç®—每个小矩形的样式
const subRectStylec = (rectIndex, subIndex) => {
  const width = '18px';
  const marginRight = '8px';
  const totalWidth = 6 * (parseInt(width) + parseInt(marginRight));
  const right = `${(subIndex * (parseInt(width) + parseInt(marginRight))) / totalWidth * 100}%`;
  return {
    position: 'absolute',
    width,
    height: '100%',
    marginRight,
    top: '0px',
    backgroundColor: '#911005',
    right,
  };
};
// è®¡ç®—每个小矩形的样式
const subRectStyled = (rectIndex, subIndex) => {
  const width = '18px';
  const marginRight = '8px';
  const totalWidth = 6 * (parseInt(width) + parseInt(marginRight));
  const right = `${(subIndex * (parseInt(width) + parseInt(marginRight))) / totalWidth * 100}%`;
  return {
    position: 'absolute',
    width,
    height: '100%',
    marginRight,
    top: '0px',
    backgroundColor: '#911005',
    right,
  };
};
// è®¡ç®—每个小矩形的样式
const subRectStylee = (rectIndex, subIndex) => {
  const width = '18px';
  const marginRight = '8px';
  const totalWidth = 6 * (parseInt(width) + parseInt(marginRight));
@@ -1055,22 +1160,6 @@
    closeWebSocket(socket);
    }
    });
function getStatusType(enableState: number) {
  switch (enableState) {
    case 100:
      return 'success';
    case 102:
      return 'warning';
  }
}
function getStatusText(enableState: number) {
  switch (enableState) {
    case 100:
      return t('searchOrder.zailong');
    case 102:
      return t('searchOrder.rengongxp');
  }
}
function getStatusTypea(ishorizontal: number) {  
  switch (ishorizontal) {  
    case 0:
@@ -1255,7 +1344,7 @@
    ></div>
    </div>
    </div>
 <div v-show="cell2" style="width: 170px;height: 53px;position: relative;top:72px;left: 445px;">
 <div v-show="cell2" style="width: 170px;height: 53px;position: relative;top:70px;left: 445px;">
    <div v-for="(rect, rectIndex) in adjustedRectsa" :key="rect.id" :style="rectStylea(rect, rectIndex)">
    <div
      v-for="(subRect, subIndex) in getSubRectsa(rectIndex)"
@@ -1264,7 +1353,7 @@
    ></div>
    </div>
    </div>
  <div v-show="cell3" style="width: 170px;height: 53px;position: relative;top:81px;left: 445px;">
  <div v-show="cell3" style="width: 170px;height: 53px;position: relative;top:76px;left: 445px;">
    <div v-for="(rect, rectIndex) in adjustedRectsb" :key="rect.id" :style="rectStyleb(rect, rectIndex)">
    <div
      v-for="(subRect, subIndex) in getSubRectsb(rectIndex)"
@@ -1273,12 +1362,30 @@
    ></div>
    </div>
    </div>
  <div v-show="cell4" style="width: 170px;height: 53px;position: relative;top:89px;left: 445px;">
  <div v-show="cell4" style="width: 170px;height: 53px;position: relative;top:84px;left: 445px;">
    <div v-for="(rect, rectIndex) in adjustedRectsc" :key="rect.id" :style="rectStylec(rect, rectIndex)">
    <div
      v-for="(subRect, subIndex) in getSubRectsc(rectIndex)"
      :key="subIndex"
      :style="subRectStylec(rectIndex, subIndex)"
    ></div>
    </div>
    </div>
  <div v-show="cell5" style="width: 170px;height: 53px;position: relative;top:-16px;left: 45px;">
    <div v-for="(rect, rectIndex) in adjustedRectsd" :key="rect.id" :style="rectStyled(rect, rectIndex)">
    <div
      v-for="(subRect, subIndex) in getSubRectsd(rectIndex)"
      :key="subIndex"
      :style="subRectStyled(rectIndex, subIndex)"
    ></div>
    </div>
    </div>
  <div v-show="cell6" style="width: 170px;height: 53px;position: relative;top:-6px;left: 45px;">
    <div v-for="(rect, rectIndex) in adjustedRectse" :key="rect.id" :style="rectStylee(rect, rectIndex)">
    <div
      v-for="(subRect, subIndex) in getSubRectse(rectIndex)"
      :key="subIndex"
      :style="subRectStylee(rectIndex, subIndex)"
    ></div>
    </div>
    </div>
@@ -1415,71 +1522,18 @@
  :title="$t('searchOrder.cageinformation')">
  <div v-loading="isLoading" class="loading-container" :element-loading-text="$t('searchOrder.loadingText')" >
  <div style="display: flex;">
    <el-input v-model="engineerId" clearable style="margin-left: 10px;margin-bottom: 10px;width: 240px;" :placeholder="$t('processCard.projectnumber')"/>
    <el-input v-model="glassId" clearable style="margin-left: 10px;margin-bottom: 10px;width: 240px;" :placeholder="$t('searchOrder.inglassID')"/>
    <el-input v-model="flowCardId" clearable style="margin-left: 10px;margin-bottom: 10px;width: 240px;" :placeholder="$t('searchOrder.incardnumber')" />
    <el-input v-model="filmsId" clearable style="margin-left: 10px;margin-bottom: 10px;width: 240px;" :placeholder="$t('film.infilms')"/>
    <el-input v-model="thickness" clearable style="margin-left: 10px;margin-bottom: 10px;width: 240px;" :placeholder="$t('searchOrder.inthickness')"/>
    <el-button type="primary" style="margin-left: 10px;margin-bottom: 10px;" @click="fetchxianga">
      {{$t('reportmanage.inquire')}}</el-button>
  </div>
    <el-table
          :data="tableDataa"
          @row-click="handleRowClick"
          height="700"
          @expand-change="handleExpandChange"
          row-key="id"
          default-expand-all
          :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}"
        >
          <el-table-column type="expand">
            <template #default="props">
              <div v-if="props.row.bigStorageCageDetails && props.row.bigStorageCageDetails.length">
                <el-table
                  :data="props.row.bigStorageCageDetails"
                  border
                  style="width: 98%;margin-left: 20px;"
                  row-key="id"
                  :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}"
                >
          <!-- <el-table-column prop="menuName" label="二级菜单栏" align="center" min-width="140" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}"/>   -->
          <el-table-column prop="glassId" :label="$t('searchOrder.glassID')" align="center" min-width="120"/>
          <el-table-column prop="flowCardId" align="center" :label="$t('searchOrder.cardnumber')" min-width="130" />
          <el-table-column prop="filmsId" align="center" :label="$t('searchOrder.coatingtypes')" min-width="80" />
          <!-- <el-table-column prop="glassType" align="center" :label="$t('searchOrder.typeglass')" min-width="80" /> -->
          <el-table-column prop="width" align="center" :label="$t('searchOrder.width')" min-width="80" />
          <el-table-column prop="height" align="center" :label="$t('searchOrder.height')" min-width="80" />
          <el-table-column prop="thickness" align="center" :label="$t('searchOrder.thickness')" min-width="80" />
          <el-table-column prop="temperingLayoutId" align="center" :label="$t('searchOrder.layoutID')" min-width="100" />
          <el-table-column prop="temperingFeedSequence" align="center" :label="$t('searchOrder.picturesequence')" min-width="120" />
          <el-table-column
            align="center"
            :label="$t('searchOrder.startstatus')"
            min-width="80"
            prop="state"
          >
          <template #default="scope">
        <el-tag :type="getStatusType(scope.row.state)">
          {{ getStatusText(scope.row.state) }}
        </el-tag>
      </template>
          </el-table-column>
          <el-table-column prop="gap" align="center" :label="$t('searchOrder.glassgaps')" min-width="80" />
           <el-table-column fixed="right" :label="$t('searchOrder.operate')" align="center"  min-width="220">
            <template #default="scope">
              <el-button type="text" plain @click="broke(scope.row)">{{ $t('searchOrder.breakage') }}</el-button>
              <el-button type="text" plain @click="brokec(scope.row)">{{ $t('searchOrder.takeout') }}</el-button>
              <el-button type="text" plain @click="opena(scope.row)">{{ $t('searchOrder.delete') }}</el-button>
              <el-button type="text"
              :disabled="!((props.row.bigStorageCageDetails[0].state !== 102 && scope.$index == 0 ) || (props.row.bigStorageCageDetails[(scope.$index - 1)<0?0:scope.$index-1].state==102)&&(scope.row.state!=102))"
               plain @click="outfil(scope.row)">
               {{ $t('searchOrder.outfilm') }}
              </el-button>
            </template>
        </el-table-column>
                </el-table>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="id" :label="$t('searchOrder.cagetableID')" align="center" min-width="90"/>
    <el-table ref="table" style="margin-top: 20px;height: 700px;width: 1770px;" :data="tableDataa" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}">
          <el-table-column prop="deviceId" align="center" :label="$t('searchOrder.cagenumber')" min-width="100" />
          <el-table-column prop="engineerId" align="center" :label="$t('searchOrder.projectnumber')" min-width="100" />
          <el-table-column prop="layer" align="center" :label="$t('processCard.layer')" min-width="50" />
          <el-table-column prop="slot" align="center" :label="$t('searchOrder.gridnumber')" min-width="150" />
          <el-table-column
          align="center"
@@ -1497,12 +1551,27 @@
        </template> 
          </el-table-column>
          <el-table-column prop="remainWidth" align="center" :label="$t('searchOrder.remainingwidth')" min-width="120" />
       <el-table-column fixed="right" :label="$t('searchOrder.operate')" align="center">
            <template #default="scope">
              <el-button type="text" plain  @click="handleBindRack(scope.row)">{{ $t('searchOrder.add') }}</el-button>
            </template>
        </el-table-column>
          <el-table-column prop="glassId" :label="$t('searchOrder.glassID')" align="center" min-width="120"/>
          <el-table-column prop="flowCardId" align="center" :label="$t('searchOrder.cardnumber')" min-width="130" />
          <el-table-column prop="filmsId" align="center" :label="$t('searchOrder.coatingtypes')" min-width="80" />
          <el-table-column prop="width" align="center" :label="$t('searchOrder.width')" min-width="80" />
          <el-table-column prop="height" align="center" :label="$t('searchOrder.height')" min-width="80" />
          <el-table-column prop="thickness" align="center" :label="$t('searchOrder.thickness')" min-width="80" />
          <el-table-column prop="temperingLayoutId" align="center" :label="$t('searchOrder.layoutID')" min-width="100" />
          <el-table-column prop="temperingFeedSequence" align="center" :label="$t('searchOrder.picturesequence')" min-width="120" />
          <el-table-column fixed="right" :label="$t('film.operate')" align="center" width="240">
              <template #default="scope">
              <!-- <el-button type="text" plain @click="handleBindRack(scope.row)">{{ $t('searchOrder.add') }}</el-button> -->
              <el-button type="text" plain @click="broke(scope.row)">{{ $t('searchOrder.breakage') }}</el-button>
              <el-button type="text" plain @click="brokec(scope.row)">{{ $t('searchOrder.takeout') }}</el-button>
              <el-button type="text" plain @click="opena(scope.row)">{{ $t('searchOrder.delete') }}</el-button>
              <!-- <el-button type="text"
              :disabled="!((props.row.bigStorageCageDetails[0].state !== 102 && scope.$index == 0 ) || (props.row.bigStorageCageDetails[(scope.$index - 1)<0?0:scope.$index-1].state==102)&&(scope.row.state!=102))"
               plain @click="outfil(scope.row)">
               {{ $t('searchOrder.outfilm') }}
              </el-button> -->
                </template>
              </el-table-column>
        </el-table>
        <div>
    <!-- <div style="margin-top: 20px;margin-left: 40%;">
@@ -1844,7 +1913,7 @@
.img-dlpl{
  margin-left: 20px;
  margin-top: 0px;
  background-image:url('/ganghuaqian.png');
  background-image:url('/src/assets/ganghuaqian.png');
  background-repeat: no-repeat;
  background-attachment: local;
  min-height: 380px;
UI-Project/src/views/User/alarmLog.vue
New file
@@ -0,0 +1,170 @@
<script setup>
import request from "@/utils/request"
import { Search } from "@element-plus/icons-vue"
import { ref, onMounted, reactive, computed } from "vue"
import { useRouter } from "vue-router"
import { useI18n } from 'vue-i18n'
import { ElMessage, ElMessageBox } from 'element-plus'
let language = ref(localStorage.getItem('lang') || 'zh')
const { t } = useI18n()
const router = useRouter()
const showAlert = ref(true)
const showModal = ref(false)
// const tableData = ref([])
const tableData = [
  {
    alarmStartTime: '2025-11-03 8:25:05',//报警开始时间
    alarmEndTime: '2025-11-03 9:25:05',//报警结束时间
    equipment: '上片1号机',//设备
    content: '未收到请求',//内容
    confirmer: 'admin',//确认人
  },
  {
    alarmStartTime: '2025-11-03 10:05:05',
    alarmEndTime: '2025-11-03 10:08:05',
    equipment: '卧式理片笼',
    content: '未获取到玻璃对应尺寸信息',
    confirmer: 'admin',
  },
  {
    alarmStartTime: '2025-11-03 16:30:15',
    alarmEndTime: '2025-11-03 16:35:05',
    equipment: '钢化大理片笼',
    content: '进片玻璃ID与笼内玻璃ID相同',
    confirmer: 'admin',
  },
  {
    alarmStartTime: '2025-11-03 20:30:15',
    alarmEndTime: '2025-11-03 22:30:15',
    equipment: '中空大理片笼',
    content: '笼内存在相同规格的玻璃',
    confirmer: 'admin',
  },
]
const tableDataAlert = [
  {
    formattedCreateTime: '2025-11-03 8:25:05',
  },
]
// è­¦æŠ¥åŒå‡»å¼¹çª—
const handleDoubleClick = () => {
  showModal.value = true;
};
const handleSure = async (row) => {
  try {
    const confirmResult = await ElMessageBox.confirm(
      t('hellow.clickmakesure'),
      t('productStock.prompt'),
      {
        confirmButtonText: t('productStock.yes'),
        cancelButtonText: t('productStock.cancel'),
        type: 'warning',
      }
    );
    if (confirmResult === 'confirm') {
        showModal.value = false;
        showAlert.value = false;
        ElMessage.success();
    }
  } catch (error) {
    console.error('发生错误:', error);
  }
};
onMounted(() => {
});
</script>
<template>
  <div>
    <div v-if="showAlert" class="global-alert-bar" @dblclick="handleDoubleClick">
    <div class="alert-content">
      <el-icon><WarnTriangleFilled /></el-icon>
      <span class="alert-text">
        ç¬¼å†…存在相同规格的玻璃 (id:25103114002002)
      </span>
    </div>
    <button @click="showAlert = false" class="close-btn">×</button>
  </div>
    <el-card style="flex: 1;margin-left: 10px;margin-top: 20px;">
      <div style="width: 98%; height: calc(100% - 35px); overflow-y: auto;">
        <el-table height="780" ref="table"
        :data="tableData" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}">
          <el-table-column prop="alarmStartTime" align="center" :label="$t('delivery.alarmStartTime')" min-width="180" />
          <el-table-column prop="alarmEndTime" align="center" :label="$t('delivery.alarmEndTime')" min-width="180" />
          <el-table-column prop="equipment" align="center" :label="$t('delivery.equipment')" min-width="180" />
          <el-table-column prop="content" align="center" :label="$t('delivery.content')" min-width="180" />
          <el-table-column prop="confirmer" align="center" :label="$t('delivery.confirmer')" min-width="180" />
        </el-table>
      </div>
    </el-card>
  </div>
  <el-dialog
    v-model="showModal"
    width="40%"
    center
  >
      <el-table
      ref="table"
      border
      :data="tableDataAlert"
      max-height="calc(500px - 35px)"
      style="width: 100%;"
    >
      <el-table-column prop="formattedCreateTime" align="center" :label="$t('film.createtime')" min-width="100" />
      <el-table-column
       :label="$t('hellow.content')"
       align="center"
       min-width="220"
     >
       <template #default="scope">
           <span>
        ç¬¼å†…存在相同规格的玻璃 (id:25103114002002)
           </span>
       </template>
     </el-table-column>
      <el-table-column fixed="right" :label="$t('film.operate')" align="center" width="100">
        <template #default="scope">
          <el-button type="text" plain
            @click="handleSure(scope.row)">{{ $t('basicData.yes') }}</el-button>
        </template>
      </el-table-column>
    </el-table>
  </el-dialog>
</template>
<style scoped>
#dt { display:block; float:left;line-height: 20px;margin-left: 100px;}
#dta { display:block; float:left;line-height: 20px;margin-left: 80%;}
#dialog-footer{
  text-align: center;
  margin-top: -15px;
}
#message{
  text-align: center;
  align-items: center;
  color: black;
   width: 200px;
   height: 100px;
   background-color: #337ecc;
   margin-left: 28%;
}
#awatch{
  height: 460px;
}
.global-alert-bar {
  position: fixed;
  top: 0;
  left: 50%; /* æ°´å¹³å±…中关键 */
  transform: translateX(-50%); /* æ°´å¹³å±…中关键 */
  padding: 12px 20px;
  background-color: #dbdbd7;
  box-shadow: 0 2px 10px rgba(0,0,0,0.2);
  display: flex;
  justify-content: space-between;
  align-items: center;
  z-index: 9999;
  max-width: 80%; /* é˜²æ­¢å°å±å¹•溢出 */
  min-width: 400px; /* æœ€å°å®½åº¦ä¿è¯ */
}
</style>
UI-Project/src/views/hollow/hollowslicecage.vue
@@ -38,7 +38,7 @@
const currentAlarm = ref<any>(null)
const tableDataAlert = ref([])
const alertText = ref('')
const engineerId = ref('')
const ganghua = ref('')
const diaodu = ref('')
const hollowPriority = ref('')
@@ -46,6 +46,7 @@
const glassType = ref('')
const layer = ref('')
const filmsId = ref('')
const thickness = ref('')
const adjust = ref([]);
const adjusta = ref([]);
const adjustedRects = ref([]);
@@ -53,11 +54,13 @@
const adjustedRectsb = ref([]);
const adjustedRectsc = ref([]);
const adjustedRectsd = ref([]);
const adjustedRectse = ref([]);
const subRectsCounts = ref([]);
const subRectsCountsa = ref([]);
const subRectsCountsb = ref([]);
const subRectsCountsc = ref([]);
const subRectsCountsd = ref([]);
const subRectsCountse = ref([]);
const currentRow = reactive({}); // å½“前行的数据 
const currentLack = reactive({});
const currentPage2 = ref(1)
@@ -414,10 +417,13 @@
// ç†ç‰‡ç¬¼ä¿¡æ¯
const fetchxiang = async () => {
  try {     
    const response = await request.post('/hollowGlass/hollowBigStorageCage/queryHollowBigStorageCageDetail',{
    const response = await request.post('/hollowGlass/hollowBigStorageCageDetails/queryVerticalSheetCageDetailsList',{
        // deviceId: page,
        engineerId: engineerId.value,
        filmsId: filmsId.value,
        flowCardId: flowCardId.value,
        glassId: glassId.value,
        thickness: -1,
    })
    if (response.code === 200) {  
      ElMessage.success(response.message);
@@ -431,10 +437,13 @@
const fetchxianga = async () => {
  let page = window.localStorage.getItem('pagenumber')
  try {     
    const response = await request.post('/hollowGlass/hollowBigStorageCage/queryHollowBigStorageCageDetail',{
    const response = await request.post('/hollowGlass/hollowBigStorageCageDetails/queryVerticalSheetCageDetailsList',{
        deviceId: page,
        engineerId: engineerId.value,
        filmsId: filmsId.value,
        flowCardId: flowCardId.value,
        glassId: glassId.value,
        thickness: thickness.value ? thickness.value : -1,
    })
    if (response.code === 200) {  
      ElMessage.success(response.message);
@@ -513,18 +522,27 @@
const socketUrl = `ws://${WebSocketHost}:${host}/api/hollowGlass/api/talk/hollowGlassMessage`;
const handleMessage = (data) => {
  // æŠ¥è­¦ä¿¡æ¯
  if (data.alarmInfo[0] !=null && data.alarmInfo[0].length > 0) {
    const alert = data.alarmInfo[0]
    const { id,alarmMessage, ...rest } = alert[0];
    alertMessage.value = `${alarmMessage}`;
    alertMessage.value = `${alert[0].alarmMessage}`;
    // åŠ¨æ€ç¿»è¯‘é€»è¾‘ï¼šæ ¹æ®alarmCode选择翻译键
    alertText.value = alert[0].alarmCode === 'sizeSame'
      ? t('hellow.sizeSame')
      : t('hellow.idSame');
if (data.alarmInfo[0] != null && data.alarmInfo[0].length > 0) {
  const alert = data.alarmInfo[0];
  const { id, alarmMessage, ...rest } = alert[0];
  alertMessage.value = `${alarmMessage}`;
  alertMessage.value = `${alert[0].alarmMessage}`;
  if (alert[0].alarmCode === 'sizeSame') {
    alertText.value = t('hellow.sizeSame');
  } else if (alert[0].alarmCode === 'idSame') {
    alertText.value = t('hellow.idSame');
  } else if (alert[0].alarmCode === 'slotLess') {
    alertText.value = t('hellow.slotLess');
  } else if (alert[0].alarmCode === 'overSize') {
    alertText.value = t('hellow.overSize');
  } else if (alert[0].alarmCode === 'noGlass') {
    alertText.value = t('hellow.noGlass');
  } else {
    alertText.value = t('hellow.unknownAlert');
  }
    alarmData.value = data; // å­˜å‚¨å®Œæ•´æ•°æ®ç”¨äºŽå¼¹çª—
    showAlert.value = true;
  }
}
   const formattedData = data.alarmInfo[0].map(record => ({
     ...record,
     formattedCreateTime: formatTimestamp(record.createTime),
@@ -618,45 +636,56 @@
    adjustedRects.value = data.bigStorageCageInfos[0][1].map((rect, index) => ({
    id: index + 1,
    height: 15/55,
    top: 33/55,
    top: 64/55,
  }));
subRectsCounts.value = data.bigStorageCageInfos[0][1].map(rect => rect.count);
adjustedRectsa.value = data.bigStorageCageInfos[0][2].map((rect, index) => ({
    id: index + 1,
    height: 15/55,
    top: 33/55,
    top: 64/55,
  }));
subRectsCountsa.value = data.bigStorageCageInfos[0][2].map(rect => rect.count);
adjustedRectsb.value = data.bigStorageCageInfos[0][3].map((rect, index) => ({
    id: index + 1,
    height: 15/55,
    top: 33/55,
    top: 64/55,
  }));
subRectsCountsb.value = data.bigStorageCageInfos[0][3].map(rect => rect.count);
adjustedRectsc.value = data.bigStorageCageInfos[0][4].map((rect, index) => ({
    id: index + 1,
    height: 15/55,
    top: 33/55,
    top: 64/55,
  }));
subRectsCountsc.value = data.bigStorageCageInfos[0][4].map(rect => rect.count);
adjustedRectsd.value = data.bigStorageCageInfos[0][5].map((rect, index) => ({
    id: index + 1,
    height: 15/55,
    top: 33/55,
    top: 64/55,
  }));
subRectsCountsd.value = data.bigStorageCageInfos[0][5].map(rect => rect.count);
adjustedRectse.value = data.bigStorageCageInfos[0][6].map((rect, index) => ({
    id: index + 1,
    height: 15/55,
    top: 64/55,
  }));
subRectsCountse.value = data.bigStorageCageInfos[0][6].map(rect => rect.count);
  }else{
    adjustedRects.value = '',
    adjustedRectsa.value = '',
    adjustedRectsb.value = '',
    adjustedRectsc.value = ''
    adjustedRectsd.value = ''
    adjustedRectsc.value = '',
    adjustedRectsd.value = '',
    adjustedRectse.value = ''
  }
};
const getAlertText = (alarmCode) => {
  const codeMap = {
    sizeSame: 'hellow.sizeSame',
    idSame: 'hellow.idSame'
    idSame: 'hellow.idSame',
    slotLess: 'hellow.slotLess',
    overSize: 'hellow.overSize',
    noGlass: 'hellow.noGlass'
  };
  return alarmCode in codeMap 
    ? t(codeMap[alarmCode]) 
@@ -831,6 +860,31 @@
    left,
  };
};
// è®¡ç®—每个小矩形的样式和数量
const getSubRectse = (rectIndex) => {
  const count = subRectsCountse.value[rectIndex];
  const subRects = [];
  for (let i = 0; i < count; i++) {
    subRects.push({});
  }
  return subRects;
};
// è®¡ç®—每个小矩形的样式
const subRectStylee = (rectIndex, subIndex) => {
  const width = '18px';
  const marginLeft = '3px';
  const totalWidth = 6 * (parseInt(width) + parseInt(marginLeft));
  const left = `${(subIndex * (parseInt(width) + parseInt(marginLeft))) / totalWidth * 100}%`;
  return {
    position: 'absolute',
    width,
    height: '100%',
    marginLeft,
    top: '0px',
    backgroundColor: '#911005',
    left,
  };
};
const iframeUrl = ref('');
const handlehistorical = (row) => {
  blindb.value = true;
@@ -854,22 +908,6 @@
const minutes = String(date.getMinutes()).padStart(2, '0'); // è¡¥é›¶ï¼ˆå¦‚果需要显示时间)
const seconds = String(date.getSeconds()).padStart(2, '0'); // è¡¥é›¶ï¼ˆå¦‚果需要显示时间)
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
function getStatusType(enableState: number) {
  switch (enableState) {
    case 100:
      return 'success';
    case 102:
      return 'warning';
  }
}
function getStatusText(enableState: number) {
  switch (enableState) {
    case 100:
      return t('searchOrder.zailong');
    case 102:
      return t('searchOrder.rengongxp');
  }
}
function getcasOnea(isSame) {  
  switch (isSame) {  
@@ -993,7 +1031,7 @@
    >
    </div>
    </div>
    <div class="img-car4" :style="'z-index:999;left:588px;top:' + 450*carPosition[1] + 'px;position:absolute;'">
    <div class="img-car4" :style="'z-index:999;left:580px;top:' + 450*carPosition[1] + 'px;position:absolute;'">
      <div  
      v-for="(rect, index) in adjust"  
      :key="rect.id"  
@@ -1008,7 +1046,7 @@
    </div>
    </div>
    <div style="position: relative;">
    <div v-show="cell1" style="width: 150px;height: 33px;position: relative;top:292px;left: 418px;">
    <div v-show="cell1" style="width: 150px;height: 64px;position: relative;top:82px;left: 415px;">
      <div v-for="(rect, rectIndex) in adjustedRects" :key="rect.id" :style="rectStyle(rect, rectIndex)">
    <div
      v-for="(subRect, subIndex) in getSubRects(rectIndex)"
@@ -1017,7 +1055,7 @@
    ></div>
    </div>
    </div>
 <div v-show="cell2" style="width: 150px;height: 33px;position: relative;top:295px;left: 418px;">
 <div v-show="cell2" style="width: 150px;height: 64px;position: relative;top:88px;left: 415px;">
  <div v-for="(rect, rectIndex) in adjustedRectsa" :key="rect.id" :style="rectStylea(rect, rectIndex)">
    <div
      v-for="(subRect, subIndex) in getSubRectsa(rectIndex)"
@@ -1026,7 +1064,7 @@
    ></div>
    </div>
    </div>
  <div v-show="cell3" style="width: 150px;height: 33px;position: relative;top:298px;left: 418px;">
  <div v-show="cell3" style="width: 150px;height: 64px;position: relative;top:93px;left: 415px;">
    <div v-for="(rect, rectIndex) in adjustedRectsb" :key="rect.id" :style="rectStyleb(rect, rectIndex)">
    <div
      v-for="(subRect, subIndex) in getSubRectsb(rectIndex)"
@@ -1035,7 +1073,7 @@
    ></div>
    </div>
    </div>
  <div v-show="cell4" style="width: 150px;height: 33px;position: relative;top:301px;left: 418px;">
  <div v-show="cell4" style="width: 150px;height: 64px;position: relative;top:99px;left: 415px;">
    <div v-for="(rect, rectIndex) in adjustedRectsc" :key="rect.id" :style="rectStylec(rect, rectIndex)">
    <div
      v-for="(subRect, subIndex) in getSubRectsc(rectIndex)"
@@ -1044,12 +1082,21 @@
    ></div>
    </div>
    </div>
  <div v-show="cell5" style="width: 150px;height: 33px;position: relative;top:304px;left: 418px;">
  <div v-show="cell5" style="width: 150px;height: 64px;position: relative;top:105px;left: 415px;">
    <div v-for="(rect, rectIndex) in adjustedRectsd" :key="rect.id" :style="rectStyled(rect, rectIndex)">
    <div
      v-for="(subRect, subIndex) in getSubRectsd(rectIndex)"
      :key="subIndex"
      :style="subRectStyled(rectIndex, subIndex)"
    ></div>
    </div>
    </div>
  <div v-show="cell6" style="width: 150px;height: 64px;position: relative;top:28px;left: 40px;">
    <div v-for="(rect, rectIndex) in adjustedRectse" :key="rect.id" :style="rectStyled(rect, rectIndex)">
    <div
      v-for="(subRect, subIndex) in getSubRectse(rectIndex)"
      :key="subIndex"
      :style="subRectStylee(rectIndex, subIndex)"
    ></div>
    </div>
    </div>
@@ -1200,66 +1247,19 @@
  <!-- ç†ç‰‡ç¬¼ä¿¡æ¯ -->
<el-dialog v-model="dialogFormVisiblea" top="2vh" width="97%" :title="$t('searchOrder.cageinformation')">
  <div style="display: flex;">
    <el-input v-model="flowCardId" style="margin-left: 10px;margin-bottom: 10px;width: 240px;" :placeholder="$t('searchOrder.incardnumber')" />
    <el-input v-model="filmsId" style="margin-left: 10px;margin-bottom: 10px;width: 240px;" :placeholder="$t('film.infilms')"/>
    <el-input v-model="engineerId" clearable style="margin-left: 10px;margin-bottom: 10px;width: 240px;" :placeholder="$t('processCard.projectnumber')"/>
    <el-input v-model="glassId" clearable style="margin-left: 10px;margin-bottom: 10px;width: 240px;" :placeholder="$t('searchOrder.inglassID')"/>
    <el-input v-model="flowCardId" clearable style="margin-left: 10px;margin-bottom: 10px;width: 240px;" :placeholder="$t('searchOrder.incardnumber')" />
    <el-input v-model="filmsId" clearable style="margin-left: 10px;margin-bottom: 10px;width: 240px;" :placeholder="$t('film.infilms')"/>
    <el-input v-model="thickness" clearable style="margin-left: 10px;margin-bottom: 10px;width: 240px;" :placeholder="$t('searchOrder.inthickness')"/>
    <el-button type="primary" style="margin-left: 10px;margin-bottom: 10px;" @click="fetchxianga">
      {{$t('reportmanage.inquire')}}</el-button>
  </div>
    <el-table
          :data="tableDataa"
          @row-click="handleRowClick"
          height="700"
          row-key="id"
          default-expand-all
          :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}"
        >
          <el-table-column type="expand">
            <template #default="props">
              <div v-if="props.row.hollowBigStorageCageDetails && props.row.hollowBigStorageCageDetails.length">
                <el-table
                  :data="props.row.hollowBigStorageCageDetails"
                  border
                  style="width: 98%;margin-left: 20px;"
                  row-key="id"
                  :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}"
                >
          <!-- <el-table-column prop="menuName" label="二级菜单栏" align="center" min-width="140" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}"/>   -->
          <el-table-column prop="glassId" :label="$t('searchOrder.glassID')" align="center" min-width="130"/>
          <el-table-column prop="flowCardId" align="center" :label="$t('searchOrder.cardnumber')" min-width="130" />
          <el-table-column prop="filmsId" align="center" :label="$t('searchOrder.coatingtypes')" min-width="80" />
          <!-- <el-table-column prop="glassType" align="center" :label="$t('searchOrder.typeglass')" min-width="80" /> -->
          <el-table-column prop="width" align="center" :label="$t('searchOrder.width')" min-width="80" />
          <el-table-column prop="height" align="center" :label="$t('searchOrder.height')" min-width="80" />
          <el-table-column prop="thickness" align="center" :label="$t('searchOrder.thickness')" min-width="80" />
          <el-table-column prop="temperingLayoutId" align="center" :label="$t('searchOrder.layoutID')" min-width="100" />
          <el-table-column prop="temperingFeedSequence" align="center" :label="$t('searchOrder.picturesequence')" min-width="120" />
          <el-table-column
            align="center"
            :label="$t('searchOrder.startstatus')"
            min-width="80"
            prop="state"
          >
          <template #default="scope">
        <el-tag :type="getStatusType(scope.row.state)">
          {{ getStatusText(scope.row.state) }}
        </el-tag>
      </template>
          </el-table-column>
          <el-table-column prop="gap" align="center" :label="$t('searchOrder.glassgaps')" min-width="80" />
           <el-table-column fixed="right" :label="$t('searchOrder.operate')" align="center"  min-width="220">
            <template #default="scope">
              <el-button type="text" plain @click="broke(scope.row)">{{ $t('searchOrder.breakage') }}</el-button>
              <el-button type="text" plain @click="brokec(scope.row)">{{ $t('searchOrder.takeout') }}</el-button>
              <el-button type="text" plain @click="opena(scope.row)">{{ $t('searchOrder.delete') }}</el-button>
            </template>
        </el-table-column>
                </el-table>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="id" :label="$t('searchOrder.cagetableID')" align="center" min-width="100"/>
  <el-table ref="table" style="margin-top: 20px;height: 700px;width: 1770px;" :data="tableDataa" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}">
          <el-table-column prop="deviceId" align="center" :label="$t('searchOrder.cagenumber')" min-width="150" />
          <el-table-column prop="slot" align="center" :label="$t('searchOrder.gridnumber')" min-width="150" />
          <el-table-column prop="engineerId" align="center" :label="$t('searchOrder.projectnumber')" min-width="100" />
          <el-table-column prop="layer" align="center" :label="$t('processCard.layer')" min-width="80" />
          <el-table-column prop="slot" align="center" :label="$t('searchOrder.gridnumber')" min-width="120" />
          <el-table-column
          align="center"
            :label="$t('searchOrder.startstatus')"
@@ -1276,12 +1276,23 @@
        </template> 
          </el-table-column>
          <el-table-column prop="remainWidth" align="center" :label="$t('searchOrder.remainingwidth')" min-width="120" />
       <el-table-column fixed="right" :label="$t('searchOrder.operate')" align="center">
            <template #default="scope">
              <el-button type="text" plain  @click="handleBindRack(scope.row)">{{ $t('searchOrder.add') }}</el-button>
            </template>
        </el-table-column>
          <el-table-column prop="glassId" :label="$t('searchOrder.glassID')" align="center" min-width="130"/>
          <el-table-column prop="flowCardId" align="center" :label="$t('searchOrder.cardnumber')" min-width="130" />
          <el-table-column prop="filmsId" align="center" :label="$t('searchOrder.coatingtypes')" min-width="80" />
          <el-table-column prop="width" align="center" :label="$t('searchOrder.width')" min-width="80" />
          <el-table-column prop="height" align="center" :label="$t('searchOrder.height')" min-width="80" />
          <el-table-column prop="thickness" align="center" :label="$t('searchOrder.thickness')" min-width="80" />
          <el-table-column prop="temperingLayoutId" align="center" :label="$t('searchOrder.layoutID')" min-width="100" />
          <el-table-column prop="temperingFeedSequence" align="center" :label="$t('searchOrder.picturesequence')" min-width="120" />
          <el-table-column prop="gap" align="center" :label="$t('searchOrder.glassgaps')" min-width="80" />
          <el-table-column fixed="right" :label="$t('film.operate')" align="center" width="240">
              <template #default="scope">
              <!-- <el-button type="text" plain  @click="handleBindRack(scope.row)">{{ $t('searchOrder.add') }}</el-button> -->
              <el-button type="text" plain @click="broke(scope.row)">{{ $t('searchOrder.breakage') }}</el-button>
              <el-button type="text" plain @click="brokec(scope.row)">{{ $t('searchOrder.takeout') }}</el-button>
              <el-button type="text" plain @click="opena(scope.row)">{{ $t('searchOrder.delete') }}</el-button>
                </template>
              </el-table-column>
        </el-table>
        <div>
  </div>
@@ -1410,7 +1421,7 @@
.img-zkdlpl{
  margin-left: 20px;
  margin-top: 0px;
  background-image:url('/zhongkong.png');
  background-image:url('/src/assets/zhongkong.png');
  background-repeat: no-repeat;
  background-attachment: local;
  min-height: 500px;
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/menu/entity/SysMenu.java
@@ -65,7 +65,7 @@
    /**
     * æŽ’序
     */
    private String listSort;
    private Integer listSort;
    /**
     * åˆ›å»ºæ—¶é—´
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/menu/service/impl/SysMenuServiceImpl.java
@@ -65,11 +65,12 @@
                .innerJoin(SysRoleMenu.class, SysRoleMenu::getRoleId, SysUserRole::getRoleId)
                .innerJoin(SysMenu.class, SysMenu::getId, SysRoleMenu::getMenuId)
                .eq(SysUser::getId, user.getId())
                .like(StringUtils.isNotBlank(request.getKey()), SysMenu::getMenuName, request.getKey());
                .like(StringUtils.isNotBlank(request.getKey()), SysMenu::getMenuName, request.getKey())
                .orderByAsc(SysMenu::getListSort);
        //
        List<SysMenu> menuList = sysUserRoleMapper.selectJoinList(SysMenu.class, wrapper);
        log.info("userinfos:{}",menuList);
        log.info("userinfos:{}", menuList);
        return create(menuList);
    }
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/job/OpcCacheGlassNewTask.java
@@ -8,6 +8,8 @@
import com.github.xingshuangs.iot.protocol.s7.serializer.S7Serializer;
import com.kangaroohy.milo.model.ReadWriteEntity;
import com.kangaroohy.milo.service.MiloService;
import com.mes.alarm.entity.ProductAlarmInfo;
import com.mes.alarm.service.ProductAlarmInfoService;
import com.mes.common.config.Const;
import com.mes.common.config.ConstSysConfig;
import com.mes.damage.service.DamageService;
@@ -113,8 +115,24 @@
    private String glassIdOne = "";
    private String glassIdTwo = "";
    @Resource
    private ProductAlarmInfoService productAlarmInfoService;
    private static final String ALARM_MODULE = "磨边";
    private static final String ALARM_TYPE1 = "一线卧式理片笼";
    private static final String ALARM_TYPE2 = "二线卧式理片笼";
    private static final String ALARM_CODE_NOGLASS = "noGlass";
    @Scheduled(fixedDelay = 1000)
    public void startOneOpcTask() throws Exception {
        List<ProductAlarmInfo> alarmInfos = productAlarmInfoService.list(new LambdaQueryWrapper<ProductAlarmInfo>()
                .eq(ProductAlarmInfo::getState, Const.LOAD_RAW_GLASS_NEW)
                .eq(ProductAlarmInfo::getAlarmModule, ALARM_MODULE)
                .eq(ProductAlarmInfo::getAlarmType, ALARM_TYPE1));
        if (CollectionUtil.isNotEmpty(alarmInfos)) {
            log.info("界面报警,等待人工干预处理");
            return;
        }
        S7DataWL s7DataWLTwo = s7SerializerWLTwo.read(S7DataWL.class);
        S7DataWL s7DataWLOne = s7SerializerWLOne.read(S7DataWL.class);
        S7DataWLExtra s7DataWLExtraTwo = s7SerializerWLTwo.read(S7DataWLExtra.class);
@@ -132,6 +150,14 @@
    @Scheduled(fixedDelay = 1000)
    public void startTwoOpcTask() throws Exception {
        List<ProductAlarmInfo> alarmInfos = productAlarmInfoService.list(new LambdaQueryWrapper<ProductAlarmInfo>()
                .eq(ProductAlarmInfo::getState, Const.LOAD_RAW_GLASS_NEW)
                .eq(ProductAlarmInfo::getAlarmModule, ALARM_MODULE)
                .eq(ProductAlarmInfo::getAlarmType, ALARM_TYPE2));
        if (CollectionUtil.isNotEmpty(alarmInfos)) {
            log.info("界面报警,等待人工干预处理");
            return;
        }
        S7DataWL s7DataWLOne = s7SerializerWLOne.read(S7DataWL.class);
        S7DataWL s7DataWLTwo = s7SerializerWLTwo.read(S7DataWL.class);
        S7DataWLExtra s7DataWLExtraTwo = s7SerializerWLTwo.read(S7DataWLExtra.class);
@@ -278,8 +304,19 @@
        log.info("开始执行进片任务,任务信息为:{},设备id:{},开始时间:{}", task, deviceId, startDate);
        //获取玻璃的基本信息
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, task.getGlassIdIn()));
        if (null == glassInfo) {
        if (null == glassInfo && StringUtils.isNotBlank(task.getGlassIdIn())) {
            log.info("进片玻璃信息不存在,玻璃id:{}", task.getGlassIdIn());
            ProductAlarmInfo alarmInfo = new ProductAlarmInfo();
            alarmInfo.setState(Const.LOAD_RAW_GLASS_NEW);
            alarmInfo.setAlarmModule(ALARM_MODULE);
            if (deviceId == 1) {
                alarmInfo.setAlarmType(ALARM_TYPE1);
            } else {
                alarmInfo.setAlarmType(ALARM_TYPE2);
            }
            alarmInfo.setAlarmCode(ALARM_CODE_NOGLASS);
            alarmInfo.setAlarmMessage(task.getGlassIdIn());
            productAlarmInfoService.save(alarmInfo);
            Date endDate = new Date();
            log.info("结束进片任务设备为{},结束时间为:{},共耗时:{}ms", deviceId, endDate, endDate.getTime() - startDate.getTime());
            return Boolean.FALSE;
@@ -343,6 +380,24 @@
    private boolean outTask(S7DataWL task, int deviceId, int cellFlag) {
        Date startDate = new Date();
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, task.getGlassIdOut()));
        if (null == glassInfo && StringUtils.isNotBlank(task.getGlassIdIn())) {
            log.info("进片玻璃信息不存在,玻璃id:{}", task.getGlassIdIn());
            ProductAlarmInfo alarmInfo = new ProductAlarmInfo();
            alarmInfo.setState(Const.LOAD_RAW_GLASS_NEW);
            alarmInfo.setAlarmModule(ALARM_MODULE);
            if (deviceId == 1) {
                alarmInfo.setAlarmType(ALARM_TYPE1);
            } else {
                alarmInfo.setAlarmType(ALARM_TYPE2);
            }
            alarmInfo.setAlarmCode(ALARM_CODE_NOGLASS);
            alarmInfo.setAlarmMessage(task.getGlassIdIn());
            productAlarmInfoService.save(alarmInfo);
            Date endDate = new Date();
            log.info("结束进片任务设备为{},结束时间为:{},共耗时:{}ms", deviceId, endDate, endDate.getTime() - startDate.getTime());
            return Boolean.FALSE;
        }
        //获取对应的设备状态信息
        S7DataWL s7DataWLOne = s7SerializerWLOne.read(S7DataWL.class);
        S7DataWL s7DataWLTwo = s7SerializerWLTwo.read(S7DataWL.class);
@@ -382,9 +437,9 @@
                cell = Const.ONE_OUT_TARGET_POSITION;
            } else if (Const.OUT_BUSY.equals(twoOutState)) {
                cell = Const.TWO_OUT_TARGET_POSITION;
            }else if(Const.OUT_BUSY.equals(oneOutState)){
            } else if (Const.OUT_BUSY.equals(oneOutState)) {
                cell = Const.ONE_OUT_TARGET_POSITION;
            }else{
            } else {
                return Boolean.FALSE;
            }
        }
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/job/PushMessageToIndex.java
@@ -2,6 +2,8 @@
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mes.alarm.entity.ProductAlarmInfo;
import com.mes.alarm.service.ProductAlarmInfoService;
import com.mes.common.config.Const;
import com.mes.edgglasstask.entity.EdgGlassTaskInfo;
import com.mes.edgglasstask.service.EdgGlassTaskInfoService;
@@ -55,6 +57,13 @@
    EngineeringService engineeringService;
    @Resource
    LargenScreenService largenScreenService;
    @Resource
    private ProductAlarmInfoService productAlarmInfoService;
    private static final String ALARM_MODULE = "磨边";
    private static final String ALARM_TYPE1 = "一线卧式理片笼";
    private static final String ALARM_TYPE2 = "二线卧式理片笼";
    private static final String ALARM_CODE_NOGLASS = "noGlass";
    @Resource
    private WebSocketUtils webSocketUtils;
@@ -81,6 +90,20 @@
                .eq(EdgStorageDeviceTaskHistory::getTaskState, Const.RAW_GLASS_TASK_NEW)
                .orderByDesc(EdgStorageDeviceTaskHistory::getCreateTime).last("limit 1"));
        jsonObject.append("taskMessage", taskHistory);
        //推送报警信息
        if (deviceId == 1) {
            jsonObject.append("alarmInfo", productAlarmInfoService.list(new LambdaQueryWrapper<ProductAlarmInfo>()
                    .eq(ProductAlarmInfo::getState, Const.LOAD_RAW_GLASS_NEW)
                    .eq(ProductAlarmInfo::getAlarmModule, ALARM_MODULE)
                    .eq(ProductAlarmInfo::getAlarmType, ALARM_TYPE1)));
        } else {
            jsonObject.append("alarmInfo", productAlarmInfoService.list(new LambdaQueryWrapper<ProductAlarmInfo>()
                    .eq(ProductAlarmInfo::getState, Const.LOAD_RAW_GLASS_NEW)
                    .eq(ProductAlarmInfo::getAlarmModule, ALARM_MODULE)
                    .eq(ProductAlarmInfo::getAlarmType, ALARM_TYPE2)));
        }
        webSocketUtils.sendToWeb(webSocketName, jsonObject);
    }
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/controller/BigStorageCageDetailsController.java
@@ -6,7 +6,9 @@
import com.mes.bigstorage.entity.BigStorageCageDetails;
import com.mes.bigstorage.entity.dto.GlassInfoLackDTO;
import com.mes.bigstorage.entity.dto.TemperingGlassCountDTO;
import com.mes.bigstorage.entity.request.BigCageDetailsRequest;
import com.mes.bigstorage.entity.vo.BigStorageQueryVO;
import com.mes.bigstorage.entity.vo.BigCageDetailsVO;
import com.mes.bigstorage.service.BigStorageCageDetailsService;
import com.mes.bigstorage.service.BigStorageCageService;
import com.mes.common.config.Const;
@@ -211,5 +213,11 @@
        return Result.build(200, "", result);
    }
    @ApiOperation("(列表)按列表照查询条件(设备id、流程卡、膜系)获取设备对应的笼子玻璃信息")
    @PostMapping("/queryVerticalSheetCageDetailsList")
    public Result<List<BigCageDetailsVO>> queryVerticalSheetCageDetailsList(@RequestBody BigCageDetailsRequest request) {
        return Result.build(200, "查询成功", bigStorageCageDetailsService.queryVerticalSheetCageDetailsList(request));
    }
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/entity/request/BigCageDetailsRequest.java
New file
@@ -0,0 +1,52 @@
package com.mes.bigstorage.entity.request;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mes.base.entity.PageRequest;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
 * @Author : zhoush
 * @Date: 2025/9/4 17:04
 * @Description:
 */
@Data
public class BigCageDetailsRequest extends PageRequest {
    @ApiModelProperty(value = "设备id", position = 1)
    private Integer deviceId;
    @ApiModelProperty(value = "格子号", position = 2)
    private Integer slot;
    @ApiModelProperty(value = "流程卡", position = 3)
    private String flowCardId;
    @ApiModelProperty(value = "膜系", position = 4)
    private String filmsId;
    @ApiModelProperty(value = "厚度", position = 5)
    private int thickness;
    @ApiModelProperty(value = "钢化版图id", position = 6)
    private String engineerId;
    @ApiModelProperty(value = "玻璃id", position = 7)
    private String glassId;
    @ApiModelProperty(value = "玻璃报工状态:8破损 9拿走  è°ƒç”¨æ›´æ–°çŠ¶æ€/破损拿走接口必填", position = 8)
    private String state;
    @ApiModelProperty(value = "开始时间")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date startTime;
    @ApiModelProperty(value = "结束时间")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date endTime;
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/entity/vo/BigCageDetailsVO.java
New file
@@ -0,0 +1,110 @@
package com.mes.bigstorage.entity.vo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.mes.bigstorage.entity.BigStorageCage;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
 * @Author : zhoush
 * @Date: 2025/9/4 17:02
 * @Description:
 */
@Data
public class BigCageDetailsVO extends BigStorageCage {
    @ApiModelProperty(value = "大理片笼详情表主键 ID", position = 1)
    @TableId(value = "id", type = IdType.AUTO)
    private Long detailId;
    @ApiModelProperty(value = "设备 ID", position = 2)
    private Integer detailDeviceId;
    @ApiModelProperty(value = "栅格号", position = 3)
    private Integer detailSlot;
    @ApiModelProperty(value = "玻璃 ID", position = 4)
    private String glassId;
    @ApiModelProperty(value = "小片在格子内的顺序", position = 5)
    private Integer sequence;
    @ApiModelProperty(value = "流程卡号", position = 6)
    private String flowCardId;
    @ApiModelProperty(value = "流程卡落架编码", position = 7)
    private String flowCardSequence;
    @ApiModelProperty(value = "玻璃类型", position = 8)
    private Integer glassType;
    @ApiModelProperty(value = "玻璃宽度(单位:mm)", position = 9)
    private Double width;
    @ApiModelProperty(value = "玻璃高度(单位:mm)", position = 10)
    private Double height;
    @ApiModelProperty(value = "玻璃厚度(单位:mm)", position = 11)
    private Double thickness;
    @ApiModelProperty(value = "钢化版图 ID", position = 12)
    private Integer temperingLayoutId;
    @ApiModelProperty(value = "钢化版图片序号", position = 13)
    private Integer temperingFeedSequence;
    @ApiModelProperty(value = "X åæ ‡", position = 14)
    private Integer xCoordinate;
    @ApiModelProperty(value = "Y åæ ‡", position = 15)
    private Integer yCoordinate;
    @ApiModelProperty(value = "玻璃状态", position = 16)
    private Integer state;
    @ApiModelProperty(value = "玻璃间隙", position = 17)
    private Integer gap;
    @ApiModelProperty(value = "工程号 ID", position = 18)
    private String engineerId;
    @ApiModelProperty(value = "层号", position = 19)
    private Integer totalLayer;
    @ApiModelProperty(value = "层号", position = 20)
    private Integer layer;
    @ApiModelProperty(value = "创建时间", position = 21)
    private Date createTime;
    @ApiModelProperty(value = "更新时间", position = 22)
    private Date updateTime;
    @ApiModelProperty(value = "膜系 ID", position = 23)
    private String filmsId;
    @ApiModelProperty(value = "是否旋转(角度,单位:度)", position = 24)
    private Integer angle;
    @ApiModelProperty(value = "是否已钢化", position = 25)
    private Integer isTemp;
    @ApiModelProperty(value = "中空顺序", position = 26)
    private Integer hollowSequence;
    @ApiModelProperty(value = "是否配对", position = 27)
    private Integer isPair;
    @ApiModelProperty(value = "组号", position = 28)
    private Integer virtualSlot;
    @ApiModelProperty(value = "组序", position = 29)
    private Integer slotSequence;
    @ApiModelProperty(value = "落架顺序", position = 30)
    private Integer shelfOrder;
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/mapper/BigStorageCageDetailsMapper.java
@@ -4,7 +4,9 @@
import com.mes.base.entity.vo.BigStorageVO;
import com.mes.bigstorage.entity.BigStorageCageDetails;
import com.mes.bigstorage.entity.dto.*;
import com.mes.bigstorage.entity.request.BigCageDetailsRequest;
import com.mes.bigstorage.entity.vo.BigStorageQueryVO;
import com.mes.bigstorage.entity.vo.BigCageDetailsVO;
import com.mes.bigstoragetask.entity.UpdateBigStorageCageDTO;
import org.apache.ibatis.annotations.Param;
@@ -73,4 +75,12 @@
    BigStorageSlotDTO queryNeedDispatchSlotBySequence();
    List<TemperingGlassCountDTO> queryTemperingGlassCountSummary(int isTempering);
    /**
     * ï¼ˆåˆ—表)按列表照查询条件(设备id、流程卡、膜系)获取设备对应的笼子玻璃信息
     *
     * @param request
     * @return
     */
    List<BigCageDetailsVO> queryVerticalSheetCageDetailsList(BigCageDetailsRequest request);
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/BigStorageCageDetailsService.java
@@ -4,7 +4,9 @@
import com.mes.base.entity.vo.BigStorageVO;
import com.mes.bigstorage.entity.BigStorageCageDetails;
import com.mes.bigstorage.entity.dto.*;
import com.mes.bigstorage.entity.request.BigCageDetailsRequest;
import com.mes.bigstorage.entity.vo.BigStorageQueryVO;
import com.mes.bigstorage.entity.vo.BigCageDetailsVO;
import com.mes.bigstoragetask.entity.UpdateBigStorageCageDTO;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.pp.entity.OptimizeProject;
@@ -155,4 +157,6 @@
     * @return OptimizeProject é’¢åŒ–排产顺序
     */
    List<OptimizeProject> queryTemperingOrder();
    List<BigCageDetailsVO> queryVerticalSheetCageDetailsList(BigCageDetailsRequest request);
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/impl/BigStorageCageDetailsServiceImpl.java
@@ -11,7 +11,9 @@
import com.mes.bigstorage.entity.BigStorageCage;
import com.mes.bigstorage.entity.BigStorageCageDetails;
import com.mes.bigstorage.entity.dto.*;
import com.mes.bigstorage.entity.request.BigCageDetailsRequest;
import com.mes.bigstorage.entity.vo.BigStorageQueryVO;
import com.mes.bigstorage.entity.vo.BigCageDetailsVO;
import com.mes.bigstorage.mapper.BigStorageCageDetailsMapper;
import com.mes.bigstorage.service.BigStorageCageDetailsService;
import com.mes.bigstorage.service.BigStorageCageService;
@@ -620,4 +622,9 @@
        }
        return resultList;
    }
    @Override
    public List<BigCageDetailsVO> queryVerticalSheetCageDetailsList(BigCageDetailsRequest request) {
        return baseMapper.queryVerticalSheetCageDetailsList(request);
    }
}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/impl/BigStorageGlassInfoServiceImpl.java
@@ -4,6 +4,8 @@
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mes.alarm.entity.ProductAlarmInfo;
import com.mes.alarm.service.ProductAlarmInfoService;
import com.mes.bigstorage.entity.BigStorageCage;
import com.mes.bigstorage.entity.BigStorageCageDetails;
import com.mes.bigstorage.entity.BigStorageGlassInfo;
@@ -48,6 +50,15 @@
    BigStorageGlassRelationInfoService bigStorageGlassRelationInfoService;
    @Resource
    SysConfigService sysConfigService;
    @Resource
    private ProductAlarmInfoService productAlarmInfoService;
    private static final String ALARM_MODULE = "钢化";
    private static final String ALARM_TYPE = "钢化大理片";
    private static final String ALARM_CODE_SIZE = "sizeSame";
    private static final String ALARM_CODE_ID = "idSame";
    private static final String ALARM_CODE_SLOT = "slotLess";
    private static final String ALARM_CODE_OVER = "overSize";
//    @Value("${mes.slotWidth}")
//    private Integer slotWidth;
//    @Value("${mes.glassGap}")
@@ -118,6 +129,15 @@
            } else {
                BigStorageCage bigStorageCage = bigStorageCageService.getOne(new LambdaQueryWrapper<BigStorageCage>()
                        .eq(BigStorageCage::getEnableState, Const.SLOT_ON).eq(BigStorageCage::getSlot, beforeGlass.getSlot()));
                if (bigStorageCage == null) {
                    ProductAlarmInfo alarmInfo = new ProductAlarmInfo();
                    alarmInfo.setState(Const.LOAD_RAW_GLASS_NEW);
                    alarmInfo.setAlarmModule(ALARM_MODULE);
                    alarmInfo.setAlarmType(ALARM_TYPE);
                    alarmInfo.setAlarmCode(ALARM_CODE_SLOT);
                    alarmInfo.setAlarmMessage("");
                    productAlarmInfoService.save(alarmInfo);
                }
                Assert.isTrue(null != bigStorageCage, "没有空余的笼子存放玻璃");
                storageCageDTO = new BigStorageDTO();
                storageCageDTO.setWidth(bigStorageCage.getRemainWidth());
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/job/OpcPlcStorageCageNewTask.java
@@ -104,6 +104,8 @@
    private static final String ALARM_TYPE = "钢化大理片";
    private static final String ALARM_CODE_SIZE = "sizeSame";
    private static final String ALARM_CODE_ID = "idSame";
    private static final String ALARM_CODE_SLOT = "slotLess";
    private static final String ALARM_CODE_OVER = "overSize";
    @Resource
    private RedisUtil redisUtil;
@@ -231,6 +233,13 @@
                        .ge(BigStorageCage::getMaxThickness, entry.getKey()));
                if (count < entry.getValue()) {
                    log.info("笼内格子剩余数量不足,结束本次进片");
                    ProductAlarmInfo alarmInfo = new ProductAlarmInfo();
                    alarmInfo.setState(Const.LOAD_RAW_GLASS_NEW);
                    alarmInfo.setAlarmModule(ALARM_MODULE);
                    alarmInfo.setAlarmType(ALARM_TYPE);
                    alarmInfo.setAlarmCode(ALARM_CODE_SLOT);
                    alarmInfo.setAlarmMessage(count + "");
                    productAlarmInfoService.save(alarmInfo);
                    //向plc发送报警:笼内格子剩余数量不足
//                    miloService.writeToOpcWord(generateReadWriteEntity("DLP1A.DLP1A.alarmSignal", 16));
                    s7DataDLPOne = new S7DataDLPOne();
@@ -247,6 +256,13 @@
                    .in(BigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL));
            if (count > 0) {
                log.info("直通片台存在玻璃,结束本次进片");
                ProductAlarmInfo alarmInfo = new ProductAlarmInfo();
                alarmInfo.setState(Const.LOAD_RAW_GLASS_NEW);
                alarmInfo.setAlarmModule(ALARM_MODULE);
                alarmInfo.setAlarmType(ALARM_TYPE);
                alarmInfo.setAlarmCode(ALARM_CODE_OVER);
                alarmInfo.setAlarmMessage("");
                productAlarmInfoService.save(alarmInfo);
                //向plc发送报警:直通片台存在玻璃,无法继续直通
//                miloService.writeToOpcWord(generateReadWriteEntity("DLP1A.DLP1A.alarmSignal", 64));
                s7DataDLPOne = new S7DataDLPOne();
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/resources/mapper/BigStorageCageDetailsMapper.xml
@@ -76,7 +76,7 @@
                             WHERE ENGINEER_ID = #{engineerId}
                               AND TEMPERING_LAYOUT_ID = #{temperingLayoutId}
                             GROUP BY ENGINEER_ID,
                                      TEMPERING_LAYOUT_ID) T1
                                 TEMPERING_LAYOUT_ID) T1
                            ON T.ENGINEER_ID = T1.ENGINEER_ID
                                AND T.TEMPERING_LAYOUT_ID = T1.TEMPERING_LAYOUT_ID
                                AND T.COUNT = T1.COUNT
@@ -89,14 +89,14 @@
                        T.TEMPERING_LAYOUT_ID,
                        COUNT(T.TEMPERING_FEED_SEQUENCE) AS COUNT
                 FROM GLASS_INFO T
                          LEFT JOIN DAMAGE T1
                                    ON T.ENGINEER_ID = T1.ENGINEER_ID
                                        AND T.GLASS_ID = T1.GLASS_ID
                                        AND (T1.TYPE = 8
                                            OR T1.TYPE = 9)
                     LEFT JOIN DAMAGE T1
                 ON T.ENGINEER_ID = T1.ENGINEER_ID
                     AND T.GLASS_ID = T1.GLASS_ID
                     AND (T1.TYPE = 8
                     OR T1.TYPE = 9)
                 WHERE T1.GLASS_ID IS NULL
                 GROUP BY T.ENGINEER_ID,
                          T.TEMPERING_LAYOUT_ID
                     T.TEMPERING_LAYOUT_ID
             ) T2
                 INNER JOIN (SELECT ENGINEER_ID, TEMPERING_LAYOUT_ID, COUNT(TEMPERING_FEED_SEQUENCE) AS COUNT
                             FROM BIG_STORAGE_CAGE_DETAILS
@@ -212,31 +212,31 @@
    <select id="queryIsAllNeedDispatchVirtualSlot" resultMap="virtualSlotSequenceDTO">
        with relation_temp as (
            select engineer_id, tempering_layout_id, virtual_slot, count(1) as slot_count
            from big_storage_glass_relation_info
            group by engineer_id, tempering_layout_id, virtual_slot
        select engineer_id, tempering_layout_id, virtual_slot, count(1) as slot_count
        from big_storage_glass_relation_info
        group by engineer_id, tempering_layout_id, virtual_slot
        ),
             details_temp as (
                 select t.engineer_id, t.tempering_layout_id, t.virtual_slot, count(1) as slot_count
                 from big_storage_glass_relation_info t
                          left join big_storage_cage_details t1 on
                         t.engineer_id = t1.engineer_id and t.tempering_layout_id = t1.tempering_layout_id and
                         t.tempering_feed_sequence = t1.tempering_feed_sequence
                 where t1.state = 100
        details_temp as (
        select t.engineer_id, t.tempering_layout_id, t.virtual_slot, count(1) as slot_count
        from big_storage_glass_relation_info t
        left join big_storage_cage_details t1 on
        t.engineer_id = t1.engineer_id and t.tempering_layout_id = t1.tempering_layout_id and
        t.tempering_feed_sequence = t1.tempering_feed_sequence
        where t1.state = 100
        AND T1.DEVICE_ID IN
        <foreach collection="deviceIdList" item="item" open='(' close=')' separator=','>
            #{item}
        </foreach>
                 group by t.engineer_id, t.tempering_layout_id, t.virtual_slot
             ),
             result_one as (
                 select t.*, t1.slot_count as tslot_count
                 from relation_temp t
                          INNER JOIN details_temp t1 on t.engineer_id = t1.engineer_id and
                                                        t.tempering_layout_id = t1.tempering_layout_id and
                                                        t.virtual_slot = t1.virtual_slot
                 where t.slot_count = t1.slot_count
             )
        group by t.engineer_id, t.tempering_layout_id, t.virtual_slot
        ),
        result_one as (
        select t.*, t1.slot_count as tslot_count
        from relation_temp t
        INNER JOIN details_temp t1 on t.engineer_id = t1.engineer_id and
        t.tempering_layout_id = t1.tempering_layout_id and
        t.virtual_slot = t1.virtual_slot
        where t.slot_count = t1.slot_count
        )
        select engineer_id, tempering_layout_id, virtual_slot
        from result_one
        order by engineer_id, tempering_layout_id
@@ -296,35 +296,55 @@
    <select id="querybigStorageCageDetail" resultType="com.mes.base.entity.vo.BigStorageVO">
        select bsc.device_id, bsc.slot, count(bscd.glass_id) as count
        from big_storage_cage bsc
                 left join big_storage_cage_details bscd
                           on bsc.slot = bscd.slot and bscd.state in (100, 102, 103, 104)
            left join big_storage_cage_details bscd
        on bsc.slot = bscd.slot and bscd.state in (100, 102, 103, 104)
        group by bsc.device_id, bsc.slot
        order by bsc.device_id, bsc.slot
    </select>
    <select id="queryNeedDispatch" resultType="com.mes.bigstorage.entity.BigStorageCageDetails">
        SELECT * FROM big_storage_cage_details WHERE STATE = 100 AND SLOT = (SELECT SLOT FROM big_storage_cage_details WHERE STATE = 100 AND sequence = 1 order by slot desc LIMIT 1) ORDER BY tempering_feed_sequence
        SELECT *
        FROM big_storage_cage_details
        WHERE STATE = 100
          AND SLOT =
              (SELECT SLOT FROM big_storage_cage_details WHERE STATE = 100 AND sequence = 1 order by slot desc LIMIT 1)
        ORDER BY tempering_feed_sequence
    </select>
    <select id="queryNeedDispatchSlotBySequence" resultType="com.mes.bigstorage.entity.dto.BigStorageSlotDTO">
        with glass_temp as (
        select t.* ,t1.virtual_slot,t1.slot_sequence from big_storage_cage_details t inner join
        big_storage_glass_relation_info t1 on t.engineer_id = t1.engineer_id
        and t.tempering_layout_id = t1.tempering_layout_id
        and t.tempering_feed_sequence = t1.tempering_feed_sequence where t.state = 100
        ),slot_max_temp as (
        select ROW_NUMBER()over(PARTITION by engineer_id, tempering_layout_id, virtual_slot order by slot_sequence desc)
        as rn,t.* from glass_temp t where t.device_id in (5,6)
        ) ,slot_max_message as (select * from slot_max_temp where rn =1)
        ,slot_min_temp as (
        select ROW_NUMBER()over(PARTITION by engineer_id, tempering_layout_id, virtual_slot order by slot_sequence) as
        rn,t.* from glass_temp t where t.device_id in (5,6)
        ) ,slot_min_message as (select * from slot_min_temp where rn =1)
        ,result as (
        select t.slot as target_slot ,t1.slot as start_slot from slot_max_message t inner join slot_min_message t1 on
        t.engineer_id = t1.engineer_id and t.tempering_layout_id = t1.tempering_layout_id and t.virtual_slot =
        t1.virtual_slot and t.tempering_layout_id = t1.tempering_layout_id and t.tempering_feed_sequence =
        t1.tempering_feed_sequence -1
        )select * from result limit 1
            select t.*, t1.virtual_slot, t1.slot_sequence
            from big_storage_cage_details t
                     inner join
                 big_storage_glass_relation_info t1 on t.engineer_id = t1.engineer_id
                     and t.tempering_layout_id = t1.tempering_layout_id
                     and t.tempering_feed_sequence = t1.tempering_feed_sequence
            where t.state = 100
        )
           , slot_max_temp as (
            select ROW_NUMBER() over(PARTITION by engineer_id, tempering_layout_id, virtual_slot order by slot_sequence desc)
        as rn,t.*
            from glass_temp t
            where t.device_id in (5, 6)
        )
           , slot_max_message as (select * from slot_max_temp where rn = 1)
           , slot_min_temp as (
            select ROW_NUMBER() over(PARTITION by engineer_id, tempering_layout_id, virtual_slot order by slot_sequence) as
        rn,t.*
            from glass_temp t
            where t.device_id in (5, 6)
        )
           , slot_min_message as (select * from slot_min_temp where rn = 1)
           , result as (
            select t.slot as target_slot, t1.slot as start_slot
            from slot_max_message t
                     inner join slot_min_message t1 on
                    t.engineer_id = t1.engineer_id and t.tempering_layout_id = t1.tempering_layout_id and
                    t.virtual_slot =
                    t1.virtual_slot and t.tempering_layout_id = t1.tempering_layout_id and t.tempering_feed_sequence =
                                                                                           t1.tempering_feed_sequence - 1
        )
        select *
        from result limit 1
    </select>
    <select id="queryTemperingGlassCountSummary" resultMap="temperingGlassCount">
        with glass_info_temp as (
@@ -382,4 +402,30 @@
        from secondary_summary
        order by engineer_id, films_id, thickness
    </select>
    <select id="queryVerticalSheetCageDetailsList"
            resultType="com.mes.bigstorage.entity.vo.BigCageDetailsVO">
        SELECT t.id,t.device_id,t.slot,t.remain_width ,t.enable_state,t1.engineer_id,
        t1.id as detail_id,t1.device_id as detail_device_id ,t1.slot as
        detail_slot,t1.engineer_id,t1.glass_id,t1.tempering_layout_id,t1.tempering_feed_sequence,
        t1.flow_card_id,t1.layer,t1.width,t1.height,t1.thickness,t1.films_id
        FROM big_storage_cage t
        left join big_storage_cage_details t1 on t.slot = t1.slot
        and t1.state in (100, 102, 103, 104)
        <if test="filmsId != null and filmsId != ''">
            and t1.films_id like CONCAT('%', #{filmsId}, '%')
        </if>
        <if test="flowCardId != null and flowCardId != ''">
            and t1.flow_card_id like CONCAT('%', #{flowCardId}, '%')
        </if>
        <if test="engineerId != null and engineerId != ''">
            and t1.engineer_id like CONCAT('%', #{engineerId}, '%')
        </if>
        <if test="glassId != null and glassId != ''">
            and t1.glass_id like CONCAT('%', #{glassId}, '%')
        </if>
        <if test="thickness != -1">
            and t1.thickness = #{thickness}
        </if>
        order by t.slot
    </select>
</mapper>
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/job/Downpush.java
@@ -17,6 +17,7 @@
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.tools.DateUtil;
import com.mes.tools.WebSocketServer;
import com.mes.tools.WebSocketUtils;
import com.mes.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
@@ -25,6 +26,7 @@
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
@@ -47,6 +49,8 @@
    private DownGlassTaskService downGlassTaskService;
    @Autowired
    private GlassInfoService glassInfoService;
    @Resource
    private WebSocketUtils webSocketUtils;
    @Value("${mes.scan.ip}")
    private String scanIp;
@@ -65,15 +69,8 @@
        List<DownWorkstation> data = downWorkstationService.list();
        jsonObject.append("params", data);
        log.info(jsonObject.toString());
        ArrayList<WebSocketServer> sendwServer = WebSocketServer.sessionMap.get("unloadglass");
        if (sendwServer != null) {
            for (WebSocketServer webserver : sendwServer) {
                if (webserver != null && webserver.session.isOpen()) {
                    log.info("已发送");
                    webserver.sendMessage(jsonObject.toString());
                }
            }
        }
        webSocketUtils.sendToWeb("unloadglass", jsonObject);
    }
    @Scheduled(fixedDelay = 1000)
@@ -83,14 +80,7 @@
        List<Map<String, Object>> glassinfodata = downWorkstationService.getTotalGlassDimensionsByWorkstation(1, 3);
        jsonObject2.append("glassinfo", glassinfodata);
        log.info(jsonObject2.toString());
        ArrayList<WebSocketServer> sendwServer2 = WebSocketServer.sessionMap.get("unloadglass2");
        if (sendwServer2 != null) {
            for (WebSocketServer webserver : sendwServer2) {
                if (webserver != null && webserver.session.isOpen()) {
                    webserver.sendMessage(jsonObject2.toString());
                }
            }
        }
        webSocketUtils.sendToWeb("unloadglass2", jsonObject2);
    }
    @Scheduled(fixedDelay = 1000)
@@ -100,14 +90,7 @@
        List<Map<String, Object>> glassinfodata2 = downWorkstationService.getTotalGlassDimensionsByWorkstation(4, 6);
        jsonObject3.append("glassinfo2", glassinfodata2);
        log.info(jsonObject3.toString());
        ArrayList<WebSocketServer> sendwServer3 = WebSocketServer.sessionMap.get("unloadglass3");
        if (sendwServer3 != null) {
            for (WebSocketServer webserver : sendwServer3) {
                if (webserver != null && webserver.session.isOpen()) {
                    webserver.sendMessage(jsonObject3.toString());
                }
            }
        }
        webSocketUtils.sendToWeb("unloadglass3", jsonObject3);
    }
    @Scheduled(fixedDelay = 2000)
@@ -117,14 +100,7 @@
        List<Map<String, Object>> list = downStorageCageService.selectDownStorageCages();
        jsonObject4.append("params2", list);
        log.info(jsonObject4.toString());
        ArrayList<WebSocketServer> sendwServer4 = WebSocketServer.sessionMap.get("downcache");
        if (sendwServer4 != null) {
            for (WebSocketServer webserver : sendwServer4) {
                if (webserver != null && webserver.session.isOpen()) {
                    webserver.sendMessage(jsonObject4.toString());
                }
            }
        }
        webSocketUtils.sendToWeb("downcache", jsonObject4);
    }
    @Scheduled(fixedDelay = 2000)
@@ -170,18 +146,11 @@
                        .lt("task_status", Const.UNLOAD_GLASS_DOWN)
                        .orderByAsc("id")
        );
        if(takeGlass!=null){
        if (takeGlass != null) {
            jsonObject4.append("takeGlass", takeGlass);
        }
        ArrayList<WebSocketServer> sendwServer4 = WebSocketServer.sessionMap.get("unloadglass");
        if (sendwServer4 != null) {
            for (WebSocketServer webserver : sendwServer4) {
                if (webserver != null && webserver.session.isOpen()) {
                    webserver.sendMessage(jsonObject4.toString());
                }
            }
        }
        webSocketUtils.sendToWeb("unloadglass", jsonObject4);
    }
    @Scheduled(fixedDelay = 1000)
@@ -192,16 +161,8 @@
        jsonObject.append("downWorkstation", downWorkstation);
        List<DownGlassTask> downGlassTask = downGlassTaskService.selectOutTaskCache();
        jsonObject.append("downGlassTask", downGlassTask);
        ArrayList<WebSocketServer> sendwServer = WebSocketServer.sessionMap.get("unLoadGlassIsRun");
        if (sendwServer != null) {
            for (WebSocketServer webserver : sendwServer) {
                if (webserver != null) {
                    webserver.sendMessage(jsonObject.toString());
                } else {
                    log.info("unLoadGlassIsRun is closed");
                }
            }
        }
        webSocketUtils.sendToWeb("unLoadGlassIsRun", jsonObject);
    }
    @Scheduled(fixedDelay = Long.MAX_VALUE)
@@ -215,20 +176,14 @@
                log.info("等待扫码中......");
                String glassId = in.readLine();
                log.info("扫描到的玻璃id:{}", glassId);
                List<WebSocketServer> sendwServer = WebSocketServer.sessionMap.get("unloadglass");
                if (CollectionUtils.isNotEmpty(sendwServer)) {
                    //按照玻璃id获取玻璃信息返回给前端界面,具体需要哪些数据待确认
                    GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
                            .eq(GlassInfo::getGlassId, glassId).last("limit 1"));
                    if (null == glassInfo) {
                        log.info("按照玻璃id:{},无法找到玻璃信息", glassId);
                    } else {
                        for (WebSocketServer webserver : sendwServer) {
                                jsonObject.append("scanGlass", glassInfo);
                                webserver.sendMessage(jsonObject.toString());
                        }
                    }
                //按照玻璃id获取玻璃信息返回给前端界面,具体需要哪些数据待确认
                GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
                        .eq(GlassInfo::getGlassId, glassId).last("limit 1"));
                if (null == glassInfo) {
                    log.info("按照玻璃id:{},无法找到玻璃信息", glassId);
                    return;
                }
                webSocketUtils.sendToWeb("scanGlass", glassInfo);
            } catch (Exception exception) {
                log.info("读取异常,原因为{}", exception.getMessage());
            }
hangzhoumesParent/moduleService/hollowGlassModule/src/main/java/com/mes/hollow/controller/HollowBigStorageCageDetailsController.java
@@ -3,6 +3,8 @@
import com.mes.hollow.entity.HollowBigStorageCageDetails;
import com.mes.hollow.entity.dto.HollowBigStorageAndDetailsDTO;
import com.mes.hollow.entity.request.HollowBigCageDetailsRequest;
import com.mes.hollow.entity.vo.HollowBigCageDetailsVO;
import com.mes.hollow.service.HollowBigStorageCageDetailsService;
import com.mes.utils.Result;
import io.swagger.annotations.Api;
@@ -54,5 +56,10 @@
        return Result.build(200, "启用/禁用成功", 1);
    }
    @ApiOperation("(列表)按列表照查询条件(设备id、流程卡、膜系)获取设备对应的笼子玻璃信息")
    @PostMapping("/queryVerticalSheetCageDetailsList")
    public Result<List<HollowBigCageDetailsVO>> queryVerticalSheetCageDetailsList(@RequestBody HollowBigCageDetailsRequest request) {
        return Result.build(200, "查询成功", hollowBigStorageCageDetailsService.queryVerticalSheetCageDetailsList(request));
    }
}
hangzhoumesParent/moduleService/hollowGlassModule/src/main/java/com/mes/hollow/entity/request/HollowBigCageDetailsRequest.java
New file
@@ -0,0 +1,52 @@
package com.mes.hollow.entity.request;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mes.base.entity.PageRequest;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
 * @Author : zhoush
 * @Date: 2025/9/4 17:04
 * @Description:
 */
@Data
public class HollowBigCageDetailsRequest extends PageRequest {
    @ApiModelProperty(value = "设备id", position = 1)
    private Integer deviceId;
    @ApiModelProperty(value = "格子号", position = 2)
    private Integer slot;
    @ApiModelProperty(value = "流程卡", position = 3)
    private String flowCardId;
    @ApiModelProperty(value = "膜系", position = 4)
    private String filmsId;
    @ApiModelProperty(value = "厚度", position = 5)
    private int thickness;
    @ApiModelProperty(value = "钢化版图id", position = 6)
    private String engineerId;
    @ApiModelProperty(value = "玻璃id", position = 7)
    private String glassId;
    @ApiModelProperty(value = "玻璃报工状态:8破损 9拿走  è°ƒç”¨æ›´æ–°çŠ¶æ€/破损拿走接口必填", position = 8)
    private String state;
    @ApiModelProperty(value = "开始时间")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date startTime;
    @ApiModelProperty(value = "结束时间")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date endTime;
}
hangzhoumesParent/moduleService/hollowGlassModule/src/main/java/com/mes/hollow/entity/vo/HollowBigCageDetailsVO.java
New file
@@ -0,0 +1,110 @@
package com.mes.hollow.entity.vo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.mes.hollow.entity.HollowBigStorageCage;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
 * @Author : zhoush
 * @Date: 2025/9/4 17:02
 * @Description:
 */
@Data
public class HollowBigCageDetailsVO extends HollowBigStorageCage {
    @ApiModelProperty(value = "大理片笼详情表主键 ID", position = 1)
    @TableId(value = "id", type = IdType.AUTO)
    private Long detailId;
    @ApiModelProperty(value = "设备 ID", position = 2)
    private Integer detailDeviceId;
    @ApiModelProperty(value = "栅格号", position = 3)
    private Integer detailSlot;
    @ApiModelProperty(value = "玻璃 ID", position = 4)
    private String glassId;
    @ApiModelProperty(value = "小片在格子内的顺序", position = 5)
    private Integer sequence;
    @ApiModelProperty(value = "流程卡号", position = 6)
    private String flowCardId;
    @ApiModelProperty(value = "流程卡落架编码", position = 7)
    private String flowCardSequence;
    @ApiModelProperty(value = "玻璃类型", position = 8)
    private Integer glassType;
    @ApiModelProperty(value = "玻璃宽度(单位:mm)", position = 9)
    private Double width;
    @ApiModelProperty(value = "玻璃高度(单位:mm)", position = 10)
    private Double height;
    @ApiModelProperty(value = "玻璃厚度(单位:mm)", position = 11)
    private Double thickness;
    @ApiModelProperty(value = "钢化版图 ID", position = 12)
    private Integer temperingLayoutId;
    @ApiModelProperty(value = "钢化版图片序号", position = 13)
    private Integer temperingFeedSequence;
    @ApiModelProperty(value = "X åæ ‡", position = 14)
    private Integer xCoordinate;
    @ApiModelProperty(value = "Y åæ ‡", position = 15)
    private Integer yCoordinate;
    @ApiModelProperty(value = "玻璃状态", position = 16)
    private Integer state;
    @ApiModelProperty(value = "玻璃间隙", position = 17)
    private Integer gap;
    @ApiModelProperty(value = "工程号 ID", position = 18)
    private String engineerId;
    @ApiModelProperty(value = "层号", position = 19)
    private Integer totalLayer;
    @ApiModelProperty(value = "层号", position = 20)
    private Integer layer;
    @ApiModelProperty(value = "创建时间", position = 21)
    private Date createTime;
    @ApiModelProperty(value = "更新时间", position = 22)
    private Date updateTime;
    @ApiModelProperty(value = "膜系 ID", position = 23)
    private String filmsId;
    @ApiModelProperty(value = "是否旋转(角度,单位:度)", position = 24)
    private Integer angle;
    @ApiModelProperty(value = "是否已钢化", position = 25)
    private Integer isTemp;
    @ApiModelProperty(value = "中空顺序", position = 26)
    private Integer hollowSequence;
    @ApiModelProperty(value = "是否配对", position = 27)
    private Integer isPair;
    @ApiModelProperty(value = "组号", position = 28)
    private Integer virtualSlot;
    @ApiModelProperty(value = "组序", position = 29)
    private Integer slotSequence;
    @ApiModelProperty(value = "落架顺序", position = 30)
    private Integer shelfOrder;
}
hangzhoumesParent/moduleService/hollowGlassModule/src/main/java/com/mes/hollow/mapper/HollowBigStorageCageDetailsMapper.java
@@ -7,6 +7,8 @@
import com.mes.hollow.entity.dto.FlowCardGlassInfoDTO;
import com.mes.hollow.entity.dto.FlowCardVirtualSlotDTO;
import com.mes.hollow.entity.dto.UpdateHollowBigStorageCageDTO;
import com.mes.hollow.entity.request.HollowBigCageDetailsRequest;
import com.mes.hollow.entity.vo.HollowBigCageDetailsVO;
import com.mes.hollow.entity.vo.HollowBigStorageDetailsQueryVO;
import org.apache.ibatis.annotations.Param;
@@ -47,5 +49,7 @@
     * @return
     */
    List<FlowCardGlassInfoDTO> queryHollowAllFlowCard(HollowBigStorageDetailsQueryVO query);
    List<HollowBigCageDetailsVO> queryVerticalSheetCageDetailsList(HollowBigCageDetailsRequest request);
}
hangzhoumesParent/moduleService/hollowGlassModule/src/main/java/com/mes/hollow/service/HollowBigStorageCageDetailsService.java
@@ -4,7 +4,9 @@
import com.mes.base.entity.vo.BigStorageVO;
import com.mes.hollow.entity.HollowBigStorageCageDetails;
import com.mes.hollow.entity.dto.*;
import com.mes.hollow.entity.request.HollowBigCageDetailsRequest;
import com.mes.hollow.entity.vo.HollowAllFlowCardVO;
import com.mes.hollow.entity.vo.HollowBigCageDetailsVO;
import com.mes.hollow.entity.vo.HollowBigStorageDetailsQueryVO;
import java.util.List;
@@ -70,5 +72,7 @@
    List<FlowCardVirtualSlotDTO> queryFlowCardIdsAndLayer();
    List<FlowCardGlassInfoDTO> queryHollowAllFlowCard(HollowBigStorageDetailsQueryVO query);
    List<HollowBigCageDetailsVO> queryVerticalSheetCageDetailsList(HollowBigCageDetailsRequest request);
}
hangzhoumesParent/moduleService/hollowGlassModule/src/main/java/com/mes/hollow/service/impl/HollowBigStorageCageDetailsServiceImpl.java
@@ -11,6 +11,8 @@
import com.mes.hollow.entity.HollowBigStorageCageDetails;
import com.mes.hollow.entity.HollowGlassRelationInfo;
import com.mes.hollow.entity.dto.*;
import com.mes.hollow.entity.request.HollowBigCageDetailsRequest;
import com.mes.hollow.entity.vo.HollowBigCageDetailsVO;
import com.mes.hollow.entity.vo.HollowBigStorageDetailsQueryVO;
import com.mes.hollow.mapper.HollowBigStorageCageDetailsMapper;
import com.mes.hollow.service.HollowBigStorageCageDetailsService;
@@ -150,6 +152,11 @@
        return baseMapper.queryHollowAllFlowCard(query);
    }
    @Override
    public List<HollowBigCageDetailsVO> queryVerticalSheetCageDetailsList(HollowBigCageDetailsRequest request) {
        return baseMapper.queryVerticalSheetCageDetailsList(request);
    }
    private List<HollowBigStorageAndDetailsDTO> hollowBigStorageCageDetailsChild(String glassId, Integer deviceId, Integer slot, int state) {
        //将对应格子号的玻璃id置为101
        this.update(new LambdaUpdateWrapper<HollowBigStorageCageDetails>()
hangzhoumesParent/moduleService/hollowGlassModule/src/main/java/com/mes/job/OpcPlcStorageCageHollowTask.java
@@ -117,6 +117,8 @@
    private static final String ALARM_TYPE = "中空大理片";
    private static final String ALARM_CODE_SIZE = "sizeSame";
    private static final String ALARM_CODE_ID = "idSame";
    private static final String ALARM_CODE_SLOT = "slotLess";
    private static final String ALARM_CODE_OVER = "overSize";
    /**
     * ç›´é€šæ ¼å­
@@ -245,6 +247,13 @@
                    .ge(HollowBigStorageCage::getMaxThickness, entry.getKey()));
            if (count < entry.getValue()) {
                log.info("笼内格子剩余数量不足,结束本次进片");
                ProductAlarmInfo alarmInfo = new ProductAlarmInfo();
                alarmInfo.setState(Const.LOAD_RAW_GLASS_NEW);
                alarmInfo.setAlarmModule(ALARM_MODULE);
                alarmInfo.setAlarmType(ALARM_TYPE);
                alarmInfo.setAlarmCode(ALARM_CODE_SLOT);
                alarmInfo.setAlarmMessage(count + "");
                productAlarmInfoService.save(alarmInfo);
                //向plc发送报警:笼内格子剩余数量不足
                s7DataZKDLPOne = new S7DataZKDLPOne();
                s7DataZKDLPOne.setAlramSignal(16);
@@ -536,7 +545,7 @@
                    });
                }
                List<HollowGlassQueueInfo> infoList = unFinishHollowQueueList.stream().filter(e -> !(e.getSlot() > 500 && e.getSlot() < 900 && e.getIsPair() != 1)).collect(Collectors.toList());
                List<HollowGlassQueueInfo> infoList = unFinishHollowQueueList.stream().filter(e -> !(e.getSlot() >= 500 && e.getSlot() < 900 && e.getIsPair() != 1)).collect(Collectors.toList());
                log.info("有正在出片的中空任务");
                Integer isPair = infoList.get(0).getIsPair();
                hollowOutGlassByIsPair(infoList, hollowGlassOutRelationInfo.getCell(), isPair, hollowGlassOutRelationInfo.getTotalLayer(), hollowGlassOutRelationInfo.getIsForce());
@@ -920,6 +929,10 @@
            return;
        }
        if (StringUtils.isNotBlank(s7DataZKDLPOne.getId1())) {
            log.info("当前存在进片任务,结束");
            return;
        }
        if (StringUtils.isNotBlank(s7DataZKDLPOne.getId1())) {
            log.info("当前存在进片任务请求,结束本次大笼子调度");
            return;
        }
@@ -935,15 +948,19 @@
        if (count > 0) {
            return;
        }
        List<HollowBigStorageCageDetails> list = hollowBigStorageCageDetailsService.list(new LambdaQueryWrapper<HollowBigStorageCageDetails>()
                .eq(HollowBigStorageCageDetails::getState, Const.GLASS_STATE_IN)
//                .in(HollowBigStorageCageDetails::getDeviceId, 6)
                .in(HollowBigStorageCageDetails::getGlassId, glassIdList));
        log.info("获取调度任务列表:{}", list);
        if (CollectionUtil.isEmpty(list)) {
        HollowBigStorageCageDetails details = null;
        for (String glassId : glassIdList) {
            details = hollowBigStorageCageDetailsService.getOne(new LambdaQueryWrapper<HollowBigStorageCageDetails>()
                    .eq(HollowBigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                    .eq(HollowBigStorageCageDetails::getGlassId, glassId).last("limit 1"));
            log.info("获取调度任务:{}", details);
            if (details != null) {
                break;
            }
        }
        if (details == null) {
            return;
        }
        HollowBigStorageCageDetails details = list.get(0);
        log.info("获取需要调度的单条任务:{}", details);
        //生成进进片大车任务
        hollowBigStorageCageDetailsService.update(new LambdaUpdateWrapper<HollowBigStorageCageDetails>()
@@ -1095,6 +1112,13 @@
                    S7DataZKDLPOne s7DataZKDLPOne = new S7DataZKDLPOne();
                    s7DataZKDLPOne.setAlramSignal(16);
                    s7SerializerZKDLPOne.write(s7DataZKDLPOne);
                    ProductAlarmInfo alarmInfo = new ProductAlarmInfo();
                    alarmInfo.setState(Const.LOAD_RAW_GLASS_NEW);
                    alarmInfo.setAlarmModule(ALARM_MODULE);
                    alarmInfo.setAlarmType(ALARM_TYPE);
                    alarmInfo.setAlarmCode(ALARM_CODE_SLOT);
                    alarmInfo.setAlarmMessage("");
                    productAlarmInfoService.save(alarmInfo);
                    Assert.isFalse(storageCage == null, "任务调度没有多余格子,结束调度任务");
                }
hangzhoumesParent/moduleService/hollowGlassModule/src/main/resources/mapper/HollowBigStorageCageDetailsMapper.xml
@@ -207,8 +207,8 @@
    <select id="queryHollowbigStorageCageDetail" resultType="com.mes.base.entity.vo.BigStorageVO">
        select hbsc.device_id, hbsc.slot, count(hbscd.glass_id) as count
        from hollow_big_storage_cage hbsc
                 left join hollow_big_storage_cage_details hbscd
                           on hbsc.slot = hbscd.slot and hbscd.state in (100, 102, 103, 104)
            left join hollow_big_storage_cage_details hbscd
        on hbsc.slot = hbscd.slot and hbscd.state in (100, 102, 103, 104)
        group by hbsc.device_id, hbsc.slot
        order by hbsc.device_id, hbsc.slot
    </select>
@@ -269,7 +269,7 @@
            AND films_id LIKE CONCAT( '%', #{filmsId}, '%')
        </if>
        <if test="thickness != 0">
          AND thickness = #{thickness}
            AND thickness = #{thickness}
        </if>
        ),
        hollow_details_temp AS (
@@ -293,7 +293,7 @@
            AND films_id LIKE CONCAT( '%', #{filmsId}, '%')
        </if>
        <if test="thickness != 0">
          AND thickness = #{thickness}
            AND thickness = #{thickness}
        </if>
        ),
        hollow_through_temp AS ( SELECT flow_card_id, MIN( hollow_sequence ) AS hollow_sequence, MAX( total_layer ) AS
@@ -416,6 +416,32 @@
        ORDER BY
        t.flow_card_id
    </select>
    <select id="queryVerticalSheetCageDetailsList"
            resultType="com.mes.hollow.entity.vo.HollowBigCageDetailsVO">
        SELECT t.id,t.device_id,t.slot,t.remain_width ,t.enable_state,t1.virtual_slot,total_layer,t1.engineer_id,
        t1.id as detail_id,t1.device_id as detail_device_id ,t1.slot as
        detail_slot,t1.engineer_id,t1.glass_id,t1.tempering_layout_id,t1.tempering_feed_sequence,
        t1.flow_card_id,t1.layer,t1.width,t1.height,t1.thickness,t1.films_id
        FROM hollow_big_storage_cage t
        left join hollow_big_storage_cage_details t1 on t.slot = t1.slot
        and t1.state in (100, 102, 103, 104)
        <if test="filmsId != null and filmsId != ''">
            and t1.films_id like CONCAT('%', #{filmsId}, '%')
        </if>
        <if test="flowCardId != null and flowCardId != ''">
            and t1.flow_card_id like CONCAT('%', #{flowCardId}, '%')
        </if>
        <if test="engineerId != null and engineerId != ''">
            and t1.engineer_id like CONCAT('%', #{engineerId}, '%')
        </if>
        <if test="glassId != null and glassId != ''">
            and t1.glass_id like CONCAT('%', #{glassId}, '%')
        </if>
        <if test="thickness != -1">
            and t1.thickness = #{thickness}
        </if>
        order by t.slot
    </select>
</mapper>