pengwei
2025-04-27 366612bd8e8b88d02a98edf508f96d7add23ff9f
ÏîÄ¿´úÂë/client/src/views/tts/TheCurrentJob/Startjob.vue
@@ -1,7 +1,7 @@
<template>
  <div class="Startjob">
    <div class="rect">
      <div class="rect-top" style="position: relative">
    <div class="rect" style="position: relative">
      <div class="rect-top">
        <img src="@/assets/TheCurrentJob/left.png" alt="" />
        <img
          style="margin-left: -1.5rem; margin-right: 4rem"
@@ -111,6 +111,7 @@
                  >任务详情:</span
                >
                <span
                  ref="spanHide1"
                  @click="showDetail(!contentShow1)"
                  style="color: #1ac2f7; font-size: 0.88rem; cursor: pointer"
                  >查看</span
@@ -125,6 +126,7 @@
                  "
                >
                  <el-table
                    empty-text="暂无数据"
                    :data="taskData"
                    width="100%"
                    :header-cell-style="{
@@ -169,64 +171,135 @@
              >
            </span>
          </div>
          <div style="position: absolute; width: 47rem; height: 2.5rem">
          <div style="width: 62rem; height: 2.5rem">
            <el-table
              style="margin-top: 0.88rem"
              empty-text="暂无数据"
              style="margin-top: 0.88rem; opacity: 0.8"
              :data="gridData"
              width="100%"
              :header-cell-style="{
                height: '1.61rem',
                color: '#1AC8FE',
                background: '#0A5B91',
                color: '#fff',
                fontSize: '0.88rem',
                border: 'solid 1px #1ac2f7',
              }"
              :cell-style="{
                color: '#fff',
                background: '#147BAF',
              }"
            >
              <el-table-column
                property="craftsStep"
                label="工艺项点/步骤"
                min-width="30%"
                min-width="13%"
              >
                <template #default="scope">
                  <span
                    @click="showDetail1(!contentShow)"
                    style="
                      color: #1ac2f7;
                      font-size: 0.88rem;
                      cursor: pointer;
                      text-decoration: underline;
                    "
                    >{{ scope.row.craftsStep }}
                  </span></template
                ></el-table-column
              >
                  <el-tooltip placement="bottom" effect="light">
                    <template #content>
                      <span style="display: block; width: 15rem">{{
                        scope.row.craftsStep
                      }}</span>
                    </template>
                    <span
                      @click="true"
                      style="
                        color: #ffffff;
                        font-size: 0.88rem;
                        display: -webkit-box; /* è®¾ç½®ä¸ºWebKit内核的弹性盒子模型 */
                        -webkit-box-orient: vertical; /* åž‚直排列 */
                        -webkit-line-clamp: 1; /* é™åˆ¶æ˜¾ç¤ºä¸¤è¡Œ */
                        overflow: hidden; /* éšè—è¶…出范围的内容 */
                        text-overflow: ellipsis; /* ä½¿ç”¨çœç•¥å· */
                      "
                      >{{ scope.row.craftsStep }}</span
                    >
                  </el-tooltip>
                </template>
              </el-table-column>
              <el-table-column
                property="craftContent"
                label="工艺内容"
                min-width="70%"
                min-width="40%"
              >
                <template #default="scope">
                  <span
                    @click="true"
                    style="
                      color: #ffffff;
                      font-size: 0.88rem;
                      display: -webkit-box; /* è®¾ç½®ä¸ºWebKit内核的弹性盒子模型 */
                      -webkit-box-orient: vertical; /* åž‚直排列 */
                      -webkit-line-clamp: 2; /* é™åˆ¶æ˜¾ç¤ºä¸¤è¡Œ */
                      overflow: hidden; /* éšè—è¶…出范围的内容 */
                      text-overflow: ellipsis; /* ä½¿ç”¨çœç•¥å· */
                    "
                    >{{ scope.row.craftContent }}</span
                  ></template
                ></el-table-column
                  <el-tooltip placement="bottom" effect="light">
                    <template #content>
                      <span style="display: block; width: 15rem">{{
                        scope.row.craftContent
                      }}</span>
                    </template>
                    <span
                      @click="true"
                      style="
                        color: #ffffff;
                        font-size: 0.88rem;
                        display: -webkit-box; /* è®¾ç½®ä¸ºWebKit内核的弹性盒子模型 */
                        -webkit-box-orient: vertical; /* åž‚直排列 */
                        -webkit-line-clamp: 2; /* é™åˆ¶æ˜¾ç¤ºä¸¤è¡Œ */
                        overflow: hidden; /* éšè—è¶…出范围的内容 */
                        text-overflow: ellipsis; /* ä½¿ç”¨çœç•¥å· */
                      "
                      >{{ scope.row.craftContent }}</span
                    >
                  </el-tooltip>
                </template></el-table-column
              >
              <el-table-column property="tools" label="工具" min-width="12%">
                <template #default="scope">
                  <el-tooltip placement="bottom" effect="light">
                    <template #content>
                      <span style="display: block; width: 15rem">{{
                        scope.row.tools
                      }}</span>
                    </template>
                    <span
                      @click="true"
                      style="
                        color: #ffffff;
                        font-size: 0.88rem;
                        display: -webkit-box; /* è®¾ç½®ä¸ºWebKit内核的弹性盒子模型 */
                        -webkit-box-orient: vertical; /* åž‚直排列 */
                        -webkit-line-clamp: 2; /* é™åˆ¶æ˜¾ç¤ºä¸¤è¡Œ */
                        overflow: hidden; /* éšè—è¶…出范围的内容 */
                        text-overflow: ellipsis; /* ä½¿ç”¨çœç•¥å· */
                      "
                      >{{ scope.row.tools }}</span
                    >
                  </el-tooltip>
                </template></el-table-column
              >
              <el-table-column
                property="craftsStep"
                label="物料"
                min-width="15%"
              >
                <template #default="scope">
                  <el-tooltip placement="bottom" effect="light">
                    <template #content>
                      <span style="display: block; width: 15rem">{{
                        scope.row.material
                      }}</span>
                    </template>
                    <span
                      @click="true"
                      style="
                        color: #ffffff;
                        font-size: 0.88rem;
                        display: -webkit-box; /* è®¾ç½®ä¸ºWebKit内核的弹性盒子模型 */
                        -webkit-box-orient: vertical; /* åž‚直排列 */
                        -webkit-line-clamp: 2; /* é™åˆ¶æ˜¾ç¤ºä¸¤è¡Œ */
                        overflow: hidden; /* éšè—è¶…出范围的内容 */
                        text-overflow: ellipsis; /* ä½¿ç”¨çœç•¥å· */
                      "
                      >{{ scope.row.material }}</span
                    >
                  </el-tooltip>
                </template></el-table-column
              >
            </el-table>
            <div class="consten" v-if="contentShow">
            <!-- <div class="consten" v-show="contentShow">
              <el-table
                empty-text="暂无数据"
                :data="gridData"
                width="100%"
                :header-cell-style="{
@@ -274,30 +347,30 @@
                  ></el-table-column
                >
              </el-table>
            </div>
            </div> -->
          </div>
        </div>
        <div class="rect-item3">
          <div style="overflow: hidden">
        <div class="rect-item3" style="position: relative">
          <div style="overflow: hidden; padding-bottom: 1rem">
            <img src="@/assets/TheCurrentJob/icon/icon.png" alt="" />
            <span style="color: rgba(26, 201, 255, 1); font-size: 0.88rem"
              >力矩值显示</span
            >
            <el-scrollbar>
            <el-scrollbar ref="scrollbarRef" height="130rpx">
              <div
                ref="innerRef"
                style="
                  display: flex;
                  justify-content: center;
                  flex-direction: column;
                  padding-left: 1.5rem;
                  padding-top: 0.5rem;
                  padding-bottom: 1.5rem;
                  padding-bottom: 1rem;
                  box-sizing: border-box;
                "
              >
                <span
                  style="color: #ffffff; font-size: 1rem; margin: 0.5rem 0"
                  style="color: #ffffff; font-size: 1rem; margin: 0.4rem 0"
                  v-for="(item, index) in Torque"
                  :key="item.id"
                  >{{
@@ -305,7 +378,48 @@
                  }}</span
                >
              </div>
              <el-input
                type="number"
                v-if="isTorque"
                v-model="torqueFrom.torqueSize"
                style="font-size: 0.75rem; height: 2rem"
                placeholder="请输入扭力值"
                ><template #suffix>
                  <span style="font-size: 0.88rem; color: black">N*m</span>
                </template>
              </el-input>
              <!-- @blur="addTorque" -->
            </el-scrollbar>
          </div>
          <div
            style="
              position: absolute;
              bottom: -2.3rem;
              left: -0.1rem;
              width: 100%;
            "
          >
            <el-button
              v-if="!isTorque"
              type="primary"
              style="font-size: 0.75rem; width: 100%; height: 2rem"
              @click="showTorque"
              >手动模拟扭力值</el-button
            >
            <div v-else style="display: flex; justify-content: space-between">
              <el-button
                type="primary"
                style="font-size: 0.75rem; width: 100%; height: 2rem"
                @click="addTorque"
                >确认</el-button
              >
              <el-button
                type="primary"
                style="font-size: 0.75rem; width: 100%; height: 2rem"
                @click="isTorque = false"
                >取消</el-button
              >
            </div>
          </div>
        </div>
      </div>
@@ -316,13 +430,14 @@
          display: flex;
          justify-content: center;
          align-items: center;
          z-index: 999;
          position: absolute;
          top: 42%;
          left: 15%;
        "
      >
        <model-gltf
        <div
          ref="container"
          class="my-three"
          style="width: 100%; height: 100%"
        ></div>
        <!-- <model-gltf
          :width="400"
          :height="400"
          :backgroundAlpha="0"
@@ -331,14 +446,23 @@
          :controlsOptions="{
            enableZoom,
          }"
        />
        /> -->
      </div>
      <div style="position: absolute; bottom: 5%; left: 2%">
        <span style="color: rgba(26, 201, 255, 1); font-size: 1.5em"
          >X:{{ xPos }}&nbsp;&nbsp;Y:{{ yPos }}&nbsp;&nbsp;Z:{{ zPos }}</span
        >
      </div>
      <div
        style="
          display: flex;
          justify-content: center;
          align-items: center;
          margin-top: 30rem;
          position: absolute;
          bottom: 5%;
          right: 0%;
          transform: translateX(-20%);
          z-index: 999;
        "
      >
        <el-button
@@ -359,7 +483,7 @@
        >
        <el-button
          :disabled="obj.setpNum == sunNUm"
          @click="Next(false)"
          @click="DialogVisible = true"
          type="primary"
          :style="{
            width: '5rem',
@@ -394,7 +518,7 @@
    <!-- å¼ºåˆ¶è·³è½¬ç¡®è®¤æ¡† -->
    <el-dialog v-model="centerDialogVisible" title="确认" width="300" center>
      <span> å½“前任务未完成,是否强制跳转到下一步? </span>
      <span sty> å½“前任务未完成,是否强制跳转到下一步? </span>
      <template #footer>
        <div class="dialog-footer">
          <el-button style="width: 5rem" @click="centerDialogVisible = false"
@@ -406,10 +530,27 @@
        </div>
      </template>
    </el-dialog>
    <!-- æ˜¯å¦åˆæ ¼æˆ–已完成 -->
    <el-dialog v-model="DialogVisible" title="确认" width="300" center>
      <span style="display: block; text-align: center; font-size: 1.5rem">
        è¯·ç¡®è®¤å½“前步骤已完成且合格
      </span>
      <template #footer>
        <div class="dialog-footer">
          <el-button style="width: 5rem" @click="DialogVisible = false"
            >取消</el-button
          >
          <el-button style="width: 5rem" type="primary" @click="Next(false)">
            ç¡®è®¤
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { ref, onMounted, nextTick, onBeforeUnmount } from "vue";
import {
  GetScreenData,
  GetPre,
@@ -417,16 +558,25 @@
  Complete,
  GetTorque,
  ChangeStatus,
  AddTorque, //添加扭力值接口
} from "@/api/newapi/Thecurrentjob";
import { GetPageData } from "@/api/newapi/NjTask";
import { useRouter } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus";
import { ModelCollada, ModelGltf } from "vue-3d-model";
import { formatTime } from "@/utils/index.js";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; //gltf
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
const container = ref(null);
const router = useRouter();
const gridData = ref([]);
const contentShow = ref(false);
const contentShow1 = ref(false);
const DialogVisible = ref(false);
const info = ref({});
info.value = history.state?.info ? JSON.parse(history.state?.info) : {};
const title = ref("");
@@ -437,7 +587,7 @@
const Torque = ref("");
const showDetail1 = (va1) => {
  contentShow1.value = false;
  contentShow.value = va1;
  contentShow.value = true;
};
const showDetail = (va1) => {
  contentShow1.value = va1;
@@ -451,17 +601,60 @@
  takeid: "",
  setnum: 0,
});
const client = ref(null);
//扭力值
const torqueFrom = ref({
  creater: JSON.parse(localStorage.getItem("user")).userName, //当前登陆人
  createDate: formatTime(new Date()), //当前时间
  modifier: JSON.parse(localStorage.getItem("user")).userName,
  modifyDate: formatTime(new Date()),
  id: 0,
  deviceCode: "", //设备编号
  takeId: "", //任务id
  groupOp: "", //班组
  processSte: 0, //当前步骤
  torqueSize: null, //输入的扭力值
});
const isTorque = ref(false);
const flag = ref(false);
const innerRef = ref();
const scrollbarRef = ref();
const isJob = ref([]); //已经完成的步骤
//上一步
const Previous = (val) => {
  //上一个的值
  from.value.group = info.value.grouptype;
  from.value.takeid = info.value.njtakeid;
  from.value.setnum = obj.value.setpNum;
  flag.value = val;
  console.log(from.value, info.value);
  GetPre(from.value, flag.value).then((res) => {
    gridData.value = [res.data.nex];
    obj.value = res.data.nex;
    xPos.value =
      gridData.value[0].pointAxisXYZ != null &&
      gridData.value[0].pointAxisXYZ != 0
        ? gridData.value[0].pointAxisXYZ.split(",")[0]
        : -585;
    yPos.value =
      gridData.value[0].pointAxisXYZ != null &&
      gridData.value[0].pointAxisXYZ != 0
        ? gridData.value[0].pointAxisXYZ.split(",")[1]
        : 692;
    zPos.value =
      gridData.value[0].pointAxisXYZ != null &&
      gridData.value[0].pointAxisXYZ != 0
        ? gridData.value[0].pointAxisXYZ.split(",")[2]
        : 692;
    isJob.value = nodeList.slice(0, gridData.value[0].setpNum - 1); //已经完成的步骤
    cameraAnimate(
      [xPos.value, yPos.value, zPos.value],
      gridData.value[0].moduleName
    );
    queryData.value.setnum = obj.value.setpNum;
    GetTorque(queryData.value).then((res) => {
      Torque.value = res.data;
@@ -470,26 +663,47 @@
};
//下一步
const Next = (val) => {
  console.log(obj.value);
  from.value.group = info.value.grouptype;
  from.value.takeid = info.value.njtakeid;
  from.value.setnum = obj.value.setpNum;
  flag.value = val;
  GetNext(from.value, flag.value).then((res) => {
    if (res.message == "没有完成当前步骤") {
      gridData.value = res.data.nowdate;
      obj.value = res.data.nowdate[0];
      if (res.data.nowdate[0].setpNum == obj.value.setpNum) {
        centerDialogVisible.value = true;
        DialogVisible.value = false;
        return;
      }
      return;
    }
    centerDialogVisible.value = false;
    DialogVisible.value = false;
    gridData.value = [res.data.nex];
    xPos.value =
      gridData.value[0].pointAxisXYZ != null &&
      gridData.value[0].pointAxisXYZ != 0
        ? gridData.value[0].pointAxisXYZ.split(",")[0]
        : -585;
    yPos.value =
      gridData.value[0].pointAxisXYZ != null &&
      gridData.value[0].pointAxisXYZ != 0
        ? gridData.value[0].pointAxisXYZ.split(",")[1]
        : 692;
    zPos.value =
      gridData.value[0].pointAxisXYZ != null &&
      gridData.value[0].pointAxisXYZ != 0
        ? gridData.value[0].pointAxisXYZ.split(",")[2]
        : 692;
    isJob.value = res.data.finish.map((item) => {
      return item.moduleName;
    });
    cameraAnimate(
      [xPos.value, yPos.value, zPos.value],
      gridData.value[0].moduleName
    );
    obj.value = res.data.nex;
    queryData.value.setnum = obj.value.setpNum;
    GetTorque(queryData.value).then((res) => {
      Torque.value = res.data;
@@ -501,7 +715,6 @@
  from.value.gruops = info.value.grouptype;
  from.value.id = info.value.njtakeid;
  from.value.creater = info.value.creater;
  console.log(from.value, info.value);
  ChangeStatus(from.value).then((res) => {
    ElMessage({
@@ -513,7 +726,6 @@
};
//查看数据
const checko = () => {
  console.log(info.value);
  GetPageData({
    page: 1,
    rows: 10,
@@ -532,7 +744,6 @@
      },
    ],
  }).then((res) => {
    console.log(res);
    taskData.value = res.rows;
  });
};
@@ -541,33 +752,503 @@
  takeid: info.value.njtakeid,
  setnum: "",
});
const initData = () => {
  GetScreenData({
const initData = async () => {
  await GetScreenData({
    group: info.value.grouptype,
    takeid: info.value.njtakeid,
  }).then((res) => {
    if (res.message == "返回工艺表中的第一条") {
      gridData.value = res.data.proNoe;
      obj.value = res.data.proNoe[0];
      sunNUm.value = res.data.maxproce;
      queryData.value.setnum = obj.value.setpNum;
      GetTorque(queryData.value).then((res) => {
        Torque.value = res.data;
      });
      return;
    }
    gridData.value = res.data.maxpro;
    gridData.value = [res.data.proNow];
    sunNUm.value = res.data.maxproce;
    obj.value = res.data.maxpro[0];
    obj.value = res.data.proNow;
    queryData.value.setnum = obj.value.setpNum;
    xPos.value =
      gridData.value[0].pointAxisXYZ != null &&
      gridData.value[0].pointAxisXYZ != 0
        ? gridData.value[0].pointAxisXYZ.split(",")[0]
        : -585;
    yPos.value =
      gridData.value[0].pointAxisXYZ != null &&
      gridData.value[0].pointAxisXYZ != 0
        ? gridData.value[0].pointAxisXYZ.split(",")[1]
        : 692;
    zPos.value =
      gridData.value[0].pointAxisXYZ != null &&
      gridData.value[0].pointAxisXYZ != 0
        ? gridData.value[0].pointAxisXYZ.split(",")[2]
        : 692;
    isJob.value = res.data.finish;
    cameraAnimate(
      [xPos.value, yPos.value, zPos.value],
      gridData.value[0].moduleName
    );
    GetTorque(queryData.value).then((res) => {
      Torque.value = res.data;
    });
  });
};
const CAMERA_POS = [100, 100, 150];
const BASE_COLOR = [0.2, 0.4, 0.6];
const RED_COLOR = [3.0, 0.2, 0.4];
const GREEN_COLOR = [0.0, 1.0, 0.0];
const xPos = ref("");
const yPos = ref("");
const zPos = ref("");
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  3000
);
const renderer = new THREE.WebGLRenderer({
  antialias: true,
  alpha: true,
  precision: "highp",
});
const painting = (part) => {
  let newArr = [];
  // let newArr = flatten(isJob.value);
  scene.traverse(function (child) {
    // æ£€æŸ¥å¯¹è±¡æ˜¯å¦å…·æœ‰æè´¨å±žæ€§
    if (child.isMesh) {
      let materials = child.material;
      // å¦‚果材质是单个对象而不是数组,则将其放入数组中以便统一处理
      if (!Array.isArray(materials)) {
        materials = [materials];
      }
      let isString = []; // åˆ¤æ–­æ˜¯å¦æ˜¯å­—符串
      // éåŽ†æè´¨æ•°ç»„å¹¶è®¾ç½®é¢œè‰²
      //已经完成的节点
      isJob.value.forEach((item) => {
        if (
          item ==
            "抗蛇行减振器螺栓1,抗蛇行减振器螺栓2,抗蛇行减振器螺栓3,抗蛇行减振器螺栓4" &&
          item != part
        ) {
          isString = item.split(",");
          materials.forEach(function (material) {
            if (isString.includes(material.name)) {
              material.color.setRGB(...GREEN_COLOR);
            }
            material.needsUpdate = true; // å¼ºåˆ¶æ›´æ–°æè´¨
          });
        }
        materials.forEach(function (material) {
          if (material.name === item) {
            material.color.setRGB(...GREEN_COLOR);
          }
          material.needsUpdate = true; // å¼ºåˆ¶æ›´æ–°æè´¨
        });
      });
      if (
        part ==
        "抗蛇行减振器螺栓1,抗蛇行减振器螺栓2,抗蛇行减振器螺栓3,抗蛇行减振器螺栓4"
      ) {
        materials.forEach(function (material) {
          if (part.split(",").includes(material.name)) {
            material.color.setRGB(...RED_COLOR);
          }
          material.needsUpdate = true; // å¼ºåˆ¶æ›´æ–°æè´¨
        });
      } else {
        materials.forEach(function (material) {
          if (material.name == part) {
            material.color.setRGB(...RED_COLOR);
          }
          material.needsUpdate = true; // å¼ºåˆ¶æ›´æ–°æè´¨
        });
      }
      // if (
      //   typeof part ==
      //   "抗蛇行减振器螺栓1,抗蛇行减振器螺栓2,抗蛇行减振器螺栓3,抗蛇行减振器螺栓4"
      // ) {
      //   newArr = part.split(",");
      //   materials.forEach(function (material) {
      //     if (newArr.includes(material.name)) {
      //       material.color.setRGB(...GREEN_COLOR);
      //     }
      //     if (part.includes(material.name)) {
      //       material.color.setRGB(...RED_COLOR);
      //     } else {
      //       material.color.setRGB(...BASE_COLOR);
      //     }
      //     material.needsUpdate = true; // å¼ºåˆ¶æ›´æ–°æè´¨
      //   });
      // } else {
      //   materials.forEach(function (material) {
      //     if (newArr.includes(material.name)) {
      //       material.color.setRGB(...GREEN_COLOR);
      //     } else if (material.name === part) {
      //       material.color.setRGB(...RED_COLOR);
      //     } else {
      //       material.color.setRGB(...BASE_COLOR);
      //     }
      //     // if (newArr.includes(material.name)) {
      //     //   material.color.setRGB(...GREEN_COLOR);
      //     // }
      //     material.needsUpdate = true; // å¼ºåˆ¶æ›´æ–°æè´¨
      //   });
      // }
    }
  });
};
const cameraAnimate = (
  targetPosition = CAMERA_POS,
  part = null,
  duration = 500
) => {
  let startTime = null;
  const startPosition = {
    x: camera.position.x,
    y: camera.position.y,
    z: camera.position.z,
  };
  const distance = {
    x: targetPosition[0] - startPosition.x,
    y: targetPosition[1] - startPosition.y,
    z: targetPosition[2] - startPosition.z,
  };
  function animate(time) {
    if (!startTime) startTime = time;
    const elapsed = time - startTime;
    const progress = Math.min(elapsed / duration, 1);
    // ä½¿ç”¨çº¿æ€§æ’值计算新的位置
    camera.position.x = startPosition.x + distance.x * progress;
    camera.position.y = startPosition.y + distance.y * progress;
    camera.position.z = startPosition.z + distance.z * progress;
    xPos.value = Math.floor(camera.position.x);
    yPos.value = Math.floor(camera.position.y);
    zPos.value = Math.floor(camera.position.z);
    if (progress < 1) {
      requestAnimationFrame(animate);
    }
  }
  requestAnimationFrame(animate);
  painting(part);
  renderer.render(scene, camera); // å¼ºåˆ¶æ¸²æŸ“一次
};
const flatten = (arr) => {
  return arr.reduce(
    (acc, val) =>
      Array.isArray(val) ? acc.concat(flatten(val)) : acc.concat(val),
    []
  );
};
// window.addEventListener("resize", () => {
//   // console.log("初始化场景", window.innerWidth, window.innerHeight);
//   // camera.aspect = window.innerWidth / window.innerHeight;
//   // camera.updateProjectionMatrix();
//   // renderer.setSize(window.innerWidth, window.innerHeight);
// });
const nodeList = [
  "转向架",
  "抗蛇行减振器螺栓1,抗蛇行减振器螺栓2,抗蛇行减振器螺栓3,抗蛇行减振器螺栓4",
  "抗蛇行减振器螺栓1,抗蛇行减振器螺栓2,抗蛇行减振器螺栓3,抗蛇行减振器螺栓4",
  "抗蛇行减振器螺栓2",
  "抗蛇行减振器螺栓3",
  "抗蛇行减振器螺栓4",
  "抗蛇行减振器螺栓1,抗蛇行减振器螺栓2,抗蛇行减振器螺栓3,抗蛇行减振器螺栓4",
  "抗蛇行减振器螺栓2",
  "抗蛇行减振器螺栓3",
  "抗蛇行减振器螺栓4",
  "高度调整杆",
  "高度调整杆",
  "高度调整杆",
  "转向架",
  "转向架",
  "转向架",
  "转向架",
  "转向架",
  "转向架",
  "转向架",
  "抗蛇行减振器螺栓1,抗蛇行减振器螺栓2,抗蛇行减振器螺栓3,抗蛇行减振器螺栓4",
  "抗蛇行减振器螺栓2",
  "抗蛇行减振器螺栓3",
  "抗蛇行减振器螺栓4",
  "抗蛇行减振器螺栓1,抗蛇行减振器螺栓2,抗蛇行减振器螺栓3,抗蛇行减振器螺栓4",
  "抗蛇行减振器螺栓1,抗蛇行减振器螺栓2,抗蛇行减振器螺栓3,抗蛇行减振器螺栓4",
  "高度调整杆",
  "高度调整杆",
  "高度调整杆",
  "转向架",
  "转向架",
  "转向架",
  "转向架",
  "转向架",
  "转向架",
  "转向架",
  "转向架",
];
const spanHide = ref();
const spanHide1 = ref();
const handleClickOutside = () => {
  if (spanHide.value && !spanHide.value.contains(event.target)) {
    contentShow.value = false;
  }
  if (spanHide1.value && !spanHide1.value.contains(event.target)) {
    contentShow1.value = false;
  }
};
const showTorque = () => {
  isTorque.value = true;
  nextTick(() => {
    if (innerRef.value.clientHeight > 150) {
      scrollbarRef.value.setScrollTop(innerRef.value.clientHeight);
    }
  });
};
//添加扭力值
const addTorque = () => {
  torqueFrom.value.processSte = queryData.value.setnum;
  torqueFrom.value.takeId = queryData.value.takeid;
  torqueFrom.value.groupOp = queryData.value.grop;
  if (
    torqueFrom.value.torqueSize == null ||
    torqueFrom.value.torqueSize == "" ||
    torqueFrom.value.torqueSize == 0
  ) {
    ElMessage({
      message: "请输入力矩值",
      type: "warning",
    });
    return;
  }
  AddTorque(torqueFrom.value)
    .then((res) => {
      if (res.code == 400) {
        ElMessage({
          message: res.message,
          type: "warning",
        });
        return;
      }
      ElMessage({
        message: "添加成功",
        type: "success",
      });
      isTorque.value = false;
      initData();
    })
    .catch((error) => {
      console.error("添加失败", error);
    });
};
const timer = ref(null);
const createSocket = (url) => {
  clearInterval(timer.value);
  // åˆ›å»ºWebSocket连接
  //"ws://127.0.0.1:9295/admin"
  client.value = new WebSocket("ws://115.159.85.185:5173/");
  client.value.onopen = function () {
    console.log("WebSocket è¿žæŽ¥æˆåŠŸ");
  };
  client.value.onmessage = function (event) {
    let data = JSON.parse(event.data);
    (gridData.value = [data.process.proNow].map((item) => {
      return {
        articleOne: item.ArticleOne,
        articleOneid: item.ArticleOneid,
        articleTowid: item.ArticleTowid,
        articleTwo: item.ArticleTwo,
        craftContent: item.CraftContent,
        craftID: item.CraftID,
        craftType: item.CraftType,
        craftsStep: item.CraftsStep,
        createDate: item.CreateDate,
        creater: item.Creater,
        material: item.Material,
        modifier: item.Modifier,
        modifyDate: item.ModifyDate,
        moduleName: item.ModuleName,
        nodal: item.Nodal,
        pointAxisHPB: item.PointAxisHPB,
        pointAxisXYZ: item.PointAxisXYZ,
        setpNum: item.SetpNum,
        tools: item.Tools,
        torqueOne: item.TorqueOne,
        torqueOneQuantity: item.TorqueOneQuantity,
        torqueSum: item.TorqueSum,
        torqueTwo: item.TorqueTwo,
        torqueTwoQuantity: item.TorqueTwoQuantity,
      };
    })),
      (sunNUm.value = data.process.maxproce);
    obj.value = [data.process.proNow].map((item) => {
      return {
        articleOne: item.ArticleOne,
        articleOneid: item.ArticleOneid,
        articleTowid: item.ArticleTowid,
        articleTwo: item.ArticleTwo,
        craftContent: item.CraftContent,
        craftID: item.CraftID,
        craftType: item.CraftType,
        craftsStep: item.CraftsStep,
        createDate: item.CreateDate,
        creater: item.Creater,
        material: item.Material,
        modifier: item.Modifier,
        modifyDate: item.ModifyDate,
        moduleName: item.ModuleName,
        nodal: item.Nodal,
        pointAxisHPB: item.PointAxisHPB,
        pointAxisXYZ: item.PointAxisXYZ,
        setpNum: item.SetpNum,
        tools: item.Tools,
        torqueOne: item.TorqueOne,
        torqueOneQuantity: item.TorqueOneQuantity,
        torqueSum: item.TorqueSum,
        torqueTwo: item.TorqueTwo,
        torqueTwoQuantity: item.TorqueTwoQuantity,
      };
    })[0];
    Torque.value = data.operation.map((item) => {
      return {
        createDate: item.CreateDate,
        creater: item.Creater,
        deviceCode: item.SystemDeviceCode,
        groupOp: item.GroupOp,
        id: item.ID,
        modifier: item.Modifier,
        modifyDate: item.ModifyDate,
        processSte: item.ProcessSte,
        takeId: item.TakeId,
        torqueSize: item.TorqueSize,
      };
    });
    xPos.value =
      gridData.value[0].pointAxisXYZ != null &&
      gridData.value[0].pointAxisXYZ != 0
        ? gridData.value[0].pointAxisXYZ.split(",")[0]
        : -585;
    yPos.value =
      gridData.value[0].pointAxisXYZ != null &&
      gridData.value[0].pointAxisXYZ != 0
        ? gridData.value[0].pointAxisXYZ.split(",")[1]
        : 692;
    zPos.value =
      gridData.value[0].pointAxisXYZ != null &&
      gridData.value[0].pointAxisXYZ != 0
        ? gridData.value[0].pointAxisXYZ.split(",")[2]
        : 692;
    isJob.value = data.process.finish.map((item) => {
      return item.moduleName;
    });
    cameraAnimate(
      [xPos.value, yPos.value, zPos.value],
      gridData.value[0].moduleName
    );
    console.log(
      "WebSocket æŽ¥æ”¶åˆ°æ¶ˆæ¯",
      data,
      gridData.value,
      sunNUm.value,
      Torque.value,
      isJob.value
    );
  };
  client.value.onclose = function () {
    console.log("WebSocket è¿žæŽ¥å…³é—­");
    timer.value = setTimeout(createSocket, 1000);
  };
  client.value.onerror = function () {};
};
onMounted(() => {
  console.log("mounted", window.innerWidth, window.innerHeight);
  // åˆå§‹åŒ–场景
  renderer.setSize(window.innerWidth - 20, window.innerHeight - 100);
  renderer.setClearColor(0xeeeeee); // è®¾ç½®èƒŒæ™¯è‰²
  // å¯ç”¨ç‰©ç†æ¸²æŸ“模式
  // renderer.physicallyCorrectLights = true;
  // renderer.toneMapping = THREE.ACESFilmicToneMapping;
  const mainTag = document.querySelector(".my-three");
  mainTag.appendChild(renderer.domElement);
  // æ·»åŠ äº¤äº’æŽ§åˆ¶å™¨ï¼ˆé¼ æ ‡æ‹–æ‹½ç¼©æ”¾ï¼‰
  const controls = new OrbitControls(camera, renderer.domElement);
  controls.enablePan = false; //禁止右键拖拽
  //相机位置与观察目标点最小值
  controls.minDistance = 600;
  //相机位置与观察目标点最大值
  controls.maxDistance = 1000;
  camera.position.set(...CAMERA_POS);
  controls.update();
  // æ·»åŠ å…‰æºï¼ˆé‡è¦ï¼å¦åˆ™æ¨¡åž‹å¯èƒ½æ˜¾ç¤ºä¸ºå…¨é»‘ï¼‰
  const light = new THREE.DirectionalLight(0xffffff, 3);
  light.position.set(5, 5, 5);
  scene.add(light);
  scene.add(new THREE.AmbientLight(0x404040));
  renderer.setClearAlpha(0);
  renderer.setPixelRatio(window.devicePixelRatio);
  scene.background = null;
  let dracoLoader = new DRACOLoader();
  dracoLoader.setDecoderPath("ThreeModel/draco/");
  dracoLoader.setDecoderConfig({ type: "js" });
  dracoLoader.preload();
  // åŠ è½½GLTF模型
  const loader = new GLTFLoader();
  loader.setDRACOLoader(dracoLoader);
  loader.load(
    "ThreeModel/modelDraco.glb", // æ›¿æ¢ä¸ºä½ çš„.gltf文件路径
    (gltf) => {
      const model = gltf.scene;
      model.scale.set(80, 80, 80);
      scene.add(model);
      // è‡ªåŠ¨å±…ä¸­æ¨¡åž‹ï¼ˆå¯é€‰ï¼‰
      const box = new THREE.Box3().setFromObject(model);
      const center = box.getCenter(new THREE.Vector3());
      model.position.sub(center);
    },
    (xhr) => {
      // åŠ è½½è¿›åº¦å›žè°ƒ
      // console.log(`${(xhr.loaded / xhr.total * 100).toFixed(1)}% loaded`);
    },
    (error) => {
      console.error("加载失败:", error);
    }
  );
  // åŠ¨ç”»å¾ªçŽ¯
  const animate = () => {
    requestAnimationFrame(animate);
    controls.update(); // å¯ç”¨æŽ§åˆ¶å™¨æ—¶éœ€è¦
    renderer.render(scene, camera);
  };
  initData();
  animate();
  mainTag.addEventListener("wheel", () => {
    xPos.value = Math.floor(camera.position.x);
    yPos.value = Math.floor(camera.position.y);
    zPos.value = Math.floor(camera.position.z);
  });
  mainTag.addEventListener("mousemove", () => {
    xPos.value = Math.floor(camera.position.x);
    yPos.value = Math.floor(camera.position.y);
    zPos.value = Math.floor(camera.position.z);
  });
  // };
  document.addEventListener("click", handleClickOutside);
  console.log(window.webConfig);
  createSocket();
  // showModel();
});
onBeforeUnmount(() => {
  clearInterval(timer.value);
});
</script>
<style lang="scss" scoped>
@@ -591,7 +1272,7 @@
  background-size: 0.3rem 2rem, 2rem 0.3rem, 0.3rem 2rem, 2rem 0.3rem;
  padding: 0.2rem;
  box-sizing: border-box;
  background-color: rgba(0, 0, 0, 0.3);
  background-color: rgba(0, 0, 0, 0.1);
  overflow: hidden;
  .rect {
@@ -624,38 +1305,74 @@
    .rect-center {
      display: flex;
      justify-content: space-between;
      width: 170vh;
      justify-content: space-around;
      width: 100%;
      margin: 0 auto;
      padding: 0.8rem 2.15rem;
      box-sizing: border-box;
      position: absolute;
      left: 50%;
      top: 5%;
      transform: translateX(-50%);
      .rect-item1 {
        display: flex;
        flex-direction: column;
        width: 14.31rem;
        width: 16rem;
        height: 15.38rem;
        background-image: url("../../../assets/TheCurrentJob/bg.png");
        background-repeat: no-repeat;
        background-size: 100% 100%;
        padding: 0.28rem 0.28rem;
        // background-image: url("../../../assets/TheCurrentJob/bg.png");
        // background-repeat: no-repeat;
        // background-size: 100% 100%;
        border-radius: 8px;
        background: linear-gradient(
            0deg,
            rgba(0, 0, 0, 0.001),
            rgba(0, 0, 0, 0.001)
          ),
          rgba(0, 0, 0, 0),
          linear-gradient(
            135deg,
            rgba(30, 58, 138, 0.6) -3%,
            rgba(49, 46, 129, 0.6) 99%
          );
        box-sizing: border-box;
        border: 1px solid rgba(96, 165, 250, 0.3);
        box-shadow: 0px 4px 6px -4px rgba(0, 0, 0, 0.1),
          0px 10px 15px -3px rgba(0, 0, 0, 0.1);
        padding: 0.28rem 1.28rem;
        box-sizing: border-box;
      }
      .rect-item2 {
        width: 49.88rem;
        height: 15.38rem;
        border: 0.1rem solid #02cde6;
        width: 65rem;
        height: 14.38rem;
        border-radius: 8px;
        background: linear-gradient(
            0deg,
            rgba(0, 0, 0, 0.001),
            rgba(0, 0, 0, 0.001)
          ),
          rgba(0, 0, 0, 0),
          linear-gradient(
            135deg,
            rgba(30, 58, 138, 0.6) -3%,
            rgba(49, 46, 129, 0.6) 99%
          );
        box-sizing: border-box;
        border: 1px solid rgba(96, 165, 250, 0.3);
        box-shadow: 0px 4px 6px -4px rgba(0, 0, 0, 0.1),
          0px 10px 15px -3px rgba(0, 0, 0, 0.1);
        padding: 0.69rem 1.44rem;
        position: relative;
        .el-table :deep(.el-table__header th) {
          border: solid 1px #1ac0f6;
          // border: solid 1px #1ac0f6;
          color: white;
        }
        .consten {
          position: relative;
          top: 0;
          width: 100%;
          position: absolute;
          top: 10rem;
          z-index: 999;
        }
      }
@@ -665,9 +1382,25 @@
        flex-direction: column;
        width: 11.31rem;
        height: 15.38rem;
        background-image: url("../../../assets/TheCurrentJob/bg.png");
        background-repeat: no-repeat;
        background-size: 100% 100%;
        // background-image: url("../../../assets/TheCurrentJob/bg.png");
        // background-repeat: no-repeat;
        // background-size: 100% 100%;
        border-radius: 8px;
        background: linear-gradient(
            0deg,
            rgba(0, 0, 0, 0.001),
            rgba(0, 0, 0, 0.001)
          ),
          rgba(0, 0, 0, 0),
          linear-gradient(
            135deg,
            rgba(30, 58, 138, 0.6) -3%,
            rgba(49, 46, 129, 0.6) 99%
          );
        box-sizing: border-box;
        border: 1px solid rgba(96, 165, 250, 0.3);
        box-shadow: 0px 4px 6px -4px rgba(0, 0, 0, 0.1),
          0px 10px 15px -3px rgba(0, 0, 0, 0.1);
        padding: 0.28rem 0.28rem;
        box-sizing: border-box;
      }
@@ -687,6 +1420,19 @@
//   border-bottom: solid 1px #1ac2f7;
//   color: white;
// }
.el-table {
  --el-table-border-color: transparent;
  --el-table-border: none;
  --el-table-text-color: #bdbdbe;
  --el-table-header-text-color: #bdbdbe;
  --el-table-row-hover-bg-color: transparent;
  --el-table-current-row-bg-color: transparent;
  --el-table-header-bg-color: transparent;
  --el-table-bg-color: transparent;
  --el-table-tr-bg-color: transparent;
  --el-table-expanded-cell-bg-color: transparent;
}
.el-table :deep(.el-table__row td) {
  border: solid 1px #1ac2f7;
  color: white;
@@ -697,9 +1443,9 @@
  color: #1ac2f7;
}
.el-table :deep(.el-table__body-wrapper) {
  background-color: #1ac2f7;
}
// .el-table :deep(.el-table__body-wrapper) {
//   background-color: #1ac2f7;
// }
:deep(.el-popper) {
  background-color: #ad2525;