UI-Project/src/views/Identify/identify.vue
@@ -1,8 +1,9 @@
<template>
  <div style="height: 500px;">
    <div style="display: flex;">
      <el-input v-model="inputValue" style="margin-left: 15px;margin-top: 10px;width: 240px" :placeholder="$t('order.projectnumber')" @blur="handleBlur"/>
      <el-pagination
      <el-input v-model="engineerId" style="margin-left: 15px;margin-top: 10px;width: 240px" :placeholder="$t('order.projectnumber')"/>
          <el-button type="primary" style="margin-left: 10px;margin-top: 10px;" @click="sethistorical()">{{$t('reportmanage.inquire')}}</el-button>
          <el-pagination
          v-model:current-page="currentPage"
          :page-size="pageSize"
          :size="size"
@@ -12,36 +13,69 @@
          @current-change="handleCurrentChange"
          style="margin-top: 10px;"
      />
    </div>
    <el-card style="flex: 1;margin-left: 10px;margin-top: 10px;margin-right: 10px;height: 800px;" v-loading="loading">
       <el-select
        v-model="allDamagePatternSequence"
        :placeholder="$t('workOrder.cway')"
        clearable
        style="width: 140px; margin-left: 35%; margin-top: 10px;"
      >
        <el-option
          v-for="item in optionsb"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
      <!-- 修改一键破损按钮,添加禁用状态 -->
      <el-button
        type="warning"
        style="margin-left: 10px; margin-top: 10px;"
        @click="handleAllDamage"
        :disabled="!allDamagePatternSequence"
      >
        {{$t('order.dilapidation')}}
      </el-button>
      </div>
    <el-card style="flex: 1;margin-left: 10px;margin-top: 10px;margin-right: 10px;height: 800px;">
     <!-- <el-button @click="handleAllDamage" style="margin-left: 90%;margin-top: -20px;margin-bottom: 5px;">{{$t('order.dilapidation')}}</el-button> -->
      <el-scrollbar height="750px" width="1400px" style="background-color: #e9e9eb;">
  <div style="position: relative;">  
    <div
      v-for="(rect, index) in adjustedRects"  
      :key="rect.glass_id"
      :key="rect.glassId"
      class="rect"  
      @click="showDialog(rect.glass_id)"
      @click="showDialog(rect.glassId)"
      :style="{ position: 'absolute', 
      top: `${rect.y_axis}px`, left: `${rect.x_axis}px`, width: `${rect.width}px`, height: `${rect.height}px`,
      backgroundColor: rect.isActive ? '#ADFF2F' : getRectColor(rect.glass_state)
      top: `${rect.yaxisa}px`, left: `${rect.xaxisa}px`, width: `${rect.width}px`, height: `${rect.height}px`,
      backgroundColor: rect.isActive ? '#ADFF2F' : getRectColor(rect.state)
       }"  
    >
     <!-- 箭头 -->
     <!-- <div id="arrow"></div>
     <div id="line"></div>   -->
     <div  class="centered-text">
    <div>{{ rect.glass_id }}</div>
    <div>{{ rect.widtha }}*{{ rect.heighta }}</div>
    <div style="font-size: 20px;font-weight: bold;">{{ rect.glassId }}</div>
    <div style="font-size: 20px;font-weight: bold;">{{ rect.flowCardId }}</div>
    <div style="font-size: 30px;font-weight: bold;">{{ rect.widtha }}*{{ rect.heighta }}</div>
  </div>
  </div> 
   </div>
      </el-scrollbar>
      <el-dialog v-model="blind" top="30vh" width="15%" style="text-align: center;" @close="handleDialogClose">
        <el-button :disabled="currentGlassRect?.glass_state === 8 || currentGlassRect?.glass_state === 9" type="warning"
        <el-select
            :placeholder="$t('workOrder.cway')"
             clearable
             style="width: 140px;margin-left: 10px;margin-bottom: 10px;"
             v-model="patternSequence">
               <el-option
                v-for="item in optionsb"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
          </el-select>
        <el-button :disabled="!patternSequence || currentGlassRect?.state === 8 || currentGlassRect?.state === 9" type="warning"
                   plain :icon="Delete" @click="handleDamage(currentGlassId)" style="width: 140px;margin-left: 10px;">
          {{ $t('order.dilapidation') }}
        </el-button>
        <el-button :disabled="currentGlassRect?.glass_state === 9 || currentGlassRect?.glass_state === 8" type="danger"
        <el-button :disabled="!patternSequence || currentGlassRect?.state === 9 || currentGlassRect?.state === 8" type="danger"
                   plain @click="handleManualTake(currentGlassId)" style="width: 140px;margin-top: 10px;">
          <el-icon class="el-icon--right">
            <Upload/>
@@ -53,7 +87,7 @@
  </div>
</template>
<script setup lang="ts">
import {ElMessage} from 'element-plus'
import {avatarEmits,  ElMessage, ElMessageBox } from 'element-plus'
import {computed, onMounted, onUnmounted, ref} from 'vue';
import request from "@/utils/request"
import {host, WebSocketHost} from '@/utils/constants'
@@ -61,11 +95,9 @@
const {t} = useI18n()
let language = ref(localStorage.getItem('lang') || 'zh')
const blind = ref(false)
const olWidth = ref();
const olHeight = ref();
const glass_id = ref();
const inputValue = ref('');
const currentGlassId = ref(null); // 存储当前点击矩形的 glass_id
const engineerId = ref();
const patternSequence = ref();
const currentGlassId = ref(null);
const currentstate = ref(null);
const adjustedRects = ref([]);
const raw = ref([]);
@@ -73,18 +105,21 @@
const totalPages = ref(0);
const pageSize = ref(1);
const currentPage = ref('');
const realwidth = ref('');
const realheight = ref('');
const allDamagePatternSequence = ref();
const disabled = false;
const size = 'small';
const rawData = ref([]);
// 显示对话框并设置当前 glass_id
// 显示对话框并设置当前 glassId
const currentGlassRect = computed(() => {
  return adjustedRects.value.find(rect => rect.glass_id === currentGlassId.value);
  return adjustedRects.value.find(rect => rect.glassId === currentGlassId.value);
}); 
function showDialog(glassId: number) {
  currentGlassId.value = glassId;  
  blind.value = true;  
  adjustedRects.value = adjustedRects.value.map(rect =>  
  rect.glass_id === glassId ? { ...rect, isActive: true } : rect
  rect.glassId === glassId ? { ...rect, isActive: true } : rect
  ); 
}  
const handleDialogClose = () => {  
@@ -93,22 +128,68 @@
    isActive: false  
  }));  
}
// 一键破损所有玻璃
const handleAllDamage = async () => {
   if (!allDamagePatternSequence.value) {
    ElMessage.warning(t('workOrder.cway')); // 提示需要选择线路
    return;
  }
  try {
      const confirmResult = await ElMessageBox.confirm(
      t('order.dilapidationWhether'),
      t('workOrder.prompt'),
      {
        confirmButtonText: t('workOrder.yes'),
        cancelButtonText: t('workOrder.cancel'),
        type: 'warning',
      }
    );
    // 筛选出state不是8和9的玻璃ID
    const glassIdList = adjustedRects.value
      .filter(rect => rect.state !== 8 && rect.state !== 9)
      .map(rect => rect.glassId);
    if (glassIdList.length === 0) {
      ElMessage.warning(t('order.noGlassToDamage')); // 没有可破损的玻璃
      return;
    }
    const response = await request.post('/cacheGlass/taskCache/identControlsByPatternSequence', {
      glassIdList: glassIdList,
      state: 8,
      line: allDamagePatternSequence.value,
      workingProcedure: '切割',
      remark: '掰片'
    });
    if (response.code === 200) {
      ElMessage.success(response.message);
      // 更新所有玻璃状态
      glassIdList.forEach(glassId => {
        updateRectStatus(glassId, 8);
      });
      allDamagePatternSequence.value = '';
    } else {
      ElMessage.error(response.msg);
    }
  } catch (error) {
    console.error(error);
    ElMessage.error(t(''));
  }
};
// 破损
const handleDamage = async () => {
  try  {
  const response = await request.post('/cacheGlass/taskCache/identControls', {
    glassId: currentGlassId.value,
    state: 8,
    line: 1001,
    workingProcedure: '切割',
      glassId: currentGlassId.value,
      state: 8,
      line: patternSequence.value,
      remark: '掰片',
      workingProcedure: '切割',
    })
    if (response.code == 200) {
      ElMessage.success(response.message);
      blind.value = false;
      patternSequence.value = ''
      updateRectStatus(currentGlassId.value, 8); 
      findEngineering()
    } else {
      // 请求失败,显示错误消息
      ElMessage.error(response.msg);
    }
}
@@ -121,16 +202,17 @@
const handleManualTake = async () => {
  try  {
  const response = await request.post('/cacheGlass/taskCache/identControls', {
    glassId: currentGlassId.value,
    state: 9,
    line: 1001,
    workingProcedure: '切割',
      glassId: currentGlassId.value,
      state: 9,
      line: patternSequence.value,
      workingProcedure: '切割',
      remark: '掰片',
    })
    if (response.code == 200) {
      ElMessage.success(response.message);
      blind.value = false;
      patternSequence.value = ''
      updateRectStatus(currentGlassId.value, 9); 
      findEngineering()
  } else {
      ElMessage.error(response.msg);
    }
@@ -139,144 +221,97 @@
    console.error(error);
  }
}
const handleBlur = async () => {
  if (inputValue.value) {
    var url="/cacheGlass/taskCache/cutTerritory?current="+inputValue.value;
const sethistorical = async () => {
    var url="/cacheGlass/taskCache/queryCutDrawingByEngineerId?engineerId="+engineerId.value+ "&patternSequence=" + 1;
    const response = await request.post(url)
    if (response.code === 200) {
      const rawRects = response.data[0];
      const rawRects = response.data.currentCutDrawing;
      rawData.value = response.data;
      totalPages.value = rawData.value.length;
      const scaleFactor =  1621.78/6000;
      const scaleFactory =  750/3300;
      adjustedRects.value = rawRects.map(rect => ({
      totalPages.value = response.data.totalPatternSequence;
      realwidth.value = response.data.upPattenUsage.width;
      realheight.value = response.data.upPattenUsage.height;
      const realx = realwidth.value;
      const realy = realheight.value;
      const scaleFactor =  1621.78/realx;
      const scaleFactory =  750/realy;
      adjustedRects.value = rawRects.map(rect => ({
        ...rect,
        x_axis: (6000 -(rect.x_axis + rect.width)) * scaleFactor,
        y_axis: rect.y_axis * scaleFactory,
        width: rect.width * scaleFactor ,
        widtha: rect.width ,
        heighta: rect.height ,
        height: rect.height * scaleFactory,
        glass_state: rect.glass_state
      }));
      if (webSocket) {
        webSocket.close();
        webSocket = null;
      }
        xaxisa: rect.xaxis * scaleFactor,
        yaxisa: (realy - (rect.yaxis + rect.edgHeight )) * scaleFactory,
        width: rect.edgWidth * scaleFactor,
        widtha: rect.edgWidth,
        heighta: rect.edgHeight ,
        height: rect.edgHeight * scaleFactory,
        state: rect.state
      }));
       currentPage.value = 1;
    }  
  } else{
    connectWebSocket();
  }
};
const findEngineering = async () => {
  if (inputValue.value) {
    var url="/cacheGlass/taskCache/cutTerritory?current="+inputValue.value;
};
const handleCurrentChange = async(val: number) => {
  currentPage.value = val;
  var url="/cacheGlass/taskCache/queryCutDrawingByEngineerId?engineerId="+engineerId.value+ "&patternSequence=" + currentPage.value;
    const response = await request.post(url)
    if (response.code === 200) {
      const rawRects = response.data.currentCutDrawing;
      rawData.value = response.data;
    }
  } else{
  }
};
const handleCurrentChange = (val: number) => {
  currentPage.value = val;
  const page = currentPage.value - 1
      const scaleFactor =  1621.78/6000;
      const scaleFactory =  750/3300;
      adjustedRects.value = rawData.value[page]?.map(rect => ({
      realwidth.value = response.data.upPattenUsage.width;
      realheight.value = response.data.upPattenUsage.height;
      const realx = realwidth.value;
      const realy = realheight.value;
      const scaleFactor =  1621.78/realx;
      const scaleFactory =  750/realy;
      adjustedRects.value = rawRects.map(rect => ({
        ...rect,
        x_axis: (6000 -(rect.x_axis + rect.width)) * scaleFactor,
        y_axis: rect.y_axis * scaleFactory,
        width: rect.width * scaleFactor ,
        widtha: rect.width ,
        heighta: rect.height ,
        height: rect.height * scaleFactory,
        glass_state: rect.glass_state
      }));
        xaxisa: rect.xaxis * scaleFactor,
        yaxisa: (realy - (rect.yaxis + rect.edgHeight )) * scaleFactory,
        width: rect.edgWidth * scaleFactor,
        widtha: rect.edgWidth,
        heighta: rect.edgHeight,
        height: rect.edgHeight * scaleFactory,
        state: rect.state
      }));
    }
};
function getRectColor(state: number): string {
  switch (state) {
    case 0:
      return '#e1f3d8';
    case 100:
      return '#c8c9cc';
    case 110:
      return '#b3e19d';
    case 120:
      return '#f89898';
    case 0:
      return '#7AC5CD';
    case 1:
      return '#95d475';
    case -1:
      return '#99BBFF';
    case 2:
      return 'lightblue';
    case 3:
      return '#eebe77';
    case 4:
      return '#CD6090';
    case 8:
      return '#911005';
    case 9:
      return '#f3d19e';
      return '#4682B4';
    default:
      return '#CDAF95';
  }
}
const optionsb = [
  {
    value: 1,
    label: t('sorter.onesort'),
  },
  {
    value: 2,
    label: t('sorter.twosort'),
  },
]
// 更新矩形状态  
function updateRectStatus(glassId: string, status: number) {  
  adjustedRects.value.forEach(rect => {  
    if (rect.glass_id === glassId) {
      rect.glass_state = status; // 更新矩形的状态
    if (rect.glassId === glassId) {
      rect.state = status; // 更新矩形的状态
    }  
  });  
}
const connectWebSocket = () => {
  if (!webSocket) {
const socketUrl = `ws://${WebSocketHost}:${host}/api/cacheGlass/api/talk/cacheGlass`;
    webSocket = new WebSocket(socketUrl);
    webSocket.onmessage = (event) => {
      const data = JSON.parse(event.data);
      const scaleFactor =  1621.78/6000;
      const scaleFactory =  750/3300;
      if (data.currentCutTerritory && data.currentCutTerritory.length > 0) {
      const newRects = data.currentCutTerritory[0].map(rect => {
        const existingRect = adjustedRects.value.find(r => r.glass_id === rect.glass_id);
        if (existingRect) {
          return {
            ...existingRect,
            x_axis: (6000 - (rect.x_axis + rect.width)) * scaleFactor,
            y_axis: rect.y_axis * scaleFactory,
            width: rect.width * scaleFactor,
            height: rect.height * scaleFactory,
            widtha: rect.width,
            heighta: rect.height,
            glass_state: rect.glass_state,
            // 保持 isActive 状态不变
          };
        } else {
          // 如果不存在,则添加新矩形,默认 isActive 为 false
          return {
            ...rect,
            x_axis: (6000 - (rect.x_axis + rect.width)) * scaleFactor,
            y_axis: rect.y_axis * scaleFactory,
            width: rect.width * scaleFactor,
            height: rect.height * scaleFactory,
            widtha: rect.width,
            heighta: rect.height,
            glass_state: rect.glass_state,
            isActive: false,
            glass_id: rect.glass_id,
          };
        }
      });
      adjustedRects.value = newRects;
     } else if (data.currentCutTerritory == '') {
      adjustedRects.value = [];
     }
    };
  }
};
onMounted(() => {
  // 初始时,如果输入框为空,则连接WebSocket
  if (!inputValue.value) {
    connectWebSocket();
  }
});
onUnmounted(() => {
  if (webSocket) {
    webSocket.close();
  }
});
</script>  
<style scoped>  
.rect {  
@@ -286,7 +321,7 @@
  justify-content: center;  
  align-items: center; 
  height: 100%;
  font-size: small;
  /* font-size: large; */
}
#rect {  
  position: relative; /* 确保箭头可以相对于矩形定位 */