فهرست منبع

feature/首页路由跳转优化&&ESPO&&设备记录完成

dy 1 سال پیش
والد
کامیت
ffbc53ba2f

+ 1 - 1
src/api/process/index.ts

@@ -44,7 +44,7 @@ export function checkList() {
   });
 }
 
-// 设备点检操作
+// 设备点检提交
 export function maintenanceCheck(data: any) {
   return request({
     url: "/api/v1/process/equit/maintenanceCheck",

+ 3 - 2
src/api/prosteps/espo.ts

@@ -5,9 +5,10 @@ import request from "@/utils/request";
  *
  * @param data
  */
-export function getImgList(data: any) {
+// 数据获取
+export function esopData(data: any) {
   return request({
-    url: "/api/v1/process/opEsop/page",
+    url: `/api/v1/op/esop/page`,
     method: "post",
     data,
   });

+ 9 - 0
src/api/prosteps/shebeijilu.ts

@@ -17,3 +17,12 @@ export function equitUpdate(data: any) {
     data: data,
   });
 }
+//扫描
+export function queryByCode(data: any) {
+  return request({
+    url: "/api/v1/process/equit/queryByCode",
+    method: "post",
+    data: data,
+  });
+}
+

+ 5 - 30
src/components/PDFView/index.vue

@@ -1,36 +1,11 @@
 <template>
-  <el-button
-    v-if="contentType === 'button'"
-    :type="btnType"
-    :link="isLink"
-    @click="showPdf"
-  >
+  <el-button v-if="contentType === 'button'" :type="btnType" :link="isLink" @click="showPdf">
     {{ btnText }}
   </el-button>
-  <VuePdfEmbed
-    v-else
-    :source="pdfSource"
-    :page="pageNumber"
-    annotation-layer
-    text-layer
-    @click="showPdf"
-  />
-  <el-drawer
-    v-if="needToShowPdf"
-    v-model="visible"
-    :footer="false"
-    :header="false"
-    :show-close="false"
-    destroy-on-close
-    direction="rtl"
-    size="972px"
-  >
-    <VuePdfEmbed
-      :source="pdfSource"
-      :page="showPdfNumber"
-      annotation-layer
-      text-layer
-    />
+  <VuePdfEmbed v-else :source="pdfSource" :page="pageNumber" annotation-layer text-layer @click="showPdf" />
+  <el-drawer v-if="needToShowPdf" v-model="visible" :footer="false" :header="false" :show-close="false" destroy-on-close
+    direction="rtl" size="972px">
+    <VuePdfEmbed :source="pdfSource" :page="showPdfNumber" annotation-layer text-layer />
   </el-drawer>
 </template>
 

+ 98 - 0
src/components/PopScanCode/index.vue

@@ -0,0 +1,98 @@
+<template>
+  <div class="midPopUp" @click="handleClose" v-if="showStatus">
+    <div class="container" @click.stop>
+      <div class="headerTittle">{{ title }}</div>
+      <ScanCodeInput v-model="inputValueC" @keyup.enter="handleSubmit" />
+      <div class="bottomBtn">
+        <el-button class="leftBtn" @click="handleClose">关闭</el-button>
+        <el-button class="rightBtn" @click="handleSubmit" type="primary">确定</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import ScanCodeInput from "@/components/ScanCodeInput/index.vue";
+const props = defineProps({
+  title: {
+    type: String,
+  },
+  showStatus: {
+    type: Boolean,
+    default: false,
+  },
+  inputValue: {
+    type: String,
+  },
+});
+const boxInfoData = ref({});
+provide("boxInfoData", boxInfoData);
+const emits = defineEmits(["submit", "update:showStatus", "update:inputValue"]);
+const handleClose = () => {
+  emits("update:inputValue", "");
+  emits("update:showStatus", false);
+};
+
+const inputValueC = computed({
+  get() {
+    return props.inputValue;
+  },
+  set(val) {
+    emits("update:inputValue", val);
+  },
+});
+const handleSubmit = () => {
+  emits("submit");
+  emits("update:inputValue", "");
+};
+</script>
+
+<style lang="scss" scoped>
+.midPopUp {
+  z-index: 4;
+}
+
+.container {
+  background-color: #f1f3f5;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  height: 300px;
+  padding: 20px 40px;
+}
+
+.infoBox {
+  width: 100%;
+  height: 80px;
+  background-color: white;
+  border-radius: 16px;
+  margin-bottom: $p10;
+}
+
+.bottomBtn {
+  width: 100%;
+  height: 70px;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: $p10 10% 0 10%;
+
+  .leftBtn {
+    height: 55px;
+    width: 45%;
+    border-radius: 16px;
+    font-size: $f20;
+    color: black;
+    background-color: #00000015;
+    border: 0px;
+  }
+
+  .rightBtn {
+    height: 55px;
+    width: 45%;
+    border-radius: 16px;
+    font-size: $f20;
+    color: white;
+  }
+}
+</style>

+ 1 - 1
src/layout/index.vue

@@ -5,7 +5,7 @@
       <router-view>
         <template #default="{ Component, route }">
           <transition enter-active-class="animate__animated animate__fadeIn" mode="out-in">
-            <keep-alive exclude="Process">
+            <keep-alive :include="['ProcessMain', 'ProSteps']">
               <component :is="Component" />
             </keep-alive>
           </transition>

+ 39 - 28
src/views/pro-steps/components/ESOP.vue

@@ -6,19 +6,22 @@
           :preview-src-list="showSrcList" fit="cover" />
       </div> -->
       <div class="imgView">
-        <el-scrollbar>
-          <PDFView :need-to-show-pdf="true" :show-pdf-number="3" :is-link="true"
-            pdf-source="http://192.168.101.4:9000/jgfile/2024/04/20/%E7%AC%AC08%E7%AB%A0_%E8%81%9A%E5%90%88%E5%87%BD%E6%95%B0.pdf" />
+        <el-scrollbar ref="scrollbarRef" class="pdmView">
+          <!-- <PDFView :need-to-show-pdf="true" :show-pdf-number="3" :is-link="true"
+            pdf-source="http://192.168.101.4:9000/jgfile/2024/04/20/%E7%AC%AC08%E7%AB%A0_%E8%81%9A%E5%90%88%E5%87%BD%E6%95%B0.pdf" /> -->
+          <PDFView :need-to-show-pdf="true" :pageNumber="srcList[selectImgIndex]?.showAppointPageNum" :is-link="true"
+            :pdf-source="baseUrl + srcList[selectImgIndex]?.filePath" />
+          <Empty v-if="srcList.length < 1" />
         </el-scrollbar>
       </div>
-      <div class="textBox">
+      <!-- <div class="textBox">
         <el-scrollbar :max-height="scrollbarHeight">
           <div class="title">{{ srcList[selectImgIndex]?.title }}</div>
           <div class="describe">
             {{ srcList[selectImgIndex]?.content }}
           </div>
         </el-scrollbar>
-      </div>
+      </div> -->
     </div>
 
     <div class="footer">
@@ -28,7 +31,7 @@
               ? 'scrollbar-demo-item '
               : 'scrollbar-demo-item unScrollbarItemBorder'
             " v-for="(item, index) in srcList" @click="setImgIndex(index)">
-            <el-image class="bottomImgBox" :src="getImgurl(item.imgUrl)" fit="fill" />
+            <span>{{ item.title }}</span>
           </div>
         </div>
       </el-scrollbar>
@@ -37,48 +40,42 @@
 </template>
 
 <script lang="ts" setup>
-import { getImgList } from "@/api/prosteps/espo";
+import { esopData } from "@/api/prosteps/espo";
 import { useProcessStore } from "@/store";
 import PDFView from "@/components/PDFView/index.vue";
 const store = useProcessStore();
+const baseUrl = import.meta.env.VITE_APP_UPLOAD_URL;
 defineOptions({
   name: "Esop",
 });
-const getImgurl = (item: any) => {
-  let url = import.meta.env.VITE_APP_UPLOAD_URL + item;
-  return url;
-};
 //配置当前div高度
 const scrollbarHeight = ref(0);
+const scrollbarRef = ref(null);
 //选取的图片索引
 const selectImgIndex = ref(0);
-const setImgIndex = (index: number) => (selectImgIndex.value = index);
+const setImgIndex = (index: number) => {
+  selectImgIndex.value = index;
+  toTop();
+};
 const setScrollbarHeight = () => {
   const viewportHeight = window.innerHeight;
   scrollbarHeight.value = viewportHeight - 300;
 };
 const srcList = ref([]);
-const showSrcList = ref([]);
-const setShowSrcList = () => {
-  let array = JSON.parse(JSON.stringify(srcList.value));
-  let resArray = [];
-  array.forEach((item) => {
-    resArray.push(getImgurl(item.imgUrl));
-  });
-  showSrcList.value = resArray;
-};
-const getImgListData = async () => {
-  const { data } = await getImgList({
+const getPdfListData = async () => {
+  const { data } = await esopData({
     operationId: store.odersData.operationId,
     pageNo: 1,
     pageSize: 999,
   });
   srcList.value = data.records;
 };
+const toTop = () => {
+  scrollbarRef.value!.setScrollTop(0);
+};
 onMounted(async () => {
   setScrollbarHeight();
-  await getImgListData();
-  setShowSrcList();
+  await getPdfListData();
 });
 </script>
 
@@ -100,9 +97,13 @@ onMounted(async () => {
     height: calc(100vh - 318px);
     @include flex;
     justify-content: center;
-
     padding: $p10 0;
 
+    .pdmView {
+      width: 100%;
+      padding: $p20;
+    }
+
     .img {
       height: 100%;
       border: 0px solid;
@@ -148,18 +149,28 @@ onMounted(async () => {
       border: 2px solid #0a59f7;
       border-radius: 16px;
       box-sizing: border-box;
+      color: #0a59f7;
+
+      span {
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        padding: 5px;
+      }
 
       .bottomImgBox {
         width: 90px;
         height: 90px;
         border-radius: 16px;
-
+        background-color: white;
         @include flex;
       }
     }
 
     .unScrollbarItemBorder {
-      border: 0px;
+      border: 2px solid black;
+      color: black;
+      background-color: transparent;
     }
   }
 }

+ 42 - 22
src/views/pro-steps/components/shebeijilu.vue

@@ -10,12 +10,8 @@
       </div>
       <!-- 变量控制样式 -->
       <div class="footerBtn">
-        <el-button
-          v-if="!item.equitCode"
-          class="bottomBtn"
-          style="background-color: #0a59f7"
-          >点击扫描设备</el-button
-        >
+        <el-button v-if="!item.equitCode" class="bottomBtn" style="background-color: #0a59f7"
+          @click="openScanCode(index)">点击扫描设备</el-button>
         <div v-else class="infoBox">
           <div class="info">
             <div>
@@ -28,6 +24,7 @@
             </div>
           </div>
           <div class="info">
+            <div></div>
             <div>
               <div class="describeText" style="text-align: right">
                 检定有效期
@@ -40,15 +37,18 @@
         </div>
       </div>
     </div>
+    <PopScanCode v-model:inputValue="inputValueVal" v-model:showStatus="showStatusVal" @submit="scanCode"
+      title="请扫描设备" />
   </div>
 </template>
 
 <script lang="ts" setup>
-import { equitList, equitUpdate } from "@/api/prosteps/shebeijilu";
+import { equitList, equitUpdate, queryByCode } from "@/api/prosteps/shebeijilu";
 import { useProcessStore } from "@/store";
 defineOptions({ name: "Shebeijilu" });
 const store = useProcessStore();
 const equitListData = ref([]);
+const selectIndex = ref(null);
 const getEquitList = async () => {
   const { data } = await equitList({
     seqNo: store.scanInfo.seqNo,
@@ -59,9 +59,27 @@ const getEquitList = async () => {
   });
   equitListData.value = data;
 };
+const inputValueVal = ref("");
+const showStatusVal = ref(false);
 const equitCheck = async () => {
   await equitUpdate({});
 };
+const openScanCode = (index) => {
+  showStatusVal.value = true;
+  selectIndex.value = index;
+};
+const scanCode = async () => {
+  const { data, code } = await queryByCode({
+    deviceNo: inputValueVal.value,
+    recordId: equitListData.value[selectIndex.value].id,
+  });
+  if (code == "200") {
+    ElMessage.success("绑定成功!");
+    equitListData.value[selectIndex.value] = data;
+    inputValueVal.value = "";
+    showStatusVal.value = false;
+  }
+};
 onMounted(() => {
   getEquitList();
 });
@@ -78,11 +96,9 @@ onMounted(() => {
   flex-direction: column;
   justify-content: space-between;
 
-  .headerText {
-  }
+  .headerText {}
 
-  .describeBox {
-  }
+  .describeBox {}
 
   //按钮样式
   .footerBtn {
@@ -98,29 +114,33 @@ onMounted(() => {
       font-size: $f24;
       color: white;
     }
-  }
 
-  //描述样式
-  .footerInfo {
-    width: 100%;
-    height: 70px;
-    background-color: #00000015;
-    border-radius: 16px;
-    overflow: hidden;
+    .footerInfo {
+      width: 100%;
+      height: 70px;
+      background-color: #00000015;
+      border-radius: 16px;
+      overflow: hidden;
+    }
 
     .infoBox {
-      display: flex;
+      display: flex !important;
       align-items: center;
       justify-content: space-between;
+      width: 100%;
       height: 100%;
-      padding: 0 $p10;
+      padding: $p20 $p10;
 
       .info {
-        height: 100%;
+        width: 50%;
+        padding: 0 20px;
         display: flex;
         align-items: center;
+        justify-content: space-between;
       }
     }
   }
+
+  //描述样式
 }
 </style>

+ 33 - 24
src/views/pro-steps/index.vue

@@ -9,17 +9,9 @@
         <div class="typeContainer">
           <el-scrollbar>
             <div style="display: flex">
-              <div
-                v-for="(item, index) in stepComponents"
-                :key="index"
-                class="scrollbar-demo-item"
-              >
+              <div v-for="(item, index) in stepComponents" :key="index" class="scrollbar-demo-item">
                 <router-link :to="{ name: item.name }" replace>
-                  <div
-                    :class="getNameClass(index)"
-                    class="typeBox"
-                    @click="setSelectIndex(index)"
-                  >
+                  <div :class="getNameClass(index)" class="typeBox" @click="setSelectIndex(index)">
                     <div class="svgIcon">
                       <svg-icon :icon-class="item.iconName" size="30" />
                     </div>
@@ -35,8 +27,7 @@
           <el-scrollbar>
             <router-view v-slot="{ Component, route }">
               <keep-alive
-                include="Dianjian,Jiluxiang,Duomeiticaiji,Esop,Jingu,Mingpaibangding,Shebeijilu,Tiaoshipipei,Wuliaocaiji"
-              >
+                include="Dianjian,Jiluxiang,Duomeiticaiji,Esop,Jingu,Mingpaibangding,Shebeijilu,Tiaoshipipei,Wuliaocaiji">
                 <component :is="Component" :key="route.fullPath" />
               </keep-alive>
             </router-view>
@@ -58,7 +49,8 @@ defineOptions({ name: "ProSteps" });
 const route = useRoute();
 const router = useRouter();
 const loading = ref(false);
-
+const recondOPId = ref(null);
+const qrCode = ref(null);
 //配置标签信息Data
 const stepComponents = ref([]);
 const defaultComponents = [
@@ -140,24 +132,41 @@ const getOpCompentArray = async () => {
   const { data } = await getOpCompent(
     "/" + `${store.odersData.operationId}` + "/" + `${store.scanInfo.id}`
   );
+  recondOPId.value = store.odersData.operationId;
+  qrCode.value = store.odersData.qrCode;
   stepComponents.value = setStepComponents(data);
-  router.replace({ name: stepComponents.value[0].name });
+  router.replace({ name: stepComponents.value[selectIndex.value].name });
 };
 //设置标签是否被选中
 const setSelectIndex = (index) => {
   selectIndex.value = index;
 };
-const setSelectTag = () => {
-  const nowRouteName = route.name;
-  stepComponents.value.forEach((item, index) => {
-    if (item.name == nowRouteName) {
-      setSelectIndex(index);
+// const setSelectTag = () => {
+//   const nowRouteName = route.name;
+//   stepComponents.value.forEach((item, index) => {
+//     if (item.name == nowRouteName) {
+//       setSelectIndex(index);
+//     }
+//   });
+// };
+
+onActivated(async () => {
+  //缓存组件数据逻辑
+  if (recondOPId.value == null || qrCode.value == null) {
+    //相当于首次进入该路由
+    await getOpCompentArray();
+  } else {
+    if (
+      recondOPId.value != store.odersData.operationId ||
+      qrCode.value != store.odersData.qrCode
+    ) {
+      //当发生改变时
+      setSelectIndex(0);
+      await getOpCompentArray();
+    } else {
+      await getOpCompentArray();
     }
-  });
-};
-onMounted(async () => {
-  await getOpCompentArray();
-  setSelectTag();
+  }
 });
 </script>
 

+ 0 - 1
src/views/process/main.vue

@@ -20,7 +20,6 @@ import Orders from "@/views/process/orders.vue";
 import Processes from "@/views/process/processes.vue";
 import CurrentProduction from "@/views/process/currentProduction.vue";
 import CheckPop from "./popUpView/checkPop.vue";
-import { checkList } from "@/api/process";
 defineOptions({ name: "ProcessMain" });
 const checkPop = ref(false);
 //未完成订单数组

+ 131 - 4
src/views/process/popUpView/checkPop.vue

@@ -1,11 +1,138 @@
 <template>
-  <div class="midPopUp" v-if="modelValue">
-    <div class="container" @click.stop></div>
+  <div class="midPopUp" v-if="checkPop">
+    <div class="container" @click.stop>
+      <div class="title titleText" style="font-size: 38px">设备点检项目</div>
+      <div class="title describeText">(需填完后开工)</div>
+      <el-scrollbar class="listBody">
+        <el-form ref="formRef" :model="checkListArray" label-width="aotu">
+          <div class="item" v-for="(item, index) in checkListArray.array" :key="item.key">
+            <el-form-item :label="`${index + 1}.` + item.deviceName + ':'" :rules="{
+              required: true,
+              message: '该选项为必选',
+              trigger: 'change',
+            }" :prop="'array.' + index + '.result'">
+              <!-- <el-form-item
+              label="阿瓦达瓦大瓦大大啊达瓦大爱我的爱我的爱我的阿达阿达阿瓦阿达阿达大大阿达阿瓦阿达瓦滴答滴答滴答滴答滴答滴答的哒哒哒哒哒哒哒哒哒哒哒哒滴答滴答滴答滴答滴答滴答哒哒哒哒哒哒哒哒哒哒哒哒哒哒哒哒哒哒哒哒哒哒哒哒哒哒哒多大"
+              :rules="{
+                required: true,
+                message: '该选项为必选',
+                trigger: 'change',
+              }" :prop="'array.' + index + '.result'"> -->
+              <el-radio-group v-model="item.result">
+                <el-radio :value="0">正常</el-radio>
+                <el-radio :value="1">异常</el-radio>
+              </el-radio-group>
+            </el-form-item>
+            <el-input v-if="item.result == 1" v-model="item.remark" type="textarea" placeholder="请输入异常原因" />
+          </div>
+        </el-form>
+      </el-scrollbar>
+      <div class="btns">
+        <el-button size="large" type="primary" @click="validate" class="titleText">提交
+        </el-button>
+      </div>
+    </div>
   </div>
 </template>
 
 <script lang="ts" setup>
-const modelValue = defineModel<boolean>();
+import { checkList, maintenanceCheck } from "@/api/process";
+//点检项数组
+const checkListArray = reactive({ array: [] });
+const formRef = ref(null);
+const checkPop = ref(false);
+const getCheckList = async () => {
+  const { data } = await checkList();
+  checkListArray.array = data;
+  checkListArray.array.forEach((item, index) => {
+    item.result = null;
+    item.key = index;
+  });
+  if (checkListArray.array.length > 0) {
+    checkPop.value = true;
+  } else {
+    checkPop.value = false;
+  }
+};
+const validate = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      submit();
+    } else {
+      ElMessage.error("请检查是否有未填项");
+    }
+  });
+};
+const submit = async () => {
+  const { data, code } = await maintenanceCheck(checkListArray.array);
+  if (code == "200") {
+    ElMessage.success("提交成功!祝开工顺利");
+    checkPop.value = false;
+  }
+};
+watch(
+  () => checkListArray,
+  () => {
+    if (checkListArray.array.length > 0) {
+      checkPop.value = true;
+    } else {
+      checkPop.value = false;
+    }
+  }
+);
+onMounted(() => {
+  getCheckList();
+});
 </script>
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+.title {
+  width: 100%;
+  height: 50px;
+  text-align: center;
+}
+
+:deep(label) {
+  display: inline-block;
+}
+
+.listBody {
+  height: calc(100% - 160px);
+  padding: 0 $p20;
+
+  .item {
+    width: 100%;
+    background-color: white;
+    border-radius: 16px;
+    margin: 10px 0;
+    padding: $p10 $p20;
+  }
+}
+
+.btns {
+  width: 100%;
+  height: 60px;
+  @include flex;
+}
+
+//表单字体样式
+:deep(.el-form-item__label) {
+  font-size: $f20;
+  max-width: 600px;
+  display: inline-block;
+  height: auto;
+}
+
+:deep(.el-radio__label) {
+  font-size: $f20;
+}
+
+:deep(.el-radio) {
+  display: flex;
+  align-items: center;
+}
+
+:deep(.el-textarea__inner) {
+  font-size: $f20;
+}
+</style>