wangfei
10 小时以前 71594bd2dc9201834aa533099e9e49a9b84506cd
UI-Project/src/views/Identify/identify.vue
@@ -1,234 +1,281 @@
<template>
  <el-card style="margin-left: 10px; margin-top: 10px; margin-right: 10px;" v-loading="loading">
  <div style="height: 500px;">
    <div style="display: flex;">
      <div style="margin-left: 400px; font-size: 20px;">工程号:P20240305001 </div>
      <div style="margin-left: 150px; font-size: 20px;">版图编号:1</div>
    </div>
    <svg width="100%" height="690" xmlns="http://www.w3.org/2000/svg" style="margin-top: -40px;">
      <defs>
            <marker id="arrow" markerUnits="strokeWidth" markerWidth="12" markerHeight="12" viewBox="0 0 12 12" refX="6"
                refY="6" orient="auto">
                <path d="M2,2 L10,6 L2,10 L2,2" style="fill: #911005;" />
            </marker>
        </defs>
        <!--  <el-scrollbar height="630px">
      <div id="home-card">
      <div id="home-item" v-for="n in 20" :key="n">
            <div id="box" style="width: 100px;height: 165px;">100*65</div>
            <div id="box" style="width: 107px;height: 150px;">107*60</div>
            <div id="box" style="width: 107px;height: 155px;">109*60</div>
      <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"
          :disabled="disabled"
          layout="prev, pager, next, jumper"
          :total="totalPages"
          @current-change="handleCurrentChange"
          style="margin-top: 10px;"
      />
      </div>
    </div>
  </el-scrollbar> -->
      <g v-for="(rack, index) in racks" :key="index">
        <rect
          :x="rack.x"
          :y="rack.y"
          :width="rack.width"
          :height="rack.height"
          :fill="rack.fillColor"
          :data-index="index"
          class="rack-rect"
          style="stroke:#c8c9cc;stroke-width:3;"
          @click="showRectInfo(rack)"
        />
        <line x1='510' y1='309' x2='260' y2='310' stroke='#911005' stroke-width='2' marker-end='url(#arrow)'>
        </line>
        <line x1='850' y1='309' x2='1100' y2='310' stroke='#911005' stroke-width='2' marker-end='url(#arrow)'>
        </line>
        <line x1='510' y1='409' x2='260' y2='410' stroke='#911005' stroke-width='2' marker-end='url(#arrow)'>
        </line>
        <line x1='1200' y1='650' x2='1200' y2='470' stroke='#911005' stroke-width='2' marker-end='url(#arrow)'>
        </line>
        <text x="370" y="240" dominant-baseline="middle" text-anchor="middle">NG2024030501A-01</text>
        <text x="370" y="260" dominant-baseline="middle" text-anchor="middle">500*300</text>
        <text x="970" y="240" dominant-baseline="middle" text-anchor="middle">NG2024030501A-02</text>
        <text x="970" y="260" dominant-baseline="middle" text-anchor="middle">500*300</text>
        <text x="600" y="500" dominant-baseline="middle" text-anchor="middle">NG2024030501A-03</text>
        <text x="600" y="520" dominant-baseline="middle" text-anchor="middle">800*450</text>
        <text x="1280" y="520" dominant-baseline="middle" text-anchor="middle">NG2024030501A-04</text>
        <text x="1280" y="540" dominant-baseline="middle" text-anchor="middle">400*300</text>
        <g v-for="(item, itemIndex) in rack.items" :key="itemIndex">
          <rect
            :x="calculateItemXPosition(rack, item, itemIndex)"
            :y="calculateItemYPosition(rack, item, itemIndex)"
            :width="item.width"
            :height="item.height"
            :fill="item.fillColor"
          />
        </g>
      </g>
    </svg>
  </el-card>
    <el-card style="flex: 1;margin-left: 10px;margin-top: 10px;margin-right: 10px;height: 800px;">
      <el-scrollbar height="750px" width="1400px" style="background-color: #e9e9eb;">
  <div style="position: relative;">
    <div
      v-for="(rect, index) in adjustedRects"
      :key="rect.glassId"
      class="rect"
      @click="showDialog(rect.glassId)"
      :style="{ position: 'absolute',
      top: `${rect.yaxisa}px`, left: `${rect.xaxisa}px`, width: `${rect.width}px`, height: `${rect.height}px`,
      backgroundColor: rect.isActive ? '#ADFF2F' : getRectColor(rect.state)
       }"
    >
     <div  class="centered-text">
    <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-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="!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/>
          </el-icon>
          {{ $t('order.takeaway') }}
        </el-button>
      </el-dialog>
    </el-card>
  </div>
</template>
<script>
import Swal from 'sweetalert2'
import request from "@/utils/request";
request.get("/TidyUpGlassModule/CurrentCutTerritory").then((res) => {
          if (res.code == 200) {
          console.log(res.data);
          } else {
          ElMessage.warning(res.msg)
          router.push("/login")
          }
          });
export default {
  data() {
    return {
      loading: false,
      racks: [
        {
          x: 70, y: 126, width: 600, height: 240, fillColor: '#93d2f3',
          items: [
            { position: 'top-left', width: 40, height: 30, fillColor: '#ffffff', content: 'NG123456',y: '20'},
            { position: 'bottom-left', width: 40, height: 30, fillColor: '#ffffff', content: 'NG1234567' },
            { position: 'bottom-right', width: 40, height: 30, fillColor: '#ffffff', content: 'NG12345678' }
          ]
        },
        {
          x: 685, y: 126, width: 600, height: 240,  fillColor: '#93d2f3',
          items: [
            { position: 'bottom-left', width: 40, height: 30, fillColor: '#ffffff', content: 'NG123456' },
            { position: 'bottom-right', width: 40, height: 30, fillColor: '#ffffff', content: 'NG123456' },
            { position: 'top-right', width: 40, height: 30, fillColor: '#ffffff', content: 'NG1234567' }
          ]
        },
        {
          x: 70, y: 380, width: 1100, height: 260, fillColor: '#81b337',
          items: [
            { position: 'top-left', width: 40, height: 30, fillColor: '#ffffff', content: 'NG123456' },
            { position: 'bottom-right', width: 40, height: 30, fillColor: '#ffffff', content: 'NG123456' },
            { position: 'top-right', width: 40, height: 30, fillColor: '#ffffff', content: 'NG1234567' }
          ]
        },
        {
          x: 1185, y: 380, width: 200, height: 300,fillColor: '#81b337',
          items: [
            { position: 'bottom-right', width: 40, height: 30, fillColor: '#ffffff', content: 'NG123456' },
            { position: 'top-right',width: 40, height: 30, fillColor: '#ffffff', content: 'NG123456' },
            { position: 'top-left', width: 40, height: 30, fillColor: '#ffffff', content: 'NG1234567' },
          ]
        }
        // Add more racks and items here as needed
      ],
    };
  },
  methods: {
    calculateItemXPosition(rack, item, index) {
      if (item.position === 'top-right' || item.position === 'bottom-right') {
        return Math.min(rack.x + rack.width - item.width, rack.x + rack.width);
      } else {
        return rack.x;
      }
    },
    calculateItemYPosition(rack, item, index) {
      if (item.position === 'bottom-left' || item.position === 'bottom-right') {
        return Math.min(rack.y + rack.height - item.height, rack.y + rack.height);
      } else {
        return rack.y;
      }
    },
    showCustomAlert(content) {
      Swal.fire({
    // type: 'warning', // 弹框类型
    title: '该片玻璃状态', //标题
    // text: "注销后将无法恢复,请谨慎操作!", //显示内容
    confirmButtonColor: '#3085d6',// 确定按钮的 颜色
    confirmButtonText: '人工拿走',// 确定按钮的 文字
    showCancelButton: true, // 是否显示取消按钮
    cancelButtonColor: '#d33', // 取消按钮的 颜色
    cancelButtonText: "破损", // 取消按钮的 文字
    // focusCancel: true, // 是否聚焦 取消按钮
    reverseButtons: true  // 是否 反转 两个按钮的位置 默认是  左边 确定  右边 取消
}).then((isConfirm) => {
    try {
        //判断 是否 点击的 确定按钮
        if (isConfirm.value) {
            Swal.fire("人工拿走", "点击了人工拿走", "success");
        }
        else {
            Swal.fire("破损", "点击了破损", "error");
        }
    } catch (e) {
        alert(e);
<script setup lang="ts">
import {ElMessage} from 'element-plus'
import {computed, onMounted, onUnmounted, ref} from 'vue';
import request from "@/utils/request"
import {host, WebSocketHost} from '@/utils/constants'
import {useI18n} from 'vue-i18n'
const {t} = useI18n()
let language = ref(localStorage.getItem('lang') || 'zh')
const blind = ref(false)
const engineerId = ref();
const patternSequence = ref();
const currentGlassId = ref(null);
const currentstate = ref(null);
const adjustedRects = ref([]);
const raw = ref([]);
let webSocket: WebSocket | null = null;
const totalPages = ref(0);
const pageSize = ref(1);
const currentPage = ref('');
const realwidth = ref('');
const realheight = ref('');
const disabled = false;
const size = 'small';
const rawData = ref([]);
// 显示对话框并设置当前 glassId
const currentGlassRect = computed(() => {
  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.glassId === glassId ? { ...rect, isActive: true } : rect
  );
}
const handleDialogClose = () => {
  adjustedRects.value = adjustedRects.value.map(rect => ({
    ...rect,
    isActive: false
  }));
}
// 破损
const handleDamage = async () => {
  try  {
  const response = await request.post('/cacheGlass/taskCache/identControls', {
      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);
    } else {
      ElMessage.error(response.msg);
    }
});
    },
    showRectInfo(rectInfo) {
      const contents = rectInfo.items.map(item => item.content).join(', ');
      this.$nextTick(() => {
        this.showCustomAlert(contents);
      });
    },
}
catch (error) {
    // 处理错误
    console.error(error);
  }
}
 // 人工拿走
const handleManualTake = async () => {
  try  {
  const response = await request.post('/cacheGlass/taskCache/identControls', {
      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);
  } else {
      ElMessage.error(response.msg);
    }
}
catch (error) {
    console.error(error);
  }
}
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.currentCutDrawing;
      rawData.value = response.data;
      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,
        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;
    }
};
</script>
<style scoped>
.glass-rack {
  width: 100%;
  height: 80vh;
}
.rack-rect:hover {
  cursor: pointer;
}
.custom-popover-class {
  background-color: lightgrey;
  color: black;
  border: 1px solid black;
}
#home-card {
    width: 100%;
    overflow: hidden;
    padding: 10px 0px;
    display: flex;
    flex-wrap: wrap;
    #home-item {
      border-style: solid;
      border-width: 1px;
      border-color: #E4E4E4;
      width: calc(34% - 20px);
      padding: 20px 0px 20px 20px;
      margin-right: 10px;
      margin-bottom: 10px;
      display: flex;
      justify-content: center;
      /* align-items: center; */
      background: #fff;
      #home-img {
        display: inline-block;
        width: 160px;
        height: 60px;
        margin: 0;
        padding: 0;
      }
      #home-right {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: flex-start;
        margin-left: 10px;
        #home-num {
          font-size: 40px;
          margin: 5px 0;
        }
      }
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;
      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,
        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 '#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 '#4682B4';
    default:
      return '#CDAF95';
  }
</style>
}
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.glassId === glassId) {
      rect.state = status; // 更新矩形的状态
    }
  });
}
</script>
<style scoped>
.rect {
  border: 1px solid black; /* 设置矩形的边框 */
}
.centered-text {
  justify-content: center;
  align-items: center;
  height: 100%;
  /* font-size: large; */
}
#rect {
  position: relative; /* 确保箭头可以相对于矩形定位 */
}
#arrow {
  position: absolute;
  top: 70%; /* 箭头位于矩形中间 */
  left: 200px; /* 箭头在矩形左侧一些距离 */
  transform: translateY(-50%); /* 垂直居中 */
  width: 0;
  height: 0;
  border-top: 10px solid transparent; /* 上边框 */
  border-bottom: 10px solid transparent; /* 下边框 */
  border-right: 20px solid #911005; /* 右边框,形成箭头 */
}
#line {
  position: absolute;
  top: 70%; /* 直线位于矩形中间 */
  left: 210px; /* 直线在箭头右侧一些距离 */
  transform: translateY(-50%); /* 垂直居中 */
  height: 2px; /* 直线的高度 */
  width: 240px; /* 直线的长度,根据需要调整 */
  background-color: #911005; /* 直线的颜色 */
}
</style>